Added startAnimations, exitAnimations, navigationBarColor, navigationBarDividerColor, secondaryToolbarColor ChromeSafariBrowser settings for Android, Added getVariationsHeader WebView static method, All ChromeSafariBrowserSettings properties are optionals
This commit is contained in:
parent
db7beffc03
commit
8e9c10246a
|
@ -3,13 +3,16 @@
|
|||
- Added `headers`, `otherLikelyURLs` arguments on `ChromeSafariBrowser.open` method for Android
|
||||
- Added `onNavigationEvent`, `onServiceConnected`, `onRelationshipValidationResult` events on `ChromeSafariBrowser` for Android
|
||||
- Added `mayLaunchUrl`, `launchUrl`, `updateActionButton`, `validateRelationship` methods on `ChromeSafariBrowser` for Android
|
||||
- Added `startAnimations`, `exitAnimations`, `navigationBarColor`, `navigationBarDividerColor`, `secondaryToolbarColor` ChromeSafariBrowser settings for Android
|
||||
- Added `didLoadSuccessfully` optional argument on `ChromeSafariBrowser.onCompletedInitialLoad` event for iOS
|
||||
- Added `onInitialLoadDidRedirect`, `onWillOpenInBrowser` events on `ChromeSafariBrowser` for iOS
|
||||
- Added `clearWebsiteData`, `prewarmConnections`, `invalidatePrewarmingToken` static methods on `ChromeSafariBrowser` for iOS
|
||||
- Added `getVariationsHeader` WebView static method
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- `ChromeSafariBrowser.onCompletedInitialLoad` event has an optional argument
|
||||
- All `ChromeSafariBrowserSettings` properties are optionals
|
||||
|
||||
## 6.0.0-beta.8
|
||||
|
||||
|
@ -78,7 +81,7 @@
|
|||
- Added `PullToRefreshController.isEnabled` method
|
||||
- Updated `getMetaThemeColor` on iOS 15.0+
|
||||
- Deprecated `onLoadError` for `onReceivedError`. `onReceivedError` will be called also for subframes
|
||||
- Deprecated `onLoadHttpError` for `onReceivedError`. `onReceivedHttpError` will be called also for subframes
|
||||
- Deprecated `onLoadHttpError` for `onReceivedHttpError`. `onReceivedHttpError` will be called also for subframes
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
|
|
|
@ -114,6 +114,14 @@ public class InAppWebViewStatic extends ChannelDelegateImpl {
|
|||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "getVariationsHeader":
|
||||
if (WebViewFeature.isFeatureSupported(WebViewFeature.GET_VARIATIONS_HEADER)) {
|
||||
result.success(WebViewCompat.getVariationsHeader());
|
||||
}
|
||||
else {
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import androidx.browser.customtabs.CustomTabsService;
|
|||
import androidx.browser.customtabs.CustomTabsSession;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.R;
|
||||
import com.pichillilorenzo.flutter_inappwebview.types.AndroidResource;
|
||||
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsActionButton;
|
||||
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsMenuItem;
|
||||
import com.pichillilorenzo.flutter_inappwebview.types.Disposable;
|
||||
|
@ -156,35 +157,27 @@ public class ChromeCustomTabsActivity extends Activity implements Disposable {
|
|||
public void launchUrl(@NonNull String url,
|
||||
@Nullable Map<String, String> headers,
|
||||
@Nullable List<String> otherLikelyURLs) {
|
||||
Uri uri = mayLaunchUrl(url, headers, otherLikelyURLs);
|
||||
mayLaunchUrl(url, otherLikelyURLs);
|
||||
builder = new CustomTabsIntent.Builder(customTabsSession);
|
||||
prepareCustomTabs();
|
||||
|
||||
CustomTabsIntent customTabsIntent = builder.build();
|
||||
prepareCustomTabsIntent(customTabsIntent);
|
||||
|
||||
CustomTabActivityHelper.openCustomTab(this, customTabsIntent, uri, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
||||
CustomTabActivityHelper.openCustomTab(this, customTabsIntent, Uri.parse(url), headers, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
||||
}
|
||||
|
||||
public Uri mayLaunchUrl(@NonNull String url,
|
||||
@Nullable Map<String, String> headers,
|
||||
@Nullable List<String> otherLikelyURLs) {
|
||||
Uri uri = Uri.parse(url);
|
||||
Bundle bundleHeaders = new Bundle();
|
||||
if (headers != null) {
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
bundleHeaders.putString(header.getKey(), header.getValue());
|
||||
}
|
||||
}
|
||||
public boolean mayLaunchUrl(@Nullable String url, @Nullable List<String> otherLikelyURLs) {
|
||||
Uri uri = url != null ? Uri.parse(url) : null;
|
||||
|
||||
List<Bundle> bundleOtherLikelyURLs = new ArrayList<>();
|
||||
if (otherLikelyURLs != null) {
|
||||
Bundle bundleOtherLikelyURL = new Bundle();
|
||||
for (String otherLikelyURL : otherLikelyURLs) {
|
||||
Bundle bundleOtherLikelyURL = new Bundle();
|
||||
bundleOtherLikelyURL.putString(CustomTabsService.KEY_URL, otherLikelyURL);
|
||||
}
|
||||
}
|
||||
customTabActivityHelper.mayLaunchUrl(uri, bundleHeaders, bundleOtherLikelyURLs);
|
||||
return uri;
|
||||
return customTabActivityHelper.mayLaunchUrl(uri, null, bundleOtherLikelyURLs);
|
||||
}
|
||||
|
||||
public void customTabsConnected() {
|
||||
|
@ -206,16 +199,34 @@ public class ChromeCustomTabsActivity extends Activity implements Disposable {
|
|||
builder.setShareState(customSettings.shareState);
|
||||
}
|
||||
|
||||
CustomTabColorSchemeParams.Builder defaultColorSchemeBuilder = new CustomTabColorSchemeParams.Builder();
|
||||
if (customSettings.toolbarBackgroundColor != null && !customSettings.toolbarBackgroundColor.isEmpty()) {
|
||||
CustomTabColorSchemeParams.Builder defaultColorSchemeBuilder = new CustomTabColorSchemeParams.Builder();
|
||||
builder.setDefaultColorSchemeParams(defaultColorSchemeBuilder
|
||||
.setToolbarColor(Color.parseColor(customSettings.toolbarBackgroundColor))
|
||||
.build());
|
||||
defaultColorSchemeBuilder.setToolbarColor(Color.parseColor(customSettings.toolbarBackgroundColor));
|
||||
}
|
||||
if (customSettings.navigationBarColor != null && !customSettings.navigationBarColor.isEmpty()) {
|
||||
defaultColorSchemeBuilder.setNavigationBarColor(Color.parseColor(customSettings.navigationBarColor));
|
||||
}
|
||||
if (customSettings.navigationBarDividerColor != null && !customSettings.navigationBarDividerColor.isEmpty()) {
|
||||
defaultColorSchemeBuilder.setNavigationBarDividerColor(Color.parseColor(customSettings.navigationBarDividerColor));
|
||||
}
|
||||
if (customSettings.secondaryToolbarColor != null && !customSettings.secondaryToolbarColor.isEmpty()) {
|
||||
defaultColorSchemeBuilder.setSecondaryToolbarColor(Color.parseColor(customSettings.secondaryToolbarColor));
|
||||
}
|
||||
builder.setDefaultColorSchemeParams(defaultColorSchemeBuilder.build());
|
||||
|
||||
builder.setShowTitle(customSettings.showTitle);
|
||||
builder.setUrlBarHidingEnabled(customSettings.enableUrlBarHiding);
|
||||
builder.setInstantAppsEnabled(customSettings.instantAppsEnabled);
|
||||
if (customSettings.startAnimations.size() == 2) {
|
||||
builder.setStartAnimations(this,
|
||||
customSettings.startAnimations.get(0).getIdentifier(this),
|
||||
customSettings.startAnimations.get(1).getIdentifier(this));
|
||||
}
|
||||
if (customSettings.exitAnimations.size() == 2) {
|
||||
builder.setExitAnimations(this,
|
||||
customSettings.exitAnimations.get(0).getIdentifier(this),
|
||||
customSettings.exitAnimations.get(1).getIdentifier(this));
|
||||
}
|
||||
|
||||
for (CustomTabsMenuItem menuItem : menuItems) {
|
||||
builder.addMenuItem(menuItem.getLabel(),
|
||||
|
|
|
@ -48,14 +48,8 @@ public class ChromeCustomTabsChannelDelegate extends ChannelDelegateImpl {
|
|||
case "mayLaunchUrl":
|
||||
if (chromeCustomTabsActivity != null) {
|
||||
String url = (String) call.argument("url");
|
||||
if (url != null) {
|
||||
Map<String, String> headers = (Map<String, String>) call.argument("headers");
|
||||
List<String> otherLikelyURLs = (List<String>) call.argument("otherLikelyURLs");
|
||||
chromeCustomTabsActivity.mayLaunchUrl(url, headers, otherLikelyURLs);
|
||||
result.success(true);
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
List<String> otherLikelyURLs = (List<String>) call.argument("otherLikelyURLs");
|
||||
result.success(chromeCustomTabsActivity.mayLaunchUrl(url, otherLikelyURLs));
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
|
@ -74,8 +68,7 @@ public class ChromeCustomTabsChannelDelegate extends ChannelDelegateImpl {
|
|||
if (chromeCustomTabsActivity != null && chromeCustomTabsActivity.customTabsSession != null) {
|
||||
Integer relation = (Integer) call.argument("relation");
|
||||
String origin = (String) call.argument("origin");
|
||||
chromeCustomTabsActivity.customTabsSession.validateRelationship(relation, Uri.parse(origin), null);
|
||||
result.success(true);
|
||||
result.success(chromeCustomTabsActivity.customTabsSession.validateRelationship(relation, Uri.parse(origin), null));
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.browser.trusted.ScreenOrientation;
|
|||
import androidx.browser.trusted.TrustedWebActivityDisplayMode;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.ISettings;
|
||||
import com.pichillilorenzo.flutter_inappwebview.types.AndroidResource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -25,6 +26,12 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
|||
public Boolean showTitle = true;
|
||||
@Nullable
|
||||
public String toolbarBackgroundColor;
|
||||
@Nullable
|
||||
public String navigationBarColor;
|
||||
@Nullable
|
||||
public String navigationBarDividerColor;
|
||||
@Nullable
|
||||
public String secondaryToolbarColor;
|
||||
public Boolean enableUrlBarHiding = false;
|
||||
public Boolean instantAppsEnabled = false;
|
||||
public String packageName;
|
||||
|
@ -35,6 +42,8 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
|||
public List<String> additionalTrustedOrigins = new ArrayList<>();
|
||||
public TrustedWebActivityDisplayMode displayMode = null;
|
||||
public Integer screenOrientation = ScreenOrientation.DEFAULT;
|
||||
public List<AndroidResource> startAnimations = new ArrayList<>();
|
||||
public List<AndroidResource> exitAnimations = new ArrayList<>();
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
|
@ -59,6 +68,15 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
|||
case "toolbarBackgroundColor":
|
||||
toolbarBackgroundColor = (String) value;
|
||||
break;
|
||||
case "navigationBarColor":
|
||||
navigationBarColor = (String) value;
|
||||
break;
|
||||
case "navigationBarDividerColor":
|
||||
navigationBarDividerColor = (String) value;
|
||||
break;
|
||||
case "secondaryToolbarColor":
|
||||
secondaryToolbarColor = (String) value;
|
||||
break;
|
||||
case "enableUrlBarHiding":
|
||||
enableUrlBarHiding = (Boolean) value;
|
||||
break;
|
||||
|
@ -102,6 +120,24 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
|||
case "screenOrientation":
|
||||
screenOrientation = (Integer) value;
|
||||
break;
|
||||
case "startAnimations":
|
||||
List<Map<String, Object>> startAnimationsList = (List<Map<String, Object>>) value;
|
||||
for (Map<String, Object> startAnimation : startAnimationsList) {
|
||||
AndroidResource androidResource = AndroidResource.fromMap(startAnimation);
|
||||
if (androidResource != null) {
|
||||
startAnimations.add(AndroidResource.fromMap(startAnimation));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "exitAnimations":
|
||||
List<Map<String, Object>> exitAnimationsList = (List<Map<String, Object>>) value;
|
||||
for (Map<String, Object> exitAnimation : exitAnimationsList) {
|
||||
AndroidResource androidResource = AndroidResource.fromMap(exitAnimation);
|
||||
if (androidResource != null) {
|
||||
exitAnimations.add(AndroidResource.fromMap(exitAnimation));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,6 +151,9 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
|||
options.put("addDefaultShareMenuItem", addDefaultShareMenuItem);
|
||||
options.put("showTitle", showTitle);
|
||||
options.put("toolbarBackgroundColor", toolbarBackgroundColor);
|
||||
options.put("navigationBarColor", navigationBarColor);
|
||||
options.put("navigationBarDividerColor", navigationBarDividerColor);
|
||||
options.put("secondaryToolbarColor", secondaryToolbarColor);
|
||||
options.put("enableUrlBarHiding", enableUrlBarHiding);
|
||||
options.put("instantAppsEnabled", instantAppsEnabled);
|
||||
options.put("packageName", packageName);
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Activity;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Browser;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.browser.customtabs.CustomTabsCallback;
|
||||
|
@ -14,6 +15,7 @@ import androidx.browser.customtabs.CustomTabsSession;
|
|||
import androidx.browser.trusted.TrustedWebActivityIntent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This is a helper class to manage the connection to the Custom Tabs Service.
|
||||
|
@ -35,18 +37,35 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||
public static void openCustomTab(Activity activity,
|
||||
CustomTabsIntent customTabsIntent,
|
||||
Uri uri,
|
||||
@Nullable Map<String, String> headers,
|
||||
int requestCode) {
|
||||
customTabsIntent.intent.setData(uri);
|
||||
if (headers != null) {
|
||||
Bundle bundleHeaders = new Bundle();
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
bundleHeaders.putString(header.getKey(), header.getValue());
|
||||
}
|
||||
customTabsIntent.intent.putExtra(Browser.EXTRA_HEADERS, bundleHeaders);
|
||||
}
|
||||
activity.startActivityForResult(customTabsIntent.intent, requestCode);
|
||||
}
|
||||
|
||||
public static void openCustomTab(Activity activity,
|
||||
TrustedWebActivityIntent trustedWebActivityIntent,
|
||||
Uri uri,
|
||||
@Nullable Map<String, String> headers,
|
||||
int requestCode) {
|
||||
trustedWebActivityIntent.getIntent().setData(uri);
|
||||
if (headers != null) {
|
||||
Bundle bundleHeaders = new Bundle();
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
bundleHeaders.putString(header.getKey(), header.getValue());
|
||||
}
|
||||
trustedWebActivityIntent.getIntent().putExtra(Browser.EXTRA_HEADERS, bundleHeaders);
|
||||
}
|
||||
activity.startActivityForResult(trustedWebActivityIntent.getIntent(), requestCode);
|
||||
}
|
||||
|
||||
|
||||
public static boolean isAvailable(Activity activity) {
|
||||
return CustomTabsHelper.getPackageNameToUse(activity) != null;
|
||||
|
|
|
@ -31,15 +31,16 @@ public class TrustedWebActivity extends ChromeCustomTabsActivity {
|
|||
if (customTabsSession == null) {
|
||||
return;
|
||||
}
|
||||
Uri uri = Uri.parse(url);
|
||||
|
||||
Uri uri = mayLaunchUrl(url, headers, otherLikelyURLs);
|
||||
mayLaunchUrl(url, otherLikelyURLs);
|
||||
builder = new TrustedWebActivityIntentBuilder(uri);
|
||||
prepareCustomTabs();
|
||||
|
||||
TrustedWebActivityIntent trustedWebActivityIntent = builder.build(customTabsSession);
|
||||
prepareCustomTabsIntent(trustedWebActivityIntent);
|
||||
|
||||
CustomTabActivityHelper.openCustomTab(this, trustedWebActivityIntent, uri, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
||||
CustomTabActivityHelper.openCustomTab(this, trustedWebActivityIntent, uri, headers, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,7 +49,6 @@ public class TrustedWebActivity extends ChromeCustomTabsActivity {
|
|||
if (initialUrl != null) {
|
||||
launchUrl(initialUrl, initialHeaders, initialOtherLikelyURLs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void prepareCustomTabs() {
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package com.pichillilorenzo.flutter_inappwebview.types;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AndroidResource {
|
||||
@NonNull
|
||||
String name;
|
||||
@Nullable
|
||||
String defType;
|
||||
@Nullable
|
||||
String defPackage;
|
||||
|
||||
public AndroidResource(@NonNull String name, @Nullable String defType, @Nullable String defPackage) {
|
||||
this.name = name;
|
||||
this.defType = defType;
|
||||
this.defPackage = defPackage;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static AndroidResource fromMap(@Nullable Map<String, Object> map) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
String name = (String) map.get("name");
|
||||
String defType = (String) map.get("defType");
|
||||
String defPackage = (String) map.get("defPackage");
|
||||
return new AndroidResource(name, defType, defPackage);
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> urlRequestMap = new HashMap<>();
|
||||
urlRequestMap.put("name", name);
|
||||
urlRequestMap.put("defType", defType);
|
||||
urlRequestMap.put("defPackage", defPackage);
|
||||
return urlRequestMap;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(@NonNull String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDefType() {
|
||||
return defType;
|
||||
}
|
||||
|
||||
public void setDefType(@Nullable String defType) {
|
||||
this.defType = defType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDefPackage() {
|
||||
return defPackage;
|
||||
}
|
||||
|
||||
public void setDefPackage(@Nullable String defPackage) {
|
||||
this.defPackage = defPackage;
|
||||
}
|
||||
|
||||
public int getIdentifier(@NonNull Context ctx) {
|
||||
return ctx.getResources().getIdentifier(name, defType, defPackage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
AndroidResource that = (AndroidResource) o;
|
||||
|
||||
if (!name.equals(that.name)) return false;
|
||||
if (defType != null ? !defType.equals(that.defType) : that.defType != null) return false;
|
||||
return defPackage != null ? defPackage.equals(that.defPackage) : that.defPackage == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = name.hashCode();
|
||||
result = 31 * result + (defType != null ? defType.hashCode() : 0);
|
||||
result = 31 * result + (defPackage != null ? defPackage.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AndroidResource{" +
|
||||
"name='" + name + '\'' +
|
||||
", type='" + defType + '\'' +
|
||||
", defPackage='" + defPackage + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -13,10 +13,12 @@ void customActionButton() {
|
|||
TargetPlatform.android,
|
||||
].contains(defaultTargetPlatform);
|
||||
|
||||
test('add custom action button', () async {
|
||||
test('add custom action button and update icon', () async {
|
||||
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||
var actionButtonIcon =
|
||||
await rootBundle.load('test_assets/images/flutter-logo.png');
|
||||
var actionButtonIcon2 =
|
||||
await rootBundle.load('test_assets/images/flutter-logo.jpg');
|
||||
chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton(
|
||||
id: 1,
|
||||
description: 'Action Button description',
|
||||
|
@ -25,15 +27,18 @@ void customActionButton() {
|
|||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
|
||||
await chromeSafariBrowser.open(url: TEST_URL_1);
|
||||
await chromeSafariBrowser.browserCreated.future;
|
||||
await chromeSafariBrowser.opened.future;
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
expect(() async {
|
||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||
}, throwsA(isInstanceOf<ChromeSafariBrowserAlreadyOpenedException>()));
|
||||
|
||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||
await chromeSafariBrowser.updateActionButton(
|
||||
icon: actionButtonIcon2.buffer.asUint8List(),
|
||||
description: 'New Action Button description');
|
||||
await chromeSafariBrowser.close();
|
||||
await chromeSafariBrowser.browserClosed.future;
|
||||
await chromeSafariBrowser.closed.future;
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
}, skip: shouldSkip);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ void customMenuItem() {
|
|||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
|
||||
await chromeSafariBrowser.open(url: TEST_URL_1);
|
||||
await chromeSafariBrowser.browserCreated.future;
|
||||
await chromeSafariBrowser.opened.future;
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
expect(() async {
|
||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||
|
@ -26,7 +26,7 @@ void customMenuItem() {
|
|||
|
||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||
await chromeSafariBrowser.close();
|
||||
await chromeSafariBrowser.browserClosed.future;
|
||||
await chromeSafariBrowser.closed.future;
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
}, skip: shouldSkip);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ void customTabs() {
|
|||
await chromeSafariBrowser.open(
|
||||
url: TEST_URL_1,
|
||||
settings: ChromeSafariBrowserSettings(isSingleInstance: true));
|
||||
await chromeSafariBrowser.browserCreated.future;
|
||||
await expectLater(chromeSafariBrowser.opened.future, completes);
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
expect(() async {
|
||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||
|
@ -28,7 +28,43 @@ void customTabs() {
|
|||
|
||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||
await chromeSafariBrowser.close();
|
||||
await chromeSafariBrowser.browserClosed.future;
|
||||
await expectLater(chromeSafariBrowser.closed.future, completes);
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
});
|
||||
|
||||
test('mayLaunchUrl and launchUrl', () async {
|
||||
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
|
||||
await chromeSafariBrowser.open();
|
||||
await expectLater(chromeSafariBrowser.serviceConnected.future, completes);
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
expect(
|
||||
await chromeSafariBrowser.mayLaunchUrl(
|
||||
url: TEST_URL_1, otherLikelyURLs: [TEST_CROSS_PLATFORM_URL_1]),
|
||||
true);
|
||||
await chromeSafariBrowser.launchUrl(
|
||||
url: TEST_URL_1,
|
||||
headers: {'accept-language': 'it-IT'},
|
||||
otherLikelyURLs: [TEST_CROSS_PLATFORM_URL_1]);
|
||||
await expectLater(chromeSafariBrowser.opened.future, completes);
|
||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||
await chromeSafariBrowser.close();
|
||||
await expectLater(chromeSafariBrowser.closed.future, completes);
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
});
|
||||
|
||||
test('onNavigationEvent', () async {
|
||||
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
|
||||
await chromeSafariBrowser.open(url: TEST_URL_1);
|
||||
await expectLater(chromeSafariBrowser.opened.future, completes);
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||
expect(await chromeSafariBrowser.navigationEvent.future, isNotNull);
|
||||
await chromeSafariBrowser.close();
|
||||
await expectLater(chromeSafariBrowser.closed.future, completes);
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
});
|
||||
}, skip: shouldSkip);
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'custom_menu_item.dart';
|
|||
import 'custom_tabs.dart';
|
||||
import 'open_and_close.dart';
|
||||
import 'trusted_web_activity.dart';
|
||||
import 'sf_safari_view_controller.dart';
|
||||
|
||||
void main() {
|
||||
final shouldSkip =
|
||||
|
@ -17,5 +18,6 @@ void main() {
|
|||
customActionButton();
|
||||
customTabs();
|
||||
trustedWebActivity();
|
||||
sfSafariViewController();
|
||||
}, skip: shouldSkip);
|
||||
}
|
||||
|
|
|
@ -15,8 +15,35 @@ void openAndClose() {
|
|||
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
|
||||
await chromeSafariBrowser.open(url: TEST_URL_1);
|
||||
await chromeSafariBrowser.browserCreated.future;
|
||||
await chromeSafariBrowser.open(
|
||||
url: TEST_URL_1,
|
||||
settings: ChromeSafariBrowserSettings(
|
||||
shareState: CustomTabsShareState.SHARE_STATE_OFF,
|
||||
startAnimations: [
|
||||
AndroidResource(
|
||||
name: "slide_in_left",
|
||||
defType: "anim",
|
||||
defPackage: "android"),
|
||||
AndroidResource(
|
||||
name: "slide_out_right",
|
||||
defType: "anim",
|
||||
defPackage: "android")
|
||||
],
|
||||
exitAnimations: [
|
||||
AndroidResource(
|
||||
name: "abc_slide_in_top",
|
||||
defType: "anim",
|
||||
defPackage:
|
||||
"com.pichillilorenzo.flutter_inappwebviewexample"),
|
||||
AndroidResource(
|
||||
name: "abc_slide_out_top",
|
||||
defType: "anim",
|
||||
defPackage: "com.pichillilorenzo.flutter_inappwebviewexample")
|
||||
],
|
||||
keepAliveEnabled: true,
|
||||
dismissButtonStyle: DismissButtonStyle.CLOSE,
|
||||
presentationStyle: ModalPresentationStyle.OVER_FULL_SCREEN));
|
||||
await chromeSafariBrowser.opened.future;
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
expect(() async {
|
||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||
|
@ -24,7 +51,7 @@ void openAndClose() {
|
|||
|
||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||
await chromeSafariBrowser.close();
|
||||
await chromeSafariBrowser.browserClosed.future;
|
||||
await chromeSafariBrowser.closed.future;
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
}, skip: shouldSkip);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
import '../util.dart';
|
||||
|
||||
void sfSafariViewController() {
|
||||
final shouldSkip = kIsWeb
|
||||
? true
|
||||
: ![
|
||||
TargetPlatform.android,
|
||||
].contains(defaultTargetPlatform);
|
||||
|
||||
group('SF Safari View Controller', () {
|
||||
test('onCompletedInitialLoad did load successfully', () async {
|
||||
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
|
||||
await chromeSafariBrowser.open(url: TEST_URL_1);
|
||||
await expectLater(chromeSafariBrowser.opened.future, completes);
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
expect(() async {
|
||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||
}, throwsA(isInstanceOf<ChromeSafariBrowserAlreadyOpenedException>()));
|
||||
|
||||
expect(await chromeSafariBrowser.firstPageLoaded.future, true);
|
||||
await chromeSafariBrowser.close();
|
||||
await expectLater(chromeSafariBrowser.closed.future, completes);
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
});
|
||||
|
||||
test('clearWebsiteData', () async {
|
||||
await expectLater(ChromeSafariBrowser.clearWebsiteData(), completes);
|
||||
});
|
||||
|
||||
test('create and invalidate Prewarming Token', () async {
|
||||
final prewarmingToken = await ChromeSafariBrowser.prewarmConnections([TEST_URL_1]);
|
||||
expect(prewarmingToken, isNotNull);
|
||||
await expectLater(ChromeSafariBrowser.invalidatePrewarmingToken(prewarmingToken!), completes);
|
||||
});
|
||||
}, skip: shouldSkip);
|
||||
}
|
|
@ -20,7 +20,7 @@ void trustedWebActivity() {
|
|||
await chromeSafariBrowser.open(
|
||||
url: TEST_URL_1,
|
||||
settings: ChromeSafariBrowserSettings(isTrustedWebActivity: true));
|
||||
await chromeSafariBrowser.browserCreated.future;
|
||||
await chromeSafariBrowser.opened.future;
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
expect(() async {
|
||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||
|
@ -28,7 +28,7 @@ void trustedWebActivity() {
|
|||
|
||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||
await chromeSafariBrowser.close();
|
||||
await chromeSafariBrowser.browserClosed.future;
|
||||
await chromeSafariBrowser.closed.future;
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
});
|
||||
|
||||
|
@ -40,7 +40,7 @@ void trustedWebActivity() {
|
|||
url: TEST_URL_1,
|
||||
settings: ChromeSafariBrowserSettings(
|
||||
isTrustedWebActivity: true, isSingleInstance: true));
|
||||
await chromeSafariBrowser.browserCreated.future;
|
||||
await chromeSafariBrowser.opened.future;
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
expect(() async {
|
||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||
|
@ -48,7 +48,25 @@ void trustedWebActivity() {
|
|||
|
||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||
await chromeSafariBrowser.close();
|
||||
await chromeSafariBrowser.browserClosed.future;
|
||||
await chromeSafariBrowser.closed.future;
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
});
|
||||
|
||||
test('validate relationship', () async {
|
||||
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
|
||||
await chromeSafariBrowser.open(
|
||||
settings: ChromeSafariBrowserSettings(isTrustedWebActivity: true));
|
||||
await chromeSafariBrowser.serviceConnected.future;
|
||||
expect(await chromeSafariBrowser.validateRelationship(relation: CustomTabsRelationType.USE_AS_ORIGIN, origin: TEST_CROSS_PLATFORM_URL_1), true);
|
||||
expect(await chromeSafariBrowser.relationshipValidationResult.future, true);
|
||||
await chromeSafariBrowser.launchUrl(url: TEST_CROSS_PLATFORM_URL_1);
|
||||
await chromeSafariBrowser.opened.future;
|
||||
expect(chromeSafariBrowser.isOpened(), true);
|
||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||
await chromeSafariBrowser.close();
|
||||
await chromeSafariBrowser.closed.future;
|
||||
expect(chromeSafariBrowser.isOpened(), false);
|
||||
});
|
||||
}, skip: shouldSkip);
|
||||
|
|
|
@ -54,22 +54,44 @@ class MyInAppBrowser extends InAppBrowser {
|
|||
}
|
||||
|
||||
class MyChromeSafariBrowser extends ChromeSafariBrowser {
|
||||
final Completer<void> browserCreated = Completer<void>();
|
||||
final Completer<void> firstPageLoaded = Completer<void>();
|
||||
final Completer<void> browserClosed = Completer<void>();
|
||||
final Completer<void> serviceConnected = Completer<void>();
|
||||
final Completer<void> opened = Completer<void>();
|
||||
final Completer<bool> firstPageLoaded = Completer<bool>();
|
||||
final Completer<void> closed = Completer<void>();
|
||||
final Completer<CustomTabsNavigationEventType?> navigationEvent = Completer<CustomTabsNavigationEventType?>();
|
||||
final Completer<bool> relationshipValidationResult = Completer<bool>();
|
||||
|
||||
@override
|
||||
void onOpened() {
|
||||
browserCreated.complete();
|
||||
void onServiceConnected() {
|
||||
serviceConnected.complete();
|
||||
}
|
||||
|
||||
@override
|
||||
void onCompletedInitialLoad() {
|
||||
firstPageLoaded.complete();
|
||||
void onOpened() {
|
||||
opened.complete();
|
||||
}
|
||||
|
||||
@override
|
||||
void onCompletedInitialLoad(didLoadSuccessfully) {
|
||||
firstPageLoaded.complete(didLoadSuccessfully);
|
||||
}
|
||||
|
||||
@override
|
||||
void onNavigationEvent(CustomTabsNavigationEventType? type) {
|
||||
if (!navigationEvent.isCompleted) {
|
||||
navigationEvent.complete(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void onRelationshipValidationResult(
|
||||
CustomTabsRelationType? relation, Uri? requestedOrigin, bool result) {
|
||||
relationshipValidationResult.complete(result);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClosed() {
|
||||
browserClosed.complete();
|
||||
closed.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ public class SafariBrowserSettings: ISettings<SafariViewController> {
|
|||
var preferredBarTintColor: String?
|
||||
var preferredControlTintColor: String?
|
||||
var presentationStyle = 0 //fullscreen
|
||||
var transitionStyle = 0 //crossDissolve
|
||||
var transitionStyle = 0 //coverVertical
|
||||
|
||||
override init(){
|
||||
super.init()
|
||||
|
|
|
@ -217,6 +217,11 @@ class WebViewFeature_ {
|
|||
const WebViewFeature_._internal(
|
||||
"ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY");
|
||||
|
||||
///This feature covers [InAppWebViewController.getVariationsHeader].
|
||||
static const GET_VARIATIONS_HEADER =
|
||||
const WebViewFeature_._internal(
|
||||
"GET_VARIATIONS_HEADER");
|
||||
|
||||
///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`.
|
||||
|
|
|
@ -217,6 +217,10 @@ class WebViewFeature {
|
|||
WebViewFeature._internal('ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY',
|
||||
'ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY');
|
||||
|
||||
///This feature covers [InAppWebViewController.getVariationsHeader].
|
||||
static const GET_VARIATIONS_HEADER = WebViewFeature._internal(
|
||||
'GET_VARIATIONS_HEADER', 'GET_VARIATIONS_HEADER');
|
||||
|
||||
///Set of all values of [WebViewFeature].
|
||||
static final Set<WebViewFeature> values = [
|
||||
WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
|
||||
|
@ -266,6 +270,7 @@ class WebViewFeature {
|
|||
WebViewFeature.ALGORITHMIC_DARKENING,
|
||||
WebViewFeature.REQUESTED_WITH_HEADER_CONTROL,
|
||||
WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY,
|
||||
WebViewFeature.GET_VARIATIONS_HEADER,
|
||||
].toSet();
|
||||
|
||||
///Gets a possible [WebViewFeature] instance from [String] value.
|
||||
|
|
|
@ -143,7 +143,9 @@ class ChromeSafariBrowser {
|
|||
///
|
||||
///[url] - The [url] to load. On iOS, the [url] is required and must use the `http` or `https` scheme.
|
||||
///
|
||||
///[headers] - extra request headers. Supported only on Android.
|
||||
///[headers] (Supported only on Android) - [whitelisted](https://fetch.spec.whatwg.org/#cors-safelisted-request-header) cross-origin request headers.
|
||||
///It is possible to attach non-whitelisted headers to cross-origin requests, when the server and client are related using a
|
||||
///[digital asset link](https://developers.google.com/digital-asset-links/v1/getting-started).
|
||||
///
|
||||
///[otherLikelyURLs] - Other likely destinations, sorted in decreasing likelihood order. Supported only on Android.
|
||||
///
|
||||
|
@ -199,7 +201,9 @@ class ChromeSafariBrowser {
|
|||
///
|
||||
///[url] - initial url.
|
||||
///
|
||||
///[headers] - extra request headers.
|
||||
///[headers] (Supported only on Android) - [whitelisted](https://fetch.spec.whatwg.org/#cors-safelisted-request-header) cross-origin request headers.
|
||||
///It is possible to attach non-whitelisted headers to cross-origin requests, when the server and client are related using a
|
||||
///[digital asset link](https://developers.google.com/digital-asset-links/v1/getting-started).
|
||||
///
|
||||
///[otherLikelyURLs] - Other likely destinations, sorted in decreasing likelihood order.
|
||||
///
|
||||
|
@ -225,22 +229,18 @@ class ChromeSafariBrowser {
|
|||
///
|
||||
///[url] - Most likely URL, may be null if otherLikelyBundles is provided.
|
||||
///
|
||||
///[headers] - extra request headers.
|
||||
///
|
||||
///[otherLikelyURLs] - Other likely destinations, sorted in decreasing likelihood order.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android ([Official API - CustomTabsSession.mayLaunchUrl](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsSession#mayLaunchUrl(android.net.Uri,android.os.Bundle,java.util.List%3Candroid.os.Bundle%3E)))
|
||||
Future<void> mayLaunchUrl(
|
||||
Future<bool> mayLaunchUrl(
|
||||
{Uri? url,
|
||||
Map<String, String>? headers,
|
||||
List<Uri>? otherLikelyURLs}) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('url', () => url?.toString());
|
||||
args.putIfAbsent('headers', () => headers);
|
||||
args.putIfAbsent('otherLikelyURLs',
|
||||
() => otherLikelyURLs?.map((e) => e.toString()).toList());
|
||||
await _channel.invokeMethod("mayLaunchUrl", args);
|
||||
return await _channel.invokeMethod("mayLaunchUrl", args);
|
||||
}
|
||||
|
||||
///Requests to validate a relationship between the application and an origin.
|
||||
|
@ -251,14 +251,20 @@ class ChromeSafariBrowser {
|
|||
///If this method returns `true`, the validation result will be provided through [onRelationshipValidationResult].
|
||||
///Otherwise the request didn't succeed.
|
||||
///
|
||||
///[relation] – Relation to check, must be one of the [CustomTabsRelationType] constants.
|
||||
///
|
||||
///[origin] – Origin.
|
||||
///
|
||||
///[extras] – Reserved for future use.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android ([Official API - CustomTabsSession.validateRelationship](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsSession#validateRelationship(int,android.net.Uri,android.os.Bundle)))
|
||||
Future<void> validateRelationship(
|
||||
Future<bool> validateRelationship(
|
||||
{required CustomTabsRelationType relation, required Uri origin}) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('relation', () => relation.toNativeValue());
|
||||
args.putIfAbsent('origin', () => origin.toString());
|
||||
await _channel.invokeMethod("validateRelationship", args);
|
||||
return await _channel.invokeMethod("validateRelationship", args);
|
||||
}
|
||||
|
||||
///Closes the [ChromeSafariBrowser] instance.
|
||||
|
|
|
@ -1,11 +1,35 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
|
||||
|
||||
import '../types/android_resource.dart';
|
||||
import '../types/custom_tabs_share_state.dart';
|
||||
import '../types/dismiss_button_style.dart';
|
||||
import '../types/main.dart';
|
||||
import '../types/modal_presentation_style.dart';
|
||||
import '../types/modal_transition_style.dart';
|
||||
import '../types/trusted_web_activity_display_mode.dart';
|
||||
import '../types/trusted_web_activity_screen_orientation.dart';
|
||||
import '../util.dart';
|
||||
import 'android/chrome_custom_tabs_options.dart';
|
||||
import 'apple/safari_options.dart';
|
||||
import '../types/main.dart';
|
||||
|
||||
part 'chrome_safari_browser_settings.g.dart';
|
||||
|
||||
TrustedWebActivityDisplayMode? _deserializeDisplayMode(
|
||||
Map<String, dynamic>? displayMode) {
|
||||
if (displayMode == null) {
|
||||
return null;
|
||||
}
|
||||
switch (displayMode["type"]) {
|
||||
case "IMMERSIVE_MODE":
|
||||
return TrustedWebActivityImmersiveDisplayMode.fromMap(displayMode);
|
||||
case "DEFAULT_MODE":
|
||||
default:
|
||||
return TrustedWebActivityDefaultDisplayMode();
|
||||
}
|
||||
}
|
||||
|
||||
class ChromeSafariBrowserOptions {
|
||||
Map<String, dynamic> toMap() {
|
||||
|
@ -31,14 +55,15 @@ class ChromeSafariBrowserOptions {
|
|||
}
|
||||
|
||||
///Class that represents the settings that can be used for an [ChromeSafariBrowser] window.
|
||||
class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||
@ExchangeableObject(copyMethod: true)
|
||||
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
|
||||
CustomTabsShareState shareState;
|
||||
CustomTabsShareState_? shareState;
|
||||
|
||||
///Set to `false` if the title shouldn't be shown in the custom tab. The default value is `true`.
|
||||
///
|
||||
|
@ -46,7 +71,7 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
bool showTitle;
|
||||
bool? showTitle;
|
||||
|
||||
///Set the custom background color of the toolbar.
|
||||
///
|
||||
|
@ -54,13 +79,31 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
///- Android
|
||||
Color? toolbarBackgroundColor;
|
||||
|
||||
///Sets the navigation bar color. Has no effect on Android API versions below L.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
Color? navigationBarColor;
|
||||
|
||||
///Sets the navigation bar divider color. Has no effect on Android API versions below P.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
Color? navigationBarDividerColor;
|
||||
|
||||
///Sets the color of the secondary toolbar.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
Color? secondaryToolbarColor;
|
||||
|
||||
///Set to `true` to enable the url bar to hide as the user scrolls down on the page. The default value is `false`.
|
||||
///
|
||||
///**NOTE**: Not available in a Trusted Web Activity.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
bool enableUrlBarHiding;
|
||||
bool? enableUrlBarHiding;
|
||||
|
||||
///Set to `true` to enable Instant Apps. The default value is `false`.
|
||||
///
|
||||
|
@ -68,7 +111,7 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
bool instantAppsEnabled;
|
||||
bool? instantAppsEnabled;
|
||||
|
||||
///Set an explicit application package name that limits
|
||||
///the components this Intent will resolve to. If left to the default
|
||||
|
@ -84,25 +127,25 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
bool keepAliveEnabled;
|
||||
bool? keepAliveEnabled;
|
||||
|
||||
///Set to `true` to launch the Android activity in `singleInstance` mode. The default value is `false`.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
bool isSingleInstance;
|
||||
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
|
||||
bool noHistory;
|
||||
bool? noHistory;
|
||||
|
||||
///Set to `true` to launch the Custom Tab as a Trusted Web Activity. The default value is `false`.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
bool isTrustedWebActivity;
|
||||
bool? isTrustedWebActivity;
|
||||
|
||||
///Sets a list of additional trusted origins that the user may navigate or be redirected to from the starting uri.
|
||||
///
|
||||
|
@ -110,7 +153,7 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
List<String> additionalTrustedOrigins;
|
||||
List<String>? additionalTrustedOrigins;
|
||||
|
||||
///Sets a display mode of a Trusted Web Activity.
|
||||
///
|
||||
|
@ -118,7 +161,8 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
TrustedWebActivityDisplayMode? displayMode;
|
||||
@ExchangeableObjectProperty(deserializer: _deserializeDisplayMode)
|
||||
TrustedWebActivityDisplayMode_? displayMode;
|
||||
|
||||
///Sets a screen orientation. This can be used e.g. to enable the locking of an orientation lock type.
|
||||
///
|
||||
|
@ -126,19 +170,35 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
TrustedWebActivityScreenOrientation screenOrientation;
|
||||
TrustedWebActivityScreenOrientation_? screenOrientation;
|
||||
|
||||
///Sets the start animations.
|
||||
///It must contain 2 [AndroidResource], where the first one represents the "enter" animation for the browser
|
||||
///and the second one represents the "exit" animation for the application.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
List<AndroidResource_>? startAnimations;
|
||||
|
||||
///Sets the exit animations.
|
||||
///It must contain 2 [AndroidResource], where the first one represents the "enter" animation for the application
|
||||
///and the second one represents the "exit" animation for the browser.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
List<AndroidResource_>? exitAnimations;
|
||||
|
||||
///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;
|
||||
bool? entersReaderIfAvailable;
|
||||
|
||||
///Set to `true` to enable bar collapsing. The default value is `false`.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
bool barCollapsingEnabled;
|
||||
bool? barCollapsingEnabled;
|
||||
|
||||
///Set the custom style for the dismiss button. The default value is [DismissButtonStyle.DONE].
|
||||
///
|
||||
|
@ -146,7 +206,7 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
DismissButtonStyle dismissButtonStyle;
|
||||
DismissButtonStyle_? dismissButtonStyle;
|
||||
|
||||
///Set the custom background color of the navigation bar and the toolbar.
|
||||
///
|
||||
|
@ -168,18 +228,22 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
ModalPresentationStyle presentationStyle;
|
||||
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;
|
||||
ModalTransitionStyle_? transitionStyle;
|
||||
|
||||
ChromeSafariBrowserSettings(
|
||||
{this.shareState = CustomTabsShareState.SHARE_STATE_DEFAULT,
|
||||
@ExchangeableObjectConstructor()
|
||||
ChromeSafariBrowserSettings_(
|
||||
{this.shareState = CustomTabsShareState_.SHARE_STATE_DEFAULT,
|
||||
this.showTitle = true,
|
||||
this.toolbarBackgroundColor,
|
||||
this.navigationBarColor,
|
||||
this.navigationBarDividerColor,
|
||||
this.secondaryToolbarColor,
|
||||
this.enableUrlBarHiding = false,
|
||||
this.instantAppsEnabled = false,
|
||||
this.packageName,
|
||||
|
@ -189,99 +253,42 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||
this.isTrustedWebActivity = false,
|
||||
this.additionalTrustedOrigins = const [],
|
||||
this.displayMode,
|
||||
this.screenOrientation = TrustedWebActivityScreenOrientation.DEFAULT,
|
||||
this.screenOrientation = TrustedWebActivityScreenOrientation_.DEFAULT,
|
||||
this.startAnimations,
|
||||
this.exitAnimations,
|
||||
this.entersReaderIfAvailable = false,
|
||||
this.barCollapsingEnabled = false,
|
||||
this.dismissButtonStyle = DismissButtonStyle.DONE,
|
||||
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.toNativeValue(),
|
||||
"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.toNativeValue(),
|
||||
"entersReaderIfAvailable": entersReaderIfAvailable,
|
||||
"barCollapsingEnabled": barCollapsingEnabled,
|
||||
"dismissButtonStyle": dismissButtonStyle.toNativeValue(),
|
||||
"preferredBarTintColor": preferredBarTintColor?.toHex(),
|
||||
"preferredControlTintColor": preferredControlTintColor?.toHex(),
|
||||
"presentationStyle": presentationStyle.toNativeValue(),
|
||||
"transitionStyle": transitionStyle.toNativeValue()
|
||||
};
|
||||
}
|
||||
|
||||
static ChromeSafariBrowserSettings fromMap(Map<String, dynamic> map) {
|
||||
ChromeSafariBrowserSettings settings = new ChromeSafariBrowserSettings();
|
||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||
settings.shareState = map["shareState"];
|
||||
settings.showTitle = map["showTitle"];
|
||||
settings.toolbarBackgroundColor =
|
||||
UtilColor.fromHex(map["toolbarBackgroundColor"]);
|
||||
settings.enableUrlBarHiding = map["enableUrlBarHiding"];
|
||||
settings.instantAppsEnabled = map["instantAppsEnabled"];
|
||||
settings.packageName = map["packageName"];
|
||||
settings.keepAliveEnabled = map["keepAliveEnabled"];
|
||||
settings.isSingleInstance = map["isSingleInstance"];
|
||||
settings.noHistory = map["noHistory"];
|
||||
settings.isTrustedWebActivity = map["isTrustedWebActivity"];
|
||||
settings.additionalTrustedOrigins = map["additionalTrustedOrigins"];
|
||||
switch (map["displayMode"]["type"]) {
|
||||
case "IMMERSIVE_MODE":
|
||||
settings.displayMode = TrustedWebActivityImmersiveDisplayMode.fromMap(
|
||||
map["displayMode"]);
|
||||
break;
|
||||
case "DEFAULT_MODE":
|
||||
default:
|
||||
settings.displayMode = TrustedWebActivityDefaultDisplayMode();
|
||||
break;
|
||||
}
|
||||
settings.screenOrientation = map["screenOrientation"];
|
||||
this.presentationStyle = ModalPresentationStyle_.FULL_SCREEN,
|
||||
this.transitionStyle = ModalTransitionStyle_.COVER_VERTICAL}) {
|
||||
if (startAnimations != null) {
|
||||
assert(startAnimations!.length == 2,
|
||||
"start animations must be have 2 android resources");
|
||||
}
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS ||
|
||||
defaultTargetPlatform == TargetPlatform.macOS) {
|
||||
settings.entersReaderIfAvailable = map["entersReaderIfAvailable"];
|
||||
settings.barCollapsingEnabled = map["barCollapsingEnabled"];
|
||||
settings.dismissButtonStyle =
|
||||
DismissButtonStyle.fromNativeValue(map["dismissButtonStyle"])!;
|
||||
settings.preferredBarTintColor =
|
||||
UtilColor.fromHex(map["preferredBarTintColor"]);
|
||||
settings.preferredControlTintColor =
|
||||
UtilColor.fromHex(map["preferredControlTintColor"]);
|
||||
settings.presentationStyle =
|
||||
ModalPresentationStyle.fromNativeValue(map["presentationStyle"])!;
|
||||
settings.transitionStyle =
|
||||
ModalTransitionStyle.fromNativeValue(map["transitionStyle"])!;
|
||||
if (exitAnimations != null) {
|
||||
assert(exitAnimations!.length == 2,
|
||||
"exit animations must be have 2 android resources");
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
@override
|
||||
@ExchangeableObjectMethod(ignore: true)
|
||||
ChromeSafariBrowserSettings_ copy() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
@ExchangeableObjectMethod(ignore: true)
|
||||
Map<String, dynamic> toJson() {
|
||||
return this.toMap();
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return toMap().toString();
|
||||
}
|
||||
|
||||
@override
|
||||
ChromeSafariBrowserSettings copy() {
|
||||
return ChromeSafariBrowserSettings.fromMap(this.toMap());
|
||||
@ExchangeableObjectMethod(ignore: true)
|
||||
Map<String, dynamic> toMap() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,330 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'chrome_safari_browser_settings.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// ExchangeableObjectGenerator
|
||||
// **************************************************************************
|
||||
|
||||
///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
|
||||
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
|
||||
bool? showTitle;
|
||||
|
||||
///Set the custom background color of the toolbar.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
Color? toolbarBackgroundColor;
|
||||
|
||||
///Sets the navigation bar color. Has no effect on Android API versions below L.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
Color? navigationBarColor;
|
||||
|
||||
///Sets the navigation bar divider color. Has no effect on Android API versions below P.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
Color? navigationBarDividerColor;
|
||||
|
||||
///Sets the color of the secondary toolbar.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
Color? secondaryToolbarColor;
|
||||
|
||||
///Set to `true` to enable the url bar to hide as the user scrolls down on the page. The default value is `false`.
|
||||
///
|
||||
///**NOTE**: Not available in a Trusted Web Activity.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
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
|
||||
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
|
||||
String? packageName;
|
||||
|
||||
///Set to `true` to enable Keep Alive. The default value is `false`.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
bool? keepAliveEnabled;
|
||||
|
||||
///Set to `true` to launch the Android activity in `singleInstance` mode. The default value is `false`.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
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
|
||||
bool? noHistory;
|
||||
|
||||
///Set to `true` to launch the Custom Tab as a Trusted Web Activity. The default value is `false`.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
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
|
||||
List<String>? additionalTrustedOrigins;
|
||||
|
||||
///Sets a display mode of a Trusted Web Activity.
|
||||
///
|
||||
///**NOTE**: Available only in a Trusted Web Activity.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
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
|
||||
TrustedWebActivityScreenOrientation? screenOrientation;
|
||||
|
||||
///Sets the start animations.
|
||||
///It must contain 2 [AndroidResource], where the first one represents the "enter" animation for the browser
|
||||
///and the second one represents the "exit" animation for the application.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
List<AndroidResource>? startAnimations;
|
||||
|
||||
///Sets the exit animations.
|
||||
///It must contain 2 [AndroidResource], where the first one represents the "enter" animation for the application
|
||||
///and the second one represents the "exit" animation for the browser.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android
|
||||
List<AndroidResource>? exitAnimations;
|
||||
|
||||
///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.navigationBarColor,
|
||||
this.navigationBarDividerColor,
|
||||
this.secondaryToolbarColor,
|
||||
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.startAnimations,
|
||||
this.exitAnimations,
|
||||
this.entersReaderIfAvailable = false,
|
||||
this.barCollapsingEnabled = false,
|
||||
this.dismissButtonStyle = DismissButtonStyle.DONE,
|
||||
this.preferredBarTintColor,
|
||||
this.preferredControlTintColor,
|
||||
this.presentationStyle = ModalPresentationStyle.FULL_SCREEN,
|
||||
this.transitionStyle = ModalTransitionStyle.COVER_VERTICAL}) {
|
||||
if (startAnimations != null) {
|
||||
assert(startAnimations!.length == 2,
|
||||
"start animations must be have 2 android resources");
|
||||
}
|
||||
if (exitAnimations != null) {
|
||||
assert(exitAnimations!.length == 2,
|
||||
"exit animations must be have 2 android resources");
|
||||
}
|
||||
}
|
||||
|
||||
///Gets a possible [ChromeSafariBrowserSettings] instance from a [Map] value.
|
||||
static ChromeSafariBrowserSettings? fromMap(Map<String, dynamic>? map) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
final instance = ChromeSafariBrowserSettings(
|
||||
toolbarBackgroundColor: map['toolbarBackgroundColor'] != null
|
||||
? UtilColor.fromStringRepresentation(map['toolbarBackgroundColor'])
|
||||
: null,
|
||||
navigationBarColor: map['navigationBarColor'] != null
|
||||
? UtilColor.fromStringRepresentation(map['navigationBarColor'])
|
||||
: null,
|
||||
navigationBarDividerColor: map['navigationBarDividerColor'] != null
|
||||
? UtilColor.fromStringRepresentation(map['navigationBarDividerColor'])
|
||||
: null,
|
||||
secondaryToolbarColor: map['secondaryToolbarColor'] != null
|
||||
? UtilColor.fromStringRepresentation(map['secondaryToolbarColor'])
|
||||
: null,
|
||||
packageName: map['packageName'],
|
||||
displayMode: _deserializeDisplayMode(map['displayMode']),
|
||||
startAnimations: map['startAnimations'] != null
|
||||
? List<AndroidResource>.from(map['startAnimations']
|
||||
.map((e) => AndroidResource.fromMap(e?.cast<String, dynamic>())!))
|
||||
: null,
|
||||
exitAnimations: map['exitAnimations'] != null
|
||||
? List<AndroidResource>.from(map['exitAnimations']
|
||||
.map((e) => AndroidResource.fromMap(e?.cast<String, dynamic>())!))
|
||||
: null,
|
||||
preferredBarTintColor: map['preferredBarTintColor'] != null
|
||||
? UtilColor.fromStringRepresentation(map['preferredBarTintColor'])
|
||||
: null,
|
||||
preferredControlTintColor: map['preferredControlTintColor'] != null
|
||||
? UtilColor.fromStringRepresentation(map['preferredControlTintColor'])
|
||||
: null,
|
||||
);
|
||||
instance.shareState =
|
||||
CustomTabsShareState.fromNativeValue(map['shareState']);
|
||||
instance.showTitle = map['showTitle'];
|
||||
instance.enableUrlBarHiding = map['enableUrlBarHiding'];
|
||||
instance.instantAppsEnabled = map['instantAppsEnabled'];
|
||||
instance.keepAliveEnabled = map['keepAliveEnabled'];
|
||||
instance.isSingleInstance = map['isSingleInstance'];
|
||||
instance.noHistory = map['noHistory'];
|
||||
instance.isTrustedWebActivity = map['isTrustedWebActivity'];
|
||||
instance.additionalTrustedOrigins =
|
||||
map['additionalTrustedOrigins']?.cast<String>();
|
||||
instance.screenOrientation =
|
||||
TrustedWebActivityScreenOrientation.fromNativeValue(
|
||||
map['screenOrientation']);
|
||||
instance.entersReaderIfAvailable = map['entersReaderIfAvailable'];
|
||||
instance.barCollapsingEnabled = map['barCollapsingEnabled'];
|
||||
instance.dismissButtonStyle =
|
||||
DismissButtonStyle.fromNativeValue(map['dismissButtonStyle']);
|
||||
instance.presentationStyle =
|
||||
ModalPresentationStyle.fromNativeValue(map['presentationStyle']);
|
||||
instance.transitionStyle =
|
||||
ModalTransitionStyle.fromNativeValue(map['transitionStyle']);
|
||||
return instance;
|
||||
}
|
||||
|
||||
///Converts instance to a map.
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
"shareState": shareState?.toNativeValue(),
|
||||
"showTitle": showTitle,
|
||||
"toolbarBackgroundColor": toolbarBackgroundColor?.toHex(),
|
||||
"navigationBarColor": navigationBarColor?.toHex(),
|
||||
"navigationBarDividerColor": navigationBarDividerColor?.toHex(),
|
||||
"secondaryToolbarColor": secondaryToolbarColor?.toHex(),
|
||||
"enableUrlBarHiding": enableUrlBarHiding,
|
||||
"instantAppsEnabled": instantAppsEnabled,
|
||||
"packageName": packageName,
|
||||
"keepAliveEnabled": keepAliveEnabled,
|
||||
"isSingleInstance": isSingleInstance,
|
||||
"noHistory": noHistory,
|
||||
"isTrustedWebActivity": isTrustedWebActivity,
|
||||
"additionalTrustedOrigins": additionalTrustedOrigins,
|
||||
"displayMode": displayMode?.toMap(),
|
||||
"screenOrientation": screenOrientation?.toNativeValue(),
|
||||
"startAnimations": startAnimations?.map((e) => e.toMap()).toList(),
|
||||
"exitAnimations": exitAnimations?.map((e) => e.toMap()).toList(),
|
||||
"entersReaderIfAvailable": entersReaderIfAvailable,
|
||||
"barCollapsingEnabled": barCollapsingEnabled,
|
||||
"dismissButtonStyle": dismissButtonStyle?.toNativeValue(),
|
||||
"preferredBarTintColor": preferredBarTintColor?.toHex(),
|
||||
"preferredControlTintColor": preferredControlTintColor?.toHex(),
|
||||
"presentationStyle": presentationStyle?.toNativeValue(),
|
||||
"transitionStyle": transitionStyle?.toNativeValue(),
|
||||
};
|
||||
}
|
||||
|
||||
///Converts instance to a map.
|
||||
Map<String, dynamic> toJson() {
|
||||
return toMap();
|
||||
}
|
||||
|
||||
///Returns a copy of ChromeSafariBrowserSettings.
|
||||
ChromeSafariBrowserSettings copy() {
|
||||
return ChromeSafariBrowserSettings.fromMap(toMap()) ??
|
||||
ChromeSafariBrowserSettings();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChromeSafariBrowserSettings{shareState: $shareState, showTitle: $showTitle, toolbarBackgroundColor: $toolbarBackgroundColor, navigationBarColor: $navigationBarColor, navigationBarDividerColor: $navigationBarDividerColor, secondaryToolbarColor: $secondaryToolbarColor, enableUrlBarHiding: $enableUrlBarHiding, instantAppsEnabled: $instantAppsEnabled, packageName: $packageName, keepAliveEnabled: $keepAliveEnabled, isSingleInstance: $isSingleInstance, noHistory: $noHistory, isTrustedWebActivity: $isTrustedWebActivity, additionalTrustedOrigins: $additionalTrustedOrigins, displayMode: $displayMode, screenOrientation: $screenOrientation, startAnimations: $startAnimations, exitAnimations: $exitAnimations, entersReaderIfAvailable: $entersReaderIfAvailable, barCollapsingEnabled: $barCollapsingEnabled, dismissButtonStyle: $dismissButtonStyle, preferredBarTintColor: $preferredBarTintColor, preferredControlTintColor: $preferredControlTintColor, presentationStyle: $presentationStyle, transitionStyle: $transitionStyle}';
|
||||
}
|
||||
}
|
|
@ -1,4 +1,8 @@
|
|||
export 'chrome_safari_browser.dart';
|
||||
export 'chrome_safari_browser_settings.dart';
|
||||
export 'chrome_safari_browser_settings.dart'
|
||||
show
|
||||
ChromeSafariBrowserOptions,
|
||||
ChromeSafariBrowserSettings,
|
||||
ChromeSafariBrowserClassOptions;
|
||||
export 'android/main.dart';
|
||||
export 'apple/main.dart';
|
||||
|
|
|
@ -3683,6 +3683,24 @@ class InAppWebViewController {
|
|||
'setWebContentsDebuggingEnabled', args);
|
||||
}
|
||||
|
||||
///Gets the WebView variations encoded to be used as the X-Client-Data HTTP header.
|
||||
///
|
||||
///The app is responsible for adding the X-Client-Data header to any request
|
||||
///that may use variations metadata, such as requests to Google web properties.
|
||||
///The returned string will be a base64 encoded ClientVariations proto:
|
||||
///https://source.chromium.org/chromium/chromium/src/+/main:components/variations/proto/client_variations.proto
|
||||
///
|
||||
///The string may be empty if the header is not available.
|
||||
///
|
||||
///**NOTE for Android native WebView**: This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.GET_VARIATIONS_HEADER].
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView ([Official API - WebViewCompat.getVariationsHeader](https://developer.android.com/reference/androidx/webkit/WebViewCompat#getVariationsHeader()))
|
||||
static Future<String?> getVariationsHeader() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
return await _staticChannel.invokeMethod('getVariationsHeader', args);
|
||||
}
|
||||
|
||||
///Returns a Boolean value that indicates whether WebKit natively supports resources with the specified URL scheme.
|
||||
///
|
||||
///[urlScheme] represents the URL scheme associated with the resource.
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
|
||||
|
||||
part 'android_resource.g.dart';
|
||||
|
||||
///Class that represents an android resource.
|
||||
@ExchangeableObject()
|
||||
class AndroidResource_ {
|
||||
///Android resource name.
|
||||
///
|
||||
///A list of available `android.R.anim` can be found
|
||||
///[here](https://developer.android.com/reference/android/R.anim).
|
||||
///
|
||||
///A list of available `androidx.appcompat.R.anim` can be found
|
||||
///[here](https://android.googlesource.com/platform/frameworks/support/+/HEAD/appcompat/appcompat/src/main/res/anim/)
|
||||
///(abc_*.xml files).
|
||||
///In this case, [defPackage] must match your App Android package name.
|
||||
String name;
|
||||
|
||||
///Optional default resource type to find, if "type/" is not included in the name.
|
||||
///Can be `null` to require an explicit type.
|
||||
///
|
||||
///Example: "anim"
|
||||
String? defType;
|
||||
|
||||
///Optional default package to find, if "package:" is not included in the name.
|
||||
///Can be `null` to require an explicit package.
|
||||
///
|
||||
///Example: "android" if you want use resources from `android.R.`
|
||||
String? defPackage;
|
||||
|
||||
AndroidResource_({required this.name,
|
||||
this.defType, this.defPackage});
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'android_resource.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// ExchangeableObjectGenerator
|
||||
// **************************************************************************
|
||||
|
||||
///Class that represents an android resource.
|
||||
class AndroidResource {
|
||||
///Android resource name.
|
||||
///
|
||||
///A list of available `android.R.anim` can be found
|
||||
///[here](https://developer.android.com/reference/android/R.anim).
|
||||
///
|
||||
///A list of available `androidx.appcompat.R.anim` can be found
|
||||
///[here](https://android.googlesource.com/platform/frameworks/support/+/HEAD/appcompat/appcompat/src/main/res/anim/)
|
||||
///(abc_*.xml files).
|
||||
///In this case, [defPackage] must match your App Android package name.
|
||||
String name;
|
||||
|
||||
///Optional default resource type to find, if "type/" is not included in the name.
|
||||
///Can be `null` to require an explicit type.
|
||||
///
|
||||
///Example: "anim"
|
||||
String? defType;
|
||||
|
||||
///Optional default package to find, if "package:" is not included in the name.
|
||||
///Can be `null` to require an explicit package.
|
||||
///
|
||||
///Example: "android" if you want use resources from `android.R.`
|
||||
String? defPackage;
|
||||
AndroidResource({required this.name, this.defType, this.defPackage});
|
||||
|
||||
///Gets a possible [AndroidResource] instance from a [Map] value.
|
||||
static AndroidResource? fromMap(Map<String, dynamic>? map) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
final instance = AndroidResource(
|
||||
name: map['name'],
|
||||
defType: map['defType'],
|
||||
defPackage: map['defPackage'],
|
||||
);
|
||||
return instance;
|
||||
}
|
||||
|
||||
///Converts instance to a map.
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
"name": name,
|
||||
"defType": defType,
|
||||
"defPackage": defPackage,
|
||||
};
|
||||
}
|
||||
|
||||
///Converts instance to a map.
|
||||
Map<String, dynamic> toJson() {
|
||||
return toMap();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AndroidResource{name: $name, defType: $defType, defPackage: $defPackage}';
|
||||
}
|
||||
}
|
|
@ -217,4 +217,5 @@ export 'window_style_mask.dart' show WindowStyleMask;
|
|||
export 'window_titlebar_separator_style.dart' show WindowTitlebarSeparatorStyle;
|
||||
export 'custom_tabs_navigation_event_type.dart' show CustomTabsNavigationEventType;
|
||||
export 'custom_tabs_relation_type.dart' show CustomTabsRelationType;
|
||||
export 'prewarming_token.dart' show PrewarmingToken;
|
||||
export 'prewarming_token.dart' show PrewarmingToken;
|
||||
export 'android_resource.dart' show AndroidResource;
|
|
@ -34,13 +34,17 @@ dart $PROJECT_DIR/tool/env.dart
|
|||
cd $PROJECT_DIR/test_node_server
|
||||
node index.js &
|
||||
|
||||
# Only for Android
|
||||
# Open Chrome on the development device, navigate to chrome://flags, search for an item called Enable command line on non-rooted devices and change it to ENABLED and then restart the browser.
|
||||
adb shell "echo '_ --disable-digital-asset-link-verification-for-url=\"https://flutter.dev\"' > /data/local/tmp/chrome-command-line" || true
|
||||
|
||||
flutter --version
|
||||
flutter clean
|
||||
flutter pub get
|
||||
cd $PROJECT_DIR/example
|
||||
flutter clean
|
||||
if [ ! -z "$2" ] && [ $PLATFORM = "web" ]; then
|
||||
flutter driver --driver=test_driver/integration_test.dart --target=integration_test/webview_flutter_test.dart --device-id=chrome
|
||||
flutter driver --driver=test_driver/integration_test.dart --target=integration_test/webview_flutter_test.dart --device-id=chrome
|
||||
else
|
||||
flutter driver --driver=test_driver/integration_test.dart --target=integration_test/webview_flutter_test.dart
|
||||
fi
|
||||
|
|
|
@ -153,6 +153,19 @@ app.get("/", (req, res) => {
|
|||
res.end()
|
||||
})
|
||||
|
||||
app.get("/echo-headers", (req, res) => {
|
||||
res.send(`
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<pre style="word-wrap: break-word; white-space: pre-wrap;">${JSON.stringify(req.headers)}</pre>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
res.end()
|
||||
})
|
||||
|
||||
app.get('/test-index', (req, res) => {
|
||||
res.sendFile(__dirname + '/public/index.html');
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue