refactored remaining classes and properties
This commit is contained in:
parent
5371b77231
commit
cdd2bdb09f
|
@ -34,7 +34,7 @@ public class ServiceWorkerManager implements MethodChannel.MethodCallHandler {
|
||||||
|
|
||||||
public ServiceWorkerManager(final InAppWebViewFlutterPlugin plugin) {
|
public ServiceWorkerManager(final InAppWebViewFlutterPlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_android_serviceworkercontroller");
|
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_serviceworkercontroller");
|
||||||
channel.setMethodCallHandler(this);
|
channel.setMethodCallHandler(this);
|
||||||
if (WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE)) {
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE)) {
|
||||||
serviceWorkerController = ServiceWorkerControllerCompat.getInstance();
|
serviceWorkerController = ServiceWorkerControllerCompat.getInstance();
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class WebViewFeatureManager implements MethodChannel.MethodCallHandler {
|
||||||
|
|
||||||
public WebViewFeatureManager(final InAppWebViewFlutterPlugin plugin) {
|
public WebViewFeatureManager(final InAppWebViewFlutterPlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_android_webviewfeature");
|
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_webviewfeature");
|
||||||
channel.setMethodCallHandler(this);
|
channel.setMethodCallHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import android.content.Intent;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.browser.customtabs.CustomTabColorSchemeParams;
|
import androidx.browser.customtabs.CustomTabColorSchemeParams;
|
||||||
import androidx.browser.customtabs.CustomTabsCallback;
|
import androidx.browser.customtabs.CustomTabsCallback;
|
||||||
|
@ -29,7 +28,7 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
||||||
public MethodChannel channel;
|
public MethodChannel channel;
|
||||||
public String id;
|
public String id;
|
||||||
public CustomTabsIntent.Builder builder;
|
public CustomTabsIntent.Builder builder;
|
||||||
public ChromeCustomTabsOptions options;
|
public ChromeCustomTabsSettings customSettings;
|
||||||
public CustomTabActivityHelper customTabActivityHelper;
|
public CustomTabActivityHelper customTabActivityHelper;
|
||||||
public CustomTabsSession customTabsSession;
|
public CustomTabsSession customTabsSession;
|
||||||
protected final int CHROME_CUSTOM_TAB_REQUEST_CODE = 100;
|
protected final int CHROME_CUSTOM_TAB_REQUEST_CODE = 100;
|
||||||
|
@ -56,8 +55,8 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
||||||
|
|
||||||
final String url = b.getString("url");
|
final String url = b.getString("url");
|
||||||
|
|
||||||
options = new ChromeCustomTabsOptions();
|
customSettings = new ChromeCustomTabsSettings();
|
||||||
options.parse((HashMap<String, Object>) b.getSerializable("options"));
|
customSettings.parse((HashMap<String, Object>) b.getSerializable("settings"));
|
||||||
|
|
||||||
final List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) b.getSerializable("menuItemList");
|
final List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) b.getSerializable("menuItemList");
|
||||||
|
|
||||||
|
@ -154,23 +153,23 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareCustomTabs(List<HashMap<String, Object>> menuItemList) {
|
private void prepareCustomTabs(List<HashMap<String, Object>> menuItemList) {
|
||||||
if (options.addDefaultShareMenuItem != null) {
|
if (customSettings.addDefaultShareMenuItem != null) {
|
||||||
builder.setShareState(options.addDefaultShareMenuItem ?
|
builder.setShareState(customSettings.addDefaultShareMenuItem ?
|
||||||
CustomTabsIntent.SHARE_STATE_ON : CustomTabsIntent.SHARE_STATE_OFF);
|
CustomTabsIntent.SHARE_STATE_ON : CustomTabsIntent.SHARE_STATE_OFF);
|
||||||
} else {
|
} else {
|
||||||
builder.setShareState(options.shareState);
|
builder.setShareState(customSettings.shareState);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.toolbarBackgroundColor != null && !options.toolbarBackgroundColor.isEmpty()) {
|
if (customSettings.toolbarBackgroundColor != null && !customSettings.toolbarBackgroundColor.isEmpty()) {
|
||||||
CustomTabColorSchemeParams.Builder defaultColorSchemeBuilder = new CustomTabColorSchemeParams.Builder();
|
CustomTabColorSchemeParams.Builder defaultColorSchemeBuilder = new CustomTabColorSchemeParams.Builder();
|
||||||
builder.setDefaultColorSchemeParams(defaultColorSchemeBuilder
|
builder.setDefaultColorSchemeParams(defaultColorSchemeBuilder
|
||||||
.setToolbarColor(Color.parseColor(options.toolbarBackgroundColor))
|
.setToolbarColor(Color.parseColor(customSettings.toolbarBackgroundColor))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setShowTitle(options.showTitle);
|
builder.setShowTitle(customSettings.showTitle);
|
||||||
builder.setUrlBarHidingEnabled(options.enableUrlBarHiding);
|
builder.setUrlBarHidingEnabled(customSettings.enableUrlBarHiding);
|
||||||
builder.setInstantAppsEnabled(options.instantAppsEnabled);
|
builder.setInstantAppsEnabled(customSettings.instantAppsEnabled);
|
||||||
|
|
||||||
for (HashMap<String, Object> menuItem : menuItemList) {
|
for (HashMap<String, Object> menuItem : menuItemList) {
|
||||||
int id = (int) menuItem.get("id");
|
int id = (int) menuItem.get("id");
|
||||||
|
@ -180,12 +179,12 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareCustomTabsIntent(CustomTabsIntent customTabsIntent) {
|
private void prepareCustomTabsIntent(CustomTabsIntent customTabsIntent) {
|
||||||
if (options.packageName != null)
|
if (customSettings.packageName != null)
|
||||||
customTabsIntent.intent.setPackage(options.packageName);
|
customTabsIntent.intent.setPackage(customSettings.packageName);
|
||||||
else
|
else
|
||||||
customTabsIntent.intent.setPackage(CustomTabsHelper.getPackageNameToUse(this));
|
customTabsIntent.intent.setPackage(CustomTabsHelper.getPackageNameToUse(this));
|
||||||
|
|
||||||
if (options.keepAliveEnabled)
|
if (customSettings.keepAliveEnabled)
|
||||||
CustomTabsHelper.addKeepAliveExtra(this, customTabsIntent.intent);
|
CustomTabsHelper.addKeepAliveExtra(this, customTabsIntent.intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,9 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ChromeCustomTabsOptions implements IWebViewSettings<ChromeCustomTabsActivity> {
|
public class ChromeCustomTabsSettings implements IWebViewSettings<ChromeCustomTabsActivity> {
|
||||||
|
|
||||||
final static String LOG_TAG = "ChromeCustomTabsOptions";
|
final static String LOG_TAG = "ChromeCustomTabsSettings";
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Boolean addDefaultShareMenuItem;
|
public Boolean addDefaultShareMenuItem;
|
||||||
|
@ -36,7 +36,7 @@ public class ChromeCustomTabsOptions implements IWebViewSettings<ChromeCustomTab
|
||||||
public Integer screenOrientation = ScreenOrientation.DEFAULT;
|
public Integer screenOrientation = ScreenOrientation.DEFAULT;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChromeCustomTabsOptions parse(Map<String, Object> options) {
|
public ChromeCustomTabsSettings parse(Map<String, Object> options) {
|
||||||
for (Map.Entry<String, Object> pair : options.entrySet()) {
|
for (Map.Entry<String, Object> pair : options.entrySet()) {
|
||||||
String key = pair.getKey();
|
String key = pair.getKey();
|
||||||
Object value = pair.getValue();
|
Object value = pair.getValue();
|
|
@ -43,9 +43,9 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
|
||||||
case "open":
|
case "open":
|
||||||
{
|
{
|
||||||
String url = (String) call.argument("url");
|
String url = (String) call.argument("url");
|
||||||
HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
|
HashMap<String, Object> settings = (HashMap<String, Object>) call.argument("settings");
|
||||||
List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) call.argument("menuItemList");
|
List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) call.argument("menuItemList");
|
||||||
open(plugin.activity, id, url, options, menuItemList, result);
|
open(plugin.activity, id, url, settings, menuItemList, result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "isAvailable":
|
case "isAvailable":
|
||||||
|
@ -56,7 +56,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void open(Activity activity, String id, String url, HashMap<String, Object> options,
|
public void open(Activity activity, String id, String url, HashMap<String, Object> settings,
|
||||||
List<HashMap<String, Object>> menuItemList, MethodChannel.Result result) {
|
List<HashMap<String, Object>> menuItemList, MethodChannel.Result result) {
|
||||||
|
|
||||||
Intent intent = null;
|
Intent intent = null;
|
||||||
|
@ -65,17 +65,17 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
|
||||||
extras.putBoolean("isData", false);
|
extras.putBoolean("isData", false);
|
||||||
extras.putString("id", id);
|
extras.putString("id", id);
|
||||||
extras.putString("managerId", this.id);
|
extras.putString("managerId", this.id);
|
||||||
extras.putSerializable("options", options);
|
extras.putSerializable("settings", settings);
|
||||||
extras.putSerializable("menuItemList", (Serializable) menuItemList);
|
extras.putSerializable("menuItemList", (Serializable) menuItemList);
|
||||||
|
|
||||||
Boolean isSingleInstance = (Boolean) Util.getOrDefault(options, "isSingleInstance", false);
|
Boolean isSingleInstance = (Boolean) Util.getOrDefault(settings, "isSingleInstance", false);
|
||||||
Boolean isTrustedWebActivity = (Boolean) Util.getOrDefault(options, "isTrustedWebActivity", false);
|
Boolean isTrustedWebActivity = (Boolean) Util.getOrDefault(settings, "isTrustedWebActivity", false);
|
||||||
if (CustomTabActivityHelper.isAvailable(activity)) {
|
if (CustomTabActivityHelper.isAvailable(activity)) {
|
||||||
intent = new Intent(activity, !isSingleInstance ?
|
intent = new Intent(activity, !isSingleInstance ?
|
||||||
(!isTrustedWebActivity ? ChromeCustomTabsActivity.class : TrustedWebActivity.class) :
|
(!isTrustedWebActivity ? ChromeCustomTabsActivity.class : TrustedWebActivity.class) :
|
||||||
(!isTrustedWebActivity ? ChromeCustomTabsActivitySingleInstance.class : TrustedWebActivitySingleInstance.class));
|
(!isTrustedWebActivity ? ChromeCustomTabsActivitySingleInstance.class : TrustedWebActivitySingleInstance.class));
|
||||||
intent.putExtras(extras);
|
intent.putExtras(extras);
|
||||||
Boolean noHistory = (Boolean) Util.getOrDefault(options, "noHistory", false);
|
Boolean noHistory = (Boolean) Util.getOrDefault(settings, "noHistory", false);
|
||||||
if (noHistory) {
|
if (noHistory) {
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,32 +33,32 @@ public class TrustedWebActivity extends ChromeCustomTabsActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareCustomTabs() {
|
private void prepareCustomTabs() {
|
||||||
if (options.toolbarBackgroundColor != null && !options.toolbarBackgroundColor.isEmpty()) {
|
if (customSettings.toolbarBackgroundColor != null && !customSettings.toolbarBackgroundColor.isEmpty()) {
|
||||||
CustomTabColorSchemeParams.Builder defaultColorSchemeBuilder = new CustomTabColorSchemeParams.Builder();
|
CustomTabColorSchemeParams.Builder defaultColorSchemeBuilder = new CustomTabColorSchemeParams.Builder();
|
||||||
builder.setDefaultColorSchemeParams(defaultColorSchemeBuilder
|
builder.setDefaultColorSchemeParams(defaultColorSchemeBuilder
|
||||||
.setToolbarColor(Color.parseColor(options.toolbarBackgroundColor))
|
.setToolbarColor(Color.parseColor(customSettings.toolbarBackgroundColor))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.additionalTrustedOrigins != null && !options.additionalTrustedOrigins.isEmpty()) {
|
if (customSettings.additionalTrustedOrigins != null && !customSettings.additionalTrustedOrigins.isEmpty()) {
|
||||||
builder.setAdditionalTrustedOrigins(options.additionalTrustedOrigins);
|
builder.setAdditionalTrustedOrigins(customSettings.additionalTrustedOrigins);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.displayMode != null) {
|
if (customSettings.displayMode != null) {
|
||||||
builder.setDisplayMode(options.displayMode);
|
builder.setDisplayMode(customSettings.displayMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setScreenOrientation(options.screenOrientation);
|
builder.setScreenOrientation(customSettings.screenOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareCustomTabsIntent(TrustedWebActivityIntent trustedWebActivityIntent) {
|
private void prepareCustomTabsIntent(TrustedWebActivityIntent trustedWebActivityIntent) {
|
||||||
Intent intent = trustedWebActivityIntent.getIntent();
|
Intent intent = trustedWebActivityIntent.getIntent();
|
||||||
if (options.packageName != null)
|
if (customSettings.packageName != null)
|
||||||
intent.setPackage(options.packageName);
|
intent.setPackage(customSettings.packageName);
|
||||||
else
|
else
|
||||||
intent.setPackage(CustomTabsHelper.getPackageNameToUse(this));
|
intent.setPackage(CustomTabsHelper.getPackageNameToUse(this));
|
||||||
|
|
||||||
if (options.keepAliveEnabled)
|
if (customSettings.keepAliveEnabled)
|
||||||
CustomTabsHelper.addKeepAliveExtra(this, intent);
|
CustomTabsHelper.addKeepAliveExtra(this, intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler {
|
||||||
String encoding = (String) arguments.get("encoding");
|
String encoding = (String) arguments.get("encoding");
|
||||||
String baseUrl = (String) arguments.get("baseUrl");
|
String baseUrl = (String) arguments.get("baseUrl");
|
||||||
String historyUrl = (String) arguments.get("historyUrl");
|
String historyUrl = (String) arguments.get("historyUrl");
|
||||||
Map<String, Object> options = (Map<String, Object>) arguments.get("options");
|
Map<String, Object> settings = (Map<String, Object>) arguments.get("settings");
|
||||||
Map<String, Object> contextMenu = (Map<String, Object>) arguments.get("contextMenu");
|
Map<String, Object> contextMenu = (Map<String, Object>) arguments.get("contextMenu");
|
||||||
Integer windowId = (Integer) arguments.get("windowId");
|
Integer windowId = (Integer) arguments.get("windowId");
|
||||||
List<Map<String, Object>> initialUserScripts = (List<Map<String, Object>>) arguments.get("initialUserScripts");
|
List<Map<String, Object>> initialUserScripts = (List<Map<String, Object>>) arguments.get("initialUserScripts");
|
||||||
|
@ -187,7 +187,7 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler {
|
||||||
extras.putString("initialHistoryUrl", historyUrl);
|
extras.putString("initialHistoryUrl", historyUrl);
|
||||||
extras.putString("id", id);
|
extras.putString("id", id);
|
||||||
extras.putString("managerId", this.id);
|
extras.putString("managerId", this.id);
|
||||||
extras.putSerializable("options", (Serializable) options);
|
extras.putSerializable("settings", (Serializable) settings);
|
||||||
extras.putSerializable("contextMenu", (Serializable) contextMenu);
|
extras.putSerializable("contextMenu", (Serializable) contextMenu);
|
||||||
extras.putInt("windowId", windowId != null ? windowId : -1);
|
extras.putInt("windowId", windowId != null ? windowId : -1);
|
||||||
extras.putSerializable("initialUserScripts", (Serializable) initialUserScripts);
|
extras.putSerializable("initialUserScripts", (Serializable) initialUserScripts);
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class PullToRefreshControl : UIRefreshControl, FlutterPlugin {
|
||||||
backgroundColor = UIColor(hexString: color)
|
backgroundColor = UIColor(hexString: color)
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "setAttributedTitle":
|
case "setStyledTitle":
|
||||||
let attributedTitleMap = arguments!["attributedTitle"] as! [String: Any?]
|
let attributedTitleMap = arguments!["attributedTitle"] as! [String: Any?]
|
||||||
attributedTitle = NSAttributedString.fromMap(map: attributedTitleMap)
|
attributedTitle = NSAttributedString.fromMap(map: attributedTitleMap)
|
||||||
result(true)
|
result(true)
|
||||||
|
|
|
@ -34,9 +34,9 @@ public class ChromeSafariBrowserManager: NSObject, FlutterPlugin {
|
||||||
case "open":
|
case "open":
|
||||||
let id: String = arguments!["id"] as! String
|
let id: String = arguments!["id"] as! String
|
||||||
let url = arguments!["url"] as! String
|
let url = arguments!["url"] as! String
|
||||||
let options = arguments!["options"] as! [String: Any?]
|
let settings = arguments!["settings"] as! [String: Any?]
|
||||||
let menuItemList = arguments!["menuItemList"] as! [[String: Any]]
|
let menuItemList = arguments!["menuItemList"] as! [[String: Any]]
|
||||||
open(id: id, url: url, options: options, menuItemList: menuItemList, result: result)
|
open(id: id, url: url, settings: settings, menuItemList: menuItemList, result: result)
|
||||||
break
|
break
|
||||||
case "isAvailable":
|
case "isAvailable":
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
|
@ -51,7 +51,7 @@ public class ChromeSafariBrowserManager: NSObject, FlutterPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func open(id: String, url: String, options: [String: Any?], menuItemList: [[String: Any]], result: @escaping FlutterResult) {
|
public func open(id: String, url: String, settings: [String: Any?], menuItemList: [[String: Any]], result: @escaping FlutterResult) {
|
||||||
let absoluteUrl = URL(string: url)!.absoluteURL
|
let absoluteUrl = URL(string: url)!.absoluteURL
|
||||||
|
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
|
@ -59,15 +59,15 @@ public class ChromeSafariBrowserManager: NSObject, FlutterPlugin {
|
||||||
if let flutterViewController = UIApplication.shared.delegate?.window.unsafelyUnwrapped?.rootViewController {
|
if let flutterViewController = UIApplication.shared.delegate?.window.unsafelyUnwrapped?.rootViewController {
|
||||||
// flutterViewController could be casted to FlutterViewController if needed
|
// flutterViewController could be casted to FlutterViewController if needed
|
||||||
|
|
||||||
let safariOptions = SafariBrowserOptions()
|
let safariSettings = SafariBrowserSettings()
|
||||||
let _ = safariOptions.parse(options: options)
|
let _ = safariSettings.parse(settings: settings)
|
||||||
|
|
||||||
let safari: SafariViewController
|
let safari: SafariViewController
|
||||||
|
|
||||||
if #available(iOS 11.0, *) {
|
if #available(iOS 11.0, *) {
|
||||||
let config = SFSafariViewController.Configuration()
|
let config = SFSafariViewController.Configuration()
|
||||||
config.entersReaderIfAvailable = safariOptions.entersReaderIfAvailable
|
config.entersReaderIfAvailable = safariSettings.entersReaderIfAvailable
|
||||||
config.barCollapsingEnabled = safariOptions.barCollapsingEnabled
|
config.barCollapsingEnabled = safariSettings.barCollapsingEnabled
|
||||||
|
|
||||||
safari = SafariViewController(url: absoluteUrl, configuration: config)
|
safari = SafariViewController(url: absoluteUrl, configuration: config)
|
||||||
} else {
|
} else {
|
||||||
|
@ -79,7 +79,7 @@ public class ChromeSafariBrowserManager: NSObject, FlutterPlugin {
|
||||||
safari.menuItemList = menuItemList
|
safari.menuItemList = menuItemList
|
||||||
safari.prepareMethodChannel()
|
safari.prepareMethodChannel()
|
||||||
safari.delegate = safari
|
safari.delegate = safari
|
||||||
safari.safariOptions = safariOptions
|
safari.safariSettings = safariSettings
|
||||||
safari.prepareSafariBrowser()
|
safari.prepareSafariBrowser()
|
||||||
|
|
||||||
flutterViewController.present(safari, animated: true) {
|
flutterViewController.present(safari, animated: true) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import Foundation
|
||||||
|
|
||||||
@available(iOS 9.0, *)
|
@available(iOS 9.0, *)
|
||||||
@objcMembers
|
@objcMembers
|
||||||
public class SafariBrowserOptions: IWebViewSettings<SafariViewController> {
|
public class SafariBrowserSettings: IWebViewSettings<SafariViewController> {
|
||||||
|
|
||||||
var entersReaderIfAvailable = false
|
var entersReaderIfAvailable = false
|
||||||
var barCollapsingEnabled = false
|
var barCollapsingEnabled = false
|
|
@ -12,7 +12,7 @@ import SafariServices
|
||||||
public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafariViewControllerDelegate {
|
public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafariViewControllerDelegate {
|
||||||
|
|
||||||
var channel: FlutterMethodChannel?
|
var channel: FlutterMethodChannel?
|
||||||
var safariOptions: SafariBrowserOptions?
|
var safariSettings: SafariBrowserSettings?
|
||||||
var id: String = ""
|
var id: String = ""
|
||||||
var menuItemList: [[String: Any]] = []
|
var menuItemList: [[String: Any]] = []
|
||||||
|
|
||||||
|
@ -55,25 +55,25 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa
|
||||||
|
|
||||||
|
|
||||||
func prepareSafariBrowser() {
|
func prepareSafariBrowser() {
|
||||||
guard let safariOptions = safariOptions else {
|
guard let safariSettings = safariSettings else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if #available(iOS 11.0, *) {
|
if #available(iOS 11.0, *) {
|
||||||
self.dismissButtonStyle = SFSafariViewController.DismissButtonStyle(rawValue: safariOptions.dismissButtonStyle)!
|
self.dismissButtonStyle = SFSafariViewController.DismissButtonStyle(rawValue: safariSettings.dismissButtonStyle)!
|
||||||
}
|
}
|
||||||
|
|
||||||
if #available(iOS 10.0, *) {
|
if #available(iOS 10.0, *) {
|
||||||
if let preferredBarTintColor = safariOptions.preferredBarTintColor, !preferredBarTintColor.isEmpty {
|
if let preferredBarTintColor = safariSettings.preferredBarTintColor, !preferredBarTintColor.isEmpty {
|
||||||
self.preferredBarTintColor = UIColor(hexString: preferredBarTintColor)
|
self.preferredBarTintColor = UIColor(hexString: preferredBarTintColor)
|
||||||
}
|
}
|
||||||
if let preferredControlTintColor = safariOptions.preferredControlTintColor, !preferredControlTintColor.isEmpty {
|
if let preferredControlTintColor = safariSettings.preferredControlTintColor, !preferredControlTintColor.isEmpty {
|
||||||
self.preferredControlTintColor = UIColor(hexString: preferredControlTintColor)
|
self.preferredControlTintColor = UIColor(hexString: preferredControlTintColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.modalPresentationStyle = UIModalPresentationStyle(rawValue: safariOptions.presentationStyle)!
|
self.modalPresentationStyle = UIModalPresentationStyle(rawValue: safariSettings.presentationStyle)!
|
||||||
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: safariOptions.transitionStyle)!
|
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: safariSettings.transitionStyle)!
|
||||||
}
|
}
|
||||||
|
|
||||||
func close(result: FlutterResult?) {
|
func close(result: FlutterResult?) {
|
||||||
|
|
|
@ -3,15 +3,184 @@ import 'package:flutter/services.dart';
|
||||||
import 'webview_feature.dart';
|
import 'webview_feature.dart';
|
||||||
import '../types.dart';
|
import '../types.dart';
|
||||||
|
|
||||||
|
///Class that manages Service Workers used by [WebView].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView ([Official API - ServiceWorkerControllerCompat](https://developer.android.com/reference/androidx/webkit/ServiceWorkerControllerCompat))
|
||||||
|
class ServiceWorkerController {
|
||||||
|
static ServiceWorkerController? _instance;
|
||||||
|
static const MethodChannel _channel = const MethodChannel(
|
||||||
|
'com.pichillilorenzo/flutter_inappwebview_serviceworkercontroller');
|
||||||
|
|
||||||
|
ServiceWorkerClient? serviceWorkerClient;
|
||||||
|
|
||||||
|
///Gets the [ServiceWorkerController] shared instance.
|
||||||
|
static ServiceWorkerController instance() {
|
||||||
|
return (_instance != null) ? _instance! : _init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ServiceWorkerController _init() {
|
||||||
|
_channel.setMethodCallHandler(_handleMethod);
|
||||||
|
_instance = ServiceWorkerController();
|
||||||
|
return _instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
|
ServiceWorkerController controller =
|
||||||
|
ServiceWorkerController.instance();
|
||||||
|
ServiceWorkerClient? serviceWorkerClient =
|
||||||
|
controller.serviceWorkerClient;
|
||||||
|
|
||||||
|
switch (call.method) {
|
||||||
|
case "shouldInterceptRequest":
|
||||||
|
if (serviceWorkerClient != null &&
|
||||||
|
serviceWorkerClient.shouldInterceptRequest != null) {
|
||||||
|
Map<String, dynamic> arguments =
|
||||||
|
call.arguments.cast<String, dynamic>();
|
||||||
|
WebResourceRequest request = WebResourceRequest.fromMap(arguments)!;
|
||||||
|
|
||||||
|
return (await serviceWorkerClient.shouldInterceptRequest!(request))
|
||||||
|
?.toMap();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw UnimplementedError("Unimplemented ${call.method} method");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
///Gets whether Service Workers support content URL access.
|
||||||
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getAllowContentAccess()
|
||||||
|
static Future<bool> getAllowContentAccess() async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
return await _channel.invokeMethod('getAllowContentAccess', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Gets whether Service Workers support file access.
|
||||||
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_FILE_ACCESS].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getAllowFileAccess()
|
||||||
|
static Future<bool> getAllowFileAccess() async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
return await _channel.invokeMethod('getAllowFileAccess', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Gets whether Service Workers are prohibited from loading any resources from the network.
|
||||||
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getBlockNetworkLoads()
|
||||||
|
static Future<bool> getBlockNetworkLoads() async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
return await _channel.invokeMethod('getBlockNetworkLoads', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Gets the current setting for overriding the cache mode.
|
||||||
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_CACHE_MODE].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getCacheMode()
|
||||||
|
static Future<CacheMode?> getCacheMode() async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
return CacheMode.fromValue(
|
||||||
|
await _channel.invokeMethod('getCacheMode', args));
|
||||||
|
}
|
||||||
|
|
||||||
|
///Enables or disables content URL access from Service Workers.
|
||||||
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setAllowContentAccess(boolean)
|
||||||
|
static Future<void> setAllowContentAccess(bool allow) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("allow", () => allow);
|
||||||
|
await _channel.invokeMethod('setAllowContentAccess', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Enables or disables file access within Service Workers.
|
||||||
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_FILE_ACCESS].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setAllowFileAccess(boolean)
|
||||||
|
static Future<void> setAllowFileAccess(bool allow) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("allow", () => allow);
|
||||||
|
await _channel.invokeMethod('setAllowFileAccess', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Sets whether Service Workers should not load resources from the network.
|
||||||
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setBlockNetworkLoads(boolean)
|
||||||
|
static Future<void> setBlockNetworkLoads(bool flag) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("flag", () => flag);
|
||||||
|
await _channel.invokeMethod('setBlockNetworkLoads', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Overrides the way the cache is used.
|
||||||
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_CACHE_MODE].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setCacheMode(int)
|
||||||
|
static Future<void> setCacheMode(CacheMode mode) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("mode", () => mode.toValue());
|
||||||
|
await _channel.invokeMethod('setCacheMode', args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///Class used by clients to capture Service Worker related callbacks.
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView ([Official API - ServiceWorkerClientCompat](https://developer.android.com/reference/androidx/webkit/ServiceWorkerClientCompat))
|
||||||
|
class ServiceWorkerClient {
|
||||||
|
///Notify the host application of a resource request and allow the application to return the data.
|
||||||
|
///If the return value is `null`, the Service Worker will continue to load the resource as usual.
|
||||||
|
///Otherwise, the return response and data will be used.
|
||||||
|
///
|
||||||
|
///This method is called only if [WebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST] is supported.
|
||||||
|
///You can check whether that flag is supported using [WebViewFeature.isFeatureSupported].
|
||||||
|
///
|
||||||
|
///[request] represents an object containing the details of the request.
|
||||||
|
///
|
||||||
|
///**NOTE**: available on Android 24+.
|
||||||
|
final Future<WebResourceResponse?> Function(WebResourceRequest request)?
|
||||||
|
shouldInterceptRequest;
|
||||||
|
|
||||||
|
ServiceWorkerClient({this.shouldInterceptRequest});
|
||||||
|
}
|
||||||
|
|
||||||
///Class that represents an Android-specific class that manages Service Workers used by [WebView].
|
///Class that represents an Android-specific class that manages Service Workers used by [WebView].
|
||||||
///
|
///
|
||||||
///**NOTE**: available on Android 24+.
|
///**NOTE**: available on Android 24+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerControllerCompat
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerControllerCompat
|
||||||
|
///
|
||||||
|
///Use [ServiceWorkerController] instead.
|
||||||
|
@Deprecated("Use ServiceWorkerController instead")
|
||||||
class AndroidServiceWorkerController {
|
class AndroidServiceWorkerController {
|
||||||
static AndroidServiceWorkerController? _instance;
|
static AndroidServiceWorkerController? _instance;
|
||||||
static const MethodChannel _channel = const MethodChannel(
|
static const MethodChannel _channel = const MethodChannel(
|
||||||
'com.pichillilorenzo/flutter_inappwebview_android_serviceworkercontroller');
|
'com.pichillilorenzo/flutter_inappwebview_serviceworkercontroller');
|
||||||
|
|
||||||
AndroidServiceWorkerClient? serviceWorkerClient;
|
AndroidServiceWorkerClient? serviceWorkerClient;
|
||||||
|
|
||||||
|
@ -150,6 +319,8 @@ class AndroidServiceWorkerController {
|
||||||
///**NOTE**: available on Android 24+.
|
///**NOTE**: available on Android 24+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerClientCompat
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerClientCompat
|
||||||
|
///Use [ServiceWorkerClient] instead.
|
||||||
|
@Deprecated("Use ServiceWorkerClient instead")
|
||||||
class AndroidServiceWorkerClient {
|
class AndroidServiceWorkerClient {
|
||||||
///Notify the host application of a resource request and allow the application to return the data.
|
///Notify the host application of a resource request and allow the application to return the data.
|
||||||
///If the return value is `null`, the Service Worker will continue to load the resource as usual.
|
///If the return value is `null`, the Service Worker will continue to load the resource as usual.
|
||||||
|
|
|
@ -2,9 +2,269 @@ import 'dart:async';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
///Class that represents an Android-specific utility class for checking which WebView Support Library features are supported on the device.
|
///Class that represents an Android-specific utility class for checking which WebView Support Library features are supported on the device.
|
||||||
|
class WebViewFeature {
|
||||||
|
static const MethodChannel _channel = const MethodChannel(
|
||||||
|
'com.pichillilorenzo/flutter_inappwebview_webviewfeature');
|
||||||
|
|
||||||
|
final String _value;
|
||||||
|
|
||||||
|
const WebViewFeature._internal(this._value);
|
||||||
|
|
||||||
|
static final Set<WebViewFeature> values = [
|
||||||
|
WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
|
||||||
|
WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS,
|
||||||
|
WebViewFeature.FORCE_DARK,
|
||||||
|
WebViewFeature.FORCE_DARK_STRATEGY,
|
||||||
|
WebViewFeature.GET_WEB_CHROME_CLIENT,
|
||||||
|
WebViewFeature.GET_WEB_VIEW_CLIENT,
|
||||||
|
WebViewFeature.GET_WEB_VIEW_RENDERER,
|
||||||
|
WebViewFeature.MULTI_PROCESS,
|
||||||
|
WebViewFeature.OFF_SCREEN_PRERASTER,
|
||||||
|
WebViewFeature.POST_WEB_MESSAGE,
|
||||||
|
WebViewFeature.PROXY_OVERRIDE,
|
||||||
|
WebViewFeature.RECEIVE_HTTP_ERROR,
|
||||||
|
WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR,
|
||||||
|
WebViewFeature.SAFE_BROWSING_ALLOWLIST,
|
||||||
|
WebViewFeature.SAFE_BROWSING_ENABLE,
|
||||||
|
WebViewFeature.SAFE_BROWSING_HIT,
|
||||||
|
WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL,
|
||||||
|
WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY,
|
||||||
|
WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED,
|
||||||
|
WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL,
|
||||||
|
WebViewFeature.SERVICE_WORKER_BASIC_USAGE,
|
||||||
|
WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS,
|
||||||
|
WebViewFeature.SERVICE_WORKER_CACHE_MODE,
|
||||||
|
WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS,
|
||||||
|
WebViewFeature.SERVICE_WORKER_FILE_ACCESS,
|
||||||
|
WebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST,
|
||||||
|
WebViewFeature.SHOULD_OVERRIDE_WITH_REDIRECTS,
|
||||||
|
WebViewFeature.START_SAFE_BROWSING,
|
||||||
|
WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE,
|
||||||
|
WebViewFeature.VISUAL_STATE_CALLBACK,
|
||||||
|
WebViewFeature.WEB_MESSAGE_CALLBACK_ON_MESSAGE,
|
||||||
|
WebViewFeature.WEB_MESSAGE_LISTENER,
|
||||||
|
WebViewFeature.WEB_MESSAGE_PORT_CLOSE,
|
||||||
|
WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE,
|
||||||
|
WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK,
|
||||||
|
WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE,
|
||||||
|
WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION,
|
||||||
|
WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
|
||||||
|
WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE,
|
||||||
|
WebViewFeature.WEB_VIEW_RENDERER_TERMINATE,
|
||||||
|
].toSet();
|
||||||
|
|
||||||
|
static WebViewFeature? fromValue(String? value) {
|
||||||
|
if (value != null) {
|
||||||
|
try {
|
||||||
|
return WebViewFeature.values
|
||||||
|
.firstWhere((element) => element.toValue() == value);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String toValue() => _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _value;
|
||||||
|
|
||||||
|
///
|
||||||
|
static const CREATE_WEB_MESSAGE_CHANNEL =
|
||||||
|
const WebViewFeature._internal("CREATE_WEB_MESSAGE_CHANNEL");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const DISABLED_ACTION_MODE_MENU_ITEMS =
|
||||||
|
const WebViewFeature._internal("DISABLED_ACTION_MODE_MENU_ITEMS");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const FORCE_DARK = const WebViewFeature._internal("FORCE_DARK");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const FORCE_DARK_STRATEGY =
|
||||||
|
const WebViewFeature._internal("FORCE_DARK_STRATEGY");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const GET_WEB_CHROME_CLIENT =
|
||||||
|
const WebViewFeature._internal("GET_WEB_CHROME_CLIENT");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const GET_WEB_VIEW_CLIENT =
|
||||||
|
const WebViewFeature._internal("GET_WEB_VIEW_CLIENT");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const GET_WEB_VIEW_RENDERER =
|
||||||
|
const WebViewFeature._internal("GET_WEB_VIEW_RENDERER");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const MULTI_PROCESS =
|
||||||
|
const WebViewFeature._internal("MULTI_PROCESS");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const OFF_SCREEN_PRERASTER =
|
||||||
|
const WebViewFeature._internal("OFF_SCREEN_PRERASTER");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const POST_WEB_MESSAGE =
|
||||||
|
const WebViewFeature._internal("POST_WEB_MESSAGE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const PROXY_OVERRIDE =
|
||||||
|
const WebViewFeature._internal("PROXY_OVERRIDE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const RECEIVE_HTTP_ERROR =
|
||||||
|
const WebViewFeature._internal("RECEIVE_HTTP_ERROR");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const RECEIVE_WEB_RESOURCE_ERROR =
|
||||||
|
const WebViewFeature._internal("RECEIVE_WEB_RESOURCE_ERROR");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SAFE_BROWSING_ALLOWLIST =
|
||||||
|
const WebViewFeature._internal("SAFE_BROWSING_ALLOWLIST");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SAFE_BROWSING_ENABLE =
|
||||||
|
const WebViewFeature._internal("SAFE_BROWSING_ENABLE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SAFE_BROWSING_HIT =
|
||||||
|
const WebViewFeature._internal("SAFE_BROWSING_HIT");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SAFE_BROWSING_PRIVACY_POLICY_URL =
|
||||||
|
const WebViewFeature._internal("SAFE_BROWSING_PRIVACY_POLICY_URL");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY =
|
||||||
|
const WebViewFeature._internal(
|
||||||
|
"SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SAFE_BROWSING_RESPONSE_PROCEED =
|
||||||
|
const WebViewFeature._internal("SAFE_BROWSING_RESPONSE_PROCEED");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL =
|
||||||
|
const WebViewFeature._internal(
|
||||||
|
"SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL");
|
||||||
|
|
||||||
|
///Use [SAFE_BROWSING_ALLOWLIST] instead.
|
||||||
|
@Deprecated('Use SAFE_BROWSING_ALLOWLIST instead')
|
||||||
|
static const SAFE_BROWSING_WHITELIST =
|
||||||
|
const WebViewFeature._internal("SAFE_BROWSING_WHITELIST");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SERVICE_WORKER_BASIC_USAGE =
|
||||||
|
const WebViewFeature._internal("SERVICE_WORKER_BASIC_USAGE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SERVICE_WORKER_BLOCK_NETWORK_LOADS =
|
||||||
|
const WebViewFeature._internal(
|
||||||
|
"SERVICE_WORKER_BLOCK_NETWORK_LOADS");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SERVICE_WORKER_CACHE_MODE =
|
||||||
|
const WebViewFeature._internal("SERVICE_WORKER_CACHE_MODE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SERVICE_WORKER_CONTENT_ACCESS =
|
||||||
|
const WebViewFeature._internal("SERVICE_WORKER_CONTENT_ACCESS");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SERVICE_WORKER_FILE_ACCESS =
|
||||||
|
const WebViewFeature._internal("SERVICE_WORKER_FILE_ACCESS");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST =
|
||||||
|
const WebViewFeature._internal(
|
||||||
|
"SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const SHOULD_OVERRIDE_WITH_REDIRECTS =
|
||||||
|
const WebViewFeature._internal("SHOULD_OVERRIDE_WITH_REDIRECTS");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const START_SAFE_BROWSING =
|
||||||
|
const WebViewFeature._internal("START_SAFE_BROWSING");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const TRACING_CONTROLLER_BASIC_USAGE =
|
||||||
|
const WebViewFeature._internal("TRACING_CONTROLLER_BASIC_USAGE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const VISUAL_STATE_CALLBACK =
|
||||||
|
const WebViewFeature._internal("VISUAL_STATE_CALLBACK");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_MESSAGE_CALLBACK_ON_MESSAGE =
|
||||||
|
const WebViewFeature._internal("WEB_MESSAGE_CALLBACK_ON_MESSAGE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_MESSAGE_LISTENER =
|
||||||
|
const WebViewFeature._internal("WEB_MESSAGE_LISTENER");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_MESSAGE_PORT_CLOSE =
|
||||||
|
const WebViewFeature._internal("WEB_MESSAGE_PORT_CLOSE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_MESSAGE_PORT_POST_MESSAGE =
|
||||||
|
const WebViewFeature._internal("WEB_MESSAGE_PORT_POST_MESSAGE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK =
|
||||||
|
const WebViewFeature._internal(
|
||||||
|
"WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_RESOURCE_ERROR_GET_CODE =
|
||||||
|
const WebViewFeature._internal("WEB_RESOURCE_ERROR_GET_CODE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_RESOURCE_ERROR_GET_DESCRIPTION =
|
||||||
|
const WebViewFeature._internal(
|
||||||
|
"WEB_RESOURCE_ERROR_GET_DESCRIPTION");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_RESOURCE_REQUEST_IS_REDIRECT =
|
||||||
|
const WebViewFeature._internal("WEB_RESOURCE_REQUEST_IS_REDIRECT");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE =
|
||||||
|
const WebViewFeature._internal(
|
||||||
|
"WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE");
|
||||||
|
|
||||||
|
///
|
||||||
|
static const WEB_VIEW_RENDERER_TERMINATE =
|
||||||
|
const WebViewFeature._internal("WEB_VIEW_RENDERER_TERMINATE");
|
||||||
|
|
||||||
|
bool operator ==(value) => value == _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => _value.hashCode;
|
||||||
|
|
||||||
|
///Return whether a feature is supported at run-time. On devices running Android version `Build.VERSION_CODES.LOLLIPOP` and higher,
|
||||||
|
///this will check whether a feature is supported, depending on the combination of the desired feature, the Android version of device,
|
||||||
|
///and the WebView APK on the device. If running on a device with a lower API level, this will always return `false`.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/WebViewFeature#isFeatureSupported(java.lang.String)
|
||||||
|
static Future<bool> isFeatureSupported(WebViewFeature feature) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("feature", () => feature.toValue());
|
||||||
|
return await _channel.invokeMethod('isFeatureSupported', args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///Class that represents an Android-specific utility class for checking which WebView Support Library features are supported on the device.
|
||||||
|
///Use [WebViewFeature] instead.
|
||||||
|
@Deprecated("Use WebViewFeature instead")
|
||||||
class AndroidWebViewFeature {
|
class AndroidWebViewFeature {
|
||||||
static const MethodChannel _channel = const MethodChannel(
|
static const MethodChannel _channel = const MethodChannel(
|
||||||
'com.pichillilorenzo/flutter_inappwebview_android_webviewfeature');
|
'com.pichillilorenzo/flutter_inappwebview_webviewfeature');
|
||||||
|
|
||||||
final String _value;
|
final String _value;
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,14 @@ import 'dart:ui';
|
||||||
import '../../util.dart';
|
import '../../util.dart';
|
||||||
import '../../types.dart';
|
import '../../types.dart';
|
||||||
|
|
||||||
import '../chrome_safari_browser_options.dart';
|
import '../chrome_safari_browser_settings.dart';
|
||||||
import '../chrome_safari_browser.dart';
|
import '../chrome_safari_browser.dart';
|
||||||
|
|
||||||
import '../../in_app_webview/android/in_app_webview_options.dart';
|
import '../../in_app_webview/android/in_app_webview_options.dart';
|
||||||
|
|
||||||
///This class represents all the Android-only [ChromeSafariBrowser] options available.
|
///This class represents all the Android-only [ChromeSafariBrowser] options available.
|
||||||
|
///Use [ChromeSafariBrowserSettings] instead.
|
||||||
|
@Deprecated('Use ChromeSafariBrowserSettings instead')
|
||||||
class AndroidChromeCustomTabsOptions
|
class AndroidChromeCustomTabsOptions
|
||||||
implements ChromeSafariBrowserOptions, AndroidOptions {
|
implements ChromeSafariBrowserOptions, AndroidOptions {
|
||||||
///Use [shareState] instead.
|
///Use [shareState] instead.
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'dart:collection';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_inappwebview/src/util.dart';
|
import 'package:flutter_inappwebview/src/util.dart';
|
||||||
|
|
||||||
import 'chrome_safari_browser_options.dart';
|
import 'chrome_safari_browser_settings.dart';
|
||||||
|
|
||||||
class ChromeSafariBrowserAlreadyOpenedException implements Exception {
|
class ChromeSafariBrowserAlreadyOpenedException implements Exception {
|
||||||
final dynamic message;
|
final dynamic message;
|
||||||
|
@ -84,8 +84,13 @@ class ChromeSafariBrowser {
|
||||||
///[url]: The [url] to load.
|
///[url]: The [url] to load.
|
||||||
///
|
///
|
||||||
///[options]: Options for the [ChromeSafariBrowser].
|
///[options]: Options for the [ChromeSafariBrowser].
|
||||||
|
///
|
||||||
|
///[settings]: Settings for the [ChromeSafariBrowser].
|
||||||
Future<void> open(
|
Future<void> open(
|
||||||
{required Uri url, ChromeSafariBrowserClassOptions? options}) async {
|
{required Uri url,
|
||||||
|
// ignore: deprecated_member_use_from_same_package
|
||||||
|
@Deprecated('Use settings instead') ChromeSafariBrowserClassOptions? options,
|
||||||
|
ChromeSafariBrowserSettings? settings}) async {
|
||||||
assert(url.toString().isNotEmpty);
|
assert(url.toString().isNotEmpty);
|
||||||
this.throwIsAlreadyOpened(message: 'Cannot open $url!');
|
this.throwIsAlreadyOpened(message: 'Cannot open $url!');
|
||||||
|
|
||||||
|
@ -94,10 +99,13 @@ class ChromeSafariBrowser {
|
||||||
menuItemList.add({"id": value.id, "label": value.label});
|
menuItemList.add({"id": value.id, "label": value.label});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var initialSettings = settings?.toMap() ?? options?.toMap() ??
|
||||||
|
ChromeSafariBrowserSettings().toMap();
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('id', () => id);
|
args.putIfAbsent('id', () => id);
|
||||||
args.putIfAbsent('url', () => url.toString());
|
args.putIfAbsent('url', () => url.toString());
|
||||||
args.putIfAbsent('options', () => options?.toMap() ?? {});
|
args.putIfAbsent('settings', () => initialSettings);
|
||||||
args.putIfAbsent('menuItemList', () => menuItemList);
|
args.putIfAbsent('menuItemList', () => menuItemList);
|
||||||
await _sharedChannel.invokeMethod('open', args);
|
await _sharedChannel.invokeMethod('open', args);
|
||||||
this._isOpened = true;
|
this._isOpened = true;
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
|
|
||||||
import 'android/chrome_custom_tabs_options.dart';
|
|
||||||
import 'ios/safari_options.dart';
|
|
||||||
|
|
||||||
class ChromeSafariBrowserOptions {
|
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
static ChromeSafariBrowserOptions fromMap(Map<String, dynamic> map) {
|
|
||||||
return new ChromeSafariBrowserOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
ChromeSafariBrowserOptions copy() {
|
|
||||||
return ChromeSafariBrowserOptions.fromMap(this.toMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return this.toMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return toMap().toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///Class that represents the options that can be used for an [ChromeSafariBrowser] window.
|
|
||||||
class ChromeSafariBrowserClassOptions {
|
|
||||||
///Android-specific options.
|
|
||||||
AndroidChromeCustomTabsOptions? android;
|
|
||||||
|
|
||||||
///iOS-specific options.
|
|
||||||
IOSSafariOptions? ios;
|
|
||||||
|
|
||||||
ChromeSafariBrowserClassOptions({this.android, this.ios}) {
|
|
||||||
this.android = this.android ?? AndroidChromeCustomTabsOptions();
|
|
||||||
this.ios = this.ios ?? IOSSafariOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
Map<String, dynamic> options = {};
|
|
||||||
if (defaultTargetPlatform == TargetPlatform.android)
|
|
||||||
options.addAll(this.android?.toMap() ?? {});
|
|
||||||
else if (defaultTargetPlatform == TargetPlatform.iOS)
|
|
||||||
options.addAll(this.ios?.toMap() ?? {});
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return this.toMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return toMap().toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,306 @@
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
import '../util.dart';
|
||||||
|
import 'android/chrome_custom_tabs_options.dart';
|
||||||
|
import 'ios/safari_options.dart';
|
||||||
|
import '../types.dart';
|
||||||
|
|
||||||
|
class ChromeSafariBrowserOptions {
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ChromeSafariBrowserOptions fromMap(Map<String, dynamic> map) {
|
||||||
|
return new ChromeSafariBrowserOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
ChromeSafariBrowserOptions copy() {
|
||||||
|
return ChromeSafariBrowserOptions.fromMap(this.toMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return toMap().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///Class that represents the settings that can be used for an [ChromeSafariBrowser] window.
|
||||||
|
class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
|
|
||||||
|
///The share state that should be applied to the custom tab. The default value is [CustomTabsShareState.SHARE_STATE_DEFAULT].
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
CustomTabsShareState shareState;
|
||||||
|
|
||||||
|
///Set to `false` if the title shouldn't be shown in the custom tab. The default value is `true`.
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
bool showTitle;
|
||||||
|
|
||||||
|
///Set the custom background color of the toolbar.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
Color? toolbarBackgroundColor;
|
||||||
|
|
||||||
|
///Set to `true` to enable the url bar to hide as the user scrolls down on the page. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
bool enableUrlBarHiding;
|
||||||
|
|
||||||
|
///Set to `true` to enable Instant Apps. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
bool instantAppsEnabled;
|
||||||
|
|
||||||
|
///Set an explicit application package name that limits
|
||||||
|
///the components this Intent will resolve to. If left to the default
|
||||||
|
///value of null, all components in all applications will considered.
|
||||||
|
///If non-null, the Intent can only match the components in the given
|
||||||
|
///application package.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
String? packageName;
|
||||||
|
|
||||||
|
///Set to `true` to enable Keep Alive. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
bool keepAliveEnabled;
|
||||||
|
|
||||||
|
///Set to `true` to launch the Android activity in `singleInstance` mode. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
bool isSingleInstance;
|
||||||
|
|
||||||
|
///Set to `true` to launch the Android intent with the flag `FLAG_ACTIVITY_NO_HISTORY`. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
bool noHistory;
|
||||||
|
|
||||||
|
///Set to `true` to launch the Custom Tab as a Trusted Web Activity. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
bool isTrustedWebActivity;
|
||||||
|
|
||||||
|
///Sets a list of additional trusted origins that the user may navigate or be redirected to from the starting uri.
|
||||||
|
///
|
||||||
|
///**NOTE**: Available only in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
List<String> additionalTrustedOrigins;
|
||||||
|
|
||||||
|
///Sets a display mode of a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**NOTE**: Available only in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
TrustedWebActivityDisplayMode? displayMode;
|
||||||
|
|
||||||
|
///Sets a screen orientation. This can be used e.g. to enable the locking of an orientation lock type.
|
||||||
|
///
|
||||||
|
///**NOTE**: Available only in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
TrustedWebActivityScreenOrientation screenOrientation;
|
||||||
|
|
||||||
|
///Set to `true` if Reader mode should be entered automatically when it is available for the webpage. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
bool entersReaderIfAvailable;
|
||||||
|
|
||||||
|
///Set to `true` to enable bar collapsing. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
bool barCollapsingEnabled;
|
||||||
|
|
||||||
|
///Set the custom style for the dismiss button. The default value is [DismissButtonStyle.DONE].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on iOS 11.0+.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
DismissButtonStyle dismissButtonStyle;
|
||||||
|
|
||||||
|
///Set the custom background color of the navigation bar and the toolbar.
|
||||||
|
///
|
||||||
|
///**NOTE**: available on iOS 10.0+.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
Color? preferredBarTintColor;
|
||||||
|
|
||||||
|
///Set the custom color of the control buttons on the navigation bar and the toolbar.
|
||||||
|
///
|
||||||
|
///**NOTE**: available on iOS 10.0+.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
Color? preferredControlTintColor;
|
||||||
|
|
||||||
|
///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN].
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
ModalPresentationStyle presentationStyle;
|
||||||
|
|
||||||
|
///Set to the custom transition style when presenting the WebView. The default value is [ModalTransitionStyle.COVER_VERTICAL].
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
ModalTransitionStyle transitionStyle;
|
||||||
|
|
||||||
|
ChromeSafariBrowserSettings(
|
||||||
|
{this.shareState = CustomTabsShareState.SHARE_STATE_DEFAULT,
|
||||||
|
this.showTitle = true,
|
||||||
|
this.toolbarBackgroundColor,
|
||||||
|
this.enableUrlBarHiding = false,
|
||||||
|
this.instantAppsEnabled = false,
|
||||||
|
this.packageName,
|
||||||
|
this.keepAliveEnabled = false,
|
||||||
|
this.isSingleInstance = false,
|
||||||
|
this.noHistory = false,
|
||||||
|
this.isTrustedWebActivity = false,
|
||||||
|
this.additionalTrustedOrigins = const [],
|
||||||
|
this.displayMode,
|
||||||
|
this.screenOrientation = TrustedWebActivityScreenOrientation.DEFAULT,
|
||||||
|
this.entersReaderIfAvailable = false,
|
||||||
|
this.barCollapsingEnabled = false,
|
||||||
|
this.dismissButtonStyle = DismissButtonStyle.DONE,
|
||||||
|
this.preferredBarTintColor,
|
||||||
|
this.preferredControlTintColor,
|
||||||
|
this.presentationStyle = ModalPresentationStyle.FULL_SCREEN,
|
||||||
|
this.transitionStyle = ModalTransitionStyle.COVER_VERTICAL});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"shareState": shareState.toValue(),
|
||||||
|
"showTitle": showTitle,
|
||||||
|
"toolbarBackgroundColor": toolbarBackgroundColor?.toHex(),
|
||||||
|
"enableUrlBarHiding": enableUrlBarHiding,
|
||||||
|
"instantAppsEnabled": instantAppsEnabled,
|
||||||
|
"packageName": packageName,
|
||||||
|
"keepAliveEnabled": keepAliveEnabled,
|
||||||
|
"isSingleInstance": isSingleInstance,
|
||||||
|
"noHistory": noHistory,
|
||||||
|
"isTrustedWebActivity": isTrustedWebActivity,
|
||||||
|
"additionalTrustedOrigins": additionalTrustedOrigins,
|
||||||
|
"displayMode": displayMode?.toMap(),
|
||||||
|
"screenOrientation": screenOrientation.toValue(),
|
||||||
|
"entersReaderIfAvailable": entersReaderIfAvailable,
|
||||||
|
"barCollapsingEnabled": barCollapsingEnabled,
|
||||||
|
"dismissButtonStyle": dismissButtonStyle.toValue(),
|
||||||
|
"preferredBarTintColor": preferredBarTintColor?.toHex(),
|
||||||
|
"preferredControlTintColor": preferredControlTintColor?.toHex(),
|
||||||
|
"presentationStyle": presentationStyle.toValue(),
|
||||||
|
"transitionStyle": transitionStyle.toValue()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ChromeSafariBrowserSettings fromMap(Map<String, dynamic> map) {
|
||||||
|
ChromeSafariBrowserSettings options =
|
||||||
|
new ChromeSafariBrowserSettings();
|
||||||
|
options.shareState = map["shareState"];
|
||||||
|
options.showTitle = map["showTitle"];
|
||||||
|
options.toolbarBackgroundColor =
|
||||||
|
UtilColor.fromHex(map["toolbarBackgroundColor"]);
|
||||||
|
options.enableUrlBarHiding = map["enableUrlBarHiding"];
|
||||||
|
options.instantAppsEnabled = map["instantAppsEnabled"];
|
||||||
|
options.packageName = map["packageName"];
|
||||||
|
options.keepAliveEnabled = map["keepAliveEnabled"];
|
||||||
|
options.isSingleInstance = map["isSingleInstance"];
|
||||||
|
options.noHistory = map["noHistory"];
|
||||||
|
options.isTrustedWebActivity = map["isTrustedWebActivity"];
|
||||||
|
options.additionalTrustedOrigins = map["additionalTrustedOrigins"];
|
||||||
|
switch (map["displayMode"]["type"]) {
|
||||||
|
case "IMMERSIVE_MODE":
|
||||||
|
options.displayMode =
|
||||||
|
TrustedWebActivityImmersiveDisplayMode.fromMap(map["displayMode"]);
|
||||||
|
break;
|
||||||
|
case "DEFAULT_MODE":
|
||||||
|
default:
|
||||||
|
options.displayMode = TrustedWebActivityDefaultDisplayMode();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
options.screenOrientation = map["screenOrientation"];
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return toMap().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ChromeSafariBrowserSettings copy() {
|
||||||
|
return ChromeSafariBrowserSettings.fromMap(this.toMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///Class that represents the options that can be used for an [ChromeSafariBrowser] window.
|
||||||
|
///Use [ChromeSafariBrowserSettings] instead.
|
||||||
|
@Deprecated('Use ChromeSafariBrowserSettings instead')
|
||||||
|
class ChromeSafariBrowserClassOptions {
|
||||||
|
///Android-specific options.
|
||||||
|
AndroidChromeCustomTabsOptions? android;
|
||||||
|
|
||||||
|
///iOS-specific options.
|
||||||
|
IOSSafariOptions? ios;
|
||||||
|
|
||||||
|
ChromeSafariBrowserClassOptions({this.android, this.ios}) {
|
||||||
|
this.android = this.android ?? AndroidChromeCustomTabsOptions();
|
||||||
|
this.ios = this.ios ?? IOSSafariOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
Map<String, dynamic> options = {};
|
||||||
|
if (defaultTargetPlatform == TargetPlatform.android)
|
||||||
|
options.addAll(this.android?.toMap() ?? {});
|
||||||
|
else if (defaultTargetPlatform == TargetPlatform.iOS)
|
||||||
|
options.addAll(this.ios?.toMap() ?? {});
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return toMap().toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,12 +3,14 @@ import 'dart:ui';
|
||||||
import '../../util.dart';
|
import '../../util.dart';
|
||||||
import '../../types.dart';
|
import '../../types.dart';
|
||||||
|
|
||||||
import '../chrome_safari_browser_options.dart';
|
import '../chrome_safari_browser_settings.dart';
|
||||||
import '../chrome_safari_browser.dart';
|
import '../chrome_safari_browser.dart';
|
||||||
|
|
||||||
import '../../in_app_webview/ios/in_app_webview_options.dart';
|
import '../../in_app_webview/ios/in_app_webview_options.dart';
|
||||||
|
|
||||||
///This class represents all the iOS-only [ChromeSafariBrowser] options available.
|
///This class represents all the iOS-only [ChromeSafariBrowser] options available.
|
||||||
|
///Use [ChromeSafariBrowserSettings] instead.
|
||||||
|
@Deprecated('Use ChromeSafariBrowserSettings instead')
|
||||||
class IOSSafariOptions implements ChromeSafariBrowserOptions, IosOptions {
|
class IOSSafariOptions implements ChromeSafariBrowserOptions, IosOptions {
|
||||||
///Set to `true` if Reader mode should be entered automatically when it is available for the webpage. The default value is `false`.
|
///Set to `true` if Reader mode should be entered automatically when it is available for the webpage. The default value is `false`.
|
||||||
bool entersReaderIfAvailable;
|
bool entersReaderIfAvailable;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export 'chrome_safari_browser.dart';
|
export 'chrome_safari_browser.dart';
|
||||||
export 'chrome_safari_browser_options.dart';
|
export 'chrome_safari_browser_settings.dart';
|
||||||
export 'android/main.dart';
|
export 'android/main.dart';
|
||||||
export 'ios/main.dart';
|
export 'ios/main.dart';
|
||||||
|
|
|
@ -28,7 +28,11 @@ class HttpAuthCredentialDatabase {
|
||||||
|
|
||||||
///Gets a map list of all HTTP auth credentials saved.
|
///Gets a map list of all HTTP auth credentials saved.
|
||||||
///Each map contains the key `protectionSpace` of type [URLProtectionSpace]
|
///Each map contains the key `protectionSpace` of type [URLProtectionSpace]
|
||||||
///and the key `credentials` of type `List<URLCredential>` that contains all the HTTP auth credentials saved for that `protectionSpace`.
|
///and the key `credentials` of type List<[URLCredential]> that contains all the HTTP auth credentials saved for that `protectionSpace`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS ([Official API - URLCredentialStorage.allCredentials](https://developer.apple.com/documentation/foundation/urlcredentialstorage/1413859-allcredentials))
|
||||||
Future<List<URLProtectionSpaceHttpAuthCredentials>>
|
Future<List<URLProtectionSpaceHttpAuthCredentials>>
|
||||||
getAllAuthCredentials() async {
|
getAllAuthCredentials() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -48,6 +52,10 @@ class HttpAuthCredentialDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets all the HTTP auth credentials saved for that [protectionSpace].
|
///Gets all the HTTP auth credentials saved for that [protectionSpace].
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS
|
||||||
Future<List<URLCredential>> getHttpAuthCredentials(
|
Future<List<URLCredential>> getHttpAuthCredentials(
|
||||||
{required URLProtectionSpace protectionSpace}) async {
|
{required URLProtectionSpace protectionSpace}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -68,6 +76,10 @@ class HttpAuthCredentialDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Saves an HTTP auth [credential] for that [protectionSpace].
|
///Saves an HTTP auth [credential] for that [protectionSpace].
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS ([Official API - URLCredentialStorage.set](https://developer.apple.com/documentation/foundation/urlcredentialstorage/1407227-set))
|
||||||
Future<void> setHttpAuthCredential(
|
Future<void> setHttpAuthCredential(
|
||||||
{required URLProtectionSpace protectionSpace,
|
{required URLProtectionSpace protectionSpace,
|
||||||
required URLCredential credential}) async {
|
required URLCredential credential}) async {
|
||||||
|
@ -82,6 +94,10 @@ class HttpAuthCredentialDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Removes an HTTP auth [credential] for that [protectionSpace].
|
///Removes an HTTP auth [credential] for that [protectionSpace].
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS ([Official API - URLCredentialStorage.remove](https://developer.apple.com/documentation/foundation/urlcredentialstorage/1408664-remove))
|
||||||
Future<void> removeHttpAuthCredential(
|
Future<void> removeHttpAuthCredential(
|
||||||
{required URLProtectionSpace protectionSpace,
|
{required URLProtectionSpace protectionSpace,
|
||||||
required URLCredential credential}) async {
|
required URLCredential credential}) async {
|
||||||
|
@ -96,6 +112,10 @@ class HttpAuthCredentialDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Removes all the HTTP auth credentials saved for that [protectionSpace].
|
///Removes all the HTTP auth credentials saved for that [protectionSpace].
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS
|
||||||
Future<void> removeHttpAuthCredentials(
|
Future<void> removeHttpAuthCredentials(
|
||||||
{required URLProtectionSpace protectionSpace}) async {
|
{required URLProtectionSpace protectionSpace}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -107,6 +127,10 @@ class HttpAuthCredentialDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Removes all the HTTP auth credentials saved in the database.
|
///Removes all the HTTP auth credentials saved in the database.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS
|
||||||
Future<void> clearAllAuthCredentials() async {
|
Future<void> clearAllAuthCredentials() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
await _channel.invokeMethod('clearAllAuthCredentials', args);
|
await _channel.invokeMethod('clearAllAuthCredentials', args);
|
||||||
|
|
|
@ -103,6 +103,8 @@ class InAppBrowser {
|
||||||
///[urlRequest]: The [urlRequest] to load.
|
///[urlRequest]: The [urlRequest] to load.
|
||||||
///
|
///
|
||||||
///[options]: Options for the [InAppBrowser].
|
///[options]: Options for the [InAppBrowser].
|
||||||
|
///
|
||||||
|
///[settings]: Settings for the [InAppBrowser].
|
||||||
Future<void> openUrlRequest(
|
Future<void> openUrlRequest(
|
||||||
{required URLRequest urlRequest,
|
{required URLRequest urlRequest,
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
|
@ -166,6 +168,8 @@ class InAppBrowser {
|
||||||
///[headers]: The additional headers to be used in the HTTP request for this URL, specified as a map from name to value.
|
///[headers]: The additional headers to be used in the HTTP request for this URL, specified as a map from name to value.
|
||||||
///
|
///
|
||||||
///[options]: Options for the [InAppBrowser].
|
///[options]: Options for the [InAppBrowser].
|
||||||
|
///
|
||||||
|
///[settings]: Settings for the [InAppBrowser].
|
||||||
Future<void> openFile(
|
Future<void> openFile(
|
||||||
{required String assetFilePath,
|
{required String assetFilePath,
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
|
@ -203,18 +207,20 @@ class InAppBrowser {
|
||||||
///The [androidHistoryUrl] parameter is the URL to use as the history entry. The default value is `about:blank`. If non-null, this must be a valid URL. This parameter is used only on Android.
|
///The [androidHistoryUrl] parameter is the URL to use as the history entry. The default value is `about:blank`. If non-null, this must be a valid URL. This parameter is used only on Android.
|
||||||
///
|
///
|
||||||
///The [options] parameter specifies the options for the [InAppBrowser].
|
///The [options] parameter specifies the options for the [InAppBrowser].
|
||||||
|
///
|
||||||
|
///[settings]: Settings for the [InAppBrowser].
|
||||||
Future<void> openData(
|
Future<void> openData(
|
||||||
{required String data,
|
{required String data,
|
||||||
String mimeType = "text/html",
|
String mimeType = "text/html",
|
||||||
String encoding = "utf8",
|
String encoding = "utf8",
|
||||||
Uri? baseUrl,
|
Uri? baseUrl,
|
||||||
Uri? androidHistoryUrl,
|
@Deprecated("Use historyUrl instead") Uri? androidHistoryUrl,
|
||||||
|
Uri? historyUrl,
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
@Deprecated('Use settings instead') InAppBrowserClassOptions? options,
|
@Deprecated('Use settings instead') InAppBrowserClassOptions? options,
|
||||||
InAppBrowserClassSettings? settings}) async {
|
InAppBrowserClassSettings? settings}) async {
|
||||||
this.throwIfAlreadyOpened(message: 'Cannot open data!');
|
this.throwIfAlreadyOpened(message: 'Cannot open data!');
|
||||||
|
|
||||||
|
|
||||||
var initialSettings = settings?.toMap() ?? options?.toMap() ??
|
var initialSettings = settings?.toMap() ?? options?.toMap() ??
|
||||||
InAppBrowserClassSettings().toMap();
|
InAppBrowserClassSettings().toMap();
|
||||||
|
|
||||||
|
@ -226,7 +232,7 @@ class InAppBrowser {
|
||||||
args.putIfAbsent('encoding', () => encoding);
|
args.putIfAbsent('encoding', () => encoding);
|
||||||
args.putIfAbsent('baseUrl', () => baseUrl?.toString() ?? "about:blank");
|
args.putIfAbsent('baseUrl', () => baseUrl?.toString() ?? "about:blank");
|
||||||
args.putIfAbsent(
|
args.putIfAbsent(
|
||||||
'historyUrl', () => androidHistoryUrl?.toString() ?? "about:blank");
|
'historyUrl', () => (historyUrl ?? androidHistoryUrl)?.toString() ?? "about:blank");
|
||||||
args.putIfAbsent('contextMenu', () => contextMenu?.toMap() ?? {});
|
args.putIfAbsent('contextMenu', () => contextMenu?.toMap() ?? {});
|
||||||
args.putIfAbsent('windowId', () => windowId);
|
args.putIfAbsent('windowId', () => windowId);
|
||||||
args.putIfAbsent('implementation', () => implementation.toValue());
|
args.putIfAbsent('implementation', () => implementation.toValue());
|
||||||
|
|
|
@ -18,7 +18,7 @@ abstract class AndroidInAppWebViewControllerMixin {
|
||||||
///This should not be called if Safe Browsing has been disabled by manifest tag or [AndroidInAppWebViewOptions.safeBrowsingEnabled].
|
///This should not be called if Safe Browsing has been disabled by manifest tag or [AndroidInAppWebViewOptions.safeBrowsingEnabled].
|
||||||
///This prepares resources used for Safe Browsing.
|
///This prepares resources used for Safe Browsing.
|
||||||
///
|
///
|
||||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.START_SAFE_BROWSING].
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.START_SAFE_BROWSING].
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - WebView.startSafeBrowsing](https://developer.android.com/reference/android/webkit/WebView#startSafeBrowsing(android.content.Context,%20android.webkit.ValueCallback%3Cjava.lang.Boolean%3E)))
|
///- Android native WebView ([Official API - WebView.startSafeBrowsing](https://developer.android.com/reference/android/webkit/WebView#startSafeBrowsing(android.content.Context,%20android.webkit.ValueCallback%3Cjava.lang.Boolean%3E)))
|
||||||
|
|
|
@ -1327,6 +1327,8 @@ class InAppWebViewController with AndroidInAppWebViewControllerMixin, IOSInAppWe
|
||||||
Uri? iosAllowingReadAccessTo,
|
Uri? iosAllowingReadAccessTo,
|
||||||
Uri? allowingReadAccessTo}) async {
|
Uri? allowingReadAccessTo}) async {
|
||||||
assert(urlRequest.url != null && urlRequest.url.toString().isNotEmpty);
|
assert(urlRequest.url != null && urlRequest.url.toString().isNotEmpty);
|
||||||
|
assert(allowingReadAccessTo == null ||
|
||||||
|
allowingReadAccessTo.isScheme("file"));
|
||||||
assert(iosAllowingReadAccessTo == null ||
|
assert(iosAllowingReadAccessTo == null ||
|
||||||
iosAllowingReadAccessTo.isScheme("file"));
|
iosAllowingReadAccessTo.isScheme("file"));
|
||||||
|
|
||||||
|
@ -1385,6 +1387,8 @@ class InAppWebViewController with AndroidInAppWebViewControllerMixin, IOSInAppWe
|
||||||
@Deprecated('Use allowingReadAccessTo instead')
|
@Deprecated('Use allowingReadAccessTo instead')
|
||||||
Uri? iosAllowingReadAccessTo,
|
Uri? iosAllowingReadAccessTo,
|
||||||
Uri? allowingReadAccessTo}) async {
|
Uri? allowingReadAccessTo}) async {
|
||||||
|
assert(allowingReadAccessTo == null ||
|
||||||
|
allowingReadAccessTo.isScheme("file"));
|
||||||
assert(iosAllowingReadAccessTo == null ||
|
assert(iosAllowingReadAccessTo == null ||
|
||||||
iosAllowingReadAccessTo.isScheme("file"));
|
iosAllowingReadAccessTo.isScheme("file"));
|
||||||
|
|
||||||
|
@ -2514,7 +2518,7 @@ class InAppWebViewController with AndroidInAppWebViewControllerMixin, IOSInAppWe
|
||||||
///
|
///
|
||||||
///This method should be called when the page is loaded, for example, when the [WebView.onLoadStop] is fired, otherwise the [WebMessageChannel] won't work.
|
///This method should be called when the page is loaded, for example, when the [WebView.onLoadStop] is fired, otherwise the [WebMessageChannel] won't work.
|
||||||
///
|
///
|
||||||
///**NOTE for Android native WebView**: This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.CREATE_WEB_MESSAGE_CHANNEL].
|
///**NOTE for Android native WebView**: This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL].
|
||||||
///
|
///
|
||||||
///**NOTE**: On iOS, it is implemented using JavaScript.
|
///**NOTE**: On iOS, it is implemented using JavaScript.
|
||||||
///
|
///
|
||||||
|
@ -2534,7 +2538,7 @@ class InAppWebViewController with AndroidInAppWebViewControllerMixin, IOSInAppWe
|
||||||
///
|
///
|
||||||
///A target origin can be set as a wildcard ("*"). However this is not recommended.
|
///A target origin can be set as a wildcard ("*"). However this is not recommended.
|
||||||
///
|
///
|
||||||
///**NOTE for Android native WebView**: This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.POST_WEB_MESSAGE].
|
///**NOTE for Android native WebView**: This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.POST_WEB_MESSAGE].
|
||||||
///
|
///
|
||||||
///**NOTE**: On iOS, it is implemented using JavaScript.
|
///**NOTE**: On iOS, it is implemented using JavaScript.
|
||||||
///
|
///
|
||||||
|
@ -2692,7 +2696,7 @@ class InAppWebViewController with AndroidInAppWebViewControllerMixin, IOSInAppWe
|
||||||
/// // Flutter App
|
/// // Flutter App
|
||||||
/// child: InAppWebView(
|
/// child: InAppWebView(
|
||||||
/// onWebViewCreated: (controller) async {
|
/// onWebViewCreated: (controller) async {
|
||||||
/// if (!Platform.isAndroid || await AndroidWebViewFeature.isFeatureSupported(AndroidWebViewFeature.WEB_MESSAGE_LISTENER)) {
|
/// if (!Platform.isAndroid || await WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
|
||||||
/// await controller.addWebMessageListener(WebMessageListener(
|
/// await controller.addWebMessageListener(WebMessageListener(
|
||||||
/// jsObjectName: "myObject",
|
/// jsObjectName: "myObject",
|
||||||
/// onPostMessage: (message, sourceOrigin, isMainFrame, replyProxy) {
|
/// onPostMessage: (message, sourceOrigin, isMainFrame, replyProxy) {
|
||||||
|
@ -2706,7 +2710,7 @@ class InAppWebViewController with AndroidInAppWebViewControllerMixin, IOSInAppWe
|
||||||
/// ),
|
/// ),
|
||||||
///```
|
///```
|
||||||
///
|
///
|
||||||
///**NOTE for Android**: This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.WEB_MESSAGE_LISTENER].
|
///**NOTE for Android**: This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.WEB_MESSAGE_LISTENER].
|
||||||
///
|
///
|
||||||
///**NOTE for iOS**: This is implemented using Javascript.
|
///**NOTE for iOS**: This is implemented using Javascript.
|
||||||
///
|
///
|
||||||
|
@ -2764,7 +2768,7 @@ class InAppWebViewController with AndroidInAppWebViewControllerMixin, IOSInAppWe
|
||||||
|
|
||||||
///Returns a URL pointing to the privacy policy for Safe Browsing reporting.
|
///Returns a URL pointing to the privacy policy for Safe Browsing reporting.
|
||||||
///
|
///
|
||||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL].
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL].
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - WebViewCompat.getSafeBrowsingPrivacyPolicyUrl](https://developer.android.com/reference/androidx/webkit/WebViewCompat#getSafeBrowsingPrivacyPolicyUrl()))
|
///- Android native WebView ([Official API - WebViewCompat.getSafeBrowsingPrivacyPolicyUrl](https://developer.android.com/reference/androidx/webkit/WebViewCompat#getSafeBrowsingPrivacyPolicyUrl()))
|
||||||
|
@ -2787,7 +2791,7 @@ class InAppWebViewController with AndroidInAppWebViewControllerMixin, IOSInAppWe
|
||||||
///
|
///
|
||||||
///All other rules, including wildcards, are invalid. The correct syntax for hosts is defined by [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3.2.2).
|
///All other rules, including wildcards, are invalid. The correct syntax for hosts is defined by [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3.2.2).
|
||||||
///
|
///
|
||||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SAFE_BROWSING_ALLOWLIST].
|
///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SAFE_BROWSING_ALLOWLIST].
|
||||||
///
|
///
|
||||||
///[hosts] represents the list of hosts. This value must never be `null`.
|
///[hosts] represents the list of hosts. This value must never be `null`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -132,13 +132,21 @@ class PullToRefreshController {
|
||||||
await _channel?.invokeMethod('setSize', args);
|
await _channel?.invokeMethod('setSize', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Sets the styled title text to display in the refresh control.
|
///Use [setStyledTitle] instead.
|
||||||
///
|
@Deprecated("Use setStyledTitle instead")
|
||||||
///**NOTE**: Available only on iOS.
|
|
||||||
Future<void> setAttributedTitle(IOSNSAttributedString attributedTitle) async {
|
Future<void> setAttributedTitle(IOSNSAttributedString attributedTitle) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('attributedTitle', () => attributedTitle.toMap());
|
args.putIfAbsent('attributedTitle', () => attributedTitle.toMap());
|
||||||
await _channel?.invokeMethod('setAttributedTitle', args);
|
await _channel?.invokeMethod('setStyledTitle', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Sets the styled title text to display in the refresh control.
|
||||||
|
///
|
||||||
|
///**NOTE**: Available only on iOS.
|
||||||
|
Future<void> setStyledTitle(AttributedString attributedTitle) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent('attributedTitle', () => attributedTitle.toMap());
|
||||||
|
await _channel?.invokeMethod('setStyledTitle', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initMethodChannel(dynamic id) {
|
void initMethodChannel(dynamic id) {
|
||||||
|
|
Loading…
Reference in New Issue