From ae199f1dc4e468d72992d0bbcf5172d0812285f2 Mon Sep 17 00:00:00 2001 From: Lorenzo Pichilli Date: Thu, 15 Dec 2022 17:43:29 +0100 Subject: [PATCH] Updated window.flutter_inappwebview.callHandler implementation: if there is an error/exception on Flutter/Dart side, the callHandler will reject the JavaScript promise with the error/exception message, so you can catch it also on JavaScript side, Fixed Android Web Storage Manager deleteAllData and deleteOrigin methods implementation, fix #1462, fix #1475 --- CHANGELOG.md | 25 ++ android/build.gradle | 12 +- .../flutter_inappwebview/MyCookieManager.java | 107 ++++-- .../flutter_inappwebview/MyWebStorage.java | 15 +- .../WebViewFeatureManager.java | 2 +- .../CredentialDatabaseHandler.java | 13 +- .../plugin_scripts_js/JavaScriptBridgeJS.java | 4 +- .../proxy/ProxyManager.java | 12 +- .../ServiceWorkerChannelDelegate.java | 18 +- .../service_worker/ServiceWorkerManager.java | 10 +- .../TracingControllerChannelDelegate.java | 1 + .../tracing/TracingControllerManager.java | 9 +- .../webview/JavaScriptBridgeInterface.java | 21 +- .../webview/in_app_webview/InAppWebView.java | 19 +- .../in_app_webview/InAppWebViewSettings.java | 21 +- .../lib/src/exchangeable_enum_generator.dart | 10 +- .../src/exchangeable_object_generator.dart | 127 ++++--- dev_packages/generators/lib/src/util.dart | 4 +- dev_packages/generators/pubspec.lock | 340 +++++++++++------- dev_packages/generators/pubspec.yaml | 10 +- example/android/app/build.gradle | 9 +- .../android/app/src/debug/AndroidManifest.xml | 3 +- .../android/app/src/main/AndroidManifest.xml | 3 +- .../app/src/profile/AndroidManifest.xml | 3 +- example/android/build.gradle | 6 +- example/android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../chrome_safari_browser/open_and_close.dart | 2 +- example/integration_test/constants.dart | 2 +- .../ios/Flutter/flutter_export_environment.sh | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 125 ++++--- example/ios/Runner/Info.plist | 2 + example/lib/generated_plugin_registrant.dart | 19 - .../lib/in_app_browser_example.screen.dart | 1 + example/lib/in_app_webiew_example.screen.dart | 1 + example/lib/main.dart | 2 +- .../Flutter/GeneratedPluginRegistrant.swift | 2 +- example/macos/Podfile | 2 +- .../macos/Runner.xcodeproj/project.pbxproj | 9 +- example/pubspec.yaml | 14 +- ios/Classes/InAppWebView/InAppWebView.swift | 37 +- .../InAppWebView/InAppWebViewSettings.swift | 10 +- .../PluginScriptsJS/JavaScriptBridgeJS.swift | 2 +- .../android/service_worker_controller.dart | 25 -- lib/src/android/webview_feature.dart | 15 +- lib/src/android/webview_feature.g.dart | 13 +- .../chrome_safari_browser_settings.dart | 12 +- .../chrome_safari_browser_settings.g.dart | 5 +- lib/src/in_app_browser/in_app_browser.dart | 1 + .../in_app_browser_settings.dart | 12 +- .../in_app_webview_controller.dart | 7 +- .../in_app_webview_settings.dart | 86 +++-- .../in_app_webview_settings.g.dart | 64 +++- lib/src/main.dart | 1 - .../pull_to_refresh_settings.dart | 4 +- lib/src/types/attributed_string.dart | 20 +- lib/src/types/client_cert_challenge.g.dart | 16 +- lib/src/types/cookie.dart | 73 +++- lib/src/types/cookie.g.dart | 58 ++- lib/src/types/main.dart | 1 - lib/src/types/permission_response.g.dart | 2 +- lib/src/types/requested_with_header_mode.dart | 19 - .../types/requested_with_header_mode.g.dart | 81 ----- lib/src/types/user_script.g.dart | 3 +- lib/src/util.dart | 6 + macos/Classes/InAppWebView/InAppWebView.swift | 30 +- .../InAppWebView/InAppWebViewSettings.swift | 18 +- .../PluginScriptsJS/JavaScriptBridgeJS.swift | 2 +- macos/Classes/Types/WKFrameInfo.swift | 4 +- .../WebAuthenticationSessionManager.swift | 4 +- pubspec.yaml | 4 +- 71 files changed, 983 insertions(+), 644 deletions(-) delete mode 100644 example/lib/generated_plugin_registrant.dart delete mode 100644 lib/src/types/requested_with_header_mode.dart delete mode 100644 lib/src/types/requested_with_header_mode.g.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index e2b6601d8..89344de3b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +## 6.0.0-beta.23 + +- Updated `androidx.webkit:webkit` dependency to `1.6.1` +- Updated `androidx.browser:browser` dependency to `1.5.0` +- Updated `androidx.appcompat:appcompat` dependency to `1.6.1` +- Added support for Android `WebViewFeature.GET_COOKIE_INFO` +- Added `requestedWithHeaderOriginAllowList` WebView setting for Android +- Added `isInspectable`, `shouldPrintBackgrounds` WebView settings for iOS and macOS +- Removed `WebViewFeature.REQUESTED_WITH_HEADER_CONTROL`, `ServiceWorkerController.setRequestedWithHeaderMode()`, `ServiceWorkerController.getRequestedWithHeaderMode()`, `InAppWebViewSettings.requestedWithHeaderMode` +- Fixed "Build fail with AGP 8.0" [#1643](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1643) +- Fixed "java.lang.RuntimeException: Unknown feature REQUESTED_WITH_HEADER_CONTROL" [#1611](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1611) +- Fixed "iOS 16.4 WebDebugging WKWebView.isInspectable" [#1629](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1629) +- Fixed some `@available` checks for macOS + +## 6.0.0-beta.22 + +- Updated `window.flutter_inappwebview.callHandler` implementation: if there is an error/exception on Flutter/Dart side, the `callHandler` will reject the JavaScript promise with the error/exception message, so you can catch it also on JavaScript side +- Fixed Android Web Storage Manager `deleteAllData` and `deleteOrigin` methods implementation +- Fixed "Xiaomi store - Conflict of Privacy Permissions, android.permission.MY_READ_INSTALLED_PACKAGES" [#1462](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1462) +- Fixed "Flutter 3.0.5 compilation issue" [#1475](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1475) + ## 6.0.0-beta.21 - Fixed "Android plugin version 6 - UserScripts not executing on new tabs." [#1455](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1455) @@ -174,6 +195,10 @@ - Removed `URLProtectionSpace.iosIsProxy` property - `historyUrl` and `baseUrl` of `InAppWebViewInitialData` can be `null` +## 5.7.2+3 + +- Fixed "Xiaomi store - Conflict of Privacy Permissions, android.permission.MY_READ_INSTALLED_PACKAGES" [#1462](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1462) + ## 5.7.2+2 - Fixed "Unexpected addWebMessageListener behaviour" [#1422](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1422) diff --git a/android/build.gradle b/android/build.gradle index 91fda8a66..2cfe7d417 100755 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:8.0.1' } } @@ -22,6 +22,10 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { + // Conditional for compatibility with AGP <4.2. + if (project.android.hasProperty("namespace")) { + namespace 'com.pichillilorenzo.flutter_inappwebview' + } compileSdkVersion 33 defaultConfig { @@ -45,9 +49,9 @@ android { } } dependencies { - implementation 'androidx.webkit:webkit:1.5.0' - implementation 'androidx.browser:browser:1.4.0' - implementation 'androidx.appcompat:appcompat:1.5.1' + implementation 'androidx.webkit:webkit:1.6.1' + implementation 'androidx.browser:browser:1.5.0' + implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java index dde98e417..991dba0b6 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java @@ -1,17 +1,24 @@ package com.pichillilorenzo.flutter_inappwebview; import android.os.Build; +import android.util.Log; import android.webkit.CookieManager; import android.webkit.CookieSyncManager; import android.webkit.ValueCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.webkit.CookieManagerCompat; +import androidx.webkit.WebViewFeature; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; +import java.text.DateFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -30,14 +37,21 @@ public class MyCookieManager extends ChannelDelegateImpl { @Nullable public InAppWebViewFlutterPlugin plugin; - public MyCookieManager(final InAppWebViewFlutterPlugin plugin) { + public MyCookieManager(@NonNull final InAppWebViewFlutterPlugin plugin) { super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); this.plugin = plugin; - cookieManager = getCookieManager(); + } + + public static void init() { + if (cookieManager == null) { + cookieManager = getCookieManager(); + } } @Override public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + init(); + switch (call.method) { case "setCookie": { @@ -192,27 +206,78 @@ public List> getCookies(final String url) { cookieManager = getCookieManager(); if (cookieManager == null) return cookieListMap; - String cookiesString = cookieManager.getCookie(url); + List cookies = new ArrayList<>(); + if (WebViewFeature.isFeatureSupported(WebViewFeature.GET_COOKIE_INFO)) { + cookies = CookieManagerCompat.getCookieInfo(cookieManager, url); + } else { + String cookiesString = cookieManager.getCookie(url); + if (cookiesString != null) { + cookies = Arrays.asList(cookiesString.split(";")); + } + } - if (cookiesString != null) { - String[] cookies = cookiesString.split(";"); - for (String cookie : cookies) { - String[] nameValue = cookie.split("=", 2); - String name = nameValue[0].trim(); - String value = (nameValue.length > 1) ? nameValue[1].trim() : ""; - Map cookieMap = new HashMap<>(); - cookieMap.put("name", name); - cookieMap.put("value", value); - cookieMap.put("expiresDate", null); - cookieMap.put("isSessionOnly", null); - cookieMap.put("domain", null); - cookieMap.put("sameSite", null); - cookieMap.put("isSecure", null); - cookieMap.put("isHttpOnly", null); - cookieMap.put("path", null); - - cookieListMap.add(cookieMap); + for (String cookie : cookies) { + String[] cookieParams = cookie.split(";"); + if (cookieParams.length == 0) continue; + + String[] nameValue = cookieParams[0].split("=", 2); + String name = nameValue[0].trim(); + String value = (nameValue.length > 1) ? nameValue[1].trim() : ""; + + Map cookieMap = new HashMap<>(); + cookieMap.put("name", name); + cookieMap.put("value", value); + cookieMap.put("expiresDate", null); + cookieMap.put("isSessionOnly", null); + cookieMap.put("domain", null); + cookieMap.put("sameSite", null); + cookieMap.put("isSecure", null); + cookieMap.put("isHttpOnly", null); + cookieMap.put("path", null); + + if (WebViewFeature.isFeatureSupported(WebViewFeature.GET_COOKIE_INFO)) { + cookieMap.put("isSecure", false); + cookieMap.put("isHttpOnly", false); + + for (int i = 1; i < cookieParams.length; i++) { + String[] cookieParamNameValue = cookieParams[i].split("=", 2); + String cookieParamName = cookieParamNameValue[0].trim(); + String cookieParamValue = (cookieParamNameValue.length > 1) ? cookieParamNameValue[1].trim() : ""; + + if (cookieParamName.equalsIgnoreCase("Expires")) { + try { + final SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss z", Locale.US); + Date expiryDate = sdf.parse(cookieParamValue); + if (expiryDate != null) { + cookieMap.put("expiresDate", expiryDate.getTime()); + } + } catch (ParseException e) { + e.printStackTrace(); + Log.e(LOG_TAG, e.getMessage()); + } + } else if (cookieParamName.equalsIgnoreCase("Max-Age")) { + try { + long maxAge = Long.parseLong(cookieParamValue); + cookieMap.put("expiresDate", System.currentTimeMillis() + maxAge); + } catch (NumberFormatException e) { + e.printStackTrace(); + Log.e(LOG_TAG, e.getMessage()); + } + } else if (cookieParamName.equalsIgnoreCase("Domain")) { + cookieMap.put("domain", cookieParamValue); + } else if (cookieParamName.equalsIgnoreCase("SameSite")) { + cookieMap.put("sameSite", cookieParamValue); + } else if (cookieParamName.equalsIgnoreCase("Secure")) { + cookieMap.put("isSecure", true); + } else if (cookieParamName.equalsIgnoreCase("HttpOnly")) { + cookieMap.put("isHttpOnly", true); + } else if (cookieParamName.equalsIgnoreCase("Path")) { + cookieMap.put("path", cookieParamValue); + } + } } + + cookieListMap.add(cookieMap); } return cookieListMap; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java index b9ff890a6..ad3cc9825 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java @@ -25,20 +25,27 @@ public class MyWebStorage extends ChannelDelegateImpl { @Nullable public InAppWebViewFlutterPlugin plugin; - public MyWebStorage(final InAppWebViewFlutterPlugin plugin) { + public MyWebStorage(@NonNull final InAppWebViewFlutterPlugin plugin) { super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); this.plugin = plugin; - webStorageManager = WebStorage.getInstance(); + } + + public static void init() { + if (webStorageManager == null) { + webStorageManager = WebStorage.getInstance(); + } } @Override public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + init(); + switch (call.method) { case "getOrigins": getOrigins(result); break; case "deleteAllData": - if (webStorageManager == null) { + if (webStorageManager != null) { webStorageManager.deleteAllData(); result.success(true); } else { @@ -47,7 +54,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result break; case "deleteOrigin": { - if (webStorageManager == null) { + if (webStorageManager != null) { String origin = (String) call.argument("origin"); webStorageManager.deleteOrigin(origin); result.success(true); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java index ac38dd941..17f57baf7 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java @@ -16,7 +16,7 @@ public class WebViewFeatureManager extends ChannelDelegateImpl { @Nullable public InAppWebViewFlutterPlugin plugin; - public WebViewFeatureManager(final InAppWebViewFlutterPlugin plugin) { + public WebViewFeatureManager(@NonNull final InAppWebViewFlutterPlugin plugin) { super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); this.plugin = plugin; } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java index bb532a9ed..eb1df65d3 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java @@ -30,14 +30,23 @@ public class CredentialDatabaseHandler extends ChannelDelegateImpl { @Nullable public InAppWebViewFlutterPlugin plugin; - public CredentialDatabaseHandler(final InAppWebViewFlutterPlugin plugin) { + public CredentialDatabaseHandler(@NonNull final InAppWebViewFlutterPlugin plugin) { super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); this.plugin = plugin; - credentialDatabase = CredentialDatabase.getInstance(plugin.applicationContext); + } + + public static void init(@NonNull InAppWebViewFlutterPlugin plugin) { + if (credentialDatabase == null) { + credentialDatabase = CredentialDatabase.getInstance(plugin.applicationContext); + } } @Override public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + if (plugin != null) { + init(plugin); + } + switch (call.method) { case "getAllAuthCredentials": { diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/plugin_scripts_js/JavaScriptBridgeJS.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/plugin_scripts_js/JavaScriptBridgeJS.java index 792e5b1db..cfdf656d2 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/plugin_scripts_js/JavaScriptBridgeJS.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/plugin_scripts_js/JavaScriptBridgeJS.java @@ -220,7 +220,7 @@ public class JavaScriptBridgeJS { " var _callHandlerID = setTimeout(function(){});" + " window." + JAVASCRIPT_BRIDGE_NAME + "._callHandler(arguments[0], _callHandlerID, JSON.stringify(Array.prototype.slice.call(arguments, 1)));" + " return new Promise(function(resolve, reject) {" + - " window." + JAVASCRIPT_BRIDGE_NAME + "[_callHandlerID] = resolve;" + + " window." + JAVASCRIPT_BRIDGE_NAME + "[_callHandlerID] = {resolve: resolve, reject: reject};" + " });" + " };" + " }"+ @@ -230,7 +230,7 @@ public class JavaScriptBridgeJS { " var _callHandlerID = setTimeout(function(){});" + " window.top." + JAVASCRIPT_BRIDGE_NAME + "._callHandler(arguments[0], _callHandlerID, JSON.stringify(Array.prototype.slice.call(arguments, 1)));" + " return new Promise(function(resolve, reject) {" + - " window.top." + JAVASCRIPT_BRIDGE_NAME + "[_callHandlerID] = resolve;" + + " window.top." + JAVASCRIPT_BRIDGE_NAME + "[_callHandlerID] = {resolve: resolve, reject: reject};" + " });" + " };" + "}" + diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/proxy/ProxyManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/proxy/ProxyManager.java index f2b5b07f4..6b3b4a00c 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/proxy/ProxyManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/proxy/ProxyManager.java @@ -25,18 +25,22 @@ public class ProxyManager extends ChannelDelegateImpl { @Nullable public InAppWebViewFlutterPlugin plugin; - public ProxyManager(final InAppWebViewFlutterPlugin plugin) { + public ProxyManager(@NonNull final InAppWebViewFlutterPlugin plugin) { super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); this.plugin = plugin; - if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) { + } + + public static void init() { + if (proxyController == null && + WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) { proxyController = ProxyController.getInstance(); - } else { - proxyController = null; } } @Override public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + init(); + switch (call.method) { case "setProxyOverride": if (proxyController != null) { diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/service_worker/ServiceWorkerChannelDelegate.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/service_worker/ServiceWorkerChannelDelegate.java index 7c6a1b047..9a6ff4792 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/service_worker/ServiceWorkerChannelDelegate.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/service_worker/ServiceWorkerChannelDelegate.java @@ -1,6 +1,5 @@ package com.pichillilorenzo.flutter_inappwebview.service_worker; -import android.annotation.SuppressLint; import android.os.Build; import androidx.annotation.NonNull; @@ -16,7 +15,6 @@ import com.pichillilorenzo.flutter_inappwebview.types.SyncBaseCallbackResultImpl; import com.pichillilorenzo.flutter_inappwebview.types.WebResourceRequestExt; import com.pichillilorenzo.flutter_inappwebview.types.WebResourceResponseExt; -import com.pichillilorenzo.flutter_inappwebview.webview.WebViewChannelDelegate; import java.util.Map; @@ -33,9 +31,9 @@ public ServiceWorkerChannelDelegate(@NonNull ServiceWorkerManager serviceWorkerM this.serviceWorkerManager = serviceWorkerManager; } - @SuppressLint("RestrictedApi") @Override public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + ServiceWorkerManager.init(); ServiceWorkerControllerCompat serviceWorkerController = ServiceWorkerManager.serviceWorkerController; ServiceWorkerWebSettingsCompat serviceWorkerWebSettings = (serviceWorkerController != null) ? serviceWorkerController.getServiceWorkerWebSettings() : null; @@ -71,13 +69,6 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result.success(false); } break; - case "getRequestedWithHeaderMode": - if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.REQUESTED_WITH_HEADER_CONTROL)) { - result.success(serviceWorkerWebSettings.getRequestedWithHeaderMode()); - } else { - result.success(null); - } - break; case "getCacheMode": if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_CACHE_MODE)) { result.success(serviceWorkerWebSettings.getCacheMode()); @@ -113,13 +104,6 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result } result.success(true); break; - case "setRequestedWithHeaderMode": - if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.REQUESTED_WITH_HEADER_CONTROL)) { - Integer mode = (Integer) call.argument("mode"); - serviceWorkerWebSettings.setRequestedWithHeaderMode(mode); - } - result.success(true); - break; default: result.notImplemented(); } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/service_worker/ServiceWorkerManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/service_worker/ServiceWorkerManager.java index b188ab0ee..74a528001 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/service_worker/ServiceWorkerManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/service_worker/ServiceWorkerManager.java @@ -33,14 +33,16 @@ public class ServiceWorkerManager implements Disposable { @Nullable public InAppWebViewFlutterPlugin plugin; - public ServiceWorkerManager(final InAppWebViewFlutterPlugin plugin) { + public ServiceWorkerManager(@NonNull final InAppWebViewFlutterPlugin plugin) { this.plugin = plugin; final MethodChannel channel = new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME); this.channelDelegate = new ServiceWorkerChannelDelegate(this, channel); - if (WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE)) { + } + + public static void init() { + if (serviceWorkerController == null && + WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE)) { serviceWorkerController = ServiceWorkerControllerCompat.getInstance(); - } else { - serviceWorkerController = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/tracing/TracingControllerChannelDelegate.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/tracing/TracingControllerChannelDelegate.java index d5e136a2a..922938753 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/tracing/TracingControllerChannelDelegate.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/tracing/TracingControllerChannelDelegate.java @@ -27,6 +27,7 @@ public TracingControllerChannelDelegate(@NonNull TracingControllerManager tracin @Override public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + TracingControllerManager.init(); TracingController tracingController = TracingControllerManager.tracingController; switch (call.method) { diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/tracing/TracingControllerManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/tracing/TracingControllerManager.java index 77aa3f991..3f46efa32 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/tracing/TracingControllerManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/tracing/TracingControllerManager.java @@ -1,6 +1,7 @@ package com.pichillilorenzo.flutter_inappwebview.tracing; import androidx.annotation.Nullable; +import androidx.webkit.ProxyController; import androidx.webkit.TracingConfig; import androidx.webkit.TracingController; import androidx.webkit.WebViewFeature; @@ -25,10 +26,12 @@ public TracingControllerManager(final InAppWebViewFlutterPlugin plugin) { this.plugin = plugin; final MethodChannel channel = new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME); this.channelDelegate = new TracingControllerChannelDelegate(this, channel); - if (WebViewFeature.isFeatureSupported(WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE)) { + } + + public static void init() { + if (tracingController == null && + WebViewFeature.isFeatureSupported(WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE)) { tracingController = TracingController.getInstance(); - } else { - tracingController = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/JavaScriptBridgeInterface.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/JavaScriptBridgeInterface.java index 1eb0cede3..fd872fa19 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/JavaScriptBridgeInterface.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/JavaScriptBridgeInterface.java @@ -130,7 +130,7 @@ public void defaultBehaviour(@Nullable Object json) { return; } String sourceCode = "if (window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "] != null) { " + - "window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "](" + json + "); " + + "window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "].resolve(" + json + "); " + "delete window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "]; " + "}"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { @@ -143,7 +143,24 @@ public void defaultBehaviour(@Nullable Object json) { @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { - Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + String message = errorCode + ((errorMessage != null) ? ", " + errorMessage : ""); + Log.e(LOG_TAG, message); + + if (inAppWebView == null) { + // The webview has already been disposed, ignore. + return; + } + + String sourceCode = "if (window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "] != null) { " + + "window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "].reject(new Error(" + JSONObject.quote(message) + ")); " + + "delete window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "]; " + + "}"; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + inAppWebView.evaluateJavascript(sourceCode, (ValueCallback) null); + } + else { + inAppWebView.loadUrl("javascript:" + sourceCode); + } } }); } 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 9380f92d9..344c5f1ee 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 @@ -433,13 +433,13 @@ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { WebSettingsCompat.setAlgorithmicDarkeningAllowed(settings, customSettings.algorithmicDarkeningAllowed); } - if (WebViewFeature.isFeatureSupported(WebViewFeature.REQUESTED_WITH_HEADER_CONTROL) && - customSettings.requestedWithHeaderMode != null) { - WebSettingsCompat.setRequestedWithHeaderMode(settings, customSettings.requestedWithHeaderMode); - } if (WebViewFeature.isFeatureSupported(WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY)) { WebSettingsCompat.setEnterpriseAuthenticationAppLinkPolicyEnabled(settings, customSettings.enterpriseAuthenticationAppLinkPolicyEnabled); } + if (customSettings.requestedWithHeaderOriginAllowList != null && + WebViewFeature.isFeatureSupported(WebViewFeature.REQUESTED_WITH_HEADER_ALLOW_LIST)) { + WebSettingsCompat.setRequestedWithHeaderOriginAllowList(settings, customSettings.requestedWithHeaderOriginAllowList); + } contentBlockerHandler.getRuleList().clear(); for (Map> contentBlocker : customSettings.contentBlockers) { @@ -1089,17 +1089,16 @@ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { WebSettingsCompat.setAlgorithmicDarkeningAllowed(settings, newCustomSettings.algorithmicDarkeningAllowed); } - if (newSettingsMap.get("requestedWithHeaderMode") != null && - !Util.objEquals(customSettings.requestedWithHeaderMode, newCustomSettings.requestedWithHeaderMode) && - WebViewFeature.isFeatureSupported(WebViewFeature.REQUESTED_WITH_HEADER_CONTROL) && - newCustomSettings.requestedWithHeaderMode != null) { - WebSettingsCompat.setRequestedWithHeaderMode(settings, newCustomSettings.requestedWithHeaderMode); - } if (newSettingsMap.get("enterpriseAuthenticationAppLinkPolicyEnabled") != null && !Util.objEquals(customSettings.enterpriseAuthenticationAppLinkPolicyEnabled, newCustomSettings.enterpriseAuthenticationAppLinkPolicyEnabled) && WebViewFeature.isFeatureSupported(WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY)) { WebSettingsCompat.setEnterpriseAuthenticationAppLinkPolicyEnabled(settings, newCustomSettings.enterpriseAuthenticationAppLinkPolicyEnabled); } + if (newSettingsMap.get("requestedWithHeaderOriginAllowList") != null && + !Util.objEquals(customSettings.requestedWithHeaderOriginAllowList, newCustomSettings.requestedWithHeaderOriginAllowList) && + WebViewFeature.isFeatureSupported(WebViewFeature.REQUESTED_WITH_HEADER_ALLOW_LIST)) { + WebSettingsCompat.setRequestedWithHeaderOriginAllowList(settings, newCustomSettings.requestedWithHeaderOriginAllowList); + } if (plugin != null) { if (webViewAssetLoaderExt != null) { diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/InAppWebViewSettings.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/InAppWebViewSettings.java index 5e415ebfb..ecc08969b 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/InAppWebViewSettings.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/InAppWebViewSettings.java @@ -19,8 +19,10 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; public class InAppWebViewSettings implements ISettings { @@ -115,13 +117,13 @@ public class InAppWebViewSettings implements ISettings { @Nullable public String horizontalScrollbarTrackColor; public Boolean algorithmicDarkeningAllowed = false; - @Nullable - public Integer requestedWithHeaderMode; public Boolean enterpriseAuthenticationAppLinkPolicyEnabled = true; @Nullable public Map webViewAssetLoader; @Nullable public byte[] defaultVideoPoster; + @Nullable + public Set requestedWithHeaderOriginAllowList; @NonNull @Override @@ -383,9 +385,6 @@ public InAppWebViewSettings parse(@NonNull Map settings) { case "algorithmicDarkeningAllowed": algorithmicDarkeningAllowed = (Boolean) value; break; - case "requestedWithHeaderMode": - requestedWithHeaderMode = (Integer) value; - break; case "enterpriseAuthenticationAppLinkPolicyEnabled": enterpriseAuthenticationAppLinkPolicyEnabled = (Boolean) value; break; @@ -398,6 +397,9 @@ public InAppWebViewSettings parse(@NonNull Map settings) { case "defaultVideoPoster": defaultVideoPoster = (byte[]) value; break; + case "requestedWithHeaderOriginAllowList": + requestedWithHeaderOriginAllowList = new HashSet<>((List) value); + break; } } @@ -491,10 +493,11 @@ public Map toMap() { settings.put("horizontalScrollbarThumbColor", horizontalScrollbarThumbColor); settings.put("horizontalScrollbarTrackColor", horizontalScrollbarTrackColor); settings.put("algorithmicDarkeningAllowed", algorithmicDarkeningAllowed); - settings.put("requestedWithHeaderMode", requestedWithHeaderMode); settings.put("enterpriseAuthenticationAppLinkPolicyEnabled", enterpriseAuthenticationAppLinkPolicyEnabled); settings.put("allowBackgroundAudioPlaying", allowBackgroundAudioPlaying); settings.put("defaultVideoPoster", defaultVideoPoster); + settings.put("requestedWithHeaderOriginAllowList", + requestedWithHeaderOriginAllowList != null ? new ArrayList<>(requestedWithHeaderOriginAllowList) : null); return settings; } @@ -586,12 +589,12 @@ public Map getRealSettings(@NonNull InAppWebViewInterface inAppW if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { realSettings.put("algorithmicDarkeningAllowed", WebSettingsCompat.isAlgorithmicDarkeningAllowed(settings)); } - if (WebViewFeature.isFeatureSupported(WebViewFeature.REQUESTED_WITH_HEADER_CONTROL)) { - realSettings.put("requestedWithHeaderMode", WebSettingsCompat.getRequestedWithHeaderMode(settings)); - } if (WebViewFeature.isFeatureSupported(WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY)) { realSettings.put("enterpriseAuthenticationAppLinkPolicyEnabled", WebSettingsCompat.getEnterpriseAuthenticationAppLinkPolicyEnabled(settings)); } + if (WebViewFeature.isFeatureSupported(WebViewFeature.REQUESTED_WITH_HEADER_ALLOW_LIST)) { + realSettings.put("requestedWithHeaderOriginAllowList", new ArrayList<>(WebSettingsCompat.getRequestedWithHeaderOriginAllowList(settings))); + } } return realSettings; } diff --git a/dev_packages/generators/lib/src/exchangeable_enum_generator.dart b/dev_packages/generators/lib/src/exchangeable_enum_generator.dart index ba7c12b13..c362e6812 100644 --- a/dev_packages/generators/lib/src/exchangeable_enum_generator.dart +++ b/dev_packages/generators/lib/src/exchangeable_enum_generator.dart @@ -23,25 +23,25 @@ class ExchangeableEnumGenerator // Visits all the children of element in no particular order. element.visitChildren(visitor); - final className = visitor.constructor.returnType.element2.name; + final className = visitor.constructor.returnType.element.name; // remove "_" to generate the correct class name final extClassName = className.replaceFirst("_", ""); final classBuffer = StringBuffer(); final classDocs = - visitor.constructor.returnType.element2.documentationComment; + visitor.constructor.returnType.element.documentationComment; if (classDocs != null) { classBuffer.writeln(classDocs); } final classSupportedDocs = Util.getSupportedDocs( _coreCheckerEnumSupportedPlatforms, - visitor.constructor.returnType.element2); + visitor.constructor.returnType.element); if (classSupportedDocs != null) { classBuffer.writeln(classSupportedDocs); } - if (visitor.constructor.returnType.element2.hasDeprecated) { + if (visitor.constructor.returnType.element.hasDeprecated) { classBuffer.writeln( - "@Deprecated('${_coreCheckerDeprecated.firstAnnotationOfExact(visitor.constructor.returnType.element2)?.getField("message")?.toStringValue()}')"); + "@Deprecated('${_coreCheckerDeprecated.firstAnnotationOfExact(visitor.constructor.returnType.element)?.getField("message")?.toStringValue()}')"); } classBuffer.writeln('class $extClassName {'); diff --git a/dev_packages/generators/lib/src/exchangeable_object_generator.dart b/dev_packages/generators/lib/src/exchangeable_object_generator.dart index caa878820..276c2e7dd 100644 --- a/dev_packages/generators/lib/src/exchangeable_object_generator.dart +++ b/dev_packages/generators/lib/src/exchangeable_object_generator.dart @@ -29,35 +29,37 @@ class ExchangeableObjectGenerator // Visits all the children of element in no particular order. element.visitChildren(visitor); - final className = visitor.constructor.returnType.element2.name; + final className = visitor.constructor.returnType.element.name; final superClass = - visitor.constructor.returnType.superclass?.element2.name != 'Object' + visitor.constructor.returnType.superclass?.element.name != 'Object' ? visitor.constructor.returnType.superclass : null; final interfaces = visitor.constructor.returnType.interfaces; - final superClassName = superClass?.element2.name.replaceFirst("_", ""); + final superClassName = superClass?.element.name.replaceFirst("_", ""); // remove "_" to generate the correct class name final extClassName = className.replaceFirst("_", ""); final classBuffer = StringBuffer(); final classDocs = - visitor.constructor.returnType.element2.documentationComment; + visitor.constructor.returnType.element.documentationComment; if (classDocs != null) { classBuffer.writeln(classDocs); } final classSupportedDocs = Util.getSupportedDocs( - _coreCheckerSupportedPlatforms, visitor.constructor.returnType.element2); + _coreCheckerSupportedPlatforms, visitor.constructor.returnType.element); if (classSupportedDocs != null) { classBuffer.writeln(classSupportedDocs); } - if (visitor.constructor.returnType.element2.hasDeprecated) { + if (visitor.constructor.returnType.element.hasDeprecated) { classBuffer.writeln( - "@Deprecated('${_coreCheckerDeprecated.firstAnnotationOfExact(visitor.constructor.returnType.element2)?.getField("message")?.toStringValue()}')"); + "@Deprecated('${_coreCheckerDeprecated.firstAnnotationOfExact(visitor.constructor.returnType.element)?.getField("message")?.toStringValue()}')"); } - classBuffer.write('${(visitor.constructor.enclosingElement3 as ClassElement).isAbstract ? 'abstract ' : ''}class $extClassName'); + classBuffer.write( + '${(visitor.constructor.enclosingElement as ClassElement).isAbstract ? 'abstract ' : ''}class $extClassName'); if (interfaces.isNotEmpty) { - classBuffer.writeln(' implements ${interfaces.map((i) => i.element2.name.replaceFirst("_", "")).join(', ')}'); + classBuffer.writeln( + ' implements ${interfaces.map((i) => i.element.name.replaceFirst("_", "")).join(', ')}'); } if (superClass != null) { classBuffer.writeln(' extends ${superClassName}'); @@ -174,7 +176,7 @@ class ExchangeableObjectGenerator if (constructorSupportedDocs == null) { constructorSupportedDocs = Util.getSupportedDocs( _coreCheckerSupportedPlatforms, - visitor.constructor.returnType.element2); + visitor.constructor.returnType.element); } if (constructorSupportedDocs != null) { classBuffer.writeln(constructorSupportedDocs); @@ -233,11 +235,13 @@ class ExchangeableObjectGenerator .trim(); final fieldElement = visitor.fields[fieldName]; if (fieldElement != null) { - final fieldTypeElement = fieldElement.type.element2; - final deprecatedFieldTypeElement = deprecatedField.type.element2; + final fieldTypeElement = fieldElement.type.element; + final deprecatedFieldTypeElement = deprecatedField.type.element; final isNullable = Util.typeIsNullable(fieldElement.type); - var hasDefaultValue = (fieldElement is ParameterElement) ? (fieldElement as ParameterElement).hasDefaultValue : false; + var hasDefaultValue = (fieldElement is ParameterElement) + ? (fieldElement as ParameterElement).hasDefaultValue + : false; if (!isNullable && hasDefaultValue) { continue; } @@ -267,10 +271,14 @@ class ExchangeableObjectGenerator } else if (hasFromValue && deprecatedHasToValue) { classBuffer.write(fieldTypeElement.name!.replaceFirst("_", "") + '.fromValue($deprecatedFieldName${deprecatedIsNullable ? '?' : ''}.toValue())${!isNullable ? '!' : ''}'); - } else if (deprecatedField.type.getDisplayString(withNullability: false) == "Uri" && - fieldElement.type.getDisplayString(withNullability: false) == "WebUri") { + } else if (deprecatedField.type + .getDisplayString(withNullability: false) == + "Uri" && + fieldElement.type.getDisplayString(withNullability: false) == + "WebUri") { if (deprecatedIsNullable) { - classBuffer.write("($deprecatedFieldName != null ? WebUri.uri($deprecatedFieldName!) : ${isNullable ? "null" : "WebUri('')"})"); + classBuffer.write( + "($deprecatedFieldName != null ? WebUri.uri($deprecatedFieldName!) : ${isNullable ? "null" : "WebUri('')"})"); } else { classBuffer.write("WebUri.uri($deprecatedFieldName)"); } @@ -288,8 +296,9 @@ class ExchangeableObjectGenerator classBuffer.writeln(';'); } - if (annotation.read("fromMapFactory").boolValue && (!visitor.methods.containsKey("fromMap") || - Util.methodHasIgnore(visitor.methods['fromMap']!))) { + if (annotation.read("fromMapFactory").boolValue && + (!visitor.methods.containsKey("fromMap") || + Util.methodHasIgnore(visitor.methods['fromMap']!))) { classBuffer.writeln( '///Gets a possible [$extClassName] instance from a [Map] value.'); final nullable = annotation.read("nullableFromMapFactory").boolValue; @@ -303,7 +312,7 @@ class ExchangeableObjectGenerator classBuffer.writeln('final instance = $extClassName('); final fieldElements = []; if (superClass != null) { - fieldElements.addAll(superClass.element2.fields); + fieldElements.addAll(superClass.element.fields); } fieldElements.addAll(fieldValuesSorted); final nonRequiredFields = []; @@ -332,7 +341,7 @@ class ExchangeableObjectGenerator ?.toFunctionValue(); if (customDeserializer != null) { final deserializerClassName = - customDeserializer.enclosingElement3.name; + customDeserializer.enclosingElement.name; if (deserializerClassName != null) { value = "$deserializerClassName.${customDeserializer.name}($value)"; @@ -387,8 +396,9 @@ class ExchangeableObjectGenerator } } - if (annotation.read("toMapMethod").boolValue && (!visitor.methods.containsKey("toMap") || - Util.methodHasIgnore(visitor.methods['toMap']!))) { + if (annotation.read("toMapMethod").boolValue && + (!visitor.methods.containsKey("toMap") || + Util.methodHasIgnore(visitor.methods['toMap']!))) { classBuffer.writeln('///Converts instance to a map.'); classBuffer.writeln('Map toMap() {'); classBuffer.writeln('return {'); @@ -404,7 +414,7 @@ class ExchangeableObjectGenerator } final fieldElements = []; if (superClass != null) { - for (final fieldElement in superClass.element2.fields) { + for (final fieldElement in superClass.element.fields) { if (!fieldElement.isPrivate && !fieldElement.hasDeprecated && !fieldElement.isStatic && @@ -434,7 +444,7 @@ class ExchangeableObjectGenerator ?.getField("serializer") ?.toFunctionValue(); if (customSerializer != null) { - final serializerClassName = customSerializer.enclosingElement3.name; + final serializerClassName = customSerializer.enclosingElement.name; if (serializerClassName != null) { mapValue = "$serializerClassName.${customSerializer.name}($mapValue)"; @@ -452,30 +462,34 @@ class ExchangeableObjectGenerator classBuffer.writeln('}'); } - if (annotation.read("toJsonMethod").boolValue && (!visitor.methods.containsKey("toJson") || - Util.methodHasIgnore(visitor.methods['toJson']!))) { + if (annotation.read("toJsonMethod").boolValue && + (!visitor.methods.containsKey("toJson") || + Util.methodHasIgnore(visitor.methods['toJson']!))) { classBuffer.writeln('///Converts instance to a map.'); classBuffer.writeln('Map toJson() {'); classBuffer.writeln('return toMap();'); classBuffer.writeln('}'); } - if (annotation.read("copyMethod").boolValue && (!visitor.methods.containsKey("copy") || - Util.methodHasIgnore(visitor.methods['copy']!))) { + 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('return $extClassName.fromMap(toMap()) ?? $extClassName();'); classBuffer.writeln('}'); } - if (annotation.read("toStringMethod").boolValue && (!visitor.methods.containsKey("toString") || - Util.methodHasIgnore(visitor.methods['toString']!))) { + if (annotation.read("toStringMethod").boolValue && + (!visitor.methods.containsKey("toString") || + Util.methodHasIgnore(visitor.methods['toString']!))) { classBuffer.writeln('@override'); classBuffer.writeln('String toString() {'); classBuffer.write('return \'$extClassName{'); final fieldNames = []; if (superClass != null) { - for (final fieldElement in superClass.element2.fields) { + for (final fieldElement in superClass.element.fields) { final fieldName = fieldElement.name; if (!fieldElement.isPrivate && !fieldElement.hasDeprecated && @@ -505,34 +519,32 @@ class ExchangeableObjectGenerator } String getFromMapValue(String value, DartType elementType) { - final fieldTypeElement = elementType.element2; + final fieldTypeElement = elementType.element; final isNullable = Util.typeIsNullable(elementType); - if (elementType.getDisplayString(withNullability: false) == "Uri") { + final displayString = elementType.getDisplayString(withNullability: false); + if (displayString == "Uri") { if (!isNullable) { return "(Uri.tryParse($value) ?? Uri())"; } else { return "$value != null ? Uri.tryParse($value) : null"; } - } else if (elementType.getDisplayString(withNullability: false) == "WebUri") { + } else if (displayString == "WebUri") { if (!isNullable) { return "WebUri($value)"; } else { return "$value != null ? WebUri($value) : null"; } - } else if (elementType.getDisplayString(withNullability: false) == - "Color") { + } else if (displayString == "Color" || displayString == "Color_") { if (!isNullable) { return "UtilColor.fromStringRepresentation($value)!"; } else { return "$value != null ? UtilColor.fromStringRepresentation($value) : null"; } - } else if (elementType.getDisplayString(withNullability: false) == - "EdgeInsets") { + } else if (displayString == "EdgeInsets") { return "MapEdgeInsets.fromMap($value?.cast())${!isNullable ? '!' : ''}"; - } else if (elementType.getDisplayString(withNullability: false) == "Size") { + } else if (displayString == "Size") { return "MapSize.fromMap($value?.cast())${!isNullable ? '!' : ''}"; - } else if (elementType.getDisplayString(withNullability: false) == - "DateTime") { + } else if (displayString == "DateTime") { if (!isNullable) { return "DateTime.fromMillisecondsSinceEpoch($value)!"; } else { @@ -541,7 +553,9 @@ class ExchangeableObjectGenerator } else if (elementType.isDartCoreList || elementType.isDartCoreSet) { final genericTypes = Util.getGenericTypes(elementType); final genericType = genericTypes.isNotEmpty ? genericTypes.first : null; - final genericTypeReplaced = genericType != null ? genericType.toString().replaceAll("_", "") : null; + final genericTypeReplaced = genericType != null + ? genericType.toString().replaceAll("_", "") + : null; if (genericType != null && !Util.isDartCoreType(genericType)) { final genericTypeFieldName = 'e'; return (isNullable ? '$value != null ? ' : '') + @@ -553,7 +567,10 @@ class ExchangeableObjectGenerator (isNullable ? ' : null' : ''); } else { if (genericType != null) { - return "$value${isNullable ? '?' : ''}.cast<${genericTypeReplaced}>()"; + return (isNullable ? '$value != null ? ' : '') + + "${elementType.isDartCoreSet ? 'Set' : 'List'}<$genericTypeReplaced>.from(" + + "$value!.cast<${genericTypeReplaced}>())" + + (isNullable ? ' : null' : ''); } else { return value; } @@ -592,22 +609,20 @@ class ExchangeableObjectGenerator } String getToMapValue(String fieldName, DartType elementType) { - final fieldTypeElement = elementType.element2; + final fieldTypeElement = elementType.element; final isNullable = Util.typeIsNullable(elementType); - if (elementType.getDisplayString(withNullability: false) == "Uri") { + final displayString = elementType.getDisplayString(withNullability: false); + if (displayString == "Uri") { return fieldName + (isNullable ? '?' : '') + '.toString()'; - } else if (elementType.getDisplayString(withNullability: false) == "WebUri") { + } else if (displayString == "WebUri") { return fieldName + (isNullable ? '?' : '') + '.toString()'; - } else if (elementType.getDisplayString(withNullability: false) == - "Color") { + } else if (displayString == "Color" || displayString == "Color_") { return fieldName + (isNullable ? '?' : '') + '.toHex()'; - } else if (elementType.getDisplayString(withNullability: false) == - "EdgeInsets") { + } else if (displayString == "EdgeInsets") { return fieldName + (isNullable ? '?' : '') + '.toMap()'; - } else if (elementType.getDisplayString(withNullability: false) == "Size") { + } else if (displayString == "Size") { return fieldName + (isNullable ? '?' : '') + '.toMap()'; - } else if (elementType.getDisplayString(withNullability: false) == - "DateTime") { + } else if (displayString == "DateTime") { return fieldName + (isNullable ? '?' : '') + '.millisecondsSinceEpoch'; } else if (elementType.isDartCoreList || elementType.isDartCoreSet) { final genericType = Util.getGenericTypes(elementType).first; @@ -619,7 +634,9 @@ class ExchangeableObjectGenerator getToMapValue('$genericTypeFieldName', genericType) + ').toList()'; } else { - return elementType.isDartCoreSet ? "$fieldName${(isNullable ? '?' : '')}.toList()" : fieldName; + return elementType.isDartCoreSet + ? "$fieldName${(isNullable ? '?' : '')}.toList()" + : fieldName; } } else if (fieldTypeElement != null && hasToMapMethod(fieldTypeElement)) { return fieldName + diff --git a/dev_packages/generators/lib/src/util.dart b/dev_packages/generators/lib/src/util.dart index 5b3d22308..1095fdade 100644 --- a/dev_packages/generators/lib/src/util.dart +++ b/dev_packages/generators/lib/src/util.dart @@ -82,7 +82,7 @@ abstract class Util { } static bool canHaveGenerics(DartType type) { - final element = type.element2; + final element = type.element; if (element is ClassElement) { return element.typeParameters.isNotEmpty; } @@ -104,6 +104,6 @@ abstract class Util { type.isDartCoreSet || type.isDartCoreString || type.isDartCoreSymbol || - type.isDynamic; + type is DynamicType; } } diff --git a/dev_packages/generators/pubspec.lock b/dev_packages/generators/pubspec.lock index 07f34adda..858bef6b6 100644 --- a/dev_packages/generators/pubspec.lock +++ b/dev_packages/generators/pubspec.lock @@ -5,177 +5,202 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - url: "https://pub.dartlang.org" + sha256: "405666cd3cf0ee0a48d21ec67e65406aad2c726d9fa58840d3375e7bdcd32a07" + url: "https://pub.dev" source: hosted - version: "49.0.0" + version: "60.0.0" analyzer: dependency: transitive description: name: analyzer - url: "https://pub.dartlang.org" + sha256: "1952250bd005bacb895a01bf1b4dc00e3ba1c526cf47dca54dfe24979c65f5b3" + url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.12.0" args: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a + url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.1" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" build: dependency: "direct main" description: name: build - url: "https://pub.dartlang.org" + sha256: "43865b79fbb78532e4bff7c33087aa43b1d488c4fdef014eaef568af6d8016dc" + url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.0" build_config: dependency: transitive description: name: build_config - url: "https://pub.dartlang.org" + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" build_daemon: dependency: transitive description: name: build_daemon - url: "https://pub.dartlang.org" + sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "4.0.0" build_resolvers: dependency: transitive description: name: build_resolvers - url: "https://pub.dartlang.org" + sha256: db49b8609ef8c81cca2b310618c3017c00f03a92af44c04d310b907b2d692d95 + url: "https://pub.dev" source: hosted - version: "2.0.10" + version: "2.2.0" build_runner: dependency: "direct dev" description: name: build_runner - url: "https://pub.dartlang.org" + sha256: "87e06c939450b9b94e3e1bb2d46e0e9780adbff5500d3969f2ba2de6bbb860cb" + url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.4.2" build_runner_core: dependency: transitive description: name: build_runner_core - url: "https://pub.dartlang.org" + sha256: "30859c90e9ddaccc484f56303931f477b1f1ba2bab74aa32ed5d6ce15870f8cf" + url: "https://pub.dev" source: hosted - version: "7.2.4" + version: "7.2.8" build_test: dependency: "direct dev" description: name: build_test - url: "https://pub.dartlang.org" + sha256: "927ef98b58c5603ec58923c0bb943a74743e58149732665885bb1eb92983befe" + url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.7" built_collection: dependency: transitive description: name: built_collection - url: "https://pub.dartlang.org" + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" source: hosted version: "5.1.1" built_value: dependency: transitive description: name: built_value - url: "https://pub.dartlang.org" + sha256: "2f17434bd5d52a26762043d6b43bb53b3acd029b4d9071a329f46d67ef297e6d" + url: "https://pub.dev" source: hosted - version: "8.4.1" + version: "8.5.0" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" checked_yaml: dependency: transitive description: name: checked_yaml - url: "https://pub.dartlang.org" + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.3" code_builder: dependency: transitive description: name: code_builder - url: "https://pub.dartlang.org" + sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe" + url: "https://pub.dev" source: hosted - version: "4.3.0" + version: "4.4.0" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.1" convert: dependency: transitive description: name: convert - url: "https://pub.dartlang.org" + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.1.1" coverage: dependency: transitive description: name: coverage - url: "https://pub.dartlang.org" + sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097" + url: "https://pub.dev" source: hosted - version: "1.6.1" + version: "1.6.3" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" csslib: dependency: transitive description: name: csslib - url: "https://pub.dartlang.org" + sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745 + url: "https://pub.dev" source: hosted version: "0.17.2" dart_style: dependency: transitive description: name: dart_style - url: "https://pub.dartlang.org" + sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad + url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.3.1" file: dependency: transitive description: name: file - url: "https://pub.dartlang.org" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" source: hosted version: "6.1.4" fixnum: dependency: transitive description: name: fixnum - url: "https://pub.dartlang.org" + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -185,177 +210,210 @@ packages: dependency: "direct main" description: name: flutter_inappwebview_internal_annotations - url: "https://pub.dartlang.org" + sha256: "064a8ccbc76217dcd3b0fd6c6ea6f549e69b2849a0233b5bb46af9632c3ce2ff" + url: "https://pub.dev" source: hosted version: "1.1.0" frontend_server_client: dependency: transitive description: name: frontend_server_client - url: "https://pub.dartlang.org" + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "3.2.0" glob: dependency: transitive description: name: glob - url: "https://pub.dartlang.org" + sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" graphs: dependency: transitive description: name: graphs - url: "https://pub.dartlang.org" + sha256: "772db3d53d23361d4ffcf5a9bb091cf3ee9b22f2be52cd107cd7a2683a89ba0e" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.3.0" html: dependency: transitive description: name: html - url: "https://pub.dartlang.org" + sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8" + url: "https://pub.dev" source: hosted - version: "0.15.0" + version: "0.15.3" http_multi_server: dependency: transitive description: name: http_multi_server - url: "https://pub.dartlang.org" + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" source: hosted version: "3.2.1" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "4.0.2" io: dependency: transitive description: name: io - url: "https://pub.dartlang.org" + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" js: dependency: transitive description: name: js - url: "https://pub.dartlang.org" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.7" json_annotation: dependency: transitive description: name: json_annotation - url: "https://pub.dartlang.org" + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.8.1" logging: dependency: transitive description: name: logging - url: "https://pub.dartlang.org" + sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.15" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mime: dependency: transitive description: name: mime - url: "https://pub.dartlang.org" + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.4" node_preamble: dependency: transitive description: name: node_preamble - url: "https://pub.dartlang.org" + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" package_config: dependency: transitive description: name: package_config - url: "https://pub.dartlang.org" + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" source: hosted version: "2.1.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" pool: dependency: transitive description: name: pool - url: "https://pub.dartlang.org" + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" source: hosted version: "1.5.1" + protobuf: + dependency: transitive + description: + name: protobuf + sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08" + url: "https://pub.dev" + source: hosted + version: "2.1.0" pub_semver: dependency: transitive description: name: pub_semver - url: "https://pub.dartlang.org" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.4" pubspec_parse: dependency: transitive description: name: pubspec_parse - url: "https://pub.dartlang.org" + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.3" shelf: dependency: transitive description: name: shelf - url: "https://pub.dartlang.org" + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler - url: "https://pub.dartlang.org" + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" shelf_static: dependency: transitive description: name: shelf_static - url: "https://pub.dartlang.org" + sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - url: "https://pub.dartlang.org" + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.4" sky_engine: dependency: transitive description: flutter @@ -365,142 +423,162 @@ packages: dependency: "direct main" description: name: source_gen - url: "https://pub.dartlang.org" + sha256: "378a173055cd1fcd2a36e94bf254786d6812688b5f53b6038a2fd180a5a5e210" + url: "https://pub.dev" source: hosted - version: "1.2.5" + version: "1.3.1" source_map_stack_trace: dependency: transitive description: name: source_map_stack_trace - url: "https://pub.dartlang.org" + sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" source_maps: dependency: transitive description: name: source_maps - url: "https://pub.dartlang.org" + sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" + url: "https://pub.dev" source: hosted - version: "0.10.10" + version: "0.10.12" source_span: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted version: "2.1.1" stream_transform: dependency: transitive description: name: stream_transform - url: "https://pub.dartlang.org" + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test: dependency: "direct dev" description: name: test - url: "https://pub.dartlang.org" + sha256: "4f92f103ef63b1bbac6f4bd1930624fca81b2574464482512c4f0896319be575" + url: "https://pub.dev" source: hosted - version: "1.21.6" + version: "1.24.2" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: daadc9baabec998b062c9091525aa95786508b1c48e9c30f1f891b8bf6ff2e64 + url: "https://pub.dev" source: hosted - version: "0.4.14" + version: "0.5.2" test_core: dependency: transitive description: name: test_core - url: "https://pub.dartlang.org" + sha256: "3642b184882f79e76ca57a9230fb971e494c3c1fd09c21ae3083ce891bcc0aa1" + url: "https://pub.dev" source: hosted - version: "0.4.18" + version: "0.5.2" timing: dependency: transitive description: name: timing - url: "https://pub.dartlang.org" + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.1" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" vm_service: dependency: transitive description: name: vm_service - url: "https://pub.dartlang.org" + sha256: "1311639ad908dfdcb64734ac1fbd60416234c06e4351846783a79c56848a5185" + url: "https://pub.dev" source: hosted - version: "9.4.0" + version: "11.7.0" watcher: dependency: transitive description: name: watcher - url: "https://pub.dartlang.org" + sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.2" web_socket_channel: dependency: transitive description: name: web_socket_channel - url: "https://pub.dartlang.org" + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.4.0" webkit_inspection_protocol: dependency: transitive description: name: webkit_inspection_protocol - url: "https://pub.dartlang.org" + sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d" + url: "https://pub.dev" source: hosted version: "1.2.0" yaml: dependency: transitive description: name: yaml - url: "https://pub.dartlang.org" + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" sdks: - dart: ">=2.18.0 <3.0.0" + dart: ">=3.0.0-134.0.dev <4.0.0" flutter: ">=2.5.0" diff --git a/dev_packages/generators/pubspec.yaml b/dev_packages/generators/pubspec.yaml index 47509f8fe..ce517d0a7 100755 --- a/dev_packages/generators/pubspec.yaml +++ b/dev_packages/generators/pubspec.yaml @@ -10,11 +10,11 @@ environment: dependencies: flutter: sdk: flutter - build: ^2.3.1 - source_gen: ^1.2.5 + build: ^2.4.0 + source_gen: ^1.3.1 flutter_inappwebview_internal_annotations: ^1.1.0 dev_dependencies: - build_runner: ^2.2.1 - build_test: ^2.1.5 - test: ^1.21.1 \ No newline at end of file + build_runner: ^2.4.2 + build_test: ^2.1.7 + test: ^1.24.2 \ No newline at end of file diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index b4ad9fef0..dadb33540 100755 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -25,6 +25,8 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { + namespace 'com.pichillilorenzo.flutterwebviewexample' + compileOptions { sourceCompatibility 1.8 targetCompatibility 1.8 @@ -32,9 +34,6 @@ android { compileSdkVersion 33 - lintOptions { - disable 'InvalidPackage' - } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). @@ -54,6 +53,10 @@ android { signingConfig signingConfigs.debug } } + namespace 'com.pichillilorenzo.flutterwebviewexample' + lint { + disable 'InvalidPackage' + } } flutter { diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml index 7bb476c7d..f880684a6 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 1f6b71c0c..4e09bbbbc 100755 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/example/android/build.gradle b/example/android/build.gradle index 4256f9173..4b30292eb 100755 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.6.21' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.4.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/example/android/gradle.properties b/example/android/gradle.properties index a6738207f..d639108ac 100755 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -2,3 +2,6 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true android.enableR8=true +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index bc6a58afd..02e5f5817 100755 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip 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 5b5a4d9ed..2c20c16e8 100644 --- a/example/integration_test/chrome_safari_browser/open_and_close.dart +++ b/example/integration_test/chrome_safari_browser/open_and_close.dart @@ -45,7 +45,7 @@ void openAndClose() { activityButton: ActivityButton( templateImage: UIImage(systemName: "sun.max"), extensionIdentifier: - "com.pichillilorenzo.flutter-inappwebview6-example.test"))); + "com.pichillilorenzo.flutter-inappwebview-example7.test"))); await chromeSafariBrowser.opened.future; expect(chromeSafariBrowser.isOpened(), true); expect(() async { diff --git a/example/integration_test/constants.dart b/example/integration_test/constants.dart index 8c13786b7..3b882ee05 100644 --- a/example/integration_test/constants.dart +++ b/example/integration_test/constants.dart @@ -27,4 +27,4 @@ final TEST_SERVICE_WORKER_URL = WebUri( 'https://mdn.github.io/dom-examples/service-worker/simple-service-worker/'); final TEST_WEBVIEW_ASSET_LOADER_DOMAIN = 'my.custom.domain.com'; final TEST_WEBVIEW_ASSET_LOADER_URL = WebUri( - 'https://$TEST_WEBVIEW_ASSET_LOADER_DOMAIN/assets/flutter_assets/assets/website/index.html'); + 'https://$TEST_WEBVIEW_ASSET_LOADER_DOMAIN/assets/flutter_assets/test_assets/website/index.html'); diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index a7647f6d0..142ae22c8 100755 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -1,6 +1,6 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=/Users/lorenzopichilli/fvm/versions/3.3.6" +export "FLUTTER_ROOT=/Users/lorenzopichilli/fvm/versions/3.10.0" export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example" export "COCOAPODS_PARALLEL_CODE_SIGN=true" export "FLUTTER_TARGET=lib/main.dart" diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 52e55bba4..c6cb5f837 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,21 +3,20 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ - 020EF14E4245221B2C22ACE5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B0FC2CF7A6002799890B3102 /* Pods_Runner.framework */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 25A517508F43E58C47090625 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 6143FF37290959650014A1FC /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6143FF36290959650014A1FC /* UniformTypeIdentifiers.framework */; }; 6143FF3A290959650014A1FC /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6143FF39290959650014A1FC /* Media.xcassets */; }; 6143FF3C290959650014A1FC /* ActionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6143FF3B290959650014A1FC /* ActionViewController.swift */; }; 6143FF3F290959650014A1FC /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6143FF3D290959650014A1FC /* MainInterface.storyboard */; }; - 6143FF43290959650014A1FC /* test.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 6143FF35290959650014A1FC /* test.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 6143FF43290959650014A1FC /* test.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 6143FF35290959650014A1FC /* test.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 61FF730023634CA10069C557 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 61FF72FF23634CA10069C557 /* libsqlite3.tbd */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 75018AFBF33C6954B9C375F0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 86871EBA13742A6D5F3F398B /* Pods_Runner.framework */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; EDC1147F21735BC200D2247A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; @@ -34,15 +33,15 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 6174FE1725CEB74E00A5020C /* Embed App Extensions */ = { + 6174FE1725CEB74E00A5020C /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 13; files = ( - 6143FF43290959650014A1FC /* test.appex in Embed App Extensions */, + 6143FF43290959650014A1FC /* test.appex in Embed Foundation Extensions */, ); - name = "Embed App Extensions"; + name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ @@ -62,6 +61,8 @@ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 80ABE07D2023159E36035B32 /* 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 = ""; }; + 86871EBA13742A6D5F3F398B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -69,9 +70,7 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9D199BB70329114343003314 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - B0FC2CF7A6002799890B3102 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - B23847D2EEA83886DC92B60F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + AA4061AE397745454F676BAB /* 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,8 +87,7 @@ buildActionMask = 2147483647; files = ( 61FF730023634CA10069C557 /* libsqlite3.tbd in Frameworks */, - 25A517508F43E58C47090625 /* (null) in Frameworks */, - 020EF14E4245221B2C22ACE5 /* Pods_Runner.framework in Frameworks */, + 75018AFBF33C6954B9C375F0 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -101,8 +99,8 @@ children = ( 61FF730123634DD10069C557 /* flutter_downloader.framework */, 61FF72FF23634CA10069C557 /* libsqlite3.tbd */, - B0FC2CF7A6002799890B3102 /* Pods_Runner.framework */, 6143FF36290959650014A1FC /* UniformTypeIdentifiers.framework */, + 86871EBA13742A6D5F3F398B /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; @@ -118,13 +116,13 @@ path = test; sourceTree = ""; }; - 647DC95AB5350DB6D2264FFE /* Pods */ = { + 7AC6E2111A9BB885C2D9F6EE /* Pods */ = { isa = PBXGroup; children = ( - B23847D2EEA83886DC92B60F /* Pods-Runner.debug.xcconfig */, - 9D199BB70329114343003314 /* Pods-Runner.release.xcconfig */, + 80ABE07D2023159E36035B32 /* Pods-Runner.debug.xcconfig */, + AA4061AE397745454F676BAB /* Pods-Runner.release.xcconfig */, ); - name = Pods; + path = Pods; sourceTree = ""; }; 9740EEB11CF90186004384FC /* Flutter */ = { @@ -145,8 +143,8 @@ 97C146F01CF9000F007C117D /* Runner */, 6143FF38290959650014A1FC /* test */, 97C146EF1CF9000F007C117D /* Products */, - 647DC95AB5350DB6D2264FFE /* Pods */, 50BAF1DF19E018DDF2B149B9 /* Frameworks */, + 7AC6E2111A9BB885C2D9F6EE /* Pods */, ); sourceTree = ""; }; @@ -206,14 +204,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 3F62E6580DEAFBE72C090A85 /* [CP] Check Pods Manifest.lock */, + DC1BB9CDFB0410A7329D249A /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 903A9F2558754FA70D0A7EA8 /* [CP] Embed Pods Frameworks */, - 6174FE1725CEB74E00A5020C /* Embed App Extensions */, + 6174FE1725CEB74E00A5020C /* Embed Foundation Extensions */, + DFFD8453B8E169BF6BE74B49 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -231,6 +229,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1400; LastUpgradeCheck = 1300; ORGANIZATIONNAME = "The Chromium Authors"; @@ -298,10 +297,12 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -310,16 +311,35 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; }; - 3F62E6580DEAFBE72C090A85 /* [CP] Check Pods Manifest.lock */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + }; + DC1BB9CDFB0410A7329D249A /* [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", ); @@ -328,7 +348,7 @@ 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; }; - 903A9F2558754FA70D0A7EA8 /* [CP] Embed Pods Frameworks */ = { + DFFD8453B8E169BF6BE74B49 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -339,7 +359,7 @@ "${BUILT_PRODUCTS_DIR}/flutter_downloader/flutter_downloader.framework", "${BUILT_PRODUCTS_DIR}/flutter_inappwebview/flutter_inappwebview.framework", "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", - "${BUILT_PRODUCTS_DIR}/path_provider_ios/path_provider_ios.framework", + "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", "${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework", ); name = "[CP] Embed Pods Frameworks"; @@ -348,7 +368,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_downloader.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappwebview.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_ios.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework", ); runOnlyForDeploymentPostprocessing = 0; @@ -356,20 +376,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -447,11 +453,15 @@ INFOPLIST_KEY_CFBundleDisplayName = test; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 The Chromium Authors. All rights reserved."; IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); MARKETING_VERSION = 1.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview6-example.test"; + PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview-example7.test"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; @@ -481,10 +491,14 @@ INFOPLIST_KEY_CFBundleDisplayName = test; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 The Chromium Authors. All rights reserved."; IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); MARKETING_VERSION = 1.0; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview6-example.test"; + PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview-example7.test"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; @@ -518,6 +532,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -526,7 +541,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -543,7 +558,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -576,6 +591,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -584,7 +600,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -595,9 +611,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -622,12 +639,15 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview6-example"; + PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview-example7"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -654,12 +674,15 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview6-example"; + PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview-example7"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index d13650c09..a5b02ad46 100755 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -51,6 +51,8 @@ Need location NSMicrophoneUsageDescription InAppWebView requires access to mic. + UIApplicationSupportsIndirectInputEvents + UIBackgroundModes fetch diff --git a/example/lib/generated_plugin_registrant.dart b/example/lib/generated_plugin_registrant.dart deleted file mode 100644 index 777d4a942..000000000 --- a/example/lib/generated_plugin_registrant.dart +++ /dev/null @@ -1,19 +0,0 @@ -// -// Generated file. Do not edit. -// - -// ignore_for_file: directives_ordering -// ignore_for_file: lines_longer_than_80_chars -// ignore_for_file: depend_on_referenced_packages - -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; -import 'package:url_launcher_web/url_launcher_web.dart'; - -import 'package:flutter_web_plugins/flutter_web_plugins.dart'; - -// ignore: public_member_api_docs -void registerPlugins(Registrar registrar) { - FlutterInAppWebViewWebPlatform.registerWith(registrar); - UrlLauncherPlugin.registerWith(registrar); - registrar.registerMessageHandler(); -} diff --git a/example/lib/in_app_browser_example.screen.dart b/example/lib/in_app_browser_example.screen.dart index fee28a14e..536afa6e0 100755 --- a/example/lib/in_app_browser_example.screen.dart +++ b/example/lib/in_app_browser_example.screen.dart @@ -115,6 +115,7 @@ class _InAppBrowserExampleScreenState extends State { toolbarTopBackgroundColor: Colors.blue, presentationStyle: ModalPresentationStyle.POPOVER), webViewSettings: InAppWebViewSettings( + isInspectable: kDebugMode, 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 2f56f4c70..c6b18fd15 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -17,6 +17,7 @@ class _InAppWebViewExampleScreenState extends State { InAppWebViewController? webViewController; InAppWebViewSettings settings = InAppWebViewSettings( + isInspectable: kDebugMode, mediaPlaybackRequiresUserGesture: false, allowsInlineMediaPlayback: true, iframeAllow: "camera; microphone", diff --git a/example/lib/main.dart b/example/lib/main.dart index 84f36a104..0d9c4ce76 100755 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -24,7 +24,7 @@ Future main() async { // await Permission.storage.request(); if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) { - await InAppWebViewController.setWebContentsDebuggingEnabled(true); + await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode); } if (!kIsWeb) { diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index 5d8a06ddf..154ccce1d 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,7 @@ import FlutterMacOS import Foundation import flutter_inappwebview -import path_provider_macos +import path_provider_foundation import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { diff --git a/example/macos/Podfile b/example/macos/Podfile index dade8dfad..049abe295 100644 --- a/example/macos/Podfile +++ b/example/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.14' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/macos/Runner.xcodeproj/project.pbxproj b/example/macos/Runner.xcodeproj/project.pbxproj index f53831bef..d1fcca567 100644 --- a/example/macos/Runner.xcodeproj/project.pbxproj +++ b/example/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -277,6 +277,7 @@ }; 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -403,7 +404,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -482,7 +483,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -529,7 +530,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 1a3687bdf..b0201df97 100755 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -12,7 +12,7 @@ version: 1.0.0+1 publish_to: none environment: - sdk: ">=2.14.0 <3.0.0" + sdk: ">=2.15.0 <4.0.0" flutter: ">=3.0.0" dependencies: @@ -22,11 +22,11 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.4 - flutter_downloader: 1.7.3 - path_provider: 2.0.9 - permission_handler: 10.0.2 - url_launcher: 6.1.6 - pointer_interceptor: ^0.9.3+3 + flutter_downloader: 1.10.2 + path_provider: 2.0.15 + permission_handler: 10.2.0 + url_launcher: 6.1.11 + pointer_interceptor: ^0.9.3+4 # connectivity: ^0.4.5+6 flutter_inappwebview: path: ../ @@ -61,10 +61,12 @@ flutter: - assets/js/ - assets/css/ - assets/images/ + - assets/website/ - test_assets/ - test_assets/js/ - test_assets/css/ - test_assets/images/ + - test_assets/website/ # To add assets to your application, add an assets section, like this: # assets: diff --git a/ios/Classes/InAppWebView/InAppWebView.swift b/ios/Classes/InAppWebView/InAppWebView.swift index 1506aab5b..dee814171 100755 --- a/ios/Classes/InAppWebView/InAppWebView.swift +++ b/ios/Classes/InAppWebView/InAppWebView.swift @@ -427,8 +427,9 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, isFindInteractionEnabled = settings.isFindInteractionEnabled } - // debugging is always enabled for iOS, - // there isn't any option to set about it such as on Android. + if #available(iOS 16.4, *) { + isInspectable = settings.isInspectable + } if settings.clearCache { clearCache() @@ -464,14 +465,16 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, configuration.defaultWebpagePreferences.allowsContentJavaScript = settings.javaScriptEnabled } - if #available(iOS 14.5, *) { + if #available(iOS 15.0, *) { configuration.preferences.isTextInteractionEnabled = settings.isTextInteractionEnabled } - if #available(iOS 15.4, *) { configuration.preferences.isSiteSpecificQuirksModeEnabled = settings.isSiteSpecificQuirksModeEnabled configuration.preferences.isElementFullscreenEnabled = settings.isElementFullscreenEnabled } + if #available(iOS 16.4, *) { + configuration.preferences.shouldPrintBackgrounds = settings.shouldPrintBackgrounds + } } } @@ -1187,16 +1190,13 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, } } - if #available(iOS 14.5, *) { + if #available(iOS 15.0, *) { if newSettingsMap["upgradeKnownHostsToHTTPS"] != nil && settings?.upgradeKnownHostsToHTTPS != newSettings.upgradeKnownHostsToHTTPS { configuration.upgradeKnownHostsToHTTPS = newSettings.upgradeKnownHostsToHTTPS } if newSettingsMap["isTextInteractionEnabled"] != nil && settings?.isTextInteractionEnabled != newSettings.isTextInteractionEnabled { configuration.preferences.isTextInteractionEnabled = newSettings.isTextInteractionEnabled } - } - - if #available(iOS 15.0, *) { if newSettingsMap["underPageBackgroundColor"] != nil, settings?.underPageBackgroundColor != newSettings.underPageBackgroundColor, let underPageBackgroundColor = newSettings.underPageBackgroundColor, !underPageBackgroundColor.isEmpty { self.underPageBackgroundColor = UIColor(hexString: underPageBackgroundColor) @@ -1214,12 +1214,19 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, setMinimumViewportInset(minViewportInset, maximumViewportInset: maxViewportInset) } } - if #available(iOS 16.0, *) { if newSettingsMap["isFindInteractionEnabled"] != nil, settings?.isFindInteractionEnabled != newSettings.isFindInteractionEnabled { isFindInteractionEnabled = newSettings.isFindInteractionEnabled } } + if #available(iOS 16.4, *) { + if newSettingsMap["isInspectable"] != nil, settings?.isInspectable != newSettings.isInspectable { + isInspectable = newSettings.isInspectable + } + if newSettingsMap["shouldPrintBackgrounds"] != nil, settings?.shouldPrintBackgrounds != newSettings.shouldPrintBackgrounds { + configuration.preferences.shouldPrintBackgrounds = newSettings.shouldPrintBackgrounds + } + } scrollView.isScrollEnabled = !(newSettings.disableVerticalScroll && newSettings.disableHorizontalScroll) @@ -2738,13 +2745,21 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, self.evaluateJavaScript(""" if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { - window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)](\(json)); + window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)].resolve(\(json)); delete window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)]; } """, completionHandler: nil) } callback.error = { (code: String, message: String?, details: Any?) in - print(code + ", " + (message ?? "")) + let errorMessage = code + (message != nil ? ", " + (message ?? "") : "") + print(errorMessage) + + self.evaluateJavaScript(""" +if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { + window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)].reject(new Error('\(errorMessage.replacingOccurrences(of: "\'", with: "\\'"))')); + delete window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)]; +} +""", completionHandler: nil) } if let channelDelegate = webView.channelDelegate { diff --git a/ios/Classes/InAppWebView/InAppWebViewSettings.swift b/ios/Classes/InAppWebView/InAppWebViewSettings.swift index 98c7dd74a..c09cd9517 100755 --- a/ios/Classes/InAppWebView/InAppWebViewSettings.swift +++ b/ios/Classes/InAppWebView/InAppWebViewSettings.swift @@ -78,6 +78,8 @@ public class InAppWebViewSettings: ISettings { var isFindInteractionEnabled = false var minimumViewportInset: UIEdgeInsets? = nil var maximumViewportInset: UIEdgeInsets? = nil + var isInspectable = false + var shouldPrintBackgrounds = false override init(){ super.init() @@ -150,11 +152,9 @@ public class InAppWebViewSettings: ISettings { realSettings["limitsNavigationsToAppBoundDomains"] = configuration.limitsNavigationsToAppBoundDomains realSettings["javaScriptEnabled"] = configuration.defaultWebpagePreferences.allowsContentJavaScript } - if #available(iOS 14.5, *) { + if #available(iOS 15.0, *) { realSettings["isTextInteractionEnabled"] = configuration.preferences.isTextInteractionEnabled realSettings["upgradeKnownHostsToHTTPS"] = configuration.upgradeKnownHostsToHTTPS - } - if #available(iOS 15.0, *) { realSettings["underPageBackgroundColor"] = webView.underPageBackgroundColor.hexString } if #available(iOS 15.4, *) { @@ -168,6 +168,10 @@ public class InAppWebViewSettings: ISettings { if #available(iOS 16.0, *) { realSettings["isFindInteractionEnabled"] = webView.isFindInteractionEnabled } + if #available(iOS 16.4, *) { + realSettings["isInspectable"] = webView.isInspectable + realSettings["shouldPrintBackgrounds"] = configuration.preferences.shouldPrintBackgrounds + } } return realSettings } diff --git a/ios/Classes/PluginScriptsJS/JavaScriptBridgeJS.swift b/ios/Classes/PluginScriptsJS/JavaScriptBridgeJS.swift index cddca764a..1549c28be 100644 --- a/ios/Classes/PluginScriptsJS/JavaScriptBridgeJS.swift +++ b/ios/Classes/PluginScriptsJS/JavaScriptBridgeJS.swift @@ -26,7 +26,7 @@ window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function() { var _callHandlerID = setTimeout(function(){}); window.webkit.messageHandlers['callHandler'].postMessage( {'handlerName': arguments[0], '_callHandlerID': _callHandlerID, 'args': JSON.stringify(Array.prototype.slice.call(arguments, 1)), '_windowId': _windowId} ); return new Promise(function(resolve, reject) { - window.\(JAVASCRIPT_BRIDGE_NAME)[_callHandlerID] = resolve; + window.\(JAVASCRIPT_BRIDGE_NAME)[_callHandlerID] = {resolve: resolve, reject: reject}; }); }; \(WEB_MESSAGE_LISTENER_JS_SOURCE) diff --git a/lib/src/android/service_worker_controller.dart b/lib/src/android/service_worker_controller.dart index 8f180332b..a4ce4fafa 100644 --- a/lib/src/android/service_worker_controller.dart +++ b/lib/src/android/service_worker_controller.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'package:flutter/services.dart'; import 'webview_feature.dart'; import '../types/main.dart'; -import '../in_app_webview/in_app_webview_settings.dart'; ///Class that manages Service Workers used by [WebView]. /// @@ -121,16 +120,6 @@ class ServiceWorkerController { await _channel.invokeMethod('getCacheMode', args)); } - ///Gets how Service Workers will set the `X-Requested-With` header on HTTP requests. - ///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.REQUESTED_WITH_HEADER_CONTROL]. - /// - ///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getRequestedWithHeaderMode() - static Future getRequestedWithHeaderMode() async { - Map args = {}; - return RequestedWithHeaderMode.fromNativeValue( - await _channel.invokeMethod('getRequestedWithHeaderMode', args)); - } - ///Enables or disables content URL access from Service Workers. ///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS]. /// @@ -178,20 +167,6 @@ class ServiceWorkerController { args.putIfAbsent("mode", () => mode.toNativeValue()); await _channel.invokeMethod('setCacheMode', args); } - - ///Sets how Service Workers will set the `X-Requested-With` header on requests. - ///If you are calling this method, you may also want to call [InAppWebViewSettings.requestedWithHeaderMode] - ///with the same parameter value to configure non-ServiceWorker requests. - ///The default behavior may vary depending on the WebView implementation. - ///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.REQUESTED_WITH_HEADER_CONTROL]. - /// - ///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setRequestedWithHeaderMode(int) - static Future setRequestedWithHeaderMode( - RequestedWithHeaderMode mode) async { - Map args = {}; - args.putIfAbsent("mode", () => mode.toNativeValue()); - await _channel.invokeMethod('setRequestedWithHeaderMode', args); - } } ///Class used by clients to capture Service Worker related callbacks. diff --git a/lib/src/android/webview_feature.dart b/lib/src/android/webview_feature.dart index 0000ef29b..a2d4a3130 100644 --- a/lib/src/android/webview_feature.dart +++ b/lib/src/android/webview_feature.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/src/cookie_manager.dart'; import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart'; import '../in_app_webview/in_app_webview_controller.dart'; import '../in_app_webview/in_app_webview_settings.dart'; @@ -22,6 +23,7 @@ class WebViewFeature_ { // ignore: unused_field final String _value; + const WebViewFeature_._internal(this._value); @ExchangeableObjectMethod(ignore: true) @@ -208,10 +210,6 @@ class WebViewFeature_ { static const ALGORITHMIC_DARKENING = const WebViewFeature_._internal("ALGORITHMIC_DARKENING"); - ///This feature covers [InAppWebViewSettings.requestedWithHeaderMode]. - static const REQUESTED_WITH_HEADER_CONTROL = - const WebViewFeature_._internal("REQUESTED_WITH_HEADER_CONTROL"); - ///This feature covers [InAppWebViewSettings.enterpriseAuthenticationAppLinkPolicyEnabled]. static const ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY = const WebViewFeature_._internal( @@ -221,6 +219,14 @@ class WebViewFeature_ { static const GET_VARIATIONS_HEADER = const WebViewFeature_._internal("GET_VARIATIONS_HEADER"); + ///This feature covers cookie attributes of [CookieManager.getCookie] and [CookieManager.getCookies] methods. + static const GET_COOKIE_INFO = + const WebViewFeature_._internal("GET_COOKIE_INFO"); + + ///This feature covers cookie attributes of [CookieManager.getCookie] and [CookieManager.getCookies] methods. + static const REQUESTED_WITH_HEADER_ALLOW_LIST = + const WebViewFeature_._internal("REQUESTED_WITH_HEADER_ALLOW_LIST"); + ///Return whether a feature is supported at run-time. On devices running Android version `Build.VERSION_CODES.LOLLIPOP` and higher, ///this will check whether a feature is supported, depending on the combination of the desired feature, the Android version of device, ///and the WebView APK on the device. If running on a device with a lower API level, this will always return `false`. @@ -244,6 +250,7 @@ class AndroidWebViewFeature_ { // ignore: unused_field final String _value; + const AndroidWebViewFeature_._internal(this._value); @ExchangeableObjectMethod(ignore: true) diff --git a/lib/src/android/webview_feature.g.dart b/lib/src/android/webview_feature.g.dart index 023f3f2ae..aa330d1c0 100644 --- a/lib/src/android/webview_feature.g.dart +++ b/lib/src/android/webview_feature.g.dart @@ -48,6 +48,10 @@ class WebViewFeature { static const FORCE_DARK_STRATEGY = WebViewFeature._internal('FORCE_DARK_STRATEGY', 'FORCE_DARK_STRATEGY'); + ///This feature covers cookie attributes of [CookieManager.getCookie] and [CookieManager.getCookies] methods. + static const GET_COOKIE_INFO = + WebViewFeature._internal('GET_COOKIE_INFO', 'GET_COOKIE_INFO'); + ///This feature covers [InAppWebViewController.getVariationsHeader]. static const GET_VARIATIONS_HEADER = WebViewFeature._internal( 'GET_VARIATIONS_HEADER', 'GET_VARIATIONS_HEADER'); @@ -92,9 +96,9 @@ class WebViewFeature { static const RECEIVE_WEB_RESOURCE_ERROR = WebViewFeature._internal( 'RECEIVE_WEB_RESOURCE_ERROR', 'RECEIVE_WEB_RESOURCE_ERROR'); - ///This feature covers [InAppWebViewSettings.requestedWithHeaderMode]. - static const REQUESTED_WITH_HEADER_CONTROL = WebViewFeature._internal( - 'REQUESTED_WITH_HEADER_CONTROL', 'REQUESTED_WITH_HEADER_CONTROL'); + ///This feature covers cookie attributes of [CookieManager.getCookie] and [CookieManager.getCookies] methods. + static const REQUESTED_WITH_HEADER_ALLOW_LIST = WebViewFeature._internal( + 'REQUESTED_WITH_HEADER_ALLOW_LIST', 'REQUESTED_WITH_HEADER_ALLOW_LIST'); ///This feature covers [InAppWebViewController.setSafeBrowsingAllowlist]. static const SAFE_BROWSING_ALLOWLIST = WebViewFeature._internal( @@ -230,6 +234,7 @@ class WebViewFeature { WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, WebViewFeature.FORCE_DARK, WebViewFeature.FORCE_DARK_STRATEGY, + WebViewFeature.GET_COOKIE_INFO, WebViewFeature.GET_VARIATIONS_HEADER, WebViewFeature.GET_WEB_CHROME_CLIENT, WebViewFeature.GET_WEB_VIEW_CLIENT, @@ -241,7 +246,7 @@ class WebViewFeature { WebViewFeature.PROXY_OVERRIDE_REVERSE_BYPASS, WebViewFeature.RECEIVE_HTTP_ERROR, WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR, - WebViewFeature.REQUESTED_WITH_HEADER_CONTROL, + WebViewFeature.REQUESTED_WITH_HEADER_ALLOW_LIST, WebViewFeature.SAFE_BROWSING_ALLOWLIST, WebViewFeature.SAFE_BROWSING_ENABLE, WebViewFeature.SAFE_BROWSING_HIT, diff --git a/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart b/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart index a828546c7..6ba488130 100755 --- a/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart +++ b/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart @@ -78,25 +78,25 @@ class ChromeSafariBrowserSettings_ implements ChromeSafariBrowserOptions { /// ///**Supported Platforms/Implementations**: ///- Android - Color? toolbarBackgroundColor; + Color_? toolbarBackgroundColor; ///Sets the navigation bar color. Has no effect on Android API versions below L. /// ///**Supported Platforms/Implementations**: ///- Android - Color? navigationBarColor; + Color_? navigationBarColor; ///Sets the navigation bar divider color. Has no effect on Android API versions below P. /// ///**Supported Platforms/Implementations**: ///- Android - Color? navigationBarDividerColor; + Color_? navigationBarDividerColor; ///Sets the color of the secondary toolbar. /// ///**Supported Platforms/Implementations**: ///- Android - Color? secondaryToolbarColor; + Color_? secondaryToolbarColor; ///Set to `true` to enable the url bar to hide as the user scrolls down on the page. The default value is `false`. /// @@ -224,7 +224,7 @@ class ChromeSafariBrowserSettings_ implements ChromeSafariBrowserOptions { /// ///**Supported Platforms/Implementations**: ///- iOS - Color? preferredBarTintColor; + Color_? preferredBarTintColor; ///Set the custom color of the control buttons on the navigation bar and the toolbar. /// @@ -232,7 +232,7 @@ class ChromeSafariBrowserSettings_ implements ChromeSafariBrowserOptions { /// ///**Supported Platforms/Implementations**: ///- iOS - Color? preferredControlTintColor; + Color_? preferredControlTintColor; ///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN]. /// diff --git a/lib/src/chrome_safari_browser/chrome_safari_browser_settings.g.dart b/lib/src/chrome_safari_browser/chrome_safari_browser_settings.g.dart index 2e7738caa..165d6b293 100644 --- a/lib/src/chrome_safari_browser/chrome_safari_browser_settings.g.dart +++ b/lib/src/chrome_safari_browser/chrome_safari_browser_settings.g.dart @@ -290,8 +290,9 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions { ? UtilColor.fromStringRepresentation(map['toolbarBackgroundColor']) : null, ); - instance.additionalTrustedOrigins = - map['additionalTrustedOrigins']?.cast(); + instance.additionalTrustedOrigins = map['additionalTrustedOrigins'] != null + ? List.from(map['additionalTrustedOrigins']!.cast()) + : null; instance.alwaysUseBrowserUI = map['alwaysUseBrowserUI']; instance.barCollapsingEnabled = map['barCollapsingEnabled']; instance.dismissButtonStyle = diff --git a/lib/src/in_app_browser/in_app_browser.dart b/lib/src/in_app_browser/in_app_browser.dart index 3fd65997f..301992759 100755 --- a/lib/src/in_app_browser/in_app_browser.dart +++ b/lib/src/in_app_browser/in_app_browser.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:collection'; import 'dart:typed_data'; +import 'dart:ui'; import 'package:flutter/services.dart'; 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 68c5d53ee..b04624f0a 100755 --- a/lib/src/in_app_browser/in_app_browser_settings.dart +++ b/lib/src/in_app_browser/in_app_browser_settings.dart @@ -121,7 +121,7 @@ class InAppBrowserSettings_ ///- Android native WebView ///- iOS ///- MacOS - Color? toolbarTopBackgroundColor; + Color_? toolbarTopBackgroundColor; ///Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`. /// @@ -180,13 +180,13 @@ class InAppBrowserSettings_ /// ///**Supported Platforms/Implementations**: ///- iOS - Color? toolbarTopBarTintColor; + Color_? toolbarTopBarTintColor; ///Set the tint color to apply to the navigation items and bar button items. /// ///**Supported Platforms/Implementations**: ///- iOS - Color? toolbarTopTintColor; + Color_? toolbarTopTintColor; ///Set to `true` to hide the toolbar at the bottom of the WebView. The default value is `false`. /// @@ -198,13 +198,13 @@ class InAppBrowserSettings_ /// ///**Supported Platforms/Implementations**: ///- iOS - Color? toolbarBottomBackgroundColor; + Color_? toolbarBottomBackgroundColor; ///Set the tint color to apply to the bar button items. /// ///**Supported Platforms/Implementations**: ///- iOS - Color? toolbarBottomTintColor; + Color_? toolbarBottomTintColor; ///Set to `true` to set the toolbar at the bottom translucent. The default value is `true`. /// @@ -222,7 +222,7 @@ class InAppBrowserSettings_ /// ///**Supported Platforms/Implementations**: ///- iOS - Color? closeButtonColor; + Color_? closeButtonColor; ///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN]. /// 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 50703aabc..12ff13a78 100644 --- a/lib/src/in_app_webview/in_app_webview_controller.dart +++ b/lib/src/in_app_webview/in_app_webview_controller.dart @@ -1378,9 +1378,10 @@ class InAppWebViewController { // convert result to json try { return jsonEncode(await javaScriptHandlersMap[handlerName]!(args)); - } catch (error) { - developer.log(error.toString(), name: this.runtimeType.toString()); - return null; + } catch (error, stacktrace) { + developer.log(error.toString() + '\n' + stacktrace.toString(), + name: 'JavaScript Handler "$handlerName"'); + throw Exception(error.toString().replaceFirst('Exception: ', '')); } } break; 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 a0c4eb305..0e66139da 100755 --- a/lib/src/in_app_webview/in_app_webview_settings.dart +++ b/lib/src/in_app_webview/in_app_webview_settings.dart @@ -2,6 +2,7 @@ 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 'dart:typed_data'; import '../android/webview_asset_loader.dart'; import '../types/action_mode_menu_item.dart'; @@ -14,7 +15,6 @@ 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'; @@ -881,7 +881,7 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri apiUrl: "https://developer.android.com/reference/android/view/View#setVerticalScrollbarThumbDrawable(android.graphics.drawable.Drawable)") ]) - Color? verticalScrollbarThumbColor; + Color_? verticalScrollbarThumbColor; ///Sets the vertical scrollbar track color. @SupportedPlatforms(platforms: [ @@ -891,7 +891,7 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri apiUrl: "https://developer.android.com/reference/android/view/View#setVerticalScrollbarTrackDrawable(android.graphics.drawable.Drawable)") ]) - Color? verticalScrollbarTrackColor; + Color_? verticalScrollbarTrackColor; ///Sets the horizontal scrollbar thumb color. @SupportedPlatforms(platforms: [ @@ -901,7 +901,7 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri apiUrl: "https://developer.android.com/reference/android/view/View#setHorizontalScrollbarThumbDrawable(android.graphics.drawable.Drawable)") ]) - Color? horizontalScrollbarThumbColor; + Color_? horizontalScrollbarThumbColor; ///Sets the horizontal scrollbar track color. @SupportedPlatforms(platforms: [ @@ -911,7 +911,7 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri apiUrl: "https://developer.android.com/reference/android/view/View#setHorizontalScrollbarTrackDrawable(android.graphics.drawable.Drawable)") ]) - Color? horizontalScrollbarTrackColor; + Color_? horizontalScrollbarTrackColor; ///Control whether algorithmic darkening is allowed. /// @@ -935,17 +935,6 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri ]) 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] - ///with the same parameter value to configure ServiceWorker requests. - ///The default behavior may vary depending on the WebView implementation. - @SupportedPlatforms(platforms: [ - AndroidPlatform( - note: - "available on Android only if [WebViewFeature.REQUESTED_WITH_HEADER_CONTROL] feature is supported.") - ]) - RequestedWithHeaderMode_? requestedWithHeaderMode; - ///Sets whether EnterpriseAuthenticationAppLinkPolicy if set by admin is allowed to have any ///effect on WebView. /// @@ -968,6 +957,23 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri @SupportedPlatforms(platforms: [AndroidPlatform()]) Uint8List? defaultVideoPoster; + ///Set an allow-list of origins to receive the X-Requested-With HTTP header from the WebView owning the passed [InAppWebViewSettings]. + /// + ///Historically, this header was sent on all requests from WebView, containing the app package name of the embedding app. Depending on the version of installed WebView, this may no longer be the case, as the header was deprecated in late 2022, and its use discontinued. + /// + ///Apps can use this method to restore the legacy behavior for servers that still rely on the deprecated header, but it should not be used to identify the webview to first-party servers under the control of the app developer. + /// + ///The format of the strings in the allow-list follows the origin rules of [InAppWebViewController.addWebMessageListener]. + @SupportedPlatforms(platforms: [ + AndroidPlatform( + apiName: "WebSettingsCompat.setRequestedWithHeaderOriginAllowList", + apiUrl: + "https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setRequestedWithHeaderOriginAllowList(android.webkit.WebSettings,java.util.Set%3Cjava.lang.String%3E)", + note: + "available on Android only if [WebViewFeature.REQUESTED_WITH_HEADER_ALLOW_LIST] feature is supported.") + ]) + Set? requestedWithHeaderOriginAllowList; + ///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`. @SupportedPlatforms(platforms: [IOSPlatform()]) bool? disallowOverScroll; @@ -1357,8 +1363,10 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri /// ///Also, on MacOS: ///- [WebView.onScrollChanged] - @SupportedPlatforms( - platforms: [IOSPlatform(available: "13.0"), MacOSPlatform()]) + @SupportedPlatforms(platforms: [ + IOSPlatform(available: "13.0"), + MacOSPlatform(available: "10.15") + ]) bool? applePayAPIEnabled; ///Used in combination with [WebView.initialUrlRequest] or [WebView.initialData] (using the `file://` scheme), it represents the URL from which to read the web content. @@ -1397,13 +1405,13 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri apiUrl: "https://developer.apple.com/documentation/webkit/wkwebview/3850574-underpagebackgroundcolor") ]) - Color? underPageBackgroundColor; + Color_? underPageBackgroundColor; ///A Boolean value indicating whether text interaction is enabled or not. ///The default value is `true`. @SupportedPlatforms(platforms: [ IOSPlatform( - available: "14.5", + available: "15.0", apiName: "WKPreferences.isTextInteractionEnabled", apiUrl: "https://developer.apple.com/documentation/webkit/wkpreferences/3727362-istextinteractionenabled"), @@ -1499,6 +1507,40 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri ]) EdgeInsets? maximumViewportInset; + ///Controls whether this WebView is inspectable in Web Inspector. + /// + ///The default value is `false`. + @SupportedPlatforms(platforms: [ + IOSPlatform( + available: "16.4", + apiName: "WKWebView.isInspectable", + apiUrl: + "https://developer.apple.com/documentation/webkit/wkwebview/4111163-isinspectable"), + MacOSPlatform( + available: "13.3", + apiName: "WKWebView.isInspectable", + apiUrl: + "https://developer.apple.com/documentation/webkit/wkwebview/4111163-isinspectable") + ]) + bool? isInspectable; + + ///A Boolean value that indicates whether to include any background color or graphics when printing content. + /// + ///The default value is `false`. + @SupportedPlatforms(platforms: [ + IOSPlatform( + available: "16.4", + apiName: "WKWebView.shouldPrintBackgrounds", + apiUrl: + "https://developer.apple.com/documentation/webkit/wkpreferences/4104043-shouldprintbackgrounds"), + MacOSPlatform( + available: "13.3", + apiName: "WKWebView.shouldPrintBackgrounds", + apiUrl: + "https://developer.apple.com/documentation/webkit/wkpreferences/4104043-shouldprintbackgrounds") + ]) + bool? shouldPrintBackgrounds; + ///Specifies a feature policy for the `