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

This commit is contained in:
Lorenzo Pichilli 2022-12-15 17:43:29 +01:00
parent 0f1c7e3029
commit ae199f1dc4
71 changed files with 1012 additions and 673 deletions

View File

@ -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 ## 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) - 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 - Removed `URLProtectionSpace.iosIsProxy` property
- `historyUrl` and `baseUrl` of `InAppWebViewInitialData` can be `null` - `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 ## 5.7.2+2
- Fixed "Unexpected addWebMessageListener behaviour" [#1422](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1422) - Fixed "Unexpected addWebMessageListener behaviour" [#1422](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1422)

View File

@ -8,7 +8,7 @@ buildscript {
} }
dependencies { 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' apply plugin: 'com.android.library'
android { android {
// Conditional for compatibility with AGP <4.2.
if (project.android.hasProperty("namespace")) {
namespace 'com.pichillilorenzo.flutter_inappwebview'
}
compileSdkVersion 33 compileSdkVersion 33
defaultConfig { defaultConfig {
@ -45,9 +49,9 @@ android {
} }
} }
dependencies { dependencies {
implementation 'androidx.webkit:webkit:1.5.0' implementation 'androidx.webkit:webkit:1.6.1'
implementation 'androidx.browser:browser:1.4.0' implementation 'androidx.browser:browser:1.5.0'
implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
} }
} }

View File

@ -1,17 +1,24 @@
package com.pichillilorenzo.flutter_inappwebview; package com.pichillilorenzo.flutter_inappwebview;
import android.os.Build; import android.os.Build;
import android.util.Log;
import android.webkit.CookieManager; import android.webkit.CookieManager;
import android.webkit.CookieSyncManager; import android.webkit.CookieSyncManager;
import android.webkit.ValueCallback; import android.webkit.ValueCallback;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.webkit.CookieManagerCompat;
import androidx.webkit.WebViewFeature;
import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -30,14 +37,21 @@ public class MyCookieManager extends ChannelDelegateImpl {
@Nullable @Nullable
public InAppWebViewFlutterPlugin plugin; public InAppWebViewFlutterPlugin plugin;
public MyCookieManager(final InAppWebViewFlutterPlugin plugin) { public MyCookieManager(@NonNull final InAppWebViewFlutterPlugin plugin) {
super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME));
this.plugin = plugin; this.plugin = plugin;
cookieManager = getCookieManager(); }
public static void init() {
if (cookieManager == null) {
cookieManager = getCookieManager();
}
} }
@Override @Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
init();
switch (call.method) { switch (call.method) {
case "setCookie": case "setCookie":
{ {
@ -192,28 +206,79 @@ public class MyCookieManager extends ChannelDelegateImpl {
cookieManager = getCookieManager(); cookieManager = getCookieManager();
if (cookieManager == null) return cookieListMap; if (cookieManager == null) return cookieListMap;
String cookiesString = cookieManager.getCookie(url); List<String> cookies = new ArrayList<>();
if (WebViewFeature.isFeatureSupported(WebViewFeature.GET_COOKIE_INFO)) {
if (cookiesString != null) { cookies = CookieManagerCompat.getCookieInfo(cookieManager, url);
String[] cookies = cookiesString.split(";"); } else {
for (String cookie : cookies) { String cookiesString = cookieManager.getCookie(url);
String[] nameValue = cookie.split("=", 2); if (cookiesString != null) {
String name = nameValue[0].trim(); cookies = Arrays.asList(cookiesString.split(";"));
String value = (nameValue.length > 1) ? nameValue[1].trim() : "";
Map<String, Object> 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<String, Object> 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; return cookieListMap;
} }

View File

@ -25,20 +25,27 @@ public class MyWebStorage extends ChannelDelegateImpl {
@Nullable @Nullable
public InAppWebViewFlutterPlugin plugin; public InAppWebViewFlutterPlugin plugin;
public MyWebStorage(final InAppWebViewFlutterPlugin plugin) { public MyWebStorage(@NonNull final InAppWebViewFlutterPlugin plugin) {
super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME));
this.plugin = plugin; this.plugin = plugin;
webStorageManager = WebStorage.getInstance(); }
public static void init() {
if (webStorageManager == null) {
webStorageManager = WebStorage.getInstance();
}
} }
@Override @Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
init();
switch (call.method) { switch (call.method) {
case "getOrigins": case "getOrigins":
getOrigins(result); getOrigins(result);
break; break;
case "deleteAllData": case "deleteAllData":
if (webStorageManager == null) { if (webStorageManager != null) {
webStorageManager.deleteAllData(); webStorageManager.deleteAllData();
result.success(true); result.success(true);
} else { } else {
@ -47,7 +54,7 @@ public class MyWebStorage extends ChannelDelegateImpl {
break; break;
case "deleteOrigin": case "deleteOrigin":
{ {
if (webStorageManager == null) { if (webStorageManager != null) {
String origin = (String) call.argument("origin"); String origin = (String) call.argument("origin");
webStorageManager.deleteOrigin(origin); webStorageManager.deleteOrigin(origin);
result.success(true); result.success(true);

View File

@ -16,7 +16,7 @@ public class WebViewFeatureManager extends ChannelDelegateImpl {
@Nullable @Nullable
public InAppWebViewFlutterPlugin plugin; public InAppWebViewFlutterPlugin plugin;
public WebViewFeatureManager(final InAppWebViewFlutterPlugin plugin) { public WebViewFeatureManager(@NonNull final InAppWebViewFlutterPlugin plugin) {
super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME));
this.plugin = plugin; this.plugin = plugin;
} }

View File

@ -30,14 +30,23 @@ public class CredentialDatabaseHandler extends ChannelDelegateImpl {
@Nullable @Nullable
public InAppWebViewFlutterPlugin plugin; public InAppWebViewFlutterPlugin plugin;
public CredentialDatabaseHandler(final InAppWebViewFlutterPlugin plugin) { public CredentialDatabaseHandler(@NonNull final InAppWebViewFlutterPlugin plugin) {
super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME));
this.plugin = plugin; this.plugin = plugin;
credentialDatabase = CredentialDatabase.getInstance(plugin.applicationContext); }
public static void init(@NonNull InAppWebViewFlutterPlugin plugin) {
if (credentialDatabase == null) {
credentialDatabase = CredentialDatabase.getInstance(plugin.applicationContext);
}
} }
@Override @Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
if (plugin != null) {
init(plugin);
}
switch (call.method) { switch (call.method) {
case "getAllAuthCredentials": case "getAllAuthCredentials":
{ {

View File

@ -220,7 +220,7 @@ public class JavaScriptBridgeJS {
" var _callHandlerID = setTimeout(function(){});" + " var _callHandlerID = setTimeout(function(){});" +
" window." + JAVASCRIPT_BRIDGE_NAME + "._callHandler(arguments[0], _callHandlerID, JSON.stringify(Array.prototype.slice.call(arguments, 1)));" + " window." + JAVASCRIPT_BRIDGE_NAME + "._callHandler(arguments[0], _callHandlerID, JSON.stringify(Array.prototype.slice.call(arguments, 1)));" +
" return new Promise(function(resolve, reject) {" + " 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(){});" + " var _callHandlerID = setTimeout(function(){});" +
" window.top." + JAVASCRIPT_BRIDGE_NAME + "._callHandler(arguments[0], _callHandlerID, JSON.stringify(Array.prototype.slice.call(arguments, 1)));" + " window.top." + JAVASCRIPT_BRIDGE_NAME + "._callHandler(arguments[0], _callHandlerID, JSON.stringify(Array.prototype.slice.call(arguments, 1)));" +
" return new Promise(function(resolve, reject) {" + " return new Promise(function(resolve, reject) {" +
" window.top." + JAVASCRIPT_BRIDGE_NAME + "[_callHandlerID] = resolve;" + " window.top." + JAVASCRIPT_BRIDGE_NAME + "[_callHandlerID] = {resolve: resolve, reject: reject};" +
" });" + " });" +
" };" + " };" +
"}" + "}" +

View File

@ -25,18 +25,22 @@ public class ProxyManager extends ChannelDelegateImpl {
@Nullable @Nullable
public InAppWebViewFlutterPlugin plugin; public InAppWebViewFlutterPlugin plugin;
public ProxyManager(final InAppWebViewFlutterPlugin plugin) { public ProxyManager(@NonNull final InAppWebViewFlutterPlugin plugin) {
super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME));
this.plugin = plugin; this.plugin = plugin;
if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) { }
public static void init() {
if (proxyController == null &&
WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) {
proxyController = ProxyController.getInstance(); proxyController = ProxyController.getInstance();
} else {
proxyController = null;
} }
} }
@Override @Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
init();
switch (call.method) { switch (call.method) {
case "setProxyOverride": case "setProxyOverride":
if (proxyController != null) { if (proxyController != null) {

View File

@ -1,6 +1,5 @@
package com.pichillilorenzo.flutter_inappwebview.service_worker; package com.pichillilorenzo.flutter_inappwebview.service_worker;
import android.annotation.SuppressLint;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -16,7 +15,6 @@ import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl;
import com.pichillilorenzo.flutter_inappwebview.types.SyncBaseCallbackResultImpl; import com.pichillilorenzo.flutter_inappwebview.types.SyncBaseCallbackResultImpl;
import com.pichillilorenzo.flutter_inappwebview.types.WebResourceRequestExt; import com.pichillilorenzo.flutter_inappwebview.types.WebResourceRequestExt;
import com.pichillilorenzo.flutter_inappwebview.types.WebResourceResponseExt; import com.pichillilorenzo.flutter_inappwebview.types.WebResourceResponseExt;
import com.pichillilorenzo.flutter_inappwebview.webview.WebViewChannelDelegate;
import java.util.Map; import java.util.Map;
@ -33,9 +31,9 @@ public class ServiceWorkerChannelDelegate extends ChannelDelegateImpl {
this.serviceWorkerManager = serviceWorkerManager; this.serviceWorkerManager = serviceWorkerManager;
} }
@SuppressLint("RestrictedApi")
@Override @Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
ServiceWorkerManager.init();
ServiceWorkerControllerCompat serviceWorkerController = ServiceWorkerManager.serviceWorkerController; ServiceWorkerControllerCompat serviceWorkerController = ServiceWorkerManager.serviceWorkerController;
ServiceWorkerWebSettingsCompat serviceWorkerWebSettings = (serviceWorkerController != null) ? ServiceWorkerWebSettingsCompat serviceWorkerWebSettings = (serviceWorkerController != null) ?
serviceWorkerController.getServiceWorkerWebSettings() : null; serviceWorkerController.getServiceWorkerWebSettings() : null;
@ -71,13 +69,6 @@ public class ServiceWorkerChannelDelegate extends ChannelDelegateImpl {
result.success(false); result.success(false);
} }
break; break;
case "getRequestedWithHeaderMode":
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.REQUESTED_WITH_HEADER_CONTROL)) {
result.success(serviceWorkerWebSettings.getRequestedWithHeaderMode());
} else {
result.success(null);
}
break;
case "getCacheMode": case "getCacheMode":
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_CACHE_MODE)) { if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_CACHE_MODE)) {
result.success(serviceWorkerWebSettings.getCacheMode()); result.success(serviceWorkerWebSettings.getCacheMode());
@ -113,13 +104,6 @@ public class ServiceWorkerChannelDelegate extends ChannelDelegateImpl {
} }
result.success(true); result.success(true);
break; 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: default:
result.notImplemented(); result.notImplemented();
} }

View File

@ -33,14 +33,16 @@ public class ServiceWorkerManager implements Disposable {
@Nullable @Nullable
public InAppWebViewFlutterPlugin plugin; public InAppWebViewFlutterPlugin plugin;
public ServiceWorkerManager(final InAppWebViewFlutterPlugin plugin) { public ServiceWorkerManager(@NonNull final InAppWebViewFlutterPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
final MethodChannel channel = new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME); final MethodChannel channel = new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME);
this.channelDelegate = new ServiceWorkerChannelDelegate(this, channel); 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(); serviceWorkerController = ServiceWorkerControllerCompat.getInstance();
} else {
serviceWorkerController = null;
} }
} }

View File

@ -27,6 +27,7 @@ public class TracingControllerChannelDelegate extends ChannelDelegateImpl {
@Override @Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
TracingControllerManager.init();
TracingController tracingController = TracingControllerManager.tracingController; TracingController tracingController = TracingControllerManager.tracingController;
switch (call.method) { switch (call.method) {

View File

@ -1,6 +1,7 @@
package com.pichillilorenzo.flutter_inappwebview.tracing; package com.pichillilorenzo.flutter_inappwebview.tracing;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.webkit.ProxyController;
import androidx.webkit.TracingConfig; import androidx.webkit.TracingConfig;
import androidx.webkit.TracingController; import androidx.webkit.TracingController;
import androidx.webkit.WebViewFeature; import androidx.webkit.WebViewFeature;
@ -25,10 +26,12 @@ public class TracingControllerManager implements Disposable {
this.plugin = plugin; this.plugin = plugin;
final MethodChannel channel = new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME); final MethodChannel channel = new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME);
this.channelDelegate = new TracingControllerChannelDelegate(this, channel); 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(); tracingController = TracingController.getInstance();
} else {
tracingController = null;
} }
} }

View File

@ -130,7 +130,7 @@ public class JavaScriptBridgeInterface {
return; return;
} }
String sourceCode = "if (window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "] != null) { " + 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 + "]; " + "delete window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "]; " +
"}"; "}";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
@ -143,7 +143,24 @@ public class JavaScriptBridgeInterface {
@Override @Override
public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { 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<String>) null);
}
else {
inAppWebView.loadUrl("javascript:" + sourceCode);
}
} }
}); });
} }

View File

@ -433,13 +433,13 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
WebSettingsCompat.setAlgorithmicDarkeningAllowed(settings, customSettings.algorithmicDarkeningAllowed); 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)) { if (WebViewFeature.isFeatureSupported(WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY)) {
WebSettingsCompat.setEnterpriseAuthenticationAppLinkPolicyEnabled(settings, customSettings.enterpriseAuthenticationAppLinkPolicyEnabled); 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(); contentBlockerHandler.getRuleList().clear();
for (Map<String, Map<String, Object>> contentBlocker : customSettings.contentBlockers) { for (Map<String, Map<String, Object>> contentBlocker : customSettings.contentBlockers) {
@ -1089,17 +1089,16 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
WebSettingsCompat.setAlgorithmicDarkeningAllowed(settings, newCustomSettings.algorithmicDarkeningAllowed); 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 && if (newSettingsMap.get("enterpriseAuthenticationAppLinkPolicyEnabled") != null &&
!Util.objEquals(customSettings.enterpriseAuthenticationAppLinkPolicyEnabled, newCustomSettings.enterpriseAuthenticationAppLinkPolicyEnabled) && !Util.objEquals(customSettings.enterpriseAuthenticationAppLinkPolicyEnabled, newCustomSettings.enterpriseAuthenticationAppLinkPolicyEnabled) &&
WebViewFeature.isFeatureSupported(WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY)) { WebViewFeature.isFeatureSupported(WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY)) {
WebSettingsCompat.setEnterpriseAuthenticationAppLinkPolicyEnabled(settings, newCustomSettings.enterpriseAuthenticationAppLinkPolicyEnabled); 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 (plugin != null) {
if (webViewAssetLoaderExt != null) { if (webViewAssetLoaderExt != null) {

View File

@ -19,8 +19,10 @@ import com.pichillilorenzo.flutter_inappwebview.webview.InAppWebViewInterface;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
public class InAppWebViewSettings implements ISettings<InAppWebViewInterface> { public class InAppWebViewSettings implements ISettings<InAppWebViewInterface> {
@ -115,13 +117,13 @@ public class InAppWebViewSettings implements ISettings<InAppWebViewInterface> {
@Nullable @Nullable
public String horizontalScrollbarTrackColor; public String horizontalScrollbarTrackColor;
public Boolean algorithmicDarkeningAllowed = false; public Boolean algorithmicDarkeningAllowed = false;
@Nullable
public Integer requestedWithHeaderMode;
public Boolean enterpriseAuthenticationAppLinkPolicyEnabled = true; public Boolean enterpriseAuthenticationAppLinkPolicyEnabled = true;
@Nullable @Nullable
public Map<String, Object> webViewAssetLoader; public Map<String, Object> webViewAssetLoader;
@Nullable @Nullable
public byte[] defaultVideoPoster; public byte[] defaultVideoPoster;
@Nullable
public Set<String> requestedWithHeaderOriginAllowList;
@NonNull @NonNull
@Override @Override
@ -383,9 +385,6 @@ public class InAppWebViewSettings implements ISettings<InAppWebViewInterface> {
case "algorithmicDarkeningAllowed": case "algorithmicDarkeningAllowed":
algorithmicDarkeningAllowed = (Boolean) value; algorithmicDarkeningAllowed = (Boolean) value;
break; break;
case "requestedWithHeaderMode":
requestedWithHeaderMode = (Integer) value;
break;
case "enterpriseAuthenticationAppLinkPolicyEnabled": case "enterpriseAuthenticationAppLinkPolicyEnabled":
enterpriseAuthenticationAppLinkPolicyEnabled = (Boolean) value; enterpriseAuthenticationAppLinkPolicyEnabled = (Boolean) value;
break; break;
@ -398,6 +397,9 @@ public class InAppWebViewSettings implements ISettings<InAppWebViewInterface> {
case "defaultVideoPoster": case "defaultVideoPoster":
defaultVideoPoster = (byte[]) value; defaultVideoPoster = (byte[]) value;
break; break;
case "requestedWithHeaderOriginAllowList":
requestedWithHeaderOriginAllowList = new HashSet<>((List<String>) value);
break;
} }
} }
@ -491,10 +493,11 @@ public class InAppWebViewSettings implements ISettings<InAppWebViewInterface> {
settings.put("horizontalScrollbarThumbColor", horizontalScrollbarThumbColor); settings.put("horizontalScrollbarThumbColor", horizontalScrollbarThumbColor);
settings.put("horizontalScrollbarTrackColor", horizontalScrollbarTrackColor); settings.put("horizontalScrollbarTrackColor", horizontalScrollbarTrackColor);
settings.put("algorithmicDarkeningAllowed", algorithmicDarkeningAllowed); settings.put("algorithmicDarkeningAllowed", algorithmicDarkeningAllowed);
settings.put("requestedWithHeaderMode", requestedWithHeaderMode);
settings.put("enterpriseAuthenticationAppLinkPolicyEnabled", enterpriseAuthenticationAppLinkPolicyEnabled); settings.put("enterpriseAuthenticationAppLinkPolicyEnabled", enterpriseAuthenticationAppLinkPolicyEnabled);
settings.put("allowBackgroundAudioPlaying", allowBackgroundAudioPlaying); settings.put("allowBackgroundAudioPlaying", allowBackgroundAudioPlaying);
settings.put("defaultVideoPoster", defaultVideoPoster); settings.put("defaultVideoPoster", defaultVideoPoster);
settings.put("requestedWithHeaderOriginAllowList",
requestedWithHeaderOriginAllowList != null ? new ArrayList<>(requestedWithHeaderOriginAllowList) : null);
return settings; return settings;
} }
@ -586,12 +589,12 @@ public class InAppWebViewSettings implements ISettings<InAppWebViewInterface> {
if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
realSettings.put("algorithmicDarkeningAllowed", WebSettingsCompat.isAlgorithmicDarkeningAllowed(settings)); 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)) { if (WebViewFeature.isFeatureSupported(WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY)) {
realSettings.put("enterpriseAuthenticationAppLinkPolicyEnabled", WebSettingsCompat.getEnterpriseAuthenticationAppLinkPolicyEnabled(settings)); 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; return realSettings;
} }

View File

@ -23,25 +23,25 @@ class ExchangeableEnumGenerator
// Visits all the children of element in no particular order. // Visits all the children of element in no particular order.
element.visitChildren(visitor); element.visitChildren(visitor);
final className = visitor.constructor.returnType.element2.name; final className = visitor.constructor.returnType.element.name;
// remove "_" to generate the correct class name // remove "_" to generate the correct class name
final extClassName = className.replaceFirst("_", ""); final extClassName = className.replaceFirst("_", "");
final classBuffer = StringBuffer(); final classBuffer = StringBuffer();
final classDocs = final classDocs =
visitor.constructor.returnType.element2.documentationComment; visitor.constructor.returnType.element.documentationComment;
if (classDocs != null) { if (classDocs != null) {
classBuffer.writeln(classDocs); classBuffer.writeln(classDocs);
} }
final classSupportedDocs = Util.getSupportedDocs( final classSupportedDocs = Util.getSupportedDocs(
_coreCheckerEnumSupportedPlatforms, _coreCheckerEnumSupportedPlatforms,
visitor.constructor.returnType.element2); visitor.constructor.returnType.element);
if (classSupportedDocs != null) { if (classSupportedDocs != null) {
classBuffer.writeln(classSupportedDocs); classBuffer.writeln(classSupportedDocs);
} }
if (visitor.constructor.returnType.element2.hasDeprecated) { if (visitor.constructor.returnType.element.hasDeprecated) {
classBuffer.writeln( 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 {'); classBuffer.writeln('class $extClassName {');

View File

@ -29,35 +29,37 @@ class ExchangeableObjectGenerator
// Visits all the children of element in no particular order. // Visits all the children of element in no particular order.
element.visitChildren(visitor); element.visitChildren(visitor);
final className = visitor.constructor.returnType.element2.name; final className = visitor.constructor.returnType.element.name;
final superClass = final superClass =
visitor.constructor.returnType.superclass?.element2.name != 'Object' visitor.constructor.returnType.superclass?.element.name != 'Object'
? visitor.constructor.returnType.superclass ? visitor.constructor.returnType.superclass
: null; : null;
final interfaces = visitor.constructor.returnType.interfaces; 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 // remove "_" to generate the correct class name
final extClassName = className.replaceFirst("_", ""); final extClassName = className.replaceFirst("_", "");
final classBuffer = StringBuffer(); final classBuffer = StringBuffer();
final classDocs = final classDocs =
visitor.constructor.returnType.element2.documentationComment; visitor.constructor.returnType.element.documentationComment;
if (classDocs != null) { if (classDocs != null) {
classBuffer.writeln(classDocs); classBuffer.writeln(classDocs);
} }
final classSupportedDocs = Util.getSupportedDocs( final classSupportedDocs = Util.getSupportedDocs(
_coreCheckerSupportedPlatforms, visitor.constructor.returnType.element2); _coreCheckerSupportedPlatforms, visitor.constructor.returnType.element);
if (classSupportedDocs != null) { if (classSupportedDocs != null) {
classBuffer.writeln(classSupportedDocs); classBuffer.writeln(classSupportedDocs);
} }
if (visitor.constructor.returnType.element2.hasDeprecated) { if (visitor.constructor.returnType.element.hasDeprecated) {
classBuffer.writeln( 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) { 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) { if (superClass != null) {
classBuffer.writeln(' extends ${superClassName}'); classBuffer.writeln(' extends ${superClassName}');
@ -174,7 +176,7 @@ class ExchangeableObjectGenerator
if (constructorSupportedDocs == null) { if (constructorSupportedDocs == null) {
constructorSupportedDocs = Util.getSupportedDocs( constructorSupportedDocs = Util.getSupportedDocs(
_coreCheckerSupportedPlatforms, _coreCheckerSupportedPlatforms,
visitor.constructor.returnType.element2); visitor.constructor.returnType.element);
} }
if (constructorSupportedDocs != null) { if (constructorSupportedDocs != null) {
classBuffer.writeln(constructorSupportedDocs); classBuffer.writeln(constructorSupportedDocs);
@ -233,11 +235,13 @@ class ExchangeableObjectGenerator
.trim(); .trim();
final fieldElement = visitor.fields[fieldName]; final fieldElement = visitor.fields[fieldName];
if (fieldElement != null) { if (fieldElement != null) {
final fieldTypeElement = fieldElement.type.element2; final fieldTypeElement = fieldElement.type.element;
final deprecatedFieldTypeElement = deprecatedField.type.element2; final deprecatedFieldTypeElement = deprecatedField.type.element;
final isNullable = Util.typeIsNullable(fieldElement.type); 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) { if (!isNullable && hasDefaultValue) {
continue; continue;
} }
@ -267,10 +271,14 @@ class ExchangeableObjectGenerator
} else if (hasFromValue && deprecatedHasToValue) { } else if (hasFromValue && deprecatedHasToValue) {
classBuffer.write(fieldTypeElement.name!.replaceFirst("_", "") + classBuffer.write(fieldTypeElement.name!.replaceFirst("_", "") +
'.fromValue($deprecatedFieldName${deprecatedIsNullable ? '?' : ''}.toValue())${!isNullable ? '!' : ''}'); '.fromValue($deprecatedFieldName${deprecatedIsNullable ? '?' : ''}.toValue())${!isNullable ? '!' : ''}');
} else if (deprecatedField.type.getDisplayString(withNullability: false) == "Uri" && } else if (deprecatedField.type
fieldElement.type.getDisplayString(withNullability: false) == "WebUri") { .getDisplayString(withNullability: false) ==
"Uri" &&
fieldElement.type.getDisplayString(withNullability: false) ==
"WebUri") {
if (deprecatedIsNullable) { if (deprecatedIsNullable) {
classBuffer.write("($deprecatedFieldName != null ? WebUri.uri($deprecatedFieldName!) : ${isNullable ? "null" : "WebUri('')"})"); classBuffer.write(
"($deprecatedFieldName != null ? WebUri.uri($deprecatedFieldName!) : ${isNullable ? "null" : "WebUri('')"})");
} else { } else {
classBuffer.write("WebUri.uri($deprecatedFieldName)"); classBuffer.write("WebUri.uri($deprecatedFieldName)");
} }
@ -288,8 +296,9 @@ class ExchangeableObjectGenerator
classBuffer.writeln(';'); classBuffer.writeln(';');
} }
if (annotation.read("fromMapFactory").boolValue && (!visitor.methods.containsKey("fromMap") || if (annotation.read("fromMapFactory").boolValue &&
Util.methodHasIgnore(visitor.methods['fromMap']!))) { (!visitor.methods.containsKey("fromMap") ||
Util.methodHasIgnore(visitor.methods['fromMap']!))) {
classBuffer.writeln( classBuffer.writeln(
'///Gets a possible [$extClassName] instance from a [Map] value.'); '///Gets a possible [$extClassName] instance from a [Map] value.');
final nullable = annotation.read("nullableFromMapFactory").boolValue; final nullable = annotation.read("nullableFromMapFactory").boolValue;
@ -303,7 +312,7 @@ class ExchangeableObjectGenerator
classBuffer.writeln('final instance = $extClassName('); classBuffer.writeln('final instance = $extClassName(');
final fieldElements = <FieldElement>[]; final fieldElements = <FieldElement>[];
if (superClass != null) { if (superClass != null) {
fieldElements.addAll(superClass.element2.fields); fieldElements.addAll(superClass.element.fields);
} }
fieldElements.addAll(fieldValuesSorted); fieldElements.addAll(fieldValuesSorted);
final nonRequiredFields = <String>[]; final nonRequiredFields = <String>[];
@ -332,7 +341,7 @@ class ExchangeableObjectGenerator
?.toFunctionValue(); ?.toFunctionValue();
if (customDeserializer != null) { if (customDeserializer != null) {
final deserializerClassName = final deserializerClassName =
customDeserializer.enclosingElement3.name; customDeserializer.enclosingElement.name;
if (deserializerClassName != null) { if (deserializerClassName != null) {
value = value =
"$deserializerClassName.${customDeserializer.name}($value)"; "$deserializerClassName.${customDeserializer.name}($value)";
@ -387,8 +396,9 @@ class ExchangeableObjectGenerator
} }
} }
if (annotation.read("toMapMethod").boolValue && (!visitor.methods.containsKey("toMap") || if (annotation.read("toMapMethod").boolValue &&
Util.methodHasIgnore(visitor.methods['toMap']!))) { (!visitor.methods.containsKey("toMap") ||
Util.methodHasIgnore(visitor.methods['toMap']!))) {
classBuffer.writeln('///Converts instance to a map.'); classBuffer.writeln('///Converts instance to a map.');
classBuffer.writeln('Map<String, dynamic> toMap() {'); classBuffer.writeln('Map<String, dynamic> toMap() {');
classBuffer.writeln('return {'); classBuffer.writeln('return {');
@ -404,7 +414,7 @@ class ExchangeableObjectGenerator
} }
final fieldElements = <FieldElement>[]; final fieldElements = <FieldElement>[];
if (superClass != null) { if (superClass != null) {
for (final fieldElement in superClass.element2.fields) { for (final fieldElement in superClass.element.fields) {
if (!fieldElement.isPrivate && if (!fieldElement.isPrivate &&
!fieldElement.hasDeprecated && !fieldElement.hasDeprecated &&
!fieldElement.isStatic && !fieldElement.isStatic &&
@ -434,7 +444,7 @@ class ExchangeableObjectGenerator
?.getField("serializer") ?.getField("serializer")
?.toFunctionValue(); ?.toFunctionValue();
if (customSerializer != null) { if (customSerializer != null) {
final serializerClassName = customSerializer.enclosingElement3.name; final serializerClassName = customSerializer.enclosingElement.name;
if (serializerClassName != null) { if (serializerClassName != null) {
mapValue = mapValue =
"$serializerClassName.${customSerializer.name}($mapValue)"; "$serializerClassName.${customSerializer.name}($mapValue)";
@ -452,30 +462,34 @@ class ExchangeableObjectGenerator
classBuffer.writeln('}'); classBuffer.writeln('}');
} }
if (annotation.read("toJsonMethod").boolValue && (!visitor.methods.containsKey("toJson") || if (annotation.read("toJsonMethod").boolValue &&
Util.methodHasIgnore(visitor.methods['toJson']!))) { (!visitor.methods.containsKey("toJson") ||
Util.methodHasIgnore(visitor.methods['toJson']!))) {
classBuffer.writeln('///Converts instance to a map.'); classBuffer.writeln('///Converts instance to a map.');
classBuffer.writeln('Map<String, dynamic> toJson() {'); classBuffer.writeln('Map<String, dynamic> toJson() {');
classBuffer.writeln('return toMap();'); classBuffer.writeln('return toMap();');
classBuffer.writeln('}'); classBuffer.writeln('}');
} }
if (annotation.read("copyMethod").boolValue && (!visitor.methods.containsKey("copy") || if (annotation.read("copyMethod").boolValue &&
Util.methodHasIgnore(visitor.methods['copy']!))) { (!visitor.methods.containsKey("copy") ||
Util.methodHasIgnore(visitor.methods['copy']!))) {
classBuffer.writeln('///Returns a copy of $extClassName.'); classBuffer.writeln('///Returns a copy of $extClassName.');
classBuffer.writeln('$extClassName copy() {'); classBuffer.writeln('$extClassName copy() {');
classBuffer.writeln('return $extClassName.fromMap(toMap()) ?? $extClassName();'); classBuffer
.writeln('return $extClassName.fromMap(toMap()) ?? $extClassName();');
classBuffer.writeln('}'); classBuffer.writeln('}');
} }
if (annotation.read("toStringMethod").boolValue && (!visitor.methods.containsKey("toString") || if (annotation.read("toStringMethod").boolValue &&
Util.methodHasIgnore(visitor.methods['toString']!))) { (!visitor.methods.containsKey("toString") ||
Util.methodHasIgnore(visitor.methods['toString']!))) {
classBuffer.writeln('@override'); classBuffer.writeln('@override');
classBuffer.writeln('String toString() {'); classBuffer.writeln('String toString() {');
classBuffer.write('return \'$extClassName{'); classBuffer.write('return \'$extClassName{');
final fieldNames = <String>[]; final fieldNames = <String>[];
if (superClass != null) { if (superClass != null) {
for (final fieldElement in superClass.element2.fields) { for (final fieldElement in superClass.element.fields) {
final fieldName = fieldElement.name; final fieldName = fieldElement.name;
if (!fieldElement.isPrivate && if (!fieldElement.isPrivate &&
!fieldElement.hasDeprecated && !fieldElement.hasDeprecated &&
@ -505,34 +519,32 @@ class ExchangeableObjectGenerator
} }
String getFromMapValue(String value, DartType elementType) { String getFromMapValue(String value, DartType elementType) {
final fieldTypeElement = elementType.element2; final fieldTypeElement = elementType.element;
final isNullable = Util.typeIsNullable(elementType); final isNullable = Util.typeIsNullable(elementType);
if (elementType.getDisplayString(withNullability: false) == "Uri") { final displayString = elementType.getDisplayString(withNullability: false);
if (displayString == "Uri") {
if (!isNullable) { if (!isNullable) {
return "(Uri.tryParse($value) ?? Uri())"; return "(Uri.tryParse($value) ?? Uri())";
} else { } else {
return "$value != null ? Uri.tryParse($value) : null"; return "$value != null ? Uri.tryParse($value) : null";
} }
} else if (elementType.getDisplayString(withNullability: false) == "WebUri") { } else if (displayString == "WebUri") {
if (!isNullable) { if (!isNullable) {
return "WebUri($value)"; return "WebUri($value)";
} else { } else {
return "$value != null ? WebUri($value) : null"; return "$value != null ? WebUri($value) : null";
} }
} else if (elementType.getDisplayString(withNullability: false) == } else if (displayString == "Color" || displayString == "Color_") {
"Color") {
if (!isNullable) { if (!isNullable) {
return "UtilColor.fromStringRepresentation($value)!"; return "UtilColor.fromStringRepresentation($value)!";
} else { } else {
return "$value != null ? UtilColor.fromStringRepresentation($value) : null"; return "$value != null ? UtilColor.fromStringRepresentation($value) : null";
} }
} else if (elementType.getDisplayString(withNullability: false) == } else if (displayString == "EdgeInsets") {
"EdgeInsets") {
return "MapEdgeInsets.fromMap($value?.cast<String, dynamic>())${!isNullable ? '!' : ''}"; return "MapEdgeInsets.fromMap($value?.cast<String, dynamic>())${!isNullable ? '!' : ''}";
} else if (elementType.getDisplayString(withNullability: false) == "Size") { } else if (displayString == "Size") {
return "MapSize.fromMap($value?.cast<String, dynamic>())${!isNullable ? '!' : ''}"; return "MapSize.fromMap($value?.cast<String, dynamic>())${!isNullable ? '!' : ''}";
} else if (elementType.getDisplayString(withNullability: false) == } else if (displayString == "DateTime") {
"DateTime") {
if (!isNullable) { if (!isNullable) {
return "DateTime.fromMillisecondsSinceEpoch($value)!"; return "DateTime.fromMillisecondsSinceEpoch($value)!";
} else { } else {
@ -541,7 +553,9 @@ class ExchangeableObjectGenerator
} else if (elementType.isDartCoreList || elementType.isDartCoreSet) { } else if (elementType.isDartCoreList || elementType.isDartCoreSet) {
final genericTypes = Util.getGenericTypes(elementType); final genericTypes = Util.getGenericTypes(elementType);
final genericType = genericTypes.isNotEmpty ? genericTypes.first : null; 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)) { if (genericType != null && !Util.isDartCoreType(genericType)) {
final genericTypeFieldName = 'e'; final genericTypeFieldName = 'e';
return (isNullable ? '$value != null ? ' : '') + return (isNullable ? '$value != null ? ' : '') +
@ -553,7 +567,10 @@ class ExchangeableObjectGenerator
(isNullable ? ' : null' : ''); (isNullable ? ' : null' : '');
} else { } else {
if (genericType != null) { if (genericType != null) {
return "$value${isNullable ? '?' : ''}.cast<${genericTypeReplaced}>()"; return (isNullable ? '$value != null ? ' : '') +
"${elementType.isDartCoreSet ? 'Set' : 'List'}<$genericTypeReplaced>.from(" +
"$value!.cast<${genericTypeReplaced}>())" +
(isNullable ? ' : null' : '');
} else { } else {
return value; return value;
} }
@ -592,22 +609,20 @@ class ExchangeableObjectGenerator
} }
String getToMapValue(String fieldName, DartType elementType) { String getToMapValue(String fieldName, DartType elementType) {
final fieldTypeElement = elementType.element2; final fieldTypeElement = elementType.element;
final isNullable = Util.typeIsNullable(elementType); final isNullable = Util.typeIsNullable(elementType);
if (elementType.getDisplayString(withNullability: false) == "Uri") { final displayString = elementType.getDisplayString(withNullability: false);
if (displayString == "Uri") {
return fieldName + (isNullable ? '?' : '') + '.toString()'; return fieldName + (isNullable ? '?' : '') + '.toString()';
} else if (elementType.getDisplayString(withNullability: false) == "WebUri") { } else if (displayString == "WebUri") {
return fieldName + (isNullable ? '?' : '') + '.toString()'; return fieldName + (isNullable ? '?' : '') + '.toString()';
} else if (elementType.getDisplayString(withNullability: false) == } else if (displayString == "Color" || displayString == "Color_") {
"Color") {
return fieldName + (isNullable ? '?' : '') + '.toHex()'; return fieldName + (isNullable ? '?' : '') + '.toHex()';
} else if (elementType.getDisplayString(withNullability: false) == } else if (displayString == "EdgeInsets") {
"EdgeInsets") {
return fieldName + (isNullable ? '?' : '') + '.toMap()'; return fieldName + (isNullable ? '?' : '') + '.toMap()';
} else if (elementType.getDisplayString(withNullability: false) == "Size") { } else if (displayString == "Size") {
return fieldName + (isNullable ? '?' : '') + '.toMap()'; return fieldName + (isNullable ? '?' : '') + '.toMap()';
} else if (elementType.getDisplayString(withNullability: false) == } else if (displayString == "DateTime") {
"DateTime") {
return fieldName + (isNullable ? '?' : '') + '.millisecondsSinceEpoch'; return fieldName + (isNullable ? '?' : '') + '.millisecondsSinceEpoch';
} else if (elementType.isDartCoreList || elementType.isDartCoreSet) { } else if (elementType.isDartCoreList || elementType.isDartCoreSet) {
final genericType = Util.getGenericTypes(elementType).first; final genericType = Util.getGenericTypes(elementType).first;
@ -619,7 +634,9 @@ class ExchangeableObjectGenerator
getToMapValue('$genericTypeFieldName', genericType) + getToMapValue('$genericTypeFieldName', genericType) +
').toList()'; ').toList()';
} else { } else {
return elementType.isDartCoreSet ? "$fieldName${(isNullable ? '?' : '')}.toList()" : fieldName; return elementType.isDartCoreSet
? "$fieldName${(isNullable ? '?' : '')}.toList()"
: fieldName;
} }
} else if (fieldTypeElement != null && hasToMapMethod(fieldTypeElement)) { } else if (fieldTypeElement != null && hasToMapMethod(fieldTypeElement)) {
return fieldName + return fieldName +

View File

@ -82,7 +82,7 @@ abstract class Util {
} }
static bool canHaveGenerics(DartType type) { static bool canHaveGenerics(DartType type) {
final element = type.element2; final element = type.element;
if (element is ClassElement) { if (element is ClassElement) {
return element.typeParameters.isNotEmpty; return element.typeParameters.isNotEmpty;
} }
@ -104,6 +104,6 @@ abstract class Util {
type.isDartCoreSet || type.isDartCoreSet ||
type.isDartCoreString || type.isDartCoreString ||
type.isDartCoreSymbol || type.isDartCoreSymbol ||
type.isDynamic; type is DynamicType;
} }
} }

View File

@ -5,177 +5,202 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: _fe_analyzer_shared name: _fe_analyzer_shared
url: "https://pub.dartlang.org" sha256: "405666cd3cf0ee0a48d21ec67e65406aad2c726d9fa58840d3375e7bdcd32a07"
url: "https://pub.dev"
source: hosted source: hosted
version: "49.0.0" version: "60.0.0"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" sha256: "1952250bd005bacb895a01bf1b4dc00e3ba1c526cf47dca54dfe24979c65f5b3"
url: "https://pub.dev"
source: hosted source: hosted
version: "5.1.0" version: "5.12.0"
args: args:
dependency: transitive dependency: transitive
description: description:
name: args name: args
url: "https://pub.dartlang.org" sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a
url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.1" version: "2.4.1"
async: async:
dependency: transitive dependency: transitive
description: description:
name: async name: async
url: "https://pub.dartlang.org" sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.9.0" version: "2.11.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
build: build:
dependency: "direct main" dependency: "direct main"
description: description:
name: build name: build
url: "https://pub.dartlang.org" sha256: "43865b79fbb78532e4bff7c33087aa43b1d488c4fdef014eaef568af6d8016dc"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.1" version: "2.4.0"
build_config: build_config:
dependency: transitive dependency: transitive
description: description:
name: build_config name: build_config
url: "https://pub.dartlang.org" sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
build_daemon: build_daemon:
dependency: transitive dependency: transitive
description: description:
name: build_daemon name: build_daemon
url: "https://pub.dartlang.org" sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.0" version: "4.0.0"
build_resolvers: build_resolvers:
dependency: transitive dependency: transitive
description: description:
name: build_resolvers name: build_resolvers
url: "https://pub.dartlang.org" sha256: db49b8609ef8c81cca2b310618c3017c00f03a92af44c04d310b907b2d692d95
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.10" version: "2.2.0"
build_runner: build_runner:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_runner name: build_runner
url: "https://pub.dartlang.org" sha256: "87e06c939450b9b94e3e1bb2d46e0e9780adbff5500d3969f2ba2de6bbb860cb"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.1" version: "2.4.2"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
name: build_runner_core name: build_runner_core
url: "https://pub.dartlang.org" sha256: "30859c90e9ddaccc484f56303931f477b1f1ba2bab74aa32ed5d6ce15870f8cf"
url: "https://pub.dev"
source: hosted source: hosted
version: "7.2.4" version: "7.2.8"
build_test: build_test:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_test name: build_test
url: "https://pub.dartlang.org" sha256: "927ef98b58c5603ec58923c0bb943a74743e58149732665885bb1eb92983befe"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.5" version: "2.1.7"
built_collection: built_collection:
dependency: transitive dependency: transitive
description: description:
name: built_collection name: built_collection
url: "https://pub.dartlang.org" sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
url: "https://pub.dev"
source: hosted source: hosted
version: "5.1.1" version: "5.1.1"
built_value: built_value:
dependency: transitive dependency: transitive
description: description:
name: built_value name: built_value
url: "https://pub.dartlang.org" sha256: "2f17434bd5d52a26762043d6b43bb53b3acd029b4d9071a329f46d67ef297e6d"
url: "https://pub.dev"
source: hosted source: hosted
version: "8.4.1" version: "8.5.0"
characters: characters:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
url: "https://pub.dartlang.org" sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.3.0"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
name: checked_yaml name: checked_yaml
url: "https://pub.dartlang.org" sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "2.0.3"
code_builder: code_builder:
dependency: transitive dependency: transitive
description: description:
name: code_builder name: code_builder
url: "https://pub.dartlang.org" sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe"
url: "https://pub.dev"
source: hosted source: hosted
version: "4.3.0" version: "4.4.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.16.0" version: "1.17.1"
convert: convert:
dependency: transitive dependency: transitive
description: description:
name: convert name: convert
url: "https://pub.dartlang.org" sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.1.1"
coverage: coverage:
dependency: transitive dependency: transitive
description: description:
name: coverage name: coverage
url: "https://pub.dartlang.org" sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.6.1" version: "1.6.3"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
name: crypto name: crypto
url: "https://pub.dartlang.org" sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.0.3"
csslib: csslib:
dependency: transitive dependency: transitive
description: description:
name: csslib name: csslib
url: "https://pub.dartlang.org" sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745
url: "https://pub.dev"
source: hosted source: hosted
version: "0.17.2" version: "0.17.2"
dart_style: dart_style:
dependency: transitive dependency: transitive
description: description:
name: dart_style name: dart_style
url: "https://pub.dartlang.org" sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad
url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.4" version: "2.3.1"
file: file:
dependency: transitive dependency: transitive
description: description:
name: file name: file
url: "https://pub.dartlang.org" sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.4" version: "6.1.4"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
name: fixnum name: fixnum
url: "https://pub.dartlang.org" sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.1.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -185,177 +210,210 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_inappwebview_internal_annotations name: flutter_inappwebview_internal_annotations
url: "https://pub.dartlang.org" sha256: "064a8ccbc76217dcd3b0fd6c6ea6f549e69b2849a0233b5bb46af9632c3ce2ff"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
frontend_server_client: frontend_server_client:
dependency: transitive dependency: transitive
description: description:
name: frontend_server_client name: frontend_server_client
url: "https://pub.dartlang.org" sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.3" version: "3.2.0"
glob: glob:
dependency: transitive dependency: transitive
description: description:
name: glob name: glob
url: "https://pub.dartlang.org" sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
graphs: graphs:
dependency: transitive dependency: transitive
description: description:
name: graphs name: graphs
url: "https://pub.dartlang.org" sha256: "772db3d53d23361d4ffcf5a9bb091cf3ee9b22f2be52cd107cd7a2683a89ba0e"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.3.0"
html: html:
dependency: transitive dependency: transitive
description: description:
name: html name: html
url: "https://pub.dartlang.org" sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8"
url: "https://pub.dev"
source: hosted source: hosted
version: "0.15.0" version: "0.15.3"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
name: http_multi_server name: http_multi_server
url: "https://pub.dartlang.org" sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.2.1" version: "3.2.1"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
name: http_parser name: http_parser
url: "https://pub.dartlang.org" sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.1" version: "4.0.2"
io: io:
dependency: transitive dependency: transitive
description: description:
name: io name: io
url: "https://pub.dartlang.org" sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.3" version: "1.0.4"
js: js:
dependency: transitive dependency: transitive
description: description:
name: js name: js
url: "https://pub.dartlang.org" sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.4" version: "0.6.7"
json_annotation: json_annotation:
dependency: transitive dependency: transitive
description: description:
name: json_annotation name: json_annotation
url: "https://pub.dartlang.org" sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
url: "https://pub.dev"
source: hosted source: hosted
version: "4.7.0" version: "4.8.1"
logging: logging:
dependency: transitive dependency: transitive
description: description:
name: logging name: logging
url: "https://pub.dartlang.org" sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.1.1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.dartlang.org" sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.12" version: "0.12.15"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
url: "https://pub.dartlang.org" sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.5" version: "0.2.0"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.8.0" version: "1.9.1"
mime: mime:
dependency: transitive dependency: transitive
description: description:
name: mime name: mime
url: "https://pub.dartlang.org" sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.0.4"
node_preamble: node_preamble:
dependency: transitive dependency: transitive
description: description:
name: node_preamble name: node_preamble
url: "https://pub.dartlang.org" sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "2.0.2"
package_config: package_config:
dependency: transitive dependency: transitive
description: description:
name: package_config name: package_config
url: "https://pub.dartlang.org" sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
url: "https://pub.dartlang.org" sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.8.2" version: "1.8.3"
pool: pool:
dependency: transitive dependency: transitive
description: description:
name: pool name: pool
url: "https://pub.dartlang.org" sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.5.1" version: "1.5.1"
protobuf:
dependency: transitive
description:
name: protobuf
sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
pub_semver: pub_semver:
dependency: transitive dependency: transitive
description: description:
name: pub_semver name: pub_semver
url: "https://pub.dartlang.org" sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.1.4"
pubspec_parse: pubspec_parse:
dependency: transitive dependency: transitive
description: description:
name: pubspec_parse name: pubspec_parse
url: "https://pub.dartlang.org" sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.3"
shelf: shelf:
dependency: transitive dependency: transitive
description: description:
name: shelf name: shelf
url: "https://pub.dartlang.org" sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.4.1"
shelf_packages_handler: shelf_packages_handler:
dependency: transitive dependency: transitive
description: description:
name: shelf_packages_handler name: shelf_packages_handler
url: "https://pub.dartlang.org" sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.2"
shelf_static: shelf_static:
dependency: transitive dependency: transitive
description: description:
name: shelf_static name: shelf_static
url: "https://pub.dartlang.org" sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e
url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.2"
shelf_web_socket: shelf_web_socket:
dependency: transitive dependency: transitive
description: description:
name: shelf_web_socket name: shelf_web_socket
url: "https://pub.dartlang.org" sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.0.4"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -365,142 +423,162 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: source_gen name: source_gen
url: "https://pub.dartlang.org" sha256: "378a173055cd1fcd2a36e94bf254786d6812688b5f53b6038a2fd180a5a5e210"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.5" version: "1.3.1"
source_map_stack_trace: source_map_stack_trace:
dependency: transitive dependency: transitive
description: description:
name: source_map_stack_trace name: source_map_stack_trace
url: "https://pub.dartlang.org" sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
source_maps: source_maps:
dependency: transitive dependency: transitive
description: description:
name: source_maps name: source_maps
url: "https://pub.dartlang.org" sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703"
url: "https://pub.dev"
source: hosted source: hosted
version: "0.10.10" version: "0.10.12"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.dartlang.org" sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.10.0"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted source: hosted
version: "1.10.0" version: "1.11.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.1.1"
stream_transform: stream_transform:
dependency: transitive dependency: transitive
description: description:
name: stream_transform name: stream_transform
url: "https://pub.dartlang.org" sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.2.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
test: test:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: test name: test
url: "https://pub.dartlang.org" sha256: "4f92f103ef63b1bbac6f4bd1930624fca81b2574464482512c4f0896319be575"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.21.6" version: "1.24.2"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" sha256: daadc9baabec998b062c9091525aa95786508b1c48e9c30f1f891b8bf6ff2e64
url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.14" version: "0.5.2"
test_core: test_core:
dependency: transitive dependency: transitive
description: description:
name: test_core name: test_core
url: "https://pub.dartlang.org" sha256: "3642b184882f79e76ca57a9230fb971e494c3c1fd09c21ae3083ce891bcc0aa1"
url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.18" version: "0.5.2"
timing: timing:
dependency: transitive dependency: transitive
description: description:
name: timing name: timing
url: "https://pub.dartlang.org" sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.0.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.1" version: "1.3.2"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.4"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
url: "https://pub.dartlang.org" sha256: "1311639ad908dfdcb64734ac1fbd60416234c06e4351846783a79c56848a5185"
url: "https://pub.dev"
source: hosted source: hosted
version: "9.4.0" version: "11.7.0"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
name: watcher name: watcher
url: "https://pub.dartlang.org" sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.2"
web_socket_channel: web_socket_channel:
dependency: transitive dependency: transitive
description: description:
name: web_socket_channel name: web_socket_channel
url: "https://pub.dartlang.org" sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.4.0"
webkit_inspection_protocol: webkit_inspection_protocol:
dependency: transitive dependency: transitive
description: description:
name: webkit_inspection_protocol name: webkit_inspection_protocol
url: "https://pub.dartlang.org" sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:
name: yaml name: yaml
url: "https://pub.dartlang.org" sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.1" version: "3.1.2"
sdks: sdks:
dart: ">=2.18.0 <3.0.0" dart: ">=3.0.0-134.0.dev <4.0.0"
flutter: ">=2.5.0" flutter: ">=2.5.0"

View File

@ -10,11 +10,11 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
build: ^2.3.1 build: ^2.4.0
source_gen: ^1.2.5 source_gen: ^1.3.1
flutter_inappwebview_internal_annotations: ^1.1.0 flutter_inappwebview_internal_annotations: ^1.1.0
dev_dependencies: dev_dependencies:
build_runner: ^2.2.1 build_runner: ^2.4.2
build_test: ^2.1.5 build_test: ^2.1.7
test: ^1.21.1 test: ^1.24.2

View File

@ -25,6 +25,8 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android { android {
namespace 'com.pichillilorenzo.flutterwebviewexample'
compileOptions { compileOptions {
sourceCompatibility 1.8 sourceCompatibility 1.8
targetCompatibility 1.8 targetCompatibility 1.8
@ -32,9 +34,6 @@ android {
compileSdkVersion 33 compileSdkVersion 33
lintOptions {
disable 'InvalidPackage'
}
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
@ -54,6 +53,10 @@ android {
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
} }
} }
namespace 'com.pichillilorenzo.flutterwebviewexample'
lint {
disable 'InvalidPackage'
}
} }
flutter { flutter {

View File

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="com.pichillilorenzo.flutterwebviewexample">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->

View File

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="com.pichillilorenzo.flutterwebviewexample">
<!-- The INTERNET permission is required for development. Specifically, <!-- The INTERNET permission is required for development. Specifically,
flutter needs it to communicate with the running application flutter needs it to communicate with the running application

View File

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="com.pichillilorenzo.flutterwebviewexample">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->

View File

@ -1,12 +1,12 @@
buildscript { buildscript {
ext.kotlin_version = '1.6.10' ext.kotlin_version = '1.6.21'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { 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" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app') project.evaluationDependsOn(':app')
} }
task clean(type: Delete) { tasks.register("clean", Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }

View File

@ -2,3 +2,6 @@ org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
android.enableR8=true android.enableR8=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists 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

View File

@ -45,7 +45,7 @@ void openAndClose() {
activityButton: ActivityButton( activityButton: ActivityButton(
templateImage: UIImage(systemName: "sun.max"), templateImage: UIImage(systemName: "sun.max"),
extensionIdentifier: extensionIdentifier:
"com.pichillilorenzo.flutter-inappwebview6-example.test"))); "com.pichillilorenzo.flutter-inappwebview-example7.test")));
await chromeSafariBrowser.opened.future; await chromeSafariBrowser.opened.future;
expect(chromeSafariBrowser.isOpened(), true); expect(chromeSafariBrowser.isOpened(), true);
expect(() async { expect(() async {

View File

@ -27,4 +27,4 @@ final TEST_SERVICE_WORKER_URL = WebUri(
'https://mdn.github.io/dom-examples/service-worker/simple-service-worker/'); '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_DOMAIN = 'my.custom.domain.com';
final TEST_WEBVIEW_ASSET_LOADER_URL = WebUri( 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');

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# This is a generated file; do not edit or check into version control. # 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 "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true" export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_TARGET=lib/main.dart"

View File

@ -3,21 +3,20 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 50; objectVersion = 54;
objects = { objects = {
/* Begin PBXBuildFile section */ /* 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 */; }; 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 */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
6143FF37290959650014A1FC /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6143FF36290959650014A1FC /* UniformTypeIdentifiers.framework */; }; 6143FF37290959650014A1FC /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6143FF36290959650014A1FC /* UniformTypeIdentifiers.framework */; };
6143FF3A290959650014A1FC /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6143FF39290959650014A1FC /* Media.xcassets */; }; 6143FF3A290959650014A1FC /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6143FF39290959650014A1FC /* Media.xcassets */; };
6143FF3C290959650014A1FC /* ActionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6143FF3B290959650014A1FC /* ActionViewController.swift */; }; 6143FF3C290959650014A1FC /* ActionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6143FF3B290959650014A1FC /* ActionViewController.swift */; };
6143FF3F290959650014A1FC /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6143FF3D290959650014A1FC /* MainInterface.storyboard */; }; 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 */; }; 61FF730023634CA10069C557 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 61FF72FF23634CA10069C557 /* libsqlite3.tbd */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 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 */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
EDC1147F21735BC200D2247A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; EDC1147F21735BC200D2247A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
@ -34,15 +33,15 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
6174FE1725CEB74E00A5020C /* Embed App Extensions */ = { 6174FE1725CEB74E00A5020C /* Embed Foundation Extensions */ = {
isa = PBXCopyFilesBuildPhase; isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
dstPath = ""; dstPath = "";
dstSubfolderSpec = 13; dstSubfolderSpec = 13;
files = ( 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; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
@ -62,6 +61,8 @@
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
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 = "<group>"; };
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 = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
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 = "<group>"; }; 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 = "<group>"; };
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 = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -88,8 +87,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
61FF730023634CA10069C557 /* libsqlite3.tbd in Frameworks */, 61FF730023634CA10069C557 /* libsqlite3.tbd in Frameworks */,
25A517508F43E58C47090625 /* (null) in Frameworks */, 75018AFBF33C6954B9C375F0 /* Pods_Runner.framework in Frameworks */,
020EF14E4245221B2C22ACE5 /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -101,8 +99,8 @@
children = ( children = (
61FF730123634DD10069C557 /* flutter_downloader.framework */, 61FF730123634DD10069C557 /* flutter_downloader.framework */,
61FF72FF23634CA10069C557 /* libsqlite3.tbd */, 61FF72FF23634CA10069C557 /* libsqlite3.tbd */,
B0FC2CF7A6002799890B3102 /* Pods_Runner.framework */,
6143FF36290959650014A1FC /* UniformTypeIdentifiers.framework */, 6143FF36290959650014A1FC /* UniformTypeIdentifiers.framework */,
86871EBA13742A6D5F3F398B /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -118,13 +116,13 @@
path = test; path = test;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
647DC95AB5350DB6D2264FFE /* Pods */ = { 7AC6E2111A9BB885C2D9F6EE /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
B23847D2EEA83886DC92B60F /* Pods-Runner.debug.xcconfig */, 80ABE07D2023159E36035B32 /* Pods-Runner.debug.xcconfig */,
9D199BB70329114343003314 /* Pods-Runner.release.xcconfig */, AA4061AE397745454F676BAB /* Pods-Runner.release.xcconfig */,
); );
name = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
@ -145,8 +143,8 @@
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
6143FF38290959650014A1FC /* test */, 6143FF38290959650014A1FC /* test */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
647DC95AB5350DB6D2264FFE /* Pods */,
50BAF1DF19E018DDF2B149B9 /* Frameworks */, 50BAF1DF19E018DDF2B149B9 /* Frameworks */,
7AC6E2111A9BB885C2D9F6EE /* Pods */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -206,14 +204,14 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
3F62E6580DEAFBE72C090A85 /* [CP] Check Pods Manifest.lock */, DC1BB9CDFB0410A7329D249A /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
903A9F2558754FA70D0A7EA8 /* [CP] Embed Pods Frameworks */, 6174FE1725CEB74E00A5020C /* Embed Foundation Extensions */,
6174FE1725CEB74E00A5020C /* Embed App Extensions */, DFFD8453B8E169BF6BE74B49 /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -231,6 +229,7 @@
97C146E61CF9000F007C117D /* Project object */ = { 97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 1400; LastSwiftUpdateCheck = 1400;
LastUpgradeCheck = 1300; LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "The Chromium Authors"; ORGANIZATIONNAME = "The Chromium Authors";
@ -298,10 +297,12 @@
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
); );
name = "Thin Binary"; name = "Thin Binary";
outputPaths = ( outputPaths = (
@ -310,54 +311,9 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
}; };
3F62E6580DEAFBE72C090A85 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
903A9F2558754FA70D0A7EA8 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/OrderedSet/OrderedSet.framework",
"${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}/url_launcher_ios/url_launcher_ios.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OrderedSet.framework",
"${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}/url_launcher_ios.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -370,6 +326,56 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; 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",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
DFFD8453B8E169BF6BE74B49 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/OrderedSet/OrderedSet.framework",
"${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_foundation/path_provider_foundation.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OrderedSet.framework",
"${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_foundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
@ -447,11 +453,15 @@
INFOPLIST_KEY_CFBundleDisplayName = test; INFOPLIST_KEY_CFBundleDisplayName = test;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 The Chromium Authors. All rights reserved."; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 The Chromium Authors. All rights reserved.";
IPHONEOS_DEPLOYMENT_TARGET = 16.0; 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; MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; 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)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
@ -481,10 +491,14 @@
INFOPLIST_KEY_CFBundleDisplayName = test; INFOPLIST_KEY_CFBundleDisplayName = test;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 The Chromium Authors. All rights reserved."; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 The Chromium Authors. All rights reserved.";
IPHONEOS_DEPLOYMENT_TARGET = 16.0; 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; MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES; 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)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
@ -518,6 +532,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
@ -526,7 +541,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_BITCODE = YES; ENABLE_BITCODE = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
@ -543,7 +558,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -576,6 +591,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
@ -584,7 +600,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_BITCODE = YES; ENABLE_BITCODE = NO;
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
@ -595,9 +611,10 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
@ -622,12 +639,15 @@
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview6-example"; PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview-example7";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -654,12 +674,15 @@
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview6-example"; PRODUCT_BUNDLE_IDENTIFIER = "com.pichillilorenzo.flutter-inappwebview-example7";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

View File

@ -51,6 +51,8 @@
<string>Need location</string> <string>Need location</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>InAppWebView requires access to mic.</string> <string>InAppWebView requires access to mic.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>fetch</string> <string>fetch</string>

View File

@ -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();
}

View File

@ -115,6 +115,7 @@ class _InAppBrowserExampleScreenState extends State<InAppBrowserExampleScreen> {
toolbarTopBackgroundColor: Colors.blue, toolbarTopBackgroundColor: Colors.blue,
presentationStyle: ModalPresentationStyle.POPOVER), presentationStyle: ModalPresentationStyle.POPOVER),
webViewSettings: InAppWebViewSettings( webViewSettings: InAppWebViewSettings(
isInspectable: kDebugMode,
useShouldOverrideUrlLoading: true, useShouldOverrideUrlLoading: true,
useOnLoadResource: true, useOnLoadResource: true,
), ),

View File

@ -17,6 +17,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
InAppWebViewController? webViewController; InAppWebViewController? webViewController;
InAppWebViewSettings settings = InAppWebViewSettings( InAppWebViewSettings settings = InAppWebViewSettings(
isInspectable: kDebugMode,
mediaPlaybackRequiresUserGesture: false, mediaPlaybackRequiresUserGesture: false,
allowsInlineMediaPlayback: true, allowsInlineMediaPlayback: true,
iframeAllow: "camera; microphone", iframeAllow: "camera; microphone",

View File

@ -24,7 +24,7 @@ Future main() async {
// await Permission.storage.request(); // await Permission.storage.request();
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) { if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
await InAppWebViewController.setWebContentsDebuggingEnabled(true); await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
} }
if (!kIsWeb) { if (!kIsWeb) {

View File

@ -6,7 +6,7 @@ import FlutterMacOS
import Foundation import Foundation
import flutter_inappwebview import flutter_inappwebview
import path_provider_macos import path_provider_foundation
import url_launcher_macos import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {

View File

@ -1,4 +1,4 @@
platform :osx, '10.11' platform :osx, '10.14'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 51; objectVersion = 54;
objects = { objects = {
/* Begin PBXAggregateTarget section */ /* Begin PBXAggregateTarget section */
@ -277,6 +277,7 @@
}; };
3399D490228B24CF009A79C7 /* ShellScript */ = { 3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -403,7 +404,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;
@ -482,7 +483,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx; SDKROOT = macosx;
@ -529,7 +530,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;

View File

@ -12,7 +12,7 @@ version: 1.0.0+1
publish_to: none publish_to: none
environment: environment:
sdk: ">=2.14.0 <3.0.0" sdk: ">=2.15.0 <4.0.0"
flutter: ">=3.0.0" flutter: ">=3.0.0"
dependencies: dependencies:
@ -22,11 +22,11 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.4 cupertino_icons: ^1.0.4
flutter_downloader: 1.7.3 flutter_downloader: 1.10.2
path_provider: 2.0.9 path_provider: 2.0.15
permission_handler: 10.0.2 permission_handler: 10.2.0
url_launcher: 6.1.6 url_launcher: 6.1.11
pointer_interceptor: ^0.9.3+3 pointer_interceptor: ^0.9.3+4
# connectivity: ^0.4.5+6 # connectivity: ^0.4.5+6
flutter_inappwebview: flutter_inappwebview:
path: ../ path: ../
@ -61,10 +61,12 @@ flutter:
- assets/js/ - assets/js/
- assets/css/ - assets/css/
- assets/images/ - assets/images/
- assets/website/
- test_assets/ - test_assets/
- test_assets/js/ - test_assets/js/
- test_assets/css/ - test_assets/css/
- test_assets/images/ - test_assets/images/
- test_assets/website/
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
# assets: # assets:

View File

@ -427,8 +427,9 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
isFindInteractionEnabled = settings.isFindInteractionEnabled isFindInteractionEnabled = settings.isFindInteractionEnabled
} }
// debugging is always enabled for iOS, if #available(iOS 16.4, *) {
// there isn't any option to set about it such as on Android. isInspectable = settings.isInspectable
}
if settings.clearCache { if settings.clearCache {
clearCache() clearCache()
@ -464,14 +465,16 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
configuration.defaultWebpagePreferences.allowsContentJavaScript = settings.javaScriptEnabled configuration.defaultWebpagePreferences.allowsContentJavaScript = settings.javaScriptEnabled
} }
if #available(iOS 14.5, *) { if #available(iOS 15.0, *) {
configuration.preferences.isTextInteractionEnabled = settings.isTextInteractionEnabled configuration.preferences.isTextInteractionEnabled = settings.isTextInteractionEnabled
} }
if #available(iOS 15.4, *) { if #available(iOS 15.4, *) {
configuration.preferences.isSiteSpecificQuirksModeEnabled = settings.isSiteSpecificQuirksModeEnabled configuration.preferences.isSiteSpecificQuirksModeEnabled = settings.isSiteSpecificQuirksModeEnabled
configuration.preferences.isElementFullscreenEnabled = settings.isElementFullscreenEnabled 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 { if newSettingsMap["upgradeKnownHostsToHTTPS"] != nil && settings?.upgradeKnownHostsToHTTPS != newSettings.upgradeKnownHostsToHTTPS {
configuration.upgradeKnownHostsToHTTPS = newSettings.upgradeKnownHostsToHTTPS configuration.upgradeKnownHostsToHTTPS = newSettings.upgradeKnownHostsToHTTPS
} }
if newSettingsMap["isTextInteractionEnabled"] != nil && settings?.isTextInteractionEnabled != newSettings.isTextInteractionEnabled { if newSettingsMap["isTextInteractionEnabled"] != nil && settings?.isTextInteractionEnabled != newSettings.isTextInteractionEnabled {
configuration.preferences.isTextInteractionEnabled = newSettings.isTextInteractionEnabled configuration.preferences.isTextInteractionEnabled = newSettings.isTextInteractionEnabled
} }
}
if #available(iOS 15.0, *) {
if newSettingsMap["underPageBackgroundColor"] != nil, settings?.underPageBackgroundColor != newSettings.underPageBackgroundColor, if newSettingsMap["underPageBackgroundColor"] != nil, settings?.underPageBackgroundColor != newSettings.underPageBackgroundColor,
let underPageBackgroundColor = newSettings.underPageBackgroundColor, !underPageBackgroundColor.isEmpty { let underPageBackgroundColor = newSettings.underPageBackgroundColor, !underPageBackgroundColor.isEmpty {
self.underPageBackgroundColor = UIColor(hexString: underPageBackgroundColor) self.underPageBackgroundColor = UIColor(hexString: underPageBackgroundColor)
@ -1214,12 +1214,19 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
setMinimumViewportInset(minViewportInset, maximumViewportInset: maxViewportInset) setMinimumViewportInset(minViewportInset, maximumViewportInset: maxViewportInset)
} }
} }
if #available(iOS 16.0, *) { if #available(iOS 16.0, *) {
if newSettingsMap["isFindInteractionEnabled"] != nil, settings?.isFindInteractionEnabled != newSettings.isFindInteractionEnabled { if newSettingsMap["isFindInteractionEnabled"] != nil, settings?.isFindInteractionEnabled != newSettings.isFindInteractionEnabled {
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) scrollView.isScrollEnabled = !(newSettings.disableVerticalScroll && newSettings.disableHorizontalScroll)
@ -2738,13 +2745,21 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
self.evaluateJavaScript(""" self.evaluateJavaScript("""
if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { 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)]; delete window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)];
} }
""", completionHandler: nil) """, completionHandler: nil)
} }
callback.error = { (code: String, message: String?, details: Any?) in 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 { if let channelDelegate = webView.channelDelegate {

View File

@ -78,6 +78,8 @@ public class InAppWebViewSettings: ISettings<InAppWebView> {
var isFindInteractionEnabled = false var isFindInteractionEnabled = false
var minimumViewportInset: UIEdgeInsets? = nil var minimumViewportInset: UIEdgeInsets? = nil
var maximumViewportInset: UIEdgeInsets? = nil var maximumViewportInset: UIEdgeInsets? = nil
var isInspectable = false
var shouldPrintBackgrounds = false
override init(){ override init(){
super.init() super.init()
@ -150,11 +152,9 @@ public class InAppWebViewSettings: ISettings<InAppWebView> {
realSettings["limitsNavigationsToAppBoundDomains"] = configuration.limitsNavigationsToAppBoundDomains realSettings["limitsNavigationsToAppBoundDomains"] = configuration.limitsNavigationsToAppBoundDomains
realSettings["javaScriptEnabled"] = configuration.defaultWebpagePreferences.allowsContentJavaScript realSettings["javaScriptEnabled"] = configuration.defaultWebpagePreferences.allowsContentJavaScript
} }
if #available(iOS 14.5, *) { if #available(iOS 15.0, *) {
realSettings["isTextInteractionEnabled"] = configuration.preferences.isTextInteractionEnabled realSettings["isTextInteractionEnabled"] = configuration.preferences.isTextInteractionEnabled
realSettings["upgradeKnownHostsToHTTPS"] = configuration.upgradeKnownHostsToHTTPS realSettings["upgradeKnownHostsToHTTPS"] = configuration.upgradeKnownHostsToHTTPS
}
if #available(iOS 15.0, *) {
realSettings["underPageBackgroundColor"] = webView.underPageBackgroundColor.hexString realSettings["underPageBackgroundColor"] = webView.underPageBackgroundColor.hexString
} }
if #available(iOS 15.4, *) { if #available(iOS 15.4, *) {
@ -168,6 +168,10 @@ public class InAppWebViewSettings: ISettings<InAppWebView> {
if #available(iOS 16.0, *) { if #available(iOS 16.0, *) {
realSettings["isFindInteractionEnabled"] = webView.isFindInteractionEnabled realSettings["isFindInteractionEnabled"] = webView.isFindInteractionEnabled
} }
if #available(iOS 16.4, *) {
realSettings["isInspectable"] = webView.isInspectable
realSettings["shouldPrintBackgrounds"] = configuration.preferences.shouldPrintBackgrounds
}
} }
return realSettings return realSettings
} }

View File

@ -26,7 +26,7 @@ window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function() {
var _callHandlerID = setTimeout(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} ); 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) { 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) \(WEB_MESSAGE_LISTENER_JS_SOURCE)

View File

@ -2,7 +2,6 @@ import 'dart:async';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'webview_feature.dart'; import 'webview_feature.dart';
import '../types/main.dart'; import '../types/main.dart';
import '../in_app_webview/in_app_webview_settings.dart';
///Class that manages Service Workers used by [WebView]. ///Class that manages Service Workers used by [WebView].
/// ///
@ -121,16 +120,6 @@ class ServiceWorkerController {
await _channel.invokeMethod('getCacheMode', args)); 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<RequestedWithHeaderMode?> getRequestedWithHeaderMode() async {
Map<String, dynamic> args = <String, dynamic>{};
return RequestedWithHeaderMode.fromNativeValue(
await _channel.invokeMethod('getRequestedWithHeaderMode', args));
}
///Enables or disables content URL access from Service Workers. ///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]. ///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()); args.putIfAbsent("mode", () => mode.toNativeValue());
await _channel.invokeMethod('setCacheMode', args); 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<void> setRequestedWithHeaderMode(
RequestedWithHeaderMode mode) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent("mode", () => mode.toNativeValue());
await _channel.invokeMethod('setRequestedWithHeaderMode', args);
}
} }
///Class used by clients to capture Service Worker related callbacks. ///Class used by clients to capture Service Worker related callbacks.

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/services.dart'; 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 '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_controller.dart';
import '../in_app_webview/in_app_webview_settings.dart'; import '../in_app_webview/in_app_webview_settings.dart';
@ -22,6 +23,7 @@ class WebViewFeature_ {
// ignore: unused_field // ignore: unused_field
final String _value; final String _value;
const WebViewFeature_._internal(this._value); const WebViewFeature_._internal(this._value);
@ExchangeableObjectMethod(ignore: true) @ExchangeableObjectMethod(ignore: true)
@ -208,10 +210,6 @@ class WebViewFeature_ {
static const ALGORITHMIC_DARKENING = static const ALGORITHMIC_DARKENING =
const WebViewFeature_._internal("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]. ///This feature covers [InAppWebViewSettings.enterpriseAuthenticationAppLinkPolicyEnabled].
static const ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY = static const ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY =
const WebViewFeature_._internal( const WebViewFeature_._internal(
@ -221,6 +219,14 @@ class WebViewFeature_ {
static const GET_VARIATIONS_HEADER = static const GET_VARIATIONS_HEADER =
const WebViewFeature_._internal("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, ///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, ///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`. ///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 // ignore: unused_field
final String _value; final String _value;
const AndroidWebViewFeature_._internal(this._value); const AndroidWebViewFeature_._internal(this._value);
@ExchangeableObjectMethod(ignore: true) @ExchangeableObjectMethod(ignore: true)

View File

@ -48,6 +48,10 @@ class WebViewFeature {
static const FORCE_DARK_STRATEGY = static const FORCE_DARK_STRATEGY =
WebViewFeature._internal('FORCE_DARK_STRATEGY', '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]. ///This feature covers [InAppWebViewController.getVariationsHeader].
static const GET_VARIATIONS_HEADER = WebViewFeature._internal( static const GET_VARIATIONS_HEADER = WebViewFeature._internal(
'GET_VARIATIONS_HEADER', 'GET_VARIATIONS_HEADER'); 'GET_VARIATIONS_HEADER', 'GET_VARIATIONS_HEADER');
@ -92,9 +96,9 @@ class WebViewFeature {
static const RECEIVE_WEB_RESOURCE_ERROR = WebViewFeature._internal( static const RECEIVE_WEB_RESOURCE_ERROR = WebViewFeature._internal(
'RECEIVE_WEB_RESOURCE_ERROR', 'RECEIVE_WEB_RESOURCE_ERROR'); 'RECEIVE_WEB_RESOURCE_ERROR', 'RECEIVE_WEB_RESOURCE_ERROR');
///This feature covers [InAppWebViewSettings.requestedWithHeaderMode]. ///This feature covers cookie attributes of [CookieManager.getCookie] and [CookieManager.getCookies] methods.
static const REQUESTED_WITH_HEADER_CONTROL = WebViewFeature._internal( static const REQUESTED_WITH_HEADER_ALLOW_LIST = WebViewFeature._internal(
'REQUESTED_WITH_HEADER_CONTROL', 'REQUESTED_WITH_HEADER_CONTROL'); 'REQUESTED_WITH_HEADER_ALLOW_LIST', 'REQUESTED_WITH_HEADER_ALLOW_LIST');
///This feature covers [InAppWebViewController.setSafeBrowsingAllowlist]. ///This feature covers [InAppWebViewController.setSafeBrowsingAllowlist].
static const SAFE_BROWSING_ALLOWLIST = WebViewFeature._internal( static const SAFE_BROWSING_ALLOWLIST = WebViewFeature._internal(
@ -230,6 +234,7 @@ class WebViewFeature {
WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY,
WebViewFeature.FORCE_DARK, WebViewFeature.FORCE_DARK,
WebViewFeature.FORCE_DARK_STRATEGY, WebViewFeature.FORCE_DARK_STRATEGY,
WebViewFeature.GET_COOKIE_INFO,
WebViewFeature.GET_VARIATIONS_HEADER, WebViewFeature.GET_VARIATIONS_HEADER,
WebViewFeature.GET_WEB_CHROME_CLIENT, WebViewFeature.GET_WEB_CHROME_CLIENT,
WebViewFeature.GET_WEB_VIEW_CLIENT, WebViewFeature.GET_WEB_VIEW_CLIENT,
@ -241,7 +246,7 @@ class WebViewFeature {
WebViewFeature.PROXY_OVERRIDE_REVERSE_BYPASS, WebViewFeature.PROXY_OVERRIDE_REVERSE_BYPASS,
WebViewFeature.RECEIVE_HTTP_ERROR, WebViewFeature.RECEIVE_HTTP_ERROR,
WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR, WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR,
WebViewFeature.REQUESTED_WITH_HEADER_CONTROL, WebViewFeature.REQUESTED_WITH_HEADER_ALLOW_LIST,
WebViewFeature.SAFE_BROWSING_ALLOWLIST, WebViewFeature.SAFE_BROWSING_ALLOWLIST,
WebViewFeature.SAFE_BROWSING_ENABLE, WebViewFeature.SAFE_BROWSING_ENABLE,
WebViewFeature.SAFE_BROWSING_HIT, WebViewFeature.SAFE_BROWSING_HIT,

View File

@ -78,25 +78,25 @@ class ChromeSafariBrowserSettings_ implements ChromeSafariBrowserOptions {
/// ///
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android ///- Android
Color? toolbarBackgroundColor; Color_? toolbarBackgroundColor;
///Sets the navigation bar color. Has no effect on Android API versions below L. ///Sets the navigation bar color. Has no effect on Android API versions below L.
/// ///
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android ///- Android
Color? navigationBarColor; Color_? navigationBarColor;
///Sets the navigation bar divider color. Has no effect on Android API versions below P. ///Sets the navigation bar divider color. Has no effect on Android API versions below P.
/// ///
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android ///- Android
Color? navigationBarDividerColor; Color_? navigationBarDividerColor;
///Sets the color of the secondary toolbar. ///Sets the color of the secondary toolbar.
/// ///
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android ///- 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`. ///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**: ///**Supported Platforms/Implementations**:
///- iOS ///- iOS
Color? preferredBarTintColor; Color_? preferredBarTintColor;
///Set the custom color of the control buttons on the navigation bar and the toolbar. ///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**: ///**Supported Platforms/Implementations**:
///- iOS ///- iOS
Color? preferredControlTintColor; Color_? preferredControlTintColor;
///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN]. ///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN].
/// ///

View File

@ -290,8 +290,9 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
? UtilColor.fromStringRepresentation(map['toolbarBackgroundColor']) ? UtilColor.fromStringRepresentation(map['toolbarBackgroundColor'])
: null, : null,
); );
instance.additionalTrustedOrigins = instance.additionalTrustedOrigins = map['additionalTrustedOrigins'] != null
map['additionalTrustedOrigins']?.cast<String>(); ? List<String>.from(map['additionalTrustedOrigins']!.cast<String>())
: null;
instance.alwaysUseBrowserUI = map['alwaysUseBrowserUI']; instance.alwaysUseBrowserUI = map['alwaysUseBrowserUI'];
instance.barCollapsingEnabled = map['barCollapsingEnabled']; instance.barCollapsingEnabled = map['barCollapsingEnabled'];
instance.dismissButtonStyle = instance.dismissButtonStyle =

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';

View File

@ -121,7 +121,7 @@ class InAppBrowserSettings_
///- Android native WebView ///- Android native WebView
///- iOS ///- iOS
///- MacOS ///- MacOS
Color? toolbarTopBackgroundColor; Color_? toolbarTopBackgroundColor;
///Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`. ///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**: ///**Supported Platforms/Implementations**:
///- iOS ///- iOS
Color? toolbarTopBarTintColor; Color_? toolbarTopBarTintColor;
///Set the tint color to apply to the navigation items and bar button items. ///Set the tint color to apply to the navigation items and bar button items.
/// ///
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- iOS ///- iOS
Color? toolbarTopTintColor; Color_? toolbarTopTintColor;
///Set to `true` to hide the toolbar at the bottom of the WebView. The default value is `false`. ///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**: ///**Supported Platforms/Implementations**:
///- iOS ///- iOS
Color? toolbarBottomBackgroundColor; Color_? toolbarBottomBackgroundColor;
///Set the tint color to apply to the bar button items. ///Set the tint color to apply to the bar button items.
/// ///
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- iOS ///- iOS
Color? toolbarBottomTintColor; Color_? toolbarBottomTintColor;
///Set to `true` to set the toolbar at the bottom translucent. The default value is `true`. ///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**: ///**Supported Platforms/Implementations**:
///- iOS ///- iOS
Color? closeButtonColor; Color_? closeButtonColor;
///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN]. ///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN].
/// ///

View File

@ -1378,9 +1378,10 @@ class InAppWebViewController {
// convert result to json // convert result to json
try { try {
return jsonEncode(await javaScriptHandlersMap[handlerName]!(args)); return jsonEncode(await javaScriptHandlersMap[handlerName]!(args));
} catch (error) { } catch (error, stacktrace) {
developer.log(error.toString(), name: this.runtimeType.toString()); developer.log(error.toString() + '\n' + stacktrace.toString(),
return null; name: 'JavaScript Handler "$handlerName"');
throw Exception(error.toString().replaceFirst('Exception: ', ''));
} }
} }
break; break;

View File

@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_inappwebview/src/types/user_preferred_content_mode.dart'; import 'package:flutter_inappwebview/src/types/user_preferred_content_mode.dart';
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart'; import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'dart:typed_data';
import '../android/webview_asset_loader.dart'; import '../android/webview_asset_loader.dart';
import '../types/action_mode_menu_item.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/over_scroll_mode.dart';
import '../types/referrer_policy.dart'; import '../types/referrer_policy.dart';
import '../types/renderer_priority_policy.dart'; import '../types/renderer_priority_policy.dart';
import '../types/requested_with_header_mode.dart';
import '../types/sandbox.dart'; import '../types/sandbox.dart';
import '../types/scrollbar_style.dart'; import '../types/scrollbar_style.dart';
import '../types/scrollview_content_inset_adjustment_behavior.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: apiUrl:
"https://developer.android.com/reference/android/view/View#setVerticalScrollbarThumbDrawable(android.graphics.drawable.Drawable)") "https://developer.android.com/reference/android/view/View#setVerticalScrollbarThumbDrawable(android.graphics.drawable.Drawable)")
]) ])
Color? verticalScrollbarThumbColor; Color_? verticalScrollbarThumbColor;
///Sets the vertical scrollbar track color. ///Sets the vertical scrollbar track color.
@SupportedPlatforms(platforms: [ @SupportedPlatforms(platforms: [
@ -891,7 +891,7 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri
apiUrl: apiUrl:
"https://developer.android.com/reference/android/view/View#setVerticalScrollbarTrackDrawable(android.graphics.drawable.Drawable)") "https://developer.android.com/reference/android/view/View#setVerticalScrollbarTrackDrawable(android.graphics.drawable.Drawable)")
]) ])
Color? verticalScrollbarTrackColor; Color_? verticalScrollbarTrackColor;
///Sets the horizontal scrollbar thumb color. ///Sets the horizontal scrollbar thumb color.
@SupportedPlatforms(platforms: [ @SupportedPlatforms(platforms: [
@ -901,7 +901,7 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri
apiUrl: apiUrl:
"https://developer.android.com/reference/android/view/View#setHorizontalScrollbarThumbDrawable(android.graphics.drawable.Drawable)") "https://developer.android.com/reference/android/view/View#setHorizontalScrollbarThumbDrawable(android.graphics.drawable.Drawable)")
]) ])
Color? horizontalScrollbarThumbColor; Color_? horizontalScrollbarThumbColor;
///Sets the horizontal scrollbar track color. ///Sets the horizontal scrollbar track color.
@SupportedPlatforms(platforms: [ @SupportedPlatforms(platforms: [
@ -911,7 +911,7 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri
apiUrl: apiUrl:
"https://developer.android.com/reference/android/view/View#setHorizontalScrollbarTrackDrawable(android.graphics.drawable.Drawable)") "https://developer.android.com/reference/android/view/View#setHorizontalScrollbarTrackDrawable(android.graphics.drawable.Drawable)")
]) ])
Color? horizontalScrollbarTrackColor; Color_? horizontalScrollbarTrackColor;
///Control whether algorithmic darkening is allowed. ///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; 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 ///Sets whether EnterpriseAuthenticationAppLinkPolicy if set by admin is allowed to have any
///effect on WebView. ///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()]) @SupportedPlatforms(platforms: [AndroidPlatform()])
Uint8List? defaultVideoPoster; 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<String>? 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`. ///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()]) @SupportedPlatforms(platforms: [IOSPlatform()])
bool? disallowOverScroll; bool? disallowOverScroll;
@ -1357,8 +1363,10 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri
/// ///
///Also, on MacOS: ///Also, on MacOS:
///- [WebView.onScrollChanged] ///- [WebView.onScrollChanged]
@SupportedPlatforms( @SupportedPlatforms(platforms: [
platforms: [IOSPlatform(available: "13.0"), MacOSPlatform()]) IOSPlatform(available: "13.0"),
MacOSPlatform(available: "10.15")
])
bool? applePayAPIEnabled; 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. ///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: apiUrl:
"https://developer.apple.com/documentation/webkit/wkwebview/3850574-underpagebackgroundcolor") "https://developer.apple.com/documentation/webkit/wkwebview/3850574-underpagebackgroundcolor")
]) ])
Color? underPageBackgroundColor; Color_? underPageBackgroundColor;
///A Boolean value indicating whether text interaction is enabled or not. ///A Boolean value indicating whether text interaction is enabled or not.
///The default value is `true`. ///The default value is `true`.
@SupportedPlatforms(platforms: [ @SupportedPlatforms(platforms: [
IOSPlatform( IOSPlatform(
available: "14.5", available: "15.0",
apiName: "WKPreferences.isTextInteractionEnabled", apiName: "WKPreferences.isTextInteractionEnabled",
apiUrl: apiUrl:
"https://developer.apple.com/documentation/webkit/wkpreferences/3727362-istextinteractionenabled"), "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; 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 `<iframe>`. ///Specifies a feature policy for the `<iframe>`.
///The policy defines what features are available to the `<iframe>` based on the origin of the request ///The policy defines what features are available to the `<iframe>` based on the origin of the request
///(e.g. access to the microphone, camera, battery, web-share API, etc.). ///(e.g. access to the microphone, camera, battery, web-share API, etc.).
@ -1648,9 +1690,9 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri
this.horizontalScrollbarThumbColor, this.horizontalScrollbarThumbColor,
this.horizontalScrollbarTrackColor, this.horizontalScrollbarTrackColor,
this.algorithmicDarkeningAllowed = false, this.algorithmicDarkeningAllowed = false,
this.requestedWithHeaderMode,
this.enterpriseAuthenticationAppLinkPolicyEnabled = true, this.enterpriseAuthenticationAppLinkPolicyEnabled = true,
this.defaultVideoPoster, this.defaultVideoPoster,
this.requestedWithHeaderOriginAllowList,
this.disallowOverScroll = false, this.disallowOverScroll = false,
this.enableViewportScale = false, this.enableViewportScale = false,
this.suppressesIncrementalRendering = false, this.suppressesIncrementalRendering = false,
@ -1692,6 +1734,8 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri
this.isFindInteractionEnabled = false, this.isFindInteractionEnabled = false,
this.minimumViewportInset, this.minimumViewportInset,
this.maximumViewportInset, this.maximumViewportInset,
this.isInspectable = false,
this.shouldPrintBackgrounds = false,
this.allowBackgroundAudioPlaying = false, this.allowBackgroundAudioPlaying = false,
this.webViewAssetLoader, this.webViewAssetLoader,
this.iframeAllow, this.iframeAllow,

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,6 @@ export 'android/main.dart';
export 'apple/main.dart'; export 'apple/main.dart';
export 'x509_certificate/main.dart'; export 'x509_certificate/main.dart';
export 'web_storage/main.dart'; export 'web_storage/main.dart';
export 'types/main.dart';
export 'cookie_manager.dart'; export 'cookie_manager.dart';
export 'in_app_localhost_server.dart'; export 'in_app_localhost_server.dart';
export 'content_blocker.dart'; export 'content_blocker.dart';

View File

@ -24,14 +24,14 @@ class PullToRefreshSettings_ {
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ///- Android native WebView
///- iOS ///- iOS
Color? color; Color_? color;
///The background color of the refresh control. ///The background color of the refresh control.
/// ///
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ///- Android native WebView
///- iOS ///- iOS
Color? backgroundColor; Color_? backgroundColor;
///The distance to trigger a sync in dips. ///The distance to trigger a sync in dips.
/// ///

View File

@ -21,7 +21,7 @@ class AttributedString_ {
///The value of this attribute is a [Color] object. ///The value of this attribute is a [Color] object.
///Use this attribute to specify the color of the background area behind the text. ///Use this attribute to specify the color of the background area behind the text.
///If you do not specify this attribute, no background color is drawn. ///If you do not specify this attribute, no background color is drawn.
Color? backgroundColor; Color_? backgroundColor;
///The vertical offset for the position of the text. ///The vertical offset for the position of the text.
/// ///
@ -40,7 +40,7 @@ class AttributedString_ {
///The value of this attribute is a [Color] object. ///The value of this attribute is a [Color] object.
///Use this attribute to specify the color of the text during rendering. ///Use this attribute to specify the color of the text during rendering.
///If you do not specify this attribute, the text is rendered in black. ///If you do not specify this attribute, the text is rendered in black.
Color? foregroundColor; Color_? foregroundColor;
///The kerning of the text. ///The kerning of the text.
/// ///
@ -68,7 +68,7 @@ class AttributedString_ {
///The color of the strikethrough. ///The color of the strikethrough.
/// ///
///The value of this attribute is a [Color] object. The default value is `null`, indicating same as foreground color. ///The value of this attribute is a [Color] object. The default value is `null`, indicating same as foreground color.
Color? strikethroughColor; Color_? strikethroughColor;
///The strikethrough style of the text. ///The strikethrough style of the text.
/// ///
@ -81,7 +81,7 @@ class AttributedString_ {
///The value of this parameter is a [Color] object. ///The value of this parameter is a [Color] object.
///If it is not defined (which is the case by default), it is assumed to be the same as the value of foregroundColor; ///If it is not defined (which is the case by default), it is assumed to be the same as the value of foregroundColor;
///otherwise, it describes the outline color. ///otherwise, it describes the outline color.
Color? strokeColor; Color_? strokeColor;
///The width of the stroke. ///The width of the stroke.
/// ///
@ -103,7 +103,7 @@ class AttributedString_ {
/// ///
///The value of this attribute is a [Color] object. ///The value of this attribute is a [Color] object.
///The default value is `null`, indicating same as foreground color. ///The default value is `null`, indicating same as foreground color.
Color? underlineColor; Color_? underlineColor;
///The underline style of the text. ///The underline style of the text.
/// ///
@ -144,7 +144,7 @@ class IOSNSAttributedString_ {
///The value of this attribute is a [Color] object. ///The value of this attribute is a [Color] object.
///Use this attribute to specify the color of the background area behind the text. ///Use this attribute to specify the color of the background area behind the text.
///If you do not specify this attribute, no background color is drawn. ///If you do not specify this attribute, no background color is drawn.
Color? backgroundColor; Color_? backgroundColor;
///The vertical offset for the position of the text. ///The vertical offset for the position of the text.
/// ///
@ -163,7 +163,7 @@ class IOSNSAttributedString_ {
///The value of this attribute is a [Color] object. ///The value of this attribute is a [Color] object.
///Use this attribute to specify the color of the text during rendering. ///Use this attribute to specify the color of the text during rendering.
///If you do not specify this attribute, the text is rendered in black. ///If you do not specify this attribute, the text is rendered in black.
Color? foregroundColor; Color_? foregroundColor;
///The kerning of the text. ///The kerning of the text.
/// ///
@ -191,7 +191,7 @@ class IOSNSAttributedString_ {
///The color of the strikethrough. ///The color of the strikethrough.
/// ///
///The value of this attribute is a [Color] object. The default value is `null`, indicating same as foreground color. ///The value of this attribute is a [Color] object. The default value is `null`, indicating same as foreground color.
Color? strikethroughColor; Color_? strikethroughColor;
///The strikethrough style of the text. ///The strikethrough style of the text.
/// ///
@ -204,7 +204,7 @@ class IOSNSAttributedString_ {
///The value of this parameter is a [Color] object. ///The value of this parameter is a [Color] object.
///If it is not defined (which is the case by default), it is assumed to be the same as the value of foregroundColor; ///If it is not defined (which is the case by default), it is assumed to be the same as the value of foregroundColor;
///otherwise, it describes the outline color. ///otherwise, it describes the outline color.
Color? strokeColor; Color_? strokeColor;
///The width of the stroke. ///The width of the stroke.
/// ///
@ -226,7 +226,7 @@ class IOSNSAttributedString_ {
/// ///
///The value of this attribute is a [Color] object. ///The value of this attribute is a [Color] object.
///The default value is `null`, indicating same as foreground color. ///The default value is `null`, indicating same as foreground color.
Color? underlineColor; Color_? underlineColor;
///The underline style of the text. ///The underline style of the text.
/// ///

View File

@ -47,10 +47,18 @@ class ClientCertChallenge extends URLAuthenticationChallenge {
final instance = ClientCertChallenge( final instance = ClientCertChallenge(
protectionSpace: URLProtectionSpace.fromMap( protectionSpace: URLProtectionSpace.fromMap(
map['protectionSpace']?.cast<String, dynamic>())!, map['protectionSpace']?.cast<String, dynamic>())!,
androidKeyTypes: map['keyTypes']?.cast<String>(), androidKeyTypes: map['keyTypes'] != null
androidPrincipals: map['principals']?.cast<String>(), ? List<String>.from(map['keyTypes']!.cast<String>())
keyTypes: map['keyTypes']?.cast<String>(), : null,
principals: map['principals']?.cast<String>(), androidPrincipals: map['principals'] != null
? List<String>.from(map['principals']!.cast<String>())
: null,
keyTypes: map['keyTypes'] != null
? List<String>.from(map['keyTypes']!.cast<String>())
: null,
principals: map['principals'] != null
? List<String>.from(map['principals']!.cast<String>())
: null,
); );
return instance; return instance;
} }

View File

@ -1,6 +1,7 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart'; import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import '../cookie_manager.dart'; import '../cookie_manager.dart';
import '../android/webview_feature.dart';
import 'http_cookie_same_site_policy.dart'; import 'http_cookie_same_site_policy.dart';
part 'cookie.g.dart'; part 'cookie.g.dart';
@ -9,44 +10,88 @@ part 'cookie.g.dart';
@ExchangeableObject() @ExchangeableObject()
class Cookie_ { class Cookie_ {
///The cookie name. ///The cookie name.
@SupportedPlatforms(platforms: [
IOSPlatform(),
MacOSPlatform(),
AndroidPlatform(),
WebPlatform()
])
String name; String name;
///The cookie value. ///The cookie value.
@SupportedPlatforms(platforms: [
IOSPlatform(),
MacOSPlatform(),
AndroidPlatform(),
WebPlatform()
])
dynamic value; dynamic value;
///The cookie expiration date in milliseconds. ///The cookie expiration date in milliseconds.
/// @SupportedPlatforms(platforms: [
///**NOTE**: on Android it will be always `null`. IOSPlatform(),
MacOSPlatform(),
AndroidPlatform(
note:
"available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.")
])
int? expiresDate; int? expiresDate;
///Indicates if the cookie is a session only cookie. ///Indicates if the cookie is a session only cookie.
/// @SupportedPlatforms(platforms: [
///**NOTE**: on Android it will be always `null`. IOSPlatform(),
MacOSPlatform()
])
bool? isSessionOnly; bool? isSessionOnly;
///The cookie domain. ///The cookie domain.
/// @SupportedPlatforms(platforms: [
///**NOTE**: on Android it will be always `null`. IOSPlatform(),
MacOSPlatform(),
AndroidPlatform(
note:
"available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.")
])
String? domain; String? domain;
///The cookie same site policy. ///The cookie same site policy.
/// @SupportedPlatforms(platforms: [
///**NOTE**: on Android it will be always `null`. IOSPlatform(),
MacOSPlatform(),
AndroidPlatform(
note:
"available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.")
])
HTTPCookieSameSitePolicy_? sameSite; HTTPCookieSameSitePolicy_? sameSite;
///Indicates if the cookie is secure or not. ///Indicates if the cookie is secure or not.
/// @SupportedPlatforms(platforms: [
///**NOTE**: on Android it will be always `null`. IOSPlatform(),
MacOSPlatform(),
AndroidPlatform(
note:
"available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.")
])
bool? isSecure; bool? isSecure;
///Indicates if the cookie is a http only cookie. ///Indicates if the cookie is a http only cookie.
/// @SupportedPlatforms(platforms: [
///**NOTE**: on Android it will be always `null`. IOSPlatform(),
MacOSPlatform(),
AndroidPlatform(
note:
"available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.")
])
bool? isHttpOnly; bool? isHttpOnly;
///The cookie path. ///The cookie path.
/// @SupportedPlatforms(platforms: [
///**NOTE**: on Android it will be always `null`. IOSPlatform(),
MacOSPlatform(),
AndroidPlatform(
note:
"available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.")
])
String? path; String? path;
Cookie_( Cookie_(

View File

@ -10,43 +10,87 @@ part of 'cookie.dart';
class Cookie { class Cookie {
///The cookie domain. ///The cookie domain.
/// ///
///**NOTE**: on Android it will be always `null`. ///**NOTE for Android native WebView**: available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.
///
///**Supported Platforms/Implementations**:
///- iOS
///- MacOS
///- Android native WebView
String? domain; String? domain;
///The cookie expiration date in milliseconds. ///The cookie expiration date in milliseconds.
/// ///
///**NOTE**: on Android it will be always `null`. ///**NOTE for Android native WebView**: available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.
///
///**Supported Platforms/Implementations**:
///- iOS
///- MacOS
///- Android native WebView
int? expiresDate; int? expiresDate;
///Indicates if the cookie is a http only cookie. ///Indicates if the cookie is a http only cookie.
/// ///
///**NOTE**: on Android it will be always `null`. ///**NOTE for Android native WebView**: available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.
///
///**Supported Platforms/Implementations**:
///- iOS
///- MacOS
///- Android native WebView
bool? isHttpOnly; bool? isHttpOnly;
///Indicates if the cookie is secure or not. ///Indicates if the cookie is secure or not.
/// ///
///**NOTE**: on Android it will be always `null`. ///**NOTE for Android native WebView**: available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.
///
///**Supported Platforms/Implementations**:
///- iOS
///- MacOS
///- Android native WebView
bool? isSecure; bool? isSecure;
///Indicates if the cookie is a session only cookie. ///Indicates if the cookie is a session only cookie.
/// ///
///**NOTE**: on Android it will be always `null`. ///**Supported Platforms/Implementations**:
///- iOS
///- MacOS
bool? isSessionOnly; bool? isSessionOnly;
///The cookie name. ///The cookie name.
///
///**Supported Platforms/Implementations**:
///- iOS
///- MacOS
///- Android native WebView
///- Web but iframe requires same origin
String name; String name;
///The cookie path. ///The cookie path.
/// ///
///**NOTE**: on Android it will be always `null`. ///**NOTE for Android native WebView**: available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.
///
///**Supported Platforms/Implementations**:
///- iOS
///- MacOS
///- Android native WebView
String? path; String? path;
///The cookie same site policy. ///The cookie same site policy.
/// ///
///**NOTE**: on Android it will be always `null`. ///**NOTE for Android native WebView**: available on Android only if [WebViewFeature.GET_COOKIE_INFO] feature is supported.
///
///**Supported Platforms/Implementations**:
///- iOS
///- MacOS
///- Android native WebView
HTTPCookieSameSitePolicy? sameSite; HTTPCookieSameSitePolicy? sameSite;
///The cookie value. ///The cookie value.
///
///**Supported Platforms/Implementations**:
///- iOS
///- MacOS
///- Android native WebView
///- Web but iframe requires same origin
dynamic value; dynamic value;
Cookie( Cookie(
{this.domain, {this.domain,

View File

@ -203,7 +203,6 @@ export 'webview_package_info.dart'
show WebViewPackageInfo, AndroidWebViewPackageInfo; show WebViewPackageInfo, AndroidWebViewPackageInfo;
export 'webview_render_process_action.dart' show WebViewRenderProcessAction; export 'webview_render_process_action.dart' show WebViewRenderProcessAction;
export 'window_features.dart' show WindowFeatures, IOSWKWindowFeatures; export 'window_features.dart' show WindowFeatures, IOSWKWindowFeatures;
export 'requested_with_header_mode.dart' show RequestedWithHeaderMode;
export 'find_session.dart' show FindSession; export 'find_session.dart' show FindSession;
export 'search_result_display_style.dart' show SearchResultDisplayStyle; export 'search_result_display_style.dart' show SearchResultDisplayStyle;
export 'content_blocker_trigger_load_context.dart' export 'content_blocker_trigger_load_context.dart'

View File

@ -70,7 +70,7 @@ class PermissionRequestResponse {
final instance = PermissionRequestResponse(); final instance = PermissionRequestResponse();
instance.action = instance.action =
PermissionRequestResponseAction.fromNativeValue(map['action']); PermissionRequestResponseAction.fromNativeValue(map['action']);
instance.resources = map['resources'].cast<String>(); instance.resources = List<String>.from(map['resources']!.cast<String>());
return instance; return instance;
} }

View File

@ -1,19 +0,0 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
part 'requested_with_header_mode.g.dart';
///Class used to set how the WebView will set the `X-Requested-With` header on requests.
@ExchangeableEnum()
class RequestedWithHeaderMode_ {
// ignore: unused_field
final int _value;
const RequestedWithHeaderMode_._internal(this._value);
///In this mode the WebView will not add an `X-Requested-With` header on HTTP requests automatically.
static const NO_HEADER = const RequestedWithHeaderMode_._internal(0);
///In this mode the WebView automatically add an `X-Requested-With` header to outgoing requests,
///if the application or the loaded webpage has not already set a header value.
///The value of this automatically added header will be the package name of the app. This is the default mode.
static const APP_PACKAGE_NAME = const RequestedWithHeaderMode_._internal(1);
}

View File

@ -1,81 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'requested_with_header_mode.dart';
// **************************************************************************
// ExchangeableEnumGenerator
// **************************************************************************
///Class used to set how the WebView will set the `X-Requested-With` header on requests.
class RequestedWithHeaderMode {
final int _value;
final int _nativeValue;
const RequestedWithHeaderMode._internal(this._value, this._nativeValue);
// ignore: unused_element
factory RequestedWithHeaderMode._internalMultiPlatform(
int value, Function nativeValue) =>
RequestedWithHeaderMode._internal(value, nativeValue());
///In this mode the WebView automatically add an `X-Requested-With` header to outgoing requests,
///if the application or the loaded webpage has not already set a header value.
///The value of this automatically added header will be the package name of the app. This is the default mode.
static const APP_PACKAGE_NAME = RequestedWithHeaderMode._internal(1, 1);
///In this mode the WebView will not add an `X-Requested-With` header on HTTP requests automatically.
static const NO_HEADER = RequestedWithHeaderMode._internal(0, 0);
///Set of all values of [RequestedWithHeaderMode].
static final Set<RequestedWithHeaderMode> values = [
RequestedWithHeaderMode.APP_PACKAGE_NAME,
RequestedWithHeaderMode.NO_HEADER,
].toSet();
///Gets a possible [RequestedWithHeaderMode] instance from [int] value.
static RequestedWithHeaderMode? fromValue(int? value) {
if (value != null) {
try {
return RequestedWithHeaderMode.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets a possible [RequestedWithHeaderMode] instance from a native value.
static RequestedWithHeaderMode? fromNativeValue(int? value) {
if (value != null) {
try {
return RequestedWithHeaderMode.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
///Gets [int] native value.
int toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
@override
String toString() {
switch (_value) {
case 1:
return 'APP_PACKAGE_NAME';
case 0:
return 'NO_HEADER';
}
return _value.toString();
}
}

View File

@ -64,7 +64,8 @@ class UserScript {
iosForMainFrameOnly: map['forMainFrameOnly'], iosForMainFrameOnly: map['forMainFrameOnly'],
source: map['source'], source: map['source'],
); );
instance.allowedOriginRules = map['allowedOriginRules'].cast<String>(); instance.allowedOriginRules =
Set<String>.from(map['allowedOriginRules']!.cast<String>());
instance.contentWorld = map['contentWorld']; instance.contentWorld = map['contentWorld'];
instance.forMainFrameOnly = map['forMainFrameOnly']; instance.forMainFrameOnly = map['forMainFrameOnly'];
return instance; return instance;

View File

@ -576,3 +576,9 @@ void debugLog(
} }
} }
} }
// Class used only by the build_runner for @ExchangeableObject annotation.
// For some strange reason, Color is not recognized anymore by the dart analyzer correctly.
class Color_ extends Color {
Color_(int value) : super(value);
}

View File

@ -138,8 +138,9 @@ public class InAppWebView: WKWebView, WKUIDelegate,
} }
} }
// debugging is always enabled for iOS, if #available(macOS 13.3, *) {
// there isn't any option to set about it such as on Android. isInspectable = settings.isInspectable
}
if settings.clearCache { if settings.clearCache {
clearCache() clearCache()
@ -170,15 +171,16 @@ public class InAppWebView: WKWebView, WKUIDelegate,
if #available(macOS 11.0, *) { if #available(macOS 11.0, *) {
configuration.defaultWebpagePreferences.allowsContentJavaScript = settings.javaScriptEnabled configuration.defaultWebpagePreferences.allowsContentJavaScript = settings.javaScriptEnabled
} }
if #available(macOS 11.3, *) { if #available(macOS 11.3, *) {
configuration.preferences.isTextInteractionEnabled = settings.isTextInteractionEnabled configuration.preferences.isTextInteractionEnabled = settings.isTextInteractionEnabled
} }
if #available(macOS 12.3, *) { if #available(macOS 12.3, *) {
configuration.preferences.isSiteSpecificQuirksModeEnabled = settings.isSiteSpecificQuirksModeEnabled configuration.preferences.isSiteSpecificQuirksModeEnabled = settings.isSiteSpecificQuirksModeEnabled
configuration.preferences.isElementFullscreenEnabled = settings.isElementFullscreenEnabled configuration.preferences.isElementFullscreenEnabled = settings.isElementFullscreenEnabled
} }
if #available(macOS 13.3, *) {
configuration.preferences.shouldPrintBackgrounds = settings.shouldPrintBackgrounds
}
} }
} }
@ -730,6 +732,14 @@ public class InAppWebView: WKWebView, WKUIDelegate,
configuration.preferences.isSiteSpecificQuirksModeEnabled = newSettings.isSiteSpecificQuirksModeEnabled configuration.preferences.isSiteSpecificQuirksModeEnabled = newSettings.isSiteSpecificQuirksModeEnabled
} }
} }
if #available(macOS 13.3, *) {
if newSettingsMap["isInspectable"] != nil, settings?.isInspectable != newSettings.isInspectable {
isInspectable = newSettings.isInspectable
}
if newSettingsMap["shouldPrintBackgrounds"] != nil, settings?.shouldPrintBackgrounds != newSettings.shouldPrintBackgrounds {
configuration.preferences.shouldPrintBackgrounds = newSettings.shouldPrintBackgrounds
}
}
self.settings = newSettings self.settings = newSettings
} }
@ -2102,13 +2112,21 @@ public class InAppWebView: WKWebView, WKUIDelegate,
self.evaluateJavaScript(""" self.evaluateJavaScript("""
if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { 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)]; delete window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)];
} }
""", completionHandler: nil) """, completionHandler: nil)
} }
callback.error = { (code: String, message: String?, details: Any?) in 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 { if let channelDelegate = webView.channelDelegate {

View File

@ -51,6 +51,8 @@ public class InAppWebViewSettings: ISettings<InAppWebView> {
var isSiteSpecificQuirksModeEnabled = true var isSiteSpecificQuirksModeEnabled = true
var upgradeKnownHostsToHTTPS = true var upgradeKnownHostsToHTTPS = true
var isElementFullscreenEnabled = true var isElementFullscreenEnabled = true
var isInspectable = false
var shouldPrintBackgrounds = false
override init(){ override init(){
super.init() super.init()
@ -58,7 +60,7 @@ public class InAppWebViewSettings: ISettings<InAppWebView> {
override func parse(settings: [String: Any?]) -> InAppWebViewSettings { override func parse(settings: [String: Any?]) -> InAppWebViewSettings {
let _ = super.parse(settings: settings) let _ = super.parse(settings: settings)
if #available(iOS 13.0, *) {} else { if #available(macOS 10.15, *) {} else {
applePayAPIEnabled = false applePayAPIEnabled = false
} }
return self return self
@ -68,12 +70,10 @@ public class InAppWebViewSettings: ISettings<InAppWebView> {
var realSettings: [String: Any?] = toMap() var realSettings: [String: Any?] = toMap()
if let webView = obj { if let webView = obj {
let configuration = webView.configuration let configuration = webView.configuration
if #available(iOS 9.0, *) { realSettings["userAgent"] = webView.customUserAgent
realSettings["userAgent"] = webView.customUserAgent realSettings["applicationNameForUserAgent"] = configuration.applicationNameForUserAgent
realSettings["applicationNameForUserAgent"] = configuration.applicationNameForUserAgent realSettings["allowsAirPlayForMediaPlayback"] = configuration.allowsAirPlayForMediaPlayback
realSettings["allowsAirPlayForMediaPlayback"] = configuration.allowsAirPlayForMediaPlayback realSettings["allowsLinkPreview"] = webView.allowsLinkPreview
realSettings["allowsLinkPreview"] = webView.allowsLinkPreview
}
realSettings["javaScriptCanOpenWindowsAutomatically"] = configuration.preferences.javaScriptCanOpenWindowsAutomatically realSettings["javaScriptCanOpenWindowsAutomatically"] = configuration.preferences.javaScriptCanOpenWindowsAutomatically
if #available(macOS 10.12, *) { if #available(macOS 10.12, *) {
realSettings["mediaPlaybackRequiresUserGesture"] = configuration.mediaTypesRequiringUserActionForPlayback == .all realSettings["mediaPlaybackRequiresUserGesture"] = configuration.mediaTypesRequiringUserActionForPlayback == .all
@ -105,6 +105,10 @@ public class InAppWebViewSettings: ISettings<InAppWebView> {
realSettings["isSiteSpecificQuirksModeEnabled"] = configuration.preferences.isSiteSpecificQuirksModeEnabled realSettings["isSiteSpecificQuirksModeEnabled"] = configuration.preferences.isSiteSpecificQuirksModeEnabled
realSettings["isElementFullscreenEnabled"] = configuration.preferences.isElementFullscreenEnabled realSettings["isElementFullscreenEnabled"] = configuration.preferences.isElementFullscreenEnabled
} }
if #available(macOS 13.3, *) {
realSettings["isInspectable"] = webView.isInspectable
realSettings["shouldPrintBackgrounds"] = configuration.preferences.shouldPrintBackgrounds
}
} }
return realSettings return realSettings
} }

View File

@ -26,7 +26,7 @@ window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function() {
var _callHandlerID = setTimeout(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} ); 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) { 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) \(WEB_MESSAGE_LISTENER_JS_SOURCE)

View File

@ -12,9 +12,7 @@ extension WKFrameInfo {
public func toMap () -> [String:Any?] { public func toMap () -> [String:Any?] {
var securityOrigin: [String:Any?]? = nil var securityOrigin: [String:Any?]? = nil
if #available(iOS 9.0, *) { securityOrigin = self.securityOrigin.toMap()
securityOrigin = self.securityOrigin.toMap()
}
// fix: self.request throws EXC_BREAKPOINT when coming from WKNavigationAction.sourceFrame // fix: self.request throws EXC_BREAKPOINT when coming from WKNavigationAction.sourceFrame
let request: URLRequest? = self.value(forKey: "request") as? URLRequest let request: URLRequest? = self.value(forKey: "request") as? URLRequest
return [ return [

View File

@ -34,7 +34,7 @@ public class WebAuthenticationSessionManager: ChannelDelegate {
create(id: id, url: url, callbackURLScheme: callbackURLScheme, settings: initialSettings, result: result) create(id: id, url: url, callbackURLScheme: callbackURLScheme, settings: initialSettings, result: result)
break break
case "isAvailable": case "isAvailable":
if #available(iOS 11.0, *) { if #available(macOS 10.15, *) {
result(true) result(true)
} else { } else {
result(false) result(false)
@ -47,7 +47,7 @@ public class WebAuthenticationSessionManager: ChannelDelegate {
} }
public func create(id: String, url: String, callbackURLScheme: String?, settings: [String: Any?], result: @escaping FlutterResult) { public func create(id: String, url: String, callbackURLScheme: String?, settings: [String: Any?], result: @escaping FlutterResult) {
if #available(iOS 11.0, *) { if #available(macOS 10.15, *) {
let sessionUrl = URL(string: url) ?? URL(string: "about:blank")! let sessionUrl = URL(string: url) ?? URL(string: "about:blank")!
let initialSettings = WebAuthenticationSessionSettings() let initialSettings = WebAuthenticationSessionSettings()
let _ = initialSettings.parse(settings: settings) let _ = initialSettings.parse(settings: settings)

View File

@ -1,12 +1,12 @@
name: flutter_inappwebview name: flutter_inappwebview
description: A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window. description: A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
version: 6.0.0-beta.21 version: 6.0.0-beta.23
homepage: https://inappwebview.dev/ homepage: https://inappwebview.dev/
repository: https://github.com/pichillilorenzo/flutter_inappwebview repository: https://github.com/pichillilorenzo/flutter_inappwebview
issue_tracker: https://github.com/pichillilorenzo/flutter_inappwebview/issues issue_tracker: https://github.com/pichillilorenzo/flutter_inappwebview/issues
environment: environment:
sdk: ">=2.14.0 <3.0.0" sdk: ">=2.15.0 <4.0.0"
flutter: ">=3.0.0" flutter: ">=3.0.0"
dependencies: dependencies: