diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d1c41c9..eca483a8 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,15 @@
## 3.4.0
-- Added `requestFocusNodeHref`, `requestImageRef`, `getMetaTags`, `getMetaThemeColor` webview methods
+- Added `requestFocusNodeHref`, `requestImageRef`, `getMetaTags`, `getMetaThemeColor`, `getScrollX`, `getScrollY` webview methods
- Added `WebStorage`, `LocalStorage` and `SessionStorage` class to manage `window.localStorage` and `window.sessionStorage` JavaScript [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)
- Added `supportZoom` webview option also on iOS
+- Added `HttpOnly`, `SameSite` set cookie options
+- Updated `Cookie` class
+- Added `animated` option to `scrollTo` and `scrollBy` webview methods
+- Added error and message to the `ServerTrustChallenge` class for iOS (class used by the `onReceivedServerTrustAuthRequest` event)
+- Added `contentInsetAdjustmentBehavior` webview iOS-specific option
+- Added `getCertificate` android-specific webview method
+- Added `copy` and `copyWithValue` methods for webview class options
- Fixed `zoomBy`, `setOptions` webview methods on Android
- Fixed `databaseEnabled` android webview option default value to `true`
@@ -12,6 +19,8 @@
- `getHtml` webview method now could return `null` if it was unable to get it.
- Moved `supportZoom` webview option to cross-platform
- `builtInZoomControls` android webview options changed default value to `true`
+- Updated `ServerTrustChallenge` class used by the `onReceivedServerTrustAuthRequest` event
+- The method `getOptions`could return null now
## 3.3.0+3
diff --git a/README.md b/README.md
index d0a69923..1761c632 100755
--- a/README.md
+++ b/README.md
@@ -59,6 +59,10 @@ Because of [Flutter AndroidX compatibility](https://flutter.dev/docs/development
Also, note that to use the `InAppWebView` widget on Android, it requires **Android API 20+** (see [AndroidView](https://api.flutter.dev/flutter/widgets/AndroidView-class.html)).
+**Support HTTP request**: Starting with Android 9 (API level 28), cleartext support is disabled by default:
+- Check the official [Network security configuration - "Opt out of cleartext traffic"](https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted) section.
+- Also, check this StackOverflow issue answer: [Cleartext HTTP traffic not permitted](https://stackoverflow.com/a/50834600/4637638).
+
### IMPORTANT Note for iOS
If you are starting a new fresh app, you need to create the Flutter App with `flutter create --androidx -i swift`
@@ -392,8 +396,8 @@ Screenshots:
* `clearMatches`: Clears the highlighting surrounding text matches created by `findAllAsync()`.
* `getTRexRunnerHtml`: Gets the html (with javascript) of the Chromium's t-rex runner game. Used in combination with `getTRexRunnerCss()`.
* `getTRexRunnerCss`: Gets the css of the Chromium's t-rex runner game. Used in combination with `getTRexRunnerHtml()`.
-* `scrollTo({@required int x, @required int y})`: Scrolls the WebView to the position.
-* `scrollBy({@required int x, @required int y})`: Moves the scrolled position of the WebView.
+* `scrollTo({@required int x, @required int y, bool animated = false})`: Scrolls the WebView to the position.
+* `scrollBy({@required int x, @required int y, bool animated = false})`: Moves the scrolled position of the WebView.
* `pauseTimers`: On Android, it pauses all layout, parsing, and JavaScript timers for all WebViews. This is a global requests, not restricted to just this WebView. This can be useful if the application has been paused. On iOS, it is restricted to just this WebView.
* `resumeTimers`: On Android, it resumes all layout, parsing, and JavaScript timers for all WebViews. This will resume dispatching all timers. On iOS, it resumes all layout, parsing, and JavaScript timers to just this WebView.
* `printCurrentPage`: Prints the current page.
@@ -406,6 +410,8 @@ Screenshots:
* `requestImageRef`: Requests the URL of the image last touched by the user.
* `getMetaTags`: Returns the list of `` tags of the current WebView.
* `getMetaThemeColor`: Returns an instance of `Color` representing the `content` value of the `` tag of the current WebView, if available, otherwise `null`.
+* `getScrollX`: Returns the scrolled left position of the current WebView.
+* `getScrollY`: Returns the scrolled top position of the current WebView.
* `static getDefaultUserAgent`: Gets the default user agent.
##### `InAppWebViewController` Android-specific methods
@@ -587,6 +593,7 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
* `isPagingEnabled`: A Boolean value that determines whether paging is enabled for the scroll view. The default value is `false`.
* `maximumZoomScale`: A floating-point value that specifies the maximum scale factor that can be applied to the scroll view's content. The default value is `1.0`.
* `minimumZoomScale`: A floating-point value that specifies the minimum scale factor that can be applied to the scroll view's content. The default value is `1.0`.
+* `contentInsetAdjustmentBehavior`: Configures how safe area insets are added to the adjusted content inset. The default value is `IOSUIScrollViewContentInsetAdjustmentBehavior.NEVER`.
#### `InAppWebView` Events
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowser/InAppBrowserActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowser/InAppBrowserActivity.java
index 9f08b3f5..f7d63369 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowser/InAppBrowserActivity.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowser/InAppBrowserActivity.java
@@ -280,7 +280,8 @@ public class InAppBrowserActivity extends AppCompatActivity implements MethodCha
{
Integer x = (Integer) call.argument("x");
Integer y = (Integer) call.argument("y");
- scrollTo(x, y);
+ Boolean animated = (Boolean) call.argument("animated");
+ scrollTo(x, y, animated);
}
result.success(true);
break;
@@ -288,7 +289,8 @@ public class InAppBrowserActivity extends AppCompatActivity implements MethodCha
{
Integer x = (Integer) call.argument("x");
Integer y = (Integer) call.argument("y");
- scrollBy(x, y);
+ Boolean animated = (Boolean) call.argument("animated");
+ scrollBy(x, y, animated);
}
result.success(true);
break;
@@ -376,6 +378,21 @@ public class InAppBrowserActivity extends AppCompatActivity implements MethodCha
}
result.success(true);
break;
+ case "requestFocusNodeHref":
+ result.success(requestFocusNodeHref());
+ break;
+ case "requestImageRef":
+ result.success(requestImageRef());
+ break;
+ case "getScrollX":
+ result.success(getScrollX());
+ break;
+ case "getScrollY":
+ result.success(getScrollY());
+ break;
+ case "getCertificate":
+ result.success(getCertificate());
+ break;
default:
result.notImplemented();
}
@@ -804,14 +821,14 @@ public class InAppBrowserActivity extends AppCompatActivity implements MethodCha
result.success(false);
}
- public void scrollTo(Integer x, Integer y) {
+ public void scrollTo(Integer x, Integer y, Boolean animated) {
if (webView != null)
- webView.scrollTo(x, y);
+ webView.scrollTo(x, y, animated);
}
- public void scrollBy(Integer x, Integer y) {
+ public void scrollBy(Integer x, Integer y, Boolean animated) {
if (webView != null)
- webView.scrollBy(x, y);
+ webView.scrollBy(x, y, animated);
}
public void onPauseWebView() {
@@ -930,6 +947,36 @@ public class InAppBrowserActivity extends AppCompatActivity implements MethodCha
webView.contextMenu = contextMenu;
}
+ public Map requestFocusNodeHref() {
+ if (webView != null)
+ return webView.requestFocusNodeHref();
+ return null;
+ }
+
+ public Map requestImageRef() {
+ if (webView != null)
+ return webView.requestImageRef();
+ return null;
+ }
+
+ public Integer getScrollX() {
+ if (webView != null)
+ return webView.getScrollX();
+ return null;
+ }
+
+ public Integer getScrollY() {
+ if (webView != null)
+ return webView.getScrollY();
+ return null;
+ }
+
+ public Map getCertificate() {
+ if (webView != null)
+ return webView.getSslCertificate();
+ return null;
+ }
+
public void dispose() {
channel.setMethodCallHandler(null);
activityResultListeners.clear();
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/FlutterWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/FlutterWebView.java
index 609c7ec2..750471e6 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/FlutterWebView.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/FlutterWebView.java
@@ -5,7 +5,6 @@ import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
-import android.os.Message;
import android.util.Log;
import android.view.View;
import android.webkit.ValueCallback;
@@ -308,7 +307,8 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
if (webView != null) {
Integer x = (Integer) call.argument("x");
Integer y = (Integer) call.argument("y");
- webView.scrollTo(x, y);
+ Boolean animated = (Boolean) call.argument("animated");
+ webView.scrollTo(x, y, animated);
}
result.success(true);
break;
@@ -316,7 +316,8 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
if (webView != null) {
Integer x = (Integer) call.argument("x");
Integer y = (Integer) call.argument("y");
- webView.scrollBy(x, y);
+ Boolean animated = (Boolean) call.argument("animated");
+ webView.scrollBy(x, y, animated);
}
result.success(true);
break;
@@ -461,14 +462,35 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
if (webView != null) {
result.success(webView.requestFocusNodeHref());
} else {
- result.success(false);
+ result.success(null);
}
break;
case "requestImageRef":
if (webView != null) {
result.success(webView.requestImageRef());
} else {
- result.success(false);
+ result.success(null);
+ }
+ break;
+ case "getScrollX":
+ if (webView != null) {
+ result.success(webView.getScrollX());
+ } else {
+ result.success(null);
+ }
+ break;
+ case "getScrollY":
+ if (webView != null) {
+ result.success(webView.getScrollY());
+ } else {
+ result.success(null);
+ }
+ break;
+ case "getCertificate":
+ if (webView != null) {
+ result.success(webView.getSslCertificate());
+ } else {
+ result.success(null);
}
break;
default:
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebView.java
index e26386bb..2d5deb98 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebView.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebView.java
@@ -1,10 +1,13 @@
package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
+import android.net.http.SslCertificate;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -36,6 +39,7 @@ import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.annotation.Keep;
import androidx.annotation.RequiresApi;
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;
@@ -52,6 +56,11 @@ import com.pichillilorenzo.flutter_inappwebview.Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -1484,6 +1493,28 @@ final public class InAppWebView extends InputAwareWebView {
channel.invokeMethod("onScrollChanged", obj);
}
+ public void scrollTo(Integer x, Integer y, Boolean animated) {
+ if (animated) {
+ PropertyValuesHolder pvhX = PropertyValuesHolder.ofInt("scrollX", x);
+ PropertyValuesHolder pvhY = PropertyValuesHolder.ofInt("scrollY", y);
+ ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY);
+ anim.setDuration(300).start();
+ } else {
+ scrollTo(x, y);
+ }
+ }
+
+ public void scrollBy(Integer x, Integer y, Boolean animated) {
+ if (animated) {
+ PropertyValuesHolder pvhX = PropertyValuesHolder.ofInt("scrollX", getScrollX() + x);
+ PropertyValuesHolder pvhY = PropertyValuesHolder.ofInt("scrollY", getScrollY() + y);
+ ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY);
+ anim.setDuration(300).start();
+ } else {
+ scrollBy(x, y);
+ }
+ }
+
class DownloadStartListener implements DownloadListener {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
@@ -1833,6 +1864,110 @@ final public class InAppWebView extends InputAwareWebView {
return obj;
}
+ public Map getSslCertificate() {
+ SslCertificate sslCertificate = getCertificate();
+
+ SslCertificate.DName issuedByName = sslCertificate.getIssuedBy();
+ Map issuedBy = new HashMap<>();
+ issuedBy.put("CName", issuedByName.getCName());
+ issuedBy.put("DName", issuedByName.getDName());
+ issuedBy.put("OName", issuedByName.getOName());
+ issuedBy.put("UName", issuedByName.getUName());
+
+ SslCertificate.DName issuedToName = sslCertificate.getIssuedTo();
+ Map issuedTo = new HashMap<>();
+ issuedTo.put("CName", issuedToName.getCName());
+ issuedTo.put("DName", issuedToName.getDName());
+ issuedTo.put("OName", issuedToName.getOName());
+ issuedTo.put("UName", issuedToName.getUName());
+
+ Map x509CertificateMap = new HashMap<>();
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
+ X509Certificate x509Certificate = sslCertificate.getX509Certificate();
+ if (x509Certificate != null) {
+ x509CertificateMap.put("basicConstraints", x509Certificate.getBasicConstraints());
+ try {
+ x509CertificateMap.put("extendedKeyUsage", x509Certificate.getExtendedKeyUsage());
+ } catch (CertificateParsingException e) {
+ x509CertificateMap.put("extendedKeyUsage", null);
+ }
+
+ Map issuerDN = new HashMap<>();
+ issuerDN.put("name", x509Certificate.getIssuerDN().getName());
+ x509CertificateMap.put("issuerDN", issuerDN);
+
+ x509CertificateMap.put("issuerUniqueID", x509Certificate.getIssuerUniqueID());
+
+ Map issuerX500Principal = new HashMap<>();
+ issuerX500Principal.put("name", x509Certificate.getIssuerX500Principal().getName());
+ issuerX500Principal.put("encoded", x509Certificate.getIssuerX500Principal().getEncoded());
+ x509CertificateMap.put("issuerX500Principal", issuerX500Principal);
+
+ x509CertificateMap.put("keyUsage", x509Certificate.getKeyUsage());
+ x509CertificateMap.put("notAfter", x509Certificate.getNotAfter().getTime());
+ x509CertificateMap.put("notBefore", x509Certificate.getNotBefore().getTime());
+ x509CertificateMap.put("serialNumber", x509Certificate.getSerialNumber().longValue());
+ x509CertificateMap.put("sigAlgName", x509Certificate.getSigAlgName());
+ x509CertificateMap.put("sigAlgOID", x509Certificate.getSigAlgOID());
+ x509CertificateMap.put("sigAlgParams", x509Certificate.getSigAlgParams());
+ x509CertificateMap.put("signature", x509Certificate.getSignature());
+
+ Map subjectDN = new HashMap<>();
+ subjectDN.put("name", x509Certificate.getSubjectDN().getName());
+ x509CertificateMap.put("subjectDN", subjectDN);
+
+ x509CertificateMap.put("subjectUniqueID", x509Certificate.getSubjectUniqueID());
+
+ Map subjectX500Principal = new HashMap<>();
+ subjectX500Principal.put("name", x509Certificate.getSubjectX500Principal().getName());
+ subjectX500Principal.put("encoded", x509Certificate.getSubjectX500Principal().getEncoded());
+ x509CertificateMap.put("subjectX500Principal", subjectX500Principal);
+
+ try {
+ x509CertificateMap.put("TBSCertificate", x509Certificate.getTBSCertificate());
+ } catch (CertificateEncodingException e) {
+ x509CertificateMap.put("TBSCertificate", null);
+ }
+
+ x509CertificateMap.put("version", x509Certificate.getVersion());
+ x509CertificateMap.put("criticalExtensionOIDs", x509Certificate.getCriticalExtensionOIDs());
+ x509CertificateMap.put("nonCriticalExtensionOIDs", x509Certificate.getNonCriticalExtensionOIDs());
+ try {
+ x509CertificateMap.put("encoded", x509Certificate.getEncoded());
+ } catch (CertificateEncodingException e) {
+ x509CertificateMap.put("encoded", null);
+ }
+
+ Map publicKey = new HashMap<>();
+ publicKey.put("algorithm", x509Certificate.getPublicKey().getAlgorithm());
+ publicKey.put("encoded", x509Certificate.getPublicKey().getEncoded());
+ publicKey.put("format", x509Certificate.getPublicKey().getFormat());
+ x509CertificateMap.put("publicKey", publicKey);
+
+ x509CertificateMap.put("type", x509Certificate.getType());
+ x509CertificateMap.put("hasUnsupportedCriticalExtension", x509Certificate.hasUnsupportedCriticalExtension());
+
+ try {
+ x509Certificate.checkValidity();
+ x509CertificateMap.put("valid", true);
+ } catch (CertificateExpiredException e) {
+ x509CertificateMap.put("valid", false);
+ } catch (CertificateNotYetValidException e) {
+ x509CertificateMap.put("valid", false);
+ }
+ }
+ }
+
+ Map obj = new HashMap<>();
+ obj.put("issuedBy", issuedBy);
+ obj.put("issuedTo", issuedTo);
+ obj.put("validNotAfterDate", sslCertificate.getValidNotAfterDate().getTime());
+ obj.put("validNotBeforeDate", sslCertificate.getValidNotBeforeDate().getTime());
+ obj.put("x509Certificate", x509CertificateMap);
+
+ return obj;
+ }
+
@Override
public void dispose() {
super.dispose();
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewClient.java
index 615929b8..c006d8ff 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewClient.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewClient.java
@@ -29,9 +29,11 @@ import com.pichillilorenzo.flutter_inappwebview.CredentialDatabase.Credential;
import com.pichillilorenzo.flutter_inappwebview.CredentialDatabase.CredentialDatabase;
import com.pichillilorenzo.flutter_inappwebview.InAppBrowser.InAppBrowserActivity;
import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface;
+import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.Util;
import java.io.ByteArrayInputStream;
+import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -426,7 +428,8 @@ public class InAppWebViewClient extends WebViewClient {
obj.put("protocol", protocol);
obj.put("realm", realm);
obj.put("port", port);
- obj.put("error", error.getPrimaryError());
+ obj.put("androidError", error.getPrimaryError());
+ obj.put("iosError", null);
obj.put("serverCertificate", null);
try {
X509Certificate certificate;
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java
index 02603bdc..dea21f16 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java
@@ -6,6 +6,8 @@ import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.ValueCallback;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@@ -47,7 +49,19 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
Long expiresDate = (expiresDateString != null ? new Long(expiresDateString) : null);
Integer maxAge = (Integer) call.argument("maxAge");
Boolean isSecure = (Boolean) call.argument("isSecure");
- MyCookieManager.setCookie(url, name, value, domain, path, expiresDate, maxAge, isSecure, result);
+ Boolean isHttpOnly = (Boolean) call.argument("isHttpOnly");
+ String sameSite = (String) call.argument("sameSite");
+ MyCookieManager.setCookie(url,
+ name,
+ value,
+ domain,
+ path,
+ expiresDate,
+ maxAge,
+ isSecure,
+ isHttpOnly,
+ sameSite,
+ result);
}
break;
case "getCookies":
@@ -86,6 +100,8 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
Long expiresDate,
Integer maxAge,
Boolean isSecure,
+ Boolean isHttpOnly,
+ String sameSite,
final MethodChannel.Result result) {
String cookieValue = name + "=" + value + "; Domain=" + domain + "; Path=" + path;
@@ -99,6 +115,12 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
if (isSecure != null && isSecure)
cookieValue += "; Secure";
+ if (isHttpOnly != null && isHttpOnly)
+ cookieValue += "; HttpOnly";
+
+ if (sameSite != null)
+ cookieValue += "; SameSite=" + sameSite;
+
cookieValue += ";";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
@@ -135,6 +157,14 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
Map cookieMap = new HashMap<>();
cookieMap.put("name", name);
cookieMap.put("value", value);
+ cookieMap.put("expiresDate", null);
+ cookieMap.put("isSessionOnly", null);
+ cookieMap.put("domain", null);
+ cookieMap.put("sameSite", null);
+ cookieMap.put("isSecure", null);
+ cookieMap.put("isHttpOnly", null);
+ cookieMap.put("path", null);
+
cookieListMap.add(cookieMap);
}
}
diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies
index a5a27a93..b6fd9f35 100755
--- a/example/.flutter-plugins-dependencies
+++ b/example/.flutter-plugins-dependencies
@@ -1 +1 @@
-{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.9/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.0+hotfix.6/","dependencies":[]}],"android":[{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.9/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.0+hotfix.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+3/","dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"e2e","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"permission_handler","dependencies":[]}],"date_created":"2020-06-12 02:54:04.283438","version":"1.17.1"}
\ No newline at end of file
+{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.9/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.0+hotfix.6/","dependencies":[]}],"android":[{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.9/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.0+hotfix.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+3/","dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"e2e","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"permission_handler","dependencies":[]}],"date_created":"2020-06-13 01:39:11.912485","version":"1.17.1"}
\ No newline at end of file
diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart
index db321396..e132a74a 100755
--- a/example/lib/in_app_webiew_example.screen.dart
+++ b/example/lib/in_app_webiew_example.screen.dart
@@ -16,6 +16,7 @@ class _InAppWebViewExampleScreenState extends State {
ContextMenu contextMenu;
String url = "";
double progress = 0;
+ CookieManager _cookieManager = CookieManager.instance();
@override
void initState() {
@@ -78,8 +79,8 @@ class _InAppWebViewExampleScreenState extends State {
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: InAppWebView(
contextMenu: contextMenu,
- // initialUrl: "https://github.com/flutter",
- initialFile: "assets/index.html",
+ initialUrl: "https://github.com/flutter",
+ // initialFile: "assets/index.html",
initialHeaders: {},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
@@ -101,37 +102,12 @@ class _InAppWebViewExampleScreenState extends State {
print("shouldOverrideUrlLoading");
return ShouldOverrideUrlLoadingAction.ALLOW;
},
- onCreateWindow: (controller, onCreateWindowRequest) {
- print("onCreateWindow");
- },
onLoadStop: (InAppWebViewController controller, String url) async {
print("onLoadStop $url");
setState(() {
this.url = url;
});
- /*var origins = await WebStorageManager.instance().android.getOrigins();
- for (var origin in origins) {
- print(origin);
- print(await WebStorageManager.instance().android.getQuotaForOrigin(origin: origin.origin));
- print(await WebStorageManager.instance().android.getUsageForOrigin(origin: origin.origin));
- }
- await WebStorageManager.instance().android.deleteAllData();
- print("\n\nDELETED\n\n");
- origins = await WebStorageManager.instance().android.getOrigins();
- for (var origin in origins) {
- print(origin);
- await WebStorageManager.instance().android.deleteOrigin(origin: origin.origin);
- }*/
- /*var records = await WebStorageManager.instance().ios.fetchDataRecords(dataTypes: IOSWKWebsiteDataType.ALL);
- for(var record in records) {
- print(record);
- }
- await WebStorageManager.instance().ios.removeDataModifiedSince(dataTypes: IOSWKWebsiteDataType.ALL, date: DateTime(0));
- print("\n\nDELETED\n\n");
- records = await WebStorageManager.instance().ios.fetchDataRecords(dataTypes: IOSWKWebsiteDataType.ALL);
- for(var record in records) {
- print(record);
- }*/
+
},
onProgressChanged: (InAppWebViewController controller, int progress) {
setState(() {
diff --git a/example/test_assets/in_app_webview_initial_file_test.html b/example/test_assets/in_app_webview_initial_file_test.html
index c81fbe74..657877d7 100755
--- a/example/test_assets/in_app_webview_initial_file_test.html
+++ b/example/test_assets/in_app_webview_initial_file_test.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/in_app_webview_javascript_handler_test.html b/example/test_assets/in_app_webview_javascript_handler_test.html
index 863f170b..46fc3fd1 100755
--- a/example/test_assets/in_app_webview_javascript_handler_test.html
+++ b/example/test_assets/in_app_webview_javascript_handler_test.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/in_app_webview_on_console_message_test.html b/example/test_assets/in_app_webview_on_console_message_test.html
index 48cd6af4..1b5d1d55 100755
--- a/example/test_assets/in_app_webview_on_console_message_test.html
+++ b/example/test_assets/in_app_webview_on_console_message_test.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/in_app_webview_on_create_window_test.html b/example/test_assets/in_app_webview_on_create_window_test.html
index 2863c2fe..84f7fd4f 100755
--- a/example/test_assets/in_app_webview_on_create_window_test.html
+++ b/example/test_assets/in_app_webview_on_create_window_test.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/in_app_webview_on_js_dialog_test.html b/example/test_assets/in_app_webview_on_js_dialog_test.html
index 6a2d93f0..75b8d31f 100755
--- a/example/test_assets/in_app_webview_on_js_dialog_test.html
+++ b/example/test_assets/in_app_webview_on_js_dialog_test.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/in_app_webview_on_load_resource_custom_scheme_test.html b/example/test_assets/in_app_webview_on_load_resource_custom_scheme_test.html
index 663ff9a6..8d674f28 100755
--- a/example/test_assets/in_app_webview_on_load_resource_custom_scheme_test.html
+++ b/example/test_assets/in_app_webview_on_load_resource_custom_scheme_test.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/in_app_webview_on_load_resource_test.html b/example/test_assets/in_app_webview_on_load_resource_test.html
index d9c33098..bb3ee318 100755
--- a/example/test_assets/in_app_webview_on_load_resource_test.html
+++ b/example/test_assets/in_app_webview_on_load_resource_test.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/in_app_webview_on_navigation_state_change_test.html b/example/test_assets/in_app_webview_on_navigation_state_change_test.html
index 4db56fdb..711c614b 100755
--- a/example/test_assets/in_app_webview_on_navigation_state_change_test.html
+++ b/example/test_assets/in_app_webview_on_navigation_state_change_test.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/index.html b/example/test_assets/index.html
index 26188d6d..157ce94d 100755
--- a/example/test_assets/index.html
+++ b/example/test_assets/index.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/page-1.html b/example/test_assets/page-1.html
index 9babbb03..38d28c6e 100755
--- a/example/test_assets/page-1.html
+++ b/example/test_assets/page-1.html
@@ -1,4 +1,4 @@
-
+
diff --git a/example/test_assets/page-2.html b/example/test_assets/page-2.html
index 537af895..aa6d2c0f 100755
--- a/example/test_assets/page-2.html
+++ b/example/test_assets/page-2.html
@@ -1,4 +1,4 @@
-
+
diff --git a/ios/Classes/FlutterWebViewController.swift b/ios/Classes/FlutterWebViewController.swift
index 6582cfd2..56c8f522 100755
--- a/ios/Classes/FlutterWebViewController.swift
+++ b/ios/Classes/FlutterWebViewController.swift
@@ -347,7 +347,8 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
if webView != nil {
let x = arguments!["x"] as! Int
let y = arguments!["y"] as! Int
- webView!.scrollTo(x: x, y: y)
+ let animated = arguments!["animated"] as! Bool
+ webView!.scrollTo(x: x, y: y, animated: animated)
}
result(true)
break
@@ -355,7 +356,8 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
if webView != nil {
let x = arguments!["x"] as! Int
let y = arguments!["y"] as! Int
- webView!.scrollBy(x: x, y: y)
+ let animated = arguments!["animated"] as! Bool
+ webView!.scrollBy(x: x, y: y, animated: animated)
}
result(true)
break
@@ -475,6 +477,20 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
result(false)
}
break
+ case "getScrollX":
+ if webView != nil {
+ result(Int(webView!.scrollView.contentOffset.x))
+ } else {
+ result(false)
+ }
+ break
+ case "getScrollY":
+ if webView != nil {
+ result(Int(webView!.scrollView.contentOffset.y))
+ } else {
+ result(false)
+ }
+ break
default:
result(FlutterMethodNotImplemented)
break
diff --git a/ios/Classes/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowserWebViewController.swift
index 75e351b3..e20e89b8 100755
--- a/ios/Classes/InAppBrowserWebViewController.swift
+++ b/ios/Classes/InAppBrowserWebViewController.swift
@@ -243,13 +243,15 @@ public class InAppBrowserWebViewController: UIViewController, FlutterPlugin, UIS
case "scrollTo":
let x = arguments!["x"] as! Int
let y = arguments!["y"] as! Int
- webView.scrollTo(x: x, y: y)
+ let animated = arguments!["animated"] as! Bool
+ webView.scrollTo(x: x, y: y, animated: animated)
result(true)
break
case "scrollBy":
let x = arguments!["x"] as! Int
let y = arguments!["y"] as! Int
- webView.scrollTo(x: x, y: y)
+ let animated = arguments!["animated"] as! Bool
+ webView.scrollTo(x: x, y: y, animated: animated)
result(true)
break
case "pauseTimers":
diff --git a/ios/Classes/InAppWebView.swift b/ios/Classes/InAppWebView.swift
index 97b3ebc2..22b8ed1c 100755
--- a/ios/Classes/InAppWebView.swift
+++ b/ios/Classes/InAppWebView.swift
@@ -1105,6 +1105,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
if #available(iOS 11.0, *) {
accessibilityIgnoresInvertColors = (options?.accessibilityIgnoresInvertColors)!
+ scrollView.contentInsetAdjustmentBehavior =
+ UIScrollView.ContentInsetAdjustmentBehavior.init(rawValue: (options?.contentInsetAdjustmentBehavior)!)!
}
configuration.suppressesIncrementalRendering = (options?.suppressesIncrementalRendering)!
@@ -1488,6 +1490,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
if newOptionsMap["accessibilityIgnoresInvertColors"] != nil && options?.accessibilityIgnoresInvertColors != newOptions.accessibilityIgnoresInvertColors {
accessibilityIgnoresInvertColors = newOptions.accessibilityIgnoresInvertColors
}
+ if newOptionsMap["contentInsetAdjustmentBehavior"] != nil && options?.contentInsetAdjustmentBehavior != newOptions.contentInsetAdjustmentBehavior {
+ scrollView.contentInsetAdjustmentBehavior =
+ UIScrollView.ContentInsetAdjustmentBehavior.init(rawValue: newOptions.contentInsetAdjustmentBehavior)!
+ }
}
if newOptionsMap["enableViewportScale"] != nil && options?.enableViewportScale != newOptions.enableViewportScale {
@@ -2542,6 +2548,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
public func onReceivedServerTrustAuthRequest(challenge: URLAuthenticationChallenge, result: FlutterResult?) {
var serverCertificateData: NSData?
let serverTrust = challenge.protectionSpace.serverTrust!
+
+ var secResult = SecTrustResultType.invalid
+ SecTrustEvaluate(serverTrust, &secResult);
+
if let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) {
let serverCertificateCFData = SecCertificateCopyData(serverCertificate)
let data = CFDataGetBytePtr(serverCertificateCFData)
@@ -2549,6 +2559,32 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
serverCertificateData = NSData(bytes: data, length: size)
}
+ let error = secResult != SecTrustResultType.proceed ? secResult.rawValue : nil
+
+ var message = ""
+ switch secResult {
+ case .deny:
+ message = "Indicates a user-configured deny; do not proceed."
+ break
+ case .fatalTrustFailure:
+ message = "Indicates a trust failure which cannot be overridden by the user."
+ break
+ case .invalid:
+ message = "Indicates an invalid setting or result."
+ break
+ case .otherError:
+ message = "Indicates a failure other than that of trust evaluation."
+ break
+ case .recoverableTrustFailure:
+ message = "Indicates a trust policy failure which can be overridden by the user."
+ break
+ case .unspecified:
+ message = "Indicates the evaluation succeeded and the certificate is implicitly trusted, but user intent was not explicitly specified."
+ break
+ default:
+ message = ""
+ }
+
let arguments: [String: Any?] = [
"host": challenge.protectionSpace.host,
"protocol": challenge.protectionSpace.protocol,
@@ -2556,8 +2592,9 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
"port": challenge.protectionSpace.port,
"previousFailureCount": challenge.previousFailureCount,
"serverCertificate": serverCertificateData,
- "error": -1,
- "message": "",
+ "androidError": nil,
+ "iosError": error,
+ "message": message,
]
channel?.invokeMethod("onReceivedServerTrustAuthRequest", arguments: arguments, result: result)
}
@@ -2746,14 +2783,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
evaluateJavaScript("wkwebview_ClearMatches();", completionHandler: completionHandler)
}
- public func scrollTo(x: Int, y: Int) {
- scrollView.setContentOffset(CGPoint(x: x, y: y), animated: false)
+ public func scrollTo(x: Int, y: Int, animated: Bool) {
+ scrollView.setContentOffset(CGPoint(x: x, y: y), animated: animated)
}
- public func scrollBy(x: Int, y: Int) {
+ public func scrollBy(x: Int, y: Int, animated: Bool) {
let newX = CGFloat(x) + scrollView.contentOffset.x
let newY = CGFloat(y) + scrollView.contentOffset.y
- scrollView.setContentOffset(CGPoint(x: newX, y: newY), animated: false)
+ scrollView.setContentOffset(CGPoint(x: newX, y: newY), animated: animated)
}
diff --git a/ios/Classes/InAppWebViewOptions.swift b/ios/Classes/InAppWebViewOptions.swift
index 38de8324..7668370a 100755
--- a/ios/Classes/InAppWebViewOptions.swift
+++ b/ios/Classes/InAppWebViewOptions.swift
@@ -59,6 +59,7 @@ public class InAppWebViewOptions: Options {
var isPagingEnabled = false
var maximumZoomScale = 1.0
var minimumZoomScale = 1.0
+ var contentInsetAdjustmentBehavior = 2 // UIScrollView.ContentInsetAdjustmentBehavior.never
override init(){
super.init()
@@ -96,6 +97,7 @@ public class InAppWebViewOptions: Options {
realOptions["selectionGranularity"] = configuration.selectionGranularity.rawValue
if #available(iOS 11.0, *) {
realOptions["accessibilityIgnoresInvertColors"] = webView.accessibilityIgnoresInvertColors
+ realOptions["contentInsetAdjustmentBehavior"] = webView.scrollView.contentInsetAdjustmentBehavior.rawValue
}
realOptions["decelerationRate"] = InAppWebView.getDecelerationRateString(type: webView.scrollView.decelerationRate)
realOptions["alwaysBounceVertical"] = webView.scrollView.alwaysBounceVertical
diff --git a/ios/Classes/MyCookieManager.swift b/ios/Classes/MyCookieManager.swift
index 6fbb2651..912e51e4 100755
--- a/ios/Classes/MyCookieManager.swift
+++ b/ios/Classes/MyCookieManager.swift
@@ -45,8 +45,20 @@ class MyCookieManager: NSObject, FlutterPlugin {
let maxAge = arguments!["maxAge"] as? Int64
let isSecure = arguments!["isSecure"] as? Bool
+ let isHttpOnly = arguments!["isHttpOnly"] as? Bool
+ let sameSite = arguments!["sameSite"] as? String
- MyCookieManager.setCookie(url: url, name: name, value: value, domain: domain, path: path, expiresDate: expiresDate, maxAge: maxAge, isSecure: isSecure, result: result)
+ MyCookieManager.setCookie(url: url,
+ name: name,
+ value: value,
+ domain: domain,
+ path: path,
+ expiresDate: expiresDate,
+ maxAge: maxAge,
+ isSecure: isSecure,
+ isHttpOnly: isHttpOnly,
+ sameSite: sameSite,
+ result: result)
break
case "getCookies":
let url = arguments!["url"] as! String
@@ -82,6 +94,8 @@ class MyCookieManager: NSObject, FlutterPlugin {
expiresDate: Int64?,
maxAge: Int64?,
isSecure: Bool?,
+ isHttpOnly: Bool?,
+ sameSite: String?,
result: @escaping FlutterResult) {
var properties: [HTTPCookiePropertyKey: Any] = [:]
properties[.originURL] = url
@@ -90,6 +104,7 @@ class MyCookieManager: NSObject, FlutterPlugin {
properties[.domain] = domain
properties[.path] = path
if expiresDate != nil {
+ // convert from milliseconds
properties[.expires] = Date(timeIntervalSince1970: TimeInterval(Double(expiresDate!)/1000))
}
if maxAge != nil {
@@ -98,21 +113,61 @@ class MyCookieManager: NSObject, FlutterPlugin {
if isSecure != nil && isSecure! {
properties[.secure] = "TRUE"
}
+ if isHttpOnly != nil && isHttpOnly! {
+ properties[.init("HttpOnly")] = "YES"
+ }
+ if sameSite != nil {
+ if #available(iOS 13.0, *) {
+ var sameSiteValue = HTTPCookieStringPolicy(rawValue: "None")
+ switch sameSite {
+ case "Lax":
+ sameSiteValue = HTTPCookieStringPolicy.sameSiteLax
+ case "Strict":
+ sameSiteValue = HTTPCookieStringPolicy.sameSiteStrict
+ default:
+ break
+ }
+ properties[.sameSitePolicy] = sameSiteValue
+ } else {
+ properties[.init("SameSite")] = sameSite
+ }
+ }
let cookie = HTTPCookie(properties: properties)!
+
MyCookieManager.httpCookieStore!.setCookie(cookie, completionHandler: {() in
result(true)
})
}
public static func getCookies(url: String, result: @escaping FlutterResult) {
- var cookieList: [[String: Any]] = []
+ var cookieList: [[String: Any?]] = []
MyCookieManager.httpCookieStore!.getAllCookies { (cookies) in
for cookie in cookies {
if cookie.domain.contains(URL(string: url)!.host!) {
+ var sameSite: String? = nil
+ if #available(iOS 13.0, *) {
+ if let sameSiteValue = cookie.sameSitePolicy?.rawValue {
+ sameSite = sameSiteValue.prefix(1).capitalized + sameSiteValue.dropFirst()
+ }
+ }
+
+ var expiresDateTimestamp: Int64 = -1
+ if let expiresDate = cookie.expiresDate?.timeIntervalSince1970 {
+ // convert to milliseconds
+ expiresDateTimestamp = Int64(expiresDate * 1000)
+ }
+
cookieList.append([
"name": cookie.name,
- "value": cookie.value
+ "value": cookie.value,
+ "expiresDate": expiresDateTimestamp != -1 ? expiresDateTimestamp : nil,
+ "isSessionOnly": cookie.isSessionOnly,
+ "domain": cookie.domain,
+ "sameSite": sameSite,
+ "isSecure": cookie.isSecure,
+ "isHttpOnly": cookie.isHTTPOnly,
+ "path": cookie.path,
])
}
}
diff --git a/lib/src/cookie_manager.dart b/lib/src/cookie_manager.dart
index 8db51de8..1db87cd2 100755
--- a/lib/src/cookie_manager.dart
+++ b/lib/src/cookie_manager.dart
@@ -40,8 +40,10 @@ class CookieManager {
String path = "/",
int expiresDate,
int maxAge,
- bool isSecure}) async {
- if (domain == null || domain.isEmpty) domain = _getDomainName(url);
+ bool isSecure,
+ bool isHttpOnly,
+ HTTPCookieSameSitePolicy sameSite}) async {
+ if (domain == null) domain = _getDomainName(url);
assert(url != null && url.isNotEmpty);
assert(name != null && name.isNotEmpty);
@@ -58,6 +60,8 @@ class CookieManager {
args.putIfAbsent('expiresDate', () => expiresDate?.toString());
args.putIfAbsent('maxAge', () => maxAge);
args.putIfAbsent('isSecure', () => isSecure);
+ args.putIfAbsent('isHttpOnly', () => isHttpOnly);
+ args.putIfAbsent('sameSite', () => sameSite?.toValue());
await _channel.invokeMethod('setCookie', args);
}
@@ -71,10 +75,19 @@ class CookieManager {
List cookieListMap =
await _channel.invokeMethod('getCookies', args);
cookieListMap = cookieListMap.cast