Merge branch 'feature/exchangeable-annotations' into develop

This commit is contained in:
Lorenzo Pichilli 2022-10-06 16:44:44 +02:00
commit 9f38a112f4
419 changed files with 27326 additions and 9766 deletions

View File

@ -16,8 +16,10 @@
### BREAKING CHANGES
- On Android, the `InAppWebView` widget uses hybrid composition by default (`useHybridComposition: true`).
- All properties of `GeolocationPermissionShowPromptResponse` cannot be `null`;
- On Android, the `InAppWebView` widget uses hybrid composition by default (`useHybridComposition: true`)
- All properties of `GeolocationPermissionShowPromptResponse` cannot be `null`
- Removed `URLProtectionSpace.iosIsProxy` property
- `historyUrl` and `baseUrl` of `InAppWebViewInitialData` can be `null`
## 5.4.4+3
@ -92,7 +94,7 @@
## 5.4.1
- Managed iOS native `detachFromEngine` flutter plugin event and updated `dispose` methods
- Managed iOS native `detachFromEngine` flutter plugin event and updated `dispose` methods
- Updated Android native `HeadlessInAppWebViewManager.dispose` and `HeadlessInAppWebView.dispose` methods
## 5.4.0+3
@ -347,7 +349,7 @@
- Renamed `toolbarTop` InAppBrowser cross-platform option to `hideToolbarTop`
- Renamed `toolbarBottom` InAppBrowser ios-specific option to `hideToolbarBottom`
- Removed `debuggingEnabled` WebView option; on Android you should use now the `AndroidInAppWebViewController.setWebContentsDebuggingEnabled(bool debuggingEnabled)` static method; on iOS, debugging is always enabled
- Removed `androidOnRequestFocus` event because it is never called
- Removed `androidOnRequestFocus` event because it is never called
- Removed `initialHeaders` WebView attribute. Use `URLRequest.headers` attribute
- Removed `headers` argument from `loadFile` WebView method
- Removed `headers` argument from `openFile` InAppBrowser method
@ -363,11 +365,11 @@
- Changed return type of `getOriginalUrl` Android-specific WebView method to `Uri`
- Changed return type of `getSafeBrowsingPrivacyPolicyUrl` Android-specific WebView method to `Uri`
- Changed type of `url` argument of `onLoadStart`, `onLoadStop`, `onLoadError`, `onLoadHttpError`, `onLoadResourceCustomScheme`, `onUpdateVisitedHistory`, `onPrint`, `onPageCommitVisible`, `androidOnSafeBrowsingHit`, `androidOnRenderProcessUnresponsive`, `androidOnRenderProcessResponsive`, `androidOnFormResubmission`, `androidOnReceivedTouchIconUrl` WebView events to `Uri`
- Changed type of `baseUrl` and `androidHistoryUrl` arguments of `loadData` WebView method and `openData` InAppBrowser method
- Changed type of `baseUrl` and `androidHistoryUrl` arguments of `loadData` WebView method and `openData` InAppBrowser method
- Changed `openUrl` InAppBrowser method to `openUrlRequest`
- Changed type of `url` argument of `openWithSystemBrowser` InAppBrowser method to `Uri`
- Changed all InAppBrowser color options type from `String` to `Color`
- Changed all ChromeSafariBrowser color options type from `String` to `Color`
- Changed all InAppBrowser color options type from `String` to `Color`
- Changed all ChromeSafariBrowser color options type from `String` to `Color`
- Updated attributes of `ShouldOverrideUrlLoadingRequest`, `ServerTrustChallenge` and `ClientCertChallenge` classes
- Changed type of `url` attribute to `Uri` for `JsAlertRequest`, `JsAlertConfirm`, `JsPromptRequest` classes

View File

@ -1,4 +1,11 @@
include: package:flutter_lints/flutter.yaml
include: package:lints/recommended.yaml
linter:
rules:
constant_identifier_names: ignore
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
analyzer:
errors:
deprecated_member_use_from_same_package: ignore

View File

@ -197,7 +197,7 @@ public class InterceptAjaxRequestJS {
" };" +
" window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + ".callHandler('shouldInterceptAjaxRequest', ajaxRequest).then(function(result) {" +
" if (result != null) {" +
" switch (result.action) {" +
" switch (result) {" +
" case 0:" +
" self.abort();" +
" return;" +

View File

@ -10,12 +10,12 @@ import java.util.HashMap;
import java.util.Map;
public class WebResourceErrorExt {
private int errorCode;
private int type;
@NonNull
private String description;
public WebResourceErrorExt(int errorCode, @NonNull String description) {
this.errorCode = errorCode;
public WebResourceErrorExt(int type, @NonNull String description) {
this.type = type;
this.description = description;
}
@ -26,17 +26,17 @@ public class WebResourceErrorExt {
public Map<String, Object> toMap() {
Map<String, Object> webResourceErrorMap = new HashMap<>();
webResourceErrorMap.put("errorCode", getErrorCode());
webResourceErrorMap.put("type", getType());
webResourceErrorMap.put("description", getDescription());
return webResourceErrorMap;
}
public int getErrorCode() {
return errorCode;
public int getType() {
return type;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
public void setType(int type) {
this.type = type;
}
@NonNull
@ -55,13 +55,13 @@ public class WebResourceErrorExt {
WebResourceErrorExt that = (WebResourceErrorExt) o;
if (errorCode != that.errorCode) return false;
if (type != that.type) return false;
return description.equals(that.description);
}
@Override
public int hashCode() {
int result = errorCode;
int result = type;
result = 31 * result + description.hashCode();
return result;
}
@ -69,7 +69,7 @@ public class WebResourceErrorExt {
@Override
public String toString() {
return "WebResourceErrorExt{" +
"errorCode=" + errorCode +
"type=" + type +
", description='" + description + '\'' +
'}';
}

View File

@ -925,8 +925,7 @@ public class WebViewChannelDelegate extends ChannelDelegateImpl {
@Nullable
@Override
public NavigationActionPolicy decodeResult(@Nullable Object obj) {
Integer action = Util.<Integer>getOrDefault((Map<String, Object>) obj,
"action", NavigationActionPolicy.CANCEL.rawValue());
Integer action = obj instanceof Integer ? (Integer) obj : NavigationActionPolicy.CANCEL.rawValue();
return NavigationActionPolicy.fromValue(action);
}
}
@ -1067,7 +1066,7 @@ public class WebViewChannelDelegate extends ChannelDelegateImpl {
@Nullable
@Override
public Integer decodeResult(@Nullable Object obj) {
return obj != null ? (Integer) ((Map<String, Object>) obj).get("action") : null;
return obj instanceof Integer ? (Integer) obj : null;
}
}
@ -1183,7 +1182,7 @@ public class WebViewChannelDelegate extends ChannelDelegateImpl {
@Nullable
@Override
public Integer decodeResult(@Nullable Object obj) {
return obj != null ? (Integer) ((Map<String, Object>) obj).get("action") : null;
return obj instanceof Integer ? (Integer) obj : null;
}
}
@ -1202,7 +1201,7 @@ public class WebViewChannelDelegate extends ChannelDelegateImpl {
@Nullable
@Override
public Integer decodeResult(@Nullable Object obj) {
return obj != null ? (Integer) ((Map<String, Object>) obj).get("action") : null;
return obj instanceof Integer ? (Integer) obj : null;
}
}

View File

@ -1201,7 +1201,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
HashMap<String, Object> result = new HashMap<>();
result.put("history", history);
result.put("list", history);
result.put("currentIndex", currentIndex);
return result;

View File

@ -0,0 +1,10 @@
library flutter_inappwebview_internal_annotations;
export 'src/exchangeable_object.dart';
export 'src/exchangeable_object_constructor.dart';
export 'src/exchangeable_object_property.dart';
export 'src/exchangeable_object_method.dart';
export 'src/exchangeable_enum.dart';
export 'src/exchangeable_enum_custom_value.dart';
export 'src/supported_platforms.dart';
export 'src/enum_supported_platforms.dart';

View File

@ -0,0 +1,115 @@
import 'supported_platforms.dart';
abstract class EnumPlatform implements Platform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
final dynamic value;
const EnumPlatform(
{this.available, this.apiName, this.apiUrl, this.note, this.value});
final name = "";
final targetPlatformName = "";
}
class EnumAndroidPlatform implements EnumPlatform, AndroidPlatform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
final dynamic value;
const EnumAndroidPlatform(
{this.available, this.apiName, this.apiUrl, this.note, this.value});
final name = "Android native WebView";
final targetPlatformName = "android";
}
class EnumIOSPlatform implements EnumPlatform, IOSPlatform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
final dynamic value;
const EnumIOSPlatform(
{this.available, this.apiName, this.apiUrl, this.note, this.value});
final name = "iOS";
final targetPlatformName = "iOS";
}
class EnumMacOSPlatform implements EnumPlatform, MacOSPlatform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
final dynamic value;
const EnumMacOSPlatform(
{this.available, this.apiName, this.apiUrl, this.note, this.value});
final name = "MacOS";
final targetPlatformName = "macOS";
}
class EnumWindowsPlatform implements EnumPlatform, WindowsPlatform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
final dynamic value;
const EnumWindowsPlatform(
{this.available, this.apiName, this.apiUrl, this.note, this.value});
final name = "Windows";
final targetPlatformName = "windows";
}
class EnumLinuxPlatform implements EnumPlatform, LinuxPlatform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
final dynamic value;
const EnumLinuxPlatform(
{this.available, this.apiName, this.apiUrl, this.note, this.value});
final name = "Linux";
final targetPlatformName = "linux";
}
class EnumWebPlatform implements EnumPlatform, WebPlatform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
final dynamic value;
final bool requiresSameOrigin;
const EnumWebPlatform(
{this.available,
this.apiName,
this.apiUrl,
this.note,
this.value,
this.requiresSameOrigin = true});
final name = "Web";
final targetPlatformName = "web";
}
class EnumSupportedPlatforms {
final List<EnumPlatform> platforms;
final dynamic defaultValue;
const EnumSupportedPlatforms({
required this.platforms,
this.defaultValue,
});
}

View File

@ -0,0 +1,23 @@
class ExchangeableEnum {
final bool valuesProperty;
final bool toValueMethod;
final bool fromValueMethod;
final bool toNativeValueMethod;
final bool fromNativeValueMethod;
final bool toStringMethod;
final bool hashCodeMethod;
final bool equalsOperator;
final bool bitwiseOrOperator;
const ExchangeableEnum({
this.valuesProperty = true,
this.toValueMethod = true,
this.fromValueMethod = true,
this.toNativeValueMethod = true,
this.fromNativeValueMethod = true,
this.toStringMethod = true,
this.hashCodeMethod = true,
this.equalsOperator = true,
this.bitwiseOrOperator = false
});
}

View File

@ -0,0 +1,3 @@
class ExchangeableEnumCustomValue {
const ExchangeableEnumCustomValue();
}

View File

@ -0,0 +1,15 @@
class ExchangeableObject {
final bool toMapMethod;
final bool toJsonMethod;
final bool fromMapFactory;
final bool nullableFromMapFactory;
final bool toStringMethod;
const ExchangeableObject({
this.toMapMethod = true,
this.toJsonMethod = true,
this.fromMapFactory = true,
this.nullableFromMapFactory = true,
this.toStringMethod = true,
});
}

View File

@ -0,0 +1,3 @@
class ExchangeableObjectConstructor {
const ExchangeableObjectConstructor();
}

View File

@ -0,0 +1,9 @@
class ExchangeableObjectMethod {
final bool ignore;
final bool toMapMergeWith;
const ExchangeableObjectMethod({
this.ignore = false,
this.toMapMergeWith = false
});
}

View File

@ -0,0 +1,9 @@
class ExchangeableObjectProperty {
final Function? serializer;
final Function? deserializer;
const ExchangeableObjectProperty({
this.serializer,
this.deserializer
});
}

View File

@ -0,0 +1,95 @@
abstract class Platform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
const Platform({this.available, this.apiName, this.apiUrl, this.note});
final name = "";
final targetPlatformName = "";
}
class AndroidPlatform implements Platform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
const AndroidPlatform({this.available, this.apiName, this.apiUrl, this.note});
final name = "Android native WebView";
final targetPlatformName = "android";
}
class IOSPlatform implements Platform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
const IOSPlatform({this.available, this.apiName, this.apiUrl, this.note});
final name = "iOS";
final targetPlatformName = "iOS";
}
class MacOSPlatform implements Platform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
const MacOSPlatform({this.available, this.apiName, this.apiUrl, this.note});
final name = "MacOS";
final targetPlatformName = "macOS";
}
class WindowsPlatform implements Platform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
const WindowsPlatform({this.available, this.apiName, this.apiUrl, this.note});
final name = "Windows";
final targetPlatformName = "windows";
}
class LinuxPlatform implements Platform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
const LinuxPlatform({this.available, this.apiName, this.apiUrl, this.note});
final name = "Linux";
final targetPlatformName = "linux";
}
class WebPlatform implements Platform {
final String? available;
final String? apiName;
final String? apiUrl;
final String? note;
final bool requiresSameOrigin;
const WebPlatform(
{this.available,
this.apiName,
this.apiUrl,
this.note,
this.requiresSameOrigin = true});
final name = "Web";
final targetPlatformName = "web";
}
class SupportedPlatforms {
final List<Platform> platforms;
const SupportedPlatforms({required this.platforms});
}

View File

@ -0,0 +1,320 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "49.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.1"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.9.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
coverage:
dependency: transitive
description:
name: coverage
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.4"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.1"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.4"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.12"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
node_preamble:
dependency: transitive
description:
name: node_preamble
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.0"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
shelf_packages_handler:
dependency: transitive
description:
name: shelf_packages_handler
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
shelf_static:
dependency: transitive
description:
name: shelf_static
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
source_map_stack_trace:
dependency: transitive
description:
name: source_map_stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
source_maps:
dependency: transitive
description:
name: source_maps
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.10"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
test:
dependency: "direct dev"
description:
name: test
url: "https://pub.dartlang.org"
source: hosted
version: "1.21.6"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.14"
test_core:
dependency: transitive
description:
name: test_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.18"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vm_service:
dependency: transitive
description:
name: vm_service
url: "https://pub.dartlang.org"
source: hosted
version: "9.4.0"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
webkit_inspection_protocol:
dependency: transitive
description:
name: webkit_inspection_protocol
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
sdks:
dart: ">=2.18.0 <3.0.0"

View File

@ -0,0 +1,10 @@
name: flutter_inappwebview_internal_annotations
description: A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
version: 1.0.0
homepage: https://github.com/pichillilorenzo/flutter_inappwebview
environment:
sdk: ">=2.14.0 <3.0.0"
dev_dependencies:
test: ^1.21.6

View File

@ -0,0 +1,21 @@
targets:
$default:
builders:
generators|flutter_inappwebview_internal_annotations:
enabled: true
builders:
generators:
target: ":generators"
# 1
import: "package:generators/builder.dart"
# 2
builder_factories: ["generateExchangeableObject", "generateExchangeableEnum"]
# 3
build_extensions: { ".dart": [".g.dart"] }
auto_apply: dependents
build_to: cache
applies_builders: ["source_gen|combining_builder"]
defaults:
generate_for:
- lib/src/**.dart

View File

@ -0,0 +1,10 @@
import 'package:build/build.dart';
import 'package:source_gen/source_gen.dart';
import 'src/exchangeable_object_generator.dart';
import 'src/exchangeable_enum_generator.dart';
Builder generateExchangeableObject(BuilderOptions options) =>
SharedPartBuilder([ExchangeableObjectGenerator()], 'exchangeable_object');
Builder generateExchangeableEnum(BuilderOptions options) =>
SharedPartBuilder([ExchangeableEnumGenerator()], 'exchangeable_enum');

View File

@ -0,0 +1 @@
library generators;

View File

@ -0,0 +1,317 @@
import 'package:build/src/builder/build_step.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:source_gen/source_gen.dart';
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'model_visitor.dart';
import 'util.dart';
final _coreCheckerEnumSupportedPlatforms =
const TypeChecker.fromRuntime(EnumSupportedPlatforms);
final _coreCheckerDeprecated = const TypeChecker.fromRuntime(Deprecated);
final _coreCheckerEnumCustomValue =
const TypeChecker.fromRuntime(ExchangeableEnumCustomValue);
class ExchangeableEnumGenerator
extends GeneratorForAnnotation<ExchangeableEnum> {
@override
String generateForAnnotatedElement(
Element element, ConstantReader annotation, BuildStep buildStep) {
final visitor = ModelVisitor();
// Visits all the children of element in no particular order.
element.visitChildren(visitor);
final className = visitor.constructor.returnType.element2.name;
// remove "_" to generate the correct class name
final extClassName = className.replaceFirst("_", "");
final classBuffer = StringBuffer();
final classDocs =
visitor.constructor.returnType.element2.documentationComment;
if (classDocs != null) {
classBuffer.writeln(classDocs);
}
final classSupportedDocs = Util.getSupportedDocs(
_coreCheckerEnumSupportedPlatforms,
visitor.constructor.returnType.element2);
if (classSupportedDocs != null) {
classBuffer.writeln(classSupportedDocs);
}
if (visitor.constructor.returnType.element2.hasDeprecated) {
classBuffer.writeln(
"@Deprecated('${_coreCheckerDeprecated.firstAnnotationOfExact(visitor.constructor.returnType.element2)?.getField("message")?.toStringValue()}')");
}
classBuffer.writeln('class $extClassName {');
final FieldElement enumValue = visitor.fields.entries
.firstWhere((element) => element.key == "_value")
.value;
final FieldElement enumNativeValue = visitor.fields.entries
.firstWhere((element) => element.key == "_nativeValue",
orElse: () => MapEntry("_nativeValue", enumValue))
.value;
classBuffer.writeln("final ${enumValue.type} _value;");
classBuffer.writeln("final ${enumNativeValue.type} _nativeValue;");
classBuffer.writeln(
"const $extClassName._internal(this._value, this._nativeValue);");
classBuffer.writeln("// ignore: unused_element");
classBuffer.writeln(
"factory $extClassName._internalMultiPlatform(${enumValue.type} value, Function nativeValue) => $extClassName._internal(value, nativeValue());");
for (final entry in visitor.fields.entries) {
final fieldName = entry.key;
final fieldElement = entry.value;
if (fieldName == "_value" || fieldName == "_nativeValue") {
continue;
}
final isEnumCustomValue = _coreCheckerEnumCustomValue
.firstAnnotationOf(fieldElement) != null;
if (isEnumCustomValue) {
ParsedLibraryResult parsed = fieldElement.session
?.getParsedLibraryByElement(fieldElement.library)
as ParsedLibraryResult;
final fieldBody = parsed
.getElementDeclaration(fieldElement)
?.node
.toString()
.replaceAll(className, extClassName);
if (fieldBody != null) {
final docs = fieldElement.documentationComment;
if (docs != null) {
classBuffer.writeln(docs);
}
if (fieldElement.isStatic) {
classBuffer.write("static ");
}
if (fieldElement.isLate) {
classBuffer.write("late ");
}
if (fieldElement.isFinal) {
classBuffer.write("final ");
}
if (fieldElement.isConst) {
classBuffer.write("const ");
}
classBuffer.writeln("$fieldBody;");
}
continue;
}
final docs = fieldElement.documentationComment;
if (docs != null) {
classBuffer.writeln(docs);
}
final fieldSupportedDocs = Util.getSupportedDocs(
_coreCheckerEnumSupportedPlatforms, fieldElement);
if (fieldSupportedDocs != null) {
classBuffer.writeln(fieldSupportedDocs);
}
if (fieldName == '_value' || fieldName == '_nativeValue') {
classBuffer.writeln(
"final ${fieldElement.type.toString().replaceFirst("_", "")} $fieldName;");
} else {
final fieldValue =
fieldElement.computeConstantValue()?.getField("_value");
final constantValue = fieldValue != null && !fieldValue.isNull
? fieldValue.toIntValue() ?? "\'${fieldValue.toStringValue()}\'"
: null;
final fieldAnnotation = _coreCheckerEnumSupportedPlatforms
.firstAnnotationOfExact(fieldElement);
if (fieldAnnotation != null) {
final defaultField = fieldAnnotation.getField('defaultValue')!;
final defaultValue = !defaultField.isNull
? defaultField.toIntValue() ?? "'${defaultField.toStringValue()}'"
: null;
var nativeValueBody = "() {";
nativeValueBody += "switch (defaultTargetPlatform) {";
final platforms =
fieldAnnotation.getField('platforms')?.toListValue() ??
<DartObject>[];
var hasWebSupport = false;
var webSupportValue = null;
if (platforms.isNotEmpty) {
for (var platform in platforms) {
final targetPlatformName =
platform.getField("targetPlatformName")!.toStringValue();
final platformValueField = platform.getField('value');
final platformValue =
platformValueField != null && !platformValueField.isNull
? platformValueField.toIntValue() ??
"'${platformValueField.toStringValue()}'"
: null;
if (targetPlatformName == "web") {
hasWebSupport = true;
webSupportValue = platformValue;
continue;
}
nativeValueBody += "case TargetPlatform.$targetPlatformName:";
nativeValueBody += "return $platformValue;";
}
nativeValueBody += "default:";
nativeValueBody += "break;";
}
nativeValueBody += "}";
if (hasWebSupport) {
nativeValueBody += "if (kIsWeb) {";
nativeValueBody += "return $webSupportValue;";
nativeValueBody += "}";
}
nativeValueBody += "return $defaultValue;";
nativeValueBody += "}";
classBuffer.writeln(
"static final $fieldName = $extClassName._internalMultiPlatform($constantValue, $nativeValueBody);");
} else {
classBuffer.writeln(
"static const $fieldName = $extClassName._internal($constantValue, $constantValue);");
}
}
}
if (annotation.read("valuesProperty").boolValue) {
classBuffer.writeln('///Set of all values of [$extClassName].');
classBuffer.writeln('static final Set<$extClassName> values = [');
for (final entry in visitor.fields.entries) {
final fieldName = entry.key;
final fieldElement = entry.value;
final isEnumCustomValue = _coreCheckerEnumCustomValue
.firstAnnotationOf(fieldElement) != null;
if (!fieldElement.isPrivate && fieldElement.isStatic && !isEnumCustomValue) {
classBuffer.writeln('$extClassName.$fieldName,');
}
}
classBuffer.writeln('].toSet();');
}
if (annotation.read("fromValueMethod").boolValue && (!visitor.methods.containsKey("fromValue") ||
Util.methodHasIgnore(visitor.methods['fromNativeValue']!))) {
final hasBitwiseOrOperator =
annotation.read("bitwiseOrOperator").boolValue;
classBuffer.writeln("""
///Gets a possible [$extClassName] instance from [${enumValue.type}] value.
static $extClassName? fromValue(${enumValue.type}${!Util.typeIsNullable(enumValue.type) ? '?' : ''} value) {
if (value != null) {
try {
return $extClassName.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return ${!hasBitwiseOrOperator ? 'null' : "$extClassName._internal(value, value)"};
}
}
return null;
}
""");
}
if (annotation.read("fromNativeValueMethod").boolValue && (!visitor.methods.containsKey("fromNativeValue") ||
Util.methodHasIgnore(visitor.methods['fromNativeValue']!))) {
final hasBitwiseOrOperator =
annotation.read("bitwiseOrOperator").boolValue;
classBuffer.writeln("""
///Gets a possible [$extClassName] instance from a native value.
static $extClassName? fromNativeValue(${enumNativeValue.type}${!Util.typeIsNullable(enumNativeValue.type) ? '?' : ''} value) {
if (value != null) {
try {
return $extClassName.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return ${!hasBitwiseOrOperator ? 'null' : "$extClassName._internal(value, value)"};
}
}
return null;
}
""");
}
for (final entry in visitor.methods.entries) {
final methodElement = entry.value;
if (Util.methodHasIgnore(methodElement)) {
continue;
}
ParsedLibraryResult parsed = methodElement.session?.getParsedLibraryByElement(methodElement.library) as ParsedLibraryResult;
final methodBody = parsed.getElementDeclaration(methodElement)?.node
.toString()
.replaceAll(className, extClassName);
if (methodBody != null) {
final docs = methodElement.documentationComment;
if (docs != null) {
classBuffer.writeln(docs);
}
final fieldSupportedDocs =
Util.getSupportedDocs(_coreCheckerEnumSupportedPlatforms, methodElement);
if (fieldSupportedDocs != null) {
classBuffer.writeln(fieldSupportedDocs);
}
classBuffer.writeln(methodBody);
}
}
if (annotation.read("toValueMethod").boolValue && (!visitor.methods.containsKey("toValue") ||
Util.methodHasIgnore(visitor.methods['toValue']!))) {
classBuffer.writeln("""
///Gets [${enumValue.type}] value.
${enumValue.type} toValue() => _value;
""");
}
if (annotation.read("toNativeValueMethod").boolValue && (!visitor.methods.containsKey("toNativeValue") ||
Util.methodHasIgnore(visitor.methods['toNativeValue']!))) {
classBuffer.writeln("""
///Gets [${enumNativeValue.type}] native value.
${enumNativeValue.type} toNativeValue() => _nativeValue;
""");
}
if (annotation.read("hashCodeMethod").boolValue && (!visitor.fields.containsKey("hashCode") ||
Util.methodHasIgnore(visitor.methods['hashCode']!))) {
classBuffer.writeln("""
@override
int get hashCode => _value.hashCode;
""");
}
if (annotation.read("equalsOperator").boolValue) {
classBuffer.writeln("""
@override
bool operator ==(value) => value == _value;
""");
}
if (annotation.read("bitwiseOrOperator").boolValue) {
classBuffer.writeln(
"$extClassName operator |($extClassName value) => $extClassName._internal(value.toValue() | _value, value.toNativeValue() | _nativeValue);");
}
if (annotation.read("toStringMethod").boolValue && (!visitor.methods.containsKey("toString") ||
Util.methodHasIgnore(visitor.methods['toString']!))) {
classBuffer.writeln('@override');
classBuffer.writeln('String toString() {');
if (enumValue.type.isDartCoreString) {
classBuffer.writeln('return _value;');
} else {
classBuffer.writeln('switch(_value) {');
for (final entry in visitor.fields.entries) {
final fieldName = entry.key;
final fieldElement = entry.value;
if (!fieldElement.isPrivate && fieldElement.isStatic) {
final fieldValue =
fieldElement.computeConstantValue()?.getField("_value");
final constantValue = fieldValue?.toIntValue();
classBuffer.writeln("case $constantValue: return '$fieldName';");
}
}
classBuffer.writeln('}');
classBuffer.writeln('return _value.toString();');
}
classBuffer.writeln('}');
}
classBuffer.writeln('}');
return classBuffer.toString();
}
}

View File

@ -0,0 +1,771 @@
import 'package:build/src/builder/build_step.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:source_gen/source_gen.dart';
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'model_visitor.dart';
import 'util.dart';
final _coreChecker = const TypeChecker.fromRuntime(ExchangeableObject);
final _coreCheckerObjectConstructor =
const TypeChecker.fromRuntime(ExchangeableObjectConstructor);
final _coreCheckerObjectProperty =
const TypeChecker.fromRuntime(ExchangeableObjectProperty);
final _coreCheckerObjectMethod =
const TypeChecker.fromRuntime(ExchangeableObjectMethod);
final _coreCheckerEnum = const TypeChecker.fromRuntime(ExchangeableEnum);
final _coreCheckerDeprecated = const TypeChecker.fromRuntime(Deprecated);
final _coreCheckerSupportedPlatforms =
const TypeChecker.fromRuntime(SupportedPlatforms);
class ExchangeableObjectGenerator
extends GeneratorForAnnotation<ExchangeableObject> {
@override
String generateForAnnotatedElement(
Element element, ConstantReader annotation, BuildStep buildStep) {
final visitor = ModelVisitor();
// Visits all the children of element in no particular order.
element.visitChildren(visitor);
final className = visitor.constructor.returnType.element2.name;
final superClass =
visitor.constructor.returnType.superclass?.element2.name != 'Object'
? visitor.constructor.returnType.superclass
: null;
final interfaces = visitor.constructor.returnType.interfaces;
final superClassName = superClass?.element2.name.replaceFirst("_", "");
// remove "_" to generate the correct class name
final extClassName = className.replaceFirst("_", "");
final classBuffer = StringBuffer();
final classDocs =
visitor.constructor.returnType.element2.documentationComment;
if (classDocs != null) {
classBuffer.writeln(classDocs);
}
final classSupportedDocs = Util.getSupportedDocs(
_coreCheckerSupportedPlatforms, visitor.constructor.returnType.element2);
if (classSupportedDocs != null) {
classBuffer.writeln(classSupportedDocs);
}
if (visitor.constructor.returnType.element2.hasDeprecated) {
classBuffer.writeln(
"@Deprecated('${_coreCheckerDeprecated.firstAnnotationOfExact(visitor.constructor.returnType.element2)?.getField("message")?.toStringValue()}')");
}
classBuffer.write('${(visitor.constructor.enclosingElement3 as ClassElement).isAbstract ? 'abstract ' : ''}class $extClassName');
if (interfaces.isNotEmpty) {
classBuffer.writeln(' implements ${interfaces.map((i) => i.element2.name.replaceFirst("_", "")).join(', ')}');
}
if (superClass != null) {
classBuffer.writeln(' extends ${superClassName}');
}
classBuffer.writeln(' {');
final deprecatedFields = <VariableElement>[];
final constructorFields = <String>[];
final superConstructorFields = <String>[];
for (final entry in visitor.fields.entries) {
final fieldName = entry.key;
final fieldElement = entry.value;
if (!fieldElement.isPrivate) {
final isNullable = Util.typeIsNullable(fieldElement.type);
final constructorParameter = visitor.constructorParameters[fieldName];
if (constructorParameter != null) {
// remove class reference terminating with "_"
var defaultValueCode =
constructorParameter.defaultValueCode?.replaceFirst("_.", ".");
var constructorField =
'${!isNullable && defaultValueCode == null ? 'required ' : ''}this.$fieldName${defaultValueCode != null ? ' = $defaultValueCode' : ''}';
if (fieldElement.hasDeprecated) {
deprecatedFields.add(fieldElement);
constructorField =
"@Deprecated('${_coreCheckerDeprecated.firstAnnotationOfExact(fieldElement)?.getField("message")?.toStringValue()}') " +
constructorField;
}
constructorFields.add(constructorField);
}
}
final docs = fieldElement.documentationComment;
if (docs != null) {
classBuffer.writeln(docs);
}
final fieldSupportedDocs =
Util.getSupportedDocs(_coreCheckerSupportedPlatforms, fieldElement);
if (fieldSupportedDocs != null) {
classBuffer.writeln(fieldSupportedDocs);
}
if (fieldElement.hasDeprecated) {
classBuffer.writeln(
"@Deprecated('${_coreCheckerDeprecated.firstAnnotationOfExact(fieldElement)?.getField("message")?.toStringValue()}')");
}
if (fieldElement.isStatic) {
classBuffer.write("static ");
}
if (fieldElement.isLate) {
classBuffer.write("late ");
}
if (fieldElement.isFinal) {
classBuffer.write("final ");
}
if (fieldElement.isConst) {
classBuffer.write("const ");
}
// remove class reference terminating with "_"
classBuffer
.write("${fieldElement.type.toString().replaceFirst("_", "")} ");
if (!fieldElement.hasInitializer) {
classBuffer.writeln("$fieldName;");
} else {
ParsedLibraryResult parsed = fieldElement.session
?.getParsedLibraryByElement(fieldElement.library)
as ParsedLibraryResult;
final fieldBody = parsed
.getElementDeclaration(fieldElement)
?.node
.toString()
.replaceAll(className, extClassName);
classBuffer.writeln("$fieldBody;");
}
}
if (superClass != null) {
ConstructorElement superConstructor = superClass.constructors.first;
for (final parameter in superConstructor.parameters) {
final parameterName = parameter.name;
final parameterType = parameter.type;
final isNullable = Util.typeIsNullable(parameter.type);
// remove class reference terminating with "_"
var defaultValueCode =
parameter.defaultValueCode?.replaceFirst("_.", ".");
var constructorField =
'${!isNullable && defaultValueCode == null ? 'required ' : ''}${parameterType.toString().replaceFirst("_", "")} $parameterName${defaultValueCode != null ? ' = $defaultValueCode' : ''}';
if (parameter.hasDeprecated) {
deprecatedFields.add(parameter);
constructorField =
"@Deprecated('${_coreCheckerDeprecated.firstAnnotationOfExact(parameter)?.getField("message")?.toStringValue()}') " +
constructorField;
}
constructorFields.add(constructorField);
superConstructorFields.add("$parameterName: $parameterName");
}
}
final hasCustomConstructor =
_coreCheckerObjectConstructor.hasAnnotationOf(visitor.constructor);
final constructorDocs = visitor.constructor.documentationComment;
if (constructorDocs != null) {
classBuffer.writeln(constructorDocs);
}
var constructorSupportedDocs = Util.getSupportedDocs(
_coreCheckerSupportedPlatforms, visitor.constructor);
if (constructorSupportedDocs == null) {
constructorSupportedDocs = Util.getSupportedDocs(
_coreCheckerSupportedPlatforms,
visitor.constructor.returnType.element2);
}
if (constructorSupportedDocs != null) {
classBuffer.writeln(constructorSupportedDocs);
}
if (hasCustomConstructor) {
ParsedLibraryResult parsed = visitor.constructor.session
?.getParsedLibraryByElement(visitor.constructor.library)
as ParsedLibraryResult;
final constructorBody =
parsed.getElementDeclaration(visitor.constructor)?.node;
if (constructorBody != null) {
classBuffer.writeln(constructorBody
.toString()
.replaceAll(className, extClassName)
.replaceAll("_.", ".")
.replaceAll("@ExchangeableObjectConstructor()", ""));
}
} else if (constructorFields.length > 0) {
if (visitor.constructor.isConst) {
classBuffer.write('const ');
}
classBuffer.writeln('$extClassName({');
classBuffer.writeln(constructorFields.join(', '));
} else {
if (visitor.constructor.isConst) {
classBuffer.write('const ');
}
classBuffer.writeln('$extClassName(');
}
if (!hasCustomConstructor && constructorFields.length > 0) {
classBuffer.write('})');
} else if (!hasCustomConstructor) {
classBuffer.write(')');
}
if (superClass != null) {
classBuffer.write(': super(');
if (superConstructorFields.isNotEmpty) {
classBuffer.write('${superConstructorFields.join(", ")}');
}
classBuffer.write(')');
}
if (!hasCustomConstructor && deprecatedFields.length > 0) {
classBuffer.writeln(' {');
for (final deprecatedField in deprecatedFields) {
final deprecatedFieldName = deprecatedField.name;
final message = _coreCheckerDeprecated
.firstAnnotationOfExact(deprecatedField)!
.getField("message")!
.toStringValue()!;
final fieldName = message
.replaceFirst("Use ", "")
.replaceFirst(" instead", "")
.trim();
final fieldElement = visitor.fields[fieldName];
if (fieldElement != null) {
final fieldTypeElement = fieldElement.type.element2;
final deprecatedFieldTypeElement = deprecatedField.type.element2;
final isNullable = Util.typeIsNullable(fieldElement.type);
var hasDefaultValue = (fieldElement is ParameterElement) ? (fieldElement as ParameterElement).hasDefaultValue : false;
if (!isNullable && hasDefaultValue) {
continue;
}
classBuffer.write('$fieldName = $fieldName ?? ');
if (fieldTypeElement != null && deprecatedFieldTypeElement != null) {
final deprecatedIsNullable =
Util.typeIsNullable(deprecatedField.type);
final hasFromMap = hasFromMapMethod(fieldTypeElement);
final hasFromNativeValue =
hasFromNativeValueMethod(fieldTypeElement);
final hasFromValue = hasFromValueMethod(fieldTypeElement);
final deprecatedHasToMap =
hasFromMapMethod(deprecatedFieldTypeElement);
final deprecatedHasToNativeValue =
hasToNativeValueMethod(deprecatedFieldTypeElement);
final deprecatedHasToValue =
hasToValueMethod(deprecatedFieldTypeElement);
if (hasFromMap && deprecatedHasToMap) {
final hasNullableFromMap =
hasNullableFromMapFactory(fieldTypeElement);
classBuffer.write(fieldTypeElement.name!.replaceFirst("_", "") +
".fromMap($deprecatedFieldName${deprecatedIsNullable ? '?' : ''}.toMap())${!isNullable && hasNullableFromMap ? '!' : ''}");
} else if (hasFromNativeValue && deprecatedHasToNativeValue) {
classBuffer.write(fieldTypeElement.name!.replaceFirst("_", "") +
'.fromNativeValue($deprecatedFieldName${deprecatedIsNullable ? '?' : ''}.toNativeValue())${!isNullable ? '!' : ''}');
} else if (hasFromValue && deprecatedHasToValue) {
classBuffer.write(fieldTypeElement.name!.replaceFirst("_", "") +
'.fromValue($deprecatedFieldName${deprecatedIsNullable ? '?' : ''}.toValue())${!isNullable ? '!' : ''}');
} else {
classBuffer.write(deprecatedFieldName);
}
} else {
classBuffer.write(deprecatedFieldName);
}
classBuffer.writeln(';');
}
}
classBuffer.writeln('}');
} else if (!hasCustomConstructor) {
classBuffer.writeln(';');
}
if (annotation.read("fromMapFactory").boolValue && (!visitor.methods.containsKey("fromMap") ||
Util.methodHasIgnore(visitor.methods['fromMap']!))) {
classBuffer.writeln(
'///Gets a possible [$extClassName] instance from a [Map] value.');
final nullable = annotation.read("nullableFromMapFactory").boolValue;
classBuffer
.writeln('static $extClassName${nullable ? '?' : ''} fromMap(');
classBuffer.writeln('Map<String, dynamic>${nullable ? '?' : ''} map');
classBuffer.writeln(') {');
if (nullable) {
classBuffer.writeln('if (map == null) { return null; }');
}
classBuffer.writeln('final instance = $extClassName(');
final fieldElements = <FieldElement>[];
if (superClass != null) {
fieldElements.addAll(superClass.element2.fields);
}
fieldElements.addAll(visitor.fields.values);
final nonRequiredFields = <String>[];
final requiredFields = <String>[];
for (final fieldElement in fieldElements) {
final fieldName = fieldElement.name;
if (!fieldElement.isPrivate &&
!fieldElement.isStatic &&
!fieldElement.type.isDartCoreFunction) {
var value = "map['$fieldName']";
final deprecationMessage = _coreCheckerDeprecated
.firstAnnotationOfExact(fieldElement)
?.getField("message")
?.toStringValue();
if (deprecationMessage != null) {
final newFieldName = deprecationMessage
.replaceFirst("Use ", "")
.replaceFirst(" instead", "")
.trim();
value = "map['$newFieldName']";
}
final customDeserializer = _coreCheckerObjectProperty
.firstAnnotationOf(fieldElement)
?.getField("deserializer")
?.toFunctionValue();
if (customDeserializer != null) {
final deserializerClassName =
customDeserializer.enclosingElement3.name;
if (deserializerClassName != null) {
value =
"$deserializerClassName.${customDeserializer.name}($value)";
} else {
value = "${customDeserializer.name}($value)";
}
} else {
value = getFromMapValue(value, fieldElement.type);
}
final constructorParameter = visitor.constructorParameters[fieldName];
final isRequiredParameter = constructorParameter != null &&
(constructorParameter.isRequiredNamed ||
constructorParameter.isFinal ||
!Util.typeIsNullable(constructorParameter.type)) &&
!constructorParameter.hasDefaultValue;
if (isRequiredParameter) {
requiredFields.add('$fieldName: $value,');
} else {
nonRequiredFields.add("instance.$fieldName = $value;");
}
}
}
classBuffer.writeln(requiredFields.join("\n") + ');');
if (nonRequiredFields.isNotEmpty) {
classBuffer.writeln(nonRequiredFields.join("\n"));
}
classBuffer.writeln('return instance;');
classBuffer.writeln('}');
}
for (final entry in visitor.methods.entries) {
final methodElement = entry.value;
if (Util.methodHasIgnore(methodElement)) {
continue;
}
ParsedLibraryResult parsed = methodElement.session
?.getParsedLibraryByElement(methodElement.library)
as ParsedLibraryResult;
final methodBody = parsed.getElementDeclaration(methodElement)?.node;
if (methodBody != null) {
final docs = methodElement.documentationComment;
if (docs != null) {
classBuffer.writeln(docs);
}
final fieldSupportedDocs = Util.getSupportedDocs(
_coreCheckerSupportedPlatforms, methodElement);
if (fieldSupportedDocs != null) {
classBuffer.writeln(fieldSupportedDocs);
}
classBuffer
.writeln(methodBody.toString().replaceAll(className, extClassName));
}
}
if (annotation.read("toMapMethod").boolValue && (!visitor.methods.containsKey("toMap") ||
Util.methodHasIgnore(visitor.methods['toMap']!))) {
classBuffer.writeln('///Converts instance to a map.');
classBuffer.writeln('Map<String, dynamic> toMap() {');
classBuffer.writeln('return {');
for (final entry in visitor.methods.entries) {
final methodElement = entry.value;
final toMapMergeWith = _coreCheckerObjectMethod
.firstAnnotationOf(methodElement)
?.getField("toMapMergeWith")
?.toBoolValue();
if (toMapMergeWith == true) {
classBuffer.writeln('...${methodElement.name}(),');
}
}
final fieldElements = <FieldElement>[];
if (superClass != null) {
for (final fieldElement in superClass.element2.fields) {
if (!fieldElement.isPrivate &&
!fieldElement.hasDeprecated &&
!fieldElement.isStatic &&
!fieldElement.type.isDartCoreFunction) {
fieldElements.add(fieldElement);
}
}
}
for (final entry in visitor.fields.entries) {
final fieldElement = entry.value;
if (!fieldElement.isPrivate &&
!fieldElement.hasDeprecated &&
!fieldElement.isStatic &&
!fieldElement.type.isDartCoreFunction) {
fieldElements.add(fieldElement);
}
}
for (final fieldElement in fieldElements) {
if (!fieldElement.isPrivate &&
!fieldElement.hasDeprecated &&
!fieldElement.isStatic &&
!fieldElement.type.isDartCoreFunction) {
final fieldName = fieldElement.name;
var mapValue = fieldName;
final customSerializer = _coreCheckerObjectProperty
.firstAnnotationOf(fieldElement)
?.getField("serializer")
?.toFunctionValue();
if (customSerializer != null) {
final serializerClassName = customSerializer.enclosingElement3.name;
if (serializerClassName != null) {
mapValue =
"$serializerClassName.${customSerializer.name}($mapValue)";
} else {
mapValue = "${customSerializer.name}($mapValue)";
}
} else {
mapValue = getToMapValue(fieldName, fieldElement.type);
}
classBuffer.writeln('"$fieldName": $mapValue,');
}
}
classBuffer.writeln('};');
classBuffer.writeln('}');
}
if (annotation.read("toJsonMethod").boolValue && (!visitor.methods.containsKey("toJson") ||
Util.methodHasIgnore(visitor.methods['toJson']!))) {
classBuffer.writeln('///Converts instance to a map.');
classBuffer.writeln('Map<String, dynamic> toJson() {');
classBuffer.writeln('return toMap();');
classBuffer.writeln('}');
}
if (annotation.read("toStringMethod").boolValue && (!visitor.methods.containsKey("toString") ||
Util.methodHasIgnore(visitor.methods['toString']!))) {
classBuffer.writeln('@override');
classBuffer.writeln('String toString() {');
classBuffer.write('return \'$extClassName{');
final fieldNames = <String>[];
if (superClass != null) {
for (final fieldElement in superClass.element2.fields) {
final fieldName = fieldElement.name;
if (!fieldElement.isPrivate &&
!fieldElement.hasDeprecated &&
!fieldElement.isStatic &&
!fieldElement.type.isDartCoreFunction) {
fieldNames.add('$fieldName: \$$fieldName');
}
}
}
for (final entry in visitor.fields.entries) {
final fieldName = entry.key;
final fieldElement = entry.value;
if (!fieldElement.isPrivate &&
!fieldElement.hasDeprecated &&
!fieldElement.isStatic &&
!fieldElement.type.isDartCoreFunction) {
fieldNames.add('$fieldName: \$$fieldName');
}
}
classBuffer.write(fieldNames.join(', '));
classBuffer.writeln('}\';');
classBuffer.writeln('}');
}
classBuffer.writeln('}');
return classBuffer.toString();
}
String getFromMapValue(String value, DartType elementType) {
final fieldTypeElement = elementType.element2;
final isNullable = Util.typeIsNullable(elementType);
if (elementType.getDisplayString(withNullability: false) == "Uri") {
if (!isNullable) {
return "Uri.parse($value)";
} else {
return "$value != null ? Uri.parse($value) : null";
}
} else if (elementType.getDisplayString(withNullability: false) ==
"Color") {
if (!isNullable) {
return "UtilColor.fromStringRepresentation($value)!";
} else {
return "$value != null ? UtilColor.fromStringRepresentation($value) : null";
}
} else if (elementType.getDisplayString(withNullability: false) ==
"EdgeInsets") {
return "MapEdgeInsets.fromMap($value?.cast<String, dynamic>())${isNullable ? '!' : ''}";
} else if (elementType.getDisplayString(withNullability: false) == "Size") {
return "MapSize.fromMap($value?.cast<String, dynamic>())${isNullable ? '!' : ''}";
} else if (elementType.getDisplayString(withNullability: false) ==
"DateTime") {
if (!isNullable) {
return "DateTime.fromMillisecondsSinceEpoch($value)!";
} else {
return "$value != null ? DateTime.fromMillisecondsSinceEpoch($value) : null";
}
} else if (elementType.isDartCoreList || elementType.isDartCoreSet) {
final genericTypes = Util.getGenericTypes(elementType);
final genericType = genericTypes.isNotEmpty ? genericTypes.first : null;
final genericTypeReplaced = genericType != null ? genericType.toString().replaceAll("_", "") : null;
if (genericType != null && !Util.isDartCoreType(genericType)) {
final genericTypeFieldName = 'e';
return (isNullable ? '$value != null ? ' : '') +
"${elementType.isDartCoreSet ? 'Set' : 'List'}<$genericTypeReplaced>.from(" +
value +
'.map(($genericTypeFieldName) => ' +
getFromMapValue('$genericTypeFieldName', genericType) +
'))' +
(isNullable ? ' : null' : '');
} else {
if (genericType != null) {
return "$value${isNullable ? '?' : ''}.cast<${genericTypeReplaced}>()";
} else {
return value;
}
}
} else if (elementType.isDartCoreMap) {
final genericTypes = Util.getGenericTypes(elementType);
return "$value${isNullable ? '?' : ''}.cast<${genericTypes.elementAt(0)}, ${genericTypes.elementAt(1)}>()";
} else if (fieldTypeElement != null && hasFromMapMethod(fieldTypeElement)) {
final hasNullableFromMap = hasNullableFromMapFactory(fieldTypeElement);
// remove class reference terminating with "_"
return fieldTypeElement.name!.replaceFirst("_", "") +
".fromMap($value?.cast<String, dynamic>())${!isNullable && hasNullableFromMap ? '!' : ''}";
} else {
final hasFromValue =
fieldTypeElement != null && hasFromValueMethod(fieldTypeElement);
final hasFromNativeValue = fieldTypeElement != null &&
hasFromNativeValueMethod(fieldTypeElement);
if (fieldTypeElement != null && (hasFromValue || hasFromNativeValue)) {
if (hasFromNativeValue) {
// remove class reference terminating with "_"
value = fieldTypeElement.name!.replaceFirst("_", "") +
'.fromNativeValue($value)';
} else {
// remove class reference terminating with "_"
value = fieldTypeElement.name!.replaceFirst("_", "") +
'.fromValue($value)';
}
if (!isNullable) {
value += '!';
}
return value;
}
}
return value;
}
String getToMapValue(String fieldName, DartType elementType) {
final fieldTypeElement = elementType.element2;
final isNullable = Util.typeIsNullable(elementType);
if (elementType.getDisplayString(withNullability: false) == "Uri") {
return fieldName + (isNullable ? '?' : '') + '.toString()';
} else if (elementType.getDisplayString(withNullability: false) ==
"Color") {
return fieldName + (isNullable ? '?' : '') + '.toHex()';
} else if (elementType.getDisplayString(withNullability: false) ==
"EdgeInsets") {
return fieldName + (isNullable ? '?' : '') + '.toMap()';
} else if (elementType.getDisplayString(withNullability: false) == "Size") {
return fieldName + (isNullable ? '?' : '') + '.toMap()';
} else if (elementType.getDisplayString(withNullability: false) ==
"DateTime") {
return fieldName + (isNullable ? '?' : '') + '.millisecondsSinceEpoch';
} else if (elementType.isDartCoreList || elementType.isDartCoreSet) {
final genericType = Util.getGenericTypes(elementType).first;
if (!Util.isDartCoreType(genericType)) {
final genericTypeFieldName = 'e';
return fieldName +
(isNullable ? '?' : '') +
'.map(($genericTypeFieldName) => ' +
getToMapValue('$genericTypeFieldName', genericType) +
').toList()';
} else {
return fieldName;
}
} else if (fieldTypeElement != null && hasToMapMethod(fieldTypeElement)) {
return fieldName +
(Util.typeIsNullable(elementType) ? '?' : '') +
'.toMap()';
} else {
final hasToValue =
fieldTypeElement != null && hasToValueMethod(fieldTypeElement);
final hasToNativeValue =
fieldTypeElement != null && hasToNativeValueMethod(fieldTypeElement);
if (fieldTypeElement != null && (hasToValue || hasToNativeValue)) {
if (hasToNativeValue) {
return fieldName + (isNullable ? '?' : '') + '.toNativeValue()';
} else {
return fieldName + (isNullable ? '?' : '') + '.toValue()';
}
}
}
return fieldName;
}
bool hasToMapMethod(Element element) {
final hasAnnotation = _coreChecker.hasAnnotationOf(element);
final toMapMethod = _coreChecker
.firstAnnotationOfExact(element)
?.getField('toMapMethod')
?.toBoolValue() ??
false;
if (hasAnnotation && toMapMethod) {
return true;
}
final fieldVisitor = ModelVisitor();
element.visitChildren(fieldVisitor);
for (var entry in fieldVisitor.methods.entries) {
if (entry.key == "toMap") {
return true;
}
}
return false;
}
bool hasFromMapMethod(Element element) {
final hasAnnotation = _coreChecker.hasAnnotationOf(element);
final fromMapFactory = _coreChecker
.firstAnnotationOfExact(element)
?.getField('fromMapFactory')
?.toBoolValue() ??
false;
if (hasAnnotation && fromMapFactory) {
return true;
}
final fieldVisitor = ModelVisitor();
element.visitChildren(fieldVisitor);
for (var entry in fieldVisitor.methods.entries) {
if (entry.key == "fromMap") {
return true;
}
}
return false;
}
bool hasNullableFromMapFactory(Element element) {
final hasAnnotation = _coreChecker.hasAnnotationOf(element);
final fromMapFactory = _coreChecker
.firstAnnotationOfExact(element)
?.getField('fromMapFactory')
?.toBoolValue() ??
false;
final nullableFromMapFactory = _coreChecker
.firstAnnotationOfExact(element)
?.getField('nullableFromMapFactory')
?.toBoolValue() ??
false;
if (hasAnnotation && fromMapFactory && nullableFromMapFactory) {
return true;
}
final fieldVisitor = ModelVisitor();
element.visitChildren(fieldVisitor);
for (var entry in fieldVisitor.methods.entries) {
if (entry.key == "fromMap" &&
Util.typeIsNullable(entry.value.returnType)) {
return true;
}
}
return false;
}
bool hasFromValueMethod(Element element) {
final hasAnnotation = _coreCheckerEnum.hasAnnotationOf(element);
final fromValueMethod = _coreCheckerEnum
.firstAnnotationOfExact(element)
?.getField('fromValueMethod')
?.toBoolValue() ??
false;
if (hasAnnotation && fromValueMethod) {
return true;
}
final fieldVisitor = ModelVisitor();
element.visitChildren(fieldVisitor);
for (var entry in fieldVisitor.methods.entries) {
if (entry.key == "fromValue") {
return true;
}
}
return false;
}
bool hasFromNativeValueMethod(Element element) {
final hasAnnotation = _coreCheckerEnum.hasAnnotationOf(element);
final fromNativeValueMethod = _coreCheckerEnum
.firstAnnotationOfExact(element)
?.getField('fromNativeValueMethod')
?.toBoolValue() ??
false;
if (hasAnnotation && fromNativeValueMethod) {
return true;
}
final fieldVisitor = ModelVisitor();
element.visitChildren(fieldVisitor);
for (var entry in fieldVisitor.methods.entries) {
if (entry.key == "fromNativeValue") {
return true;
}
}
return false;
}
bool hasToValueMethod(Element element) {
final hasAnnotation = _coreCheckerEnum.hasAnnotationOf(element);
final hasToValueMethod = _coreCheckerEnum
.firstAnnotationOfExact(element)
?.getField('toValueMethod')
?.toBoolValue() ??
false;
if (hasAnnotation && hasToValueMethod) {
return true;
}
final fieldVisitor = ModelVisitor();
element.visitChildren(fieldVisitor);
for (var entry in fieldVisitor.methods.entries) {
if (entry.key == "toValue") {
return true;
}
}
return false;
}
bool hasToNativeValueMethod(Element element) {
final hasAnnotation = _coreCheckerEnum.hasAnnotationOf(element);
final hasToNativeValueMethod = _coreCheckerEnum
.firstAnnotationOfExact(element)
?.getField('toNativeValueMethod')
?.toBoolValue() ??
false;
if (hasAnnotation && hasToNativeValueMethod) {
return true;
}
final fieldVisitor = ModelVisitor();
element.visitChildren(fieldVisitor);
for (var entry in fieldVisitor.methods.entries) {
if (entry.key == "toNativeValue") {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,27 @@
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
class ModelVisitor extends SimpleElementVisitor<void> {
late ConstructorElement constructor;
final constructorParameters = <String, ParameterElement>{};
final fields = <String, FieldElement>{};
final methods = <String, MethodElement>{};
@override
void visitConstructorElement(ConstructorElement element) {
constructor = element;
for (final param in element.parameters) {
constructorParameters.putIfAbsent(param.name, () => param);
}
}
@override
void visitFieldElement(FieldElement element) {
fields[element.name] = element;
}
@override
void visitMethodElement(MethodElement element) {
methods[element.name] = element;
}
}

View File

@ -0,0 +1,103 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:source_gen/source_gen.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
final _coreCheckerObjectMethod =
const TypeChecker.fromRuntime(ExchangeableObjectMethod);
abstract class Util {
static bool typeIsNullable(DartType type) {
return type.nullabilitySuffix != NullabilitySuffix.none ||
type.toString() == 'dynamic';
}
static bool methodHasIgnore(MethodElement method) {
return _coreCheckerObjectMethod
.firstAnnotationOf(method)
?.getField("ignore")
?.toBoolValue() ==
true;
}
static String? getSupportedDocs(TypeChecker checker, Element element) {
final platformNoteList = <String>[];
final platformSupportedList = <String>[];
final platforms = checker
.firstAnnotationOfExact(element)
?.getField('platforms')
?.toListValue() ??
<DartObject>[];
for (var platform in platforms) {
final platformName = platform.getField("name")!.toStringValue();
final note = platform.getField("note")?.toStringValue();
if (note != null) {
platformNoteList.add("///**NOTE for $platformName**: $note");
}
final apiName = platform.getField("apiName")?.toStringValue();
final apiUrl = platform.getField("apiUrl")?.toStringValue();
final available = platform.getField("available")?.toStringValue();
final requiresSameOrigin =
platform.getField("requiresSameOrigin")?.toBoolValue() ?? false;
var api = available != null ? "$available+ " : "";
if (requiresSameOrigin) {
api += "but iframe requires same origin ";
}
if (apiName != null && apiUrl != null) {
api += "([Official API - $apiName]($apiUrl))";
} else if (apiName != null) {
api += "(Official API - $apiName)";
} else if (apiUrl != null) {
api += "([Official API]($apiUrl))";
}
platformSupportedList.add("///- $platformName $api");
}
if (platformSupportedList.isNotEmpty) {
if (platformNoteList.isNotEmpty) {
return """///
${platformNoteList.join("\n///\n")}
///
///**Supported Platforms/Implementations**:
${platformSupportedList.join("\n")}""";
} else {
return """///
///**Supported Platforms/Implementations**:
${platformSupportedList.join("\n")}""";
}
}
return null;
}
static Iterable<DartType> getGenericTypes(DartType type) {
return type is ParameterizedType ? type.typeArguments : const [];
}
static bool canHaveGenerics(DartType type) {
final element = type.element2;
if (element is ClassElement) {
return element.typeParameters.isNotEmpty;
}
return false;
}
static bool isDartCoreType(DartType type) {
return type.isDartCoreBool ||
type.isDartCoreDouble ||
type.isDartCoreEnum ||
type.isDartCoreFunction ||
type.isDartCoreInt ||
type.isDartCoreIterable ||
type.isDartCoreList ||
type.isDartCoreMap ||
type.isDartCoreNull ||
type.isDartCoreNum ||
type.isDartCoreObject ||
type.isDartCoreSet ||
type.isDartCoreString ||
type.isDartCoreSymbol ||
type.isDynamic;
}
}

View File

@ -0,0 +1,506 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "49.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.1"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.9.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
build:
dependency: "direct main"
description:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.1"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.10"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "7.2.4"
build_test:
dependency: "direct dev"
description:
name: build_test
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.5"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "8.4.1"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
code_builder:
dependency: transitive
description:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.16.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
coverage:
dependency: transitive
description:
name: coverage
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
csslib:
dependency: transitive
description:
name: csslib
url: "https://pub.dartlang.org"
source: hosted
version: "0.17.2"
dart_style:
dependency: transitive
description:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.4"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.4"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_inappwebview_internal_annotations:
dependency: "direct main"
description:
path: "../flutter_inappwebview_internal_annotations"
relative: true
source: path
version: "1.0.0"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
html:
dependency: transitive
description:
name: html
url: "https://pub.dartlang.org"
source: hosted
version: "0.15.0"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.1"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.4"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "4.7.0"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
node_preamble:
dependency: transitive
description:
name: node_preamble
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
shelf_packages_handler:
dependency: transitive
description:
name: shelf_packages_handler
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
shelf_static:
dependency: transitive
description:
name: shelf_static
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_gen:
dependency: "direct main"
description:
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.5"
source_map_stack_trace:
dependency: transitive
description:
name: source_map_stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
source_maps:
dependency: transitive
description:
name: source_maps
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.10"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
test:
dependency: "direct dev"
description:
name: test
url: "https://pub.dartlang.org"
source: hosted
version: "1.21.6"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.14"
test_core:
dependency: transitive
description:
name: test_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.18"
timing:
dependency: transitive
description:
name: timing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
vm_service:
dependency: transitive
description:
name: vm_service
url: "https://pub.dartlang.org"
source: hosted
version: "9.4.0"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
webkit_inspection_protocol:
dependency: transitive
description:
name: webkit_inspection_protocol
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
sdks:
dart: ">=2.18.0 <3.0.0"
flutter: ">=2.5.0"

View File

@ -0,0 +1,21 @@
name: generators
version: 1.0.0
publish_to: none
environment:
sdk: ">=2.14.0 <3.0.0"
flutter: ">=2.5.0"
dependencies:
flutter:
sdk: flutter
build: ^2.3.1
source_gen: ^1.2.5
flutter_inappwebview_internal_annotations:
path: ../flutter_inappwebview_internal_annotations/
dev_dependencies:
build_runner: ^2.2.1
build_test: ^2.1.5
test: ^1.21.1

View File

@ -0,0 +1,11 @@
include: package:lints/recommended.yaml
linter:
rules:
constant_identifier_names: ignore
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
analyzer:
errors:
deprecated_member_use_from_same_package: ignore

View File

@ -0,0 +1,6 @@
import 'package:test_gen/src/types/main.dart';
import 'package:test_gen/src/types/test_enum.dart';
void main() {
TestClass test = TestClass(test1: "test1", test2: TestClass2(test1: ""), actionModeMenuItem: ActionModeMenuItem.MENU_ITEM_NONE);
}

View File

@ -0,0 +1,10 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
part 'test_class_2.g.dart';
@ExchangeableObject()
class TestClass2_ {
String test1;
TestClass2_({required this.test1});
}

View File

@ -0,0 +1,2 @@
export 'test_class.dart' show TestClass;
export '../test/test_class_2.dart' show TestClass2;

View File

@ -0,0 +1,186 @@
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import '../test/test_class_2.dart';
import 'test_enum.dart';
part 'test_class.g.dart';
///Custom docs
// @ExchangeableObject()
@SupportedPlatforms(platforms: [
AndroidPlatform(
apiName: "TestClass",
available: "24",
note: "[test1] is always `null`."
),
IOSPlatform(
apiName: "TestClass",
available: "15.0",
note: "[test2] is always `null`."
),
WebPlatform(),
])
class TestClass_ extends TestClass3_ {
///Docs 1
String test1;
///Docs 2
List<TestClass2_> test2;
List<Color?>? colors;
Function? onLoad;
///Docs 3
@SupportedPlatforms(platforms: [
AndroidPlatform(
apiName: "WebSettings.setDisabledActionModeMenuItems",
apiUrl: "https://developer.android.com/reference/android/webkit/WebSettings#setDisabledActionModeMenuItems(int)",
available: "24"
)
])
List<ActionModeMenuItem_?> actionModeMenuItem;
@ExchangeableObjectProperty(
serializer: Util.serializeTest,
deserializer: Util.deserializeTest
)
int test = 0;
DateTime? validNotAfterDate;
TestClass_({required String asd, this.test1 = "asdasd", required this.test2,
this.actionModeMenuItem = const [ActionModeMenuItem_.MENU_ITEM_NONE]}) : super(asd: asd);
}
@ExchangeableObject()
class TestClass3_ {
String asd;
Function? onLoad;
TestClass3_({required this.asd});
}
///Class that represents the navigation request used by the [WebView.onCreateWindow] event.
@ExchangeableObject()
class CreateWindowAction_ extends NavigationAction_ {
///The window id. Used by [WebView] to create a new WebView.
int windowId;
///Use [isDialog] instead.
@Deprecated("Use isDialog instead")
bool? androidIsDialog;
///Indicates if the new window should be a dialog, rather than a full-size window.
@SupportedPlatforms(
platforms: [
AndroidPlatform()
]
)
bool? isDialog;
CreateWindowAction_(
{required this.windowId,
@Deprecated('Use isDialog instead')
this.androidIsDialog,
this.isDialog,
required bool isForMainFrame,
@Deprecated('Use hasGesture instead')
bool? androidHasGesture,
@Deprecated('Use isRedirect instead')
bool? androidIsRedirect,
bool? hasGesture,
bool? isRedirect,
@Deprecated('Use navigationType instead')
// ignore: deprecated_member_use_from_same_package
TestClass3_? iosWKNavigationType,
TestClass3_? navigationType}) : super(
isForMainFrame: isForMainFrame,
hasGesture: hasGesture,
isRedirect: isRedirect,
navigationType: navigationType
);
}
///An object that contains information about an action that causes navigation to occur.
@ExchangeableObject()
class NavigationAction_ {
///Indicates whether the request was made for the main frame.
///
///**NOTE for Android**: If the request is associated to the [WebView.onCreateWindow] event, this is always `true`.
///Also, on Android < 21, this is always `true`.
bool isForMainFrame;
///Use [hasGesture] instead.
@Deprecated('Use hasGesture instead')
bool? androidHasGesture;
///Gets whether a gesture (such as a click) was associated with the request.
///For security reasons in certain situations this method may return `false` even though
///the sequence of events which caused the request to be created was initiated by a user
///gesture.
@SupportedPlatforms(
platforms: [
AndroidPlatform(
available: "21",
apiName: "WebResourceRequest.hasGesture",
apiUrl: "https://developer.android.com/reference/android/webkit/WebResourceRequest#hasGesture()",
note: "On Android < 21, this is always `false`"
)
]
)
bool? hasGesture;
///Use [isRedirect] instead.
@Deprecated('Use isRedirect instead')
bool? androidIsRedirect;
///Gets whether the request was a result of a server-side redirect.
///
///**NOTE**: If the request is associated to the [WebView.onCreateWindow] event, this is always `false`.
///Also, on Android < 21, this is always `false`.
@SupportedPlatforms(
platforms: [
AndroidPlatform(
available: "21",
apiName: "WebResourceRequest.isRedirect",
apiUrl: "https://developer.android.com/reference/android/webkit/WebResourceRequest#isRedirect()"
)
]
)
bool? isRedirect;
///Use [navigationType] instead.
@Deprecated("Use navigationType instead")
TestClass3_? iosWKNavigationType;
///The type of action triggering the navigation.
///
///**NOTE**: available only on iOS.
TestClass3_? navigationType;
///A value indicating whether the web content used a download attribute to indicate that this should be downloaded.
///
///**NOTE**: available only on iOS.
bool? shouldPerformDownload;
NavigationAction_(
{required this.isForMainFrame,
@Deprecated('Use hasGesture instead') this.androidHasGesture,
this.hasGesture,
@Deprecated('Use isRedirect instead') this.androidIsRedirect,
this.isRedirect,
@Deprecated("Use navigationType instead") this.iosWKNavigationType,
this.navigationType,
this.shouldPerformDownload});
}
class Util {
static String serializeTest(int source) {
return source.toString();
}
static int deserializeTest(String source) {
return int.parse(source);
}
}

View File

@ -0,0 +1,160 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'package:flutter/foundation.dart';
part 'test_enum.g.dart';
typedef myInt = int;
///Docs
@ExchangeableEnum(
bitwiseOrOperator: true
)
@EnumSupportedPlatforms(platforms: [
EnumAndroidPlatform(
apiName: "TestClass",
available: "24",
note: "[test1] is always `null`."
),
EnumIOSPlatform(
apiName: "TestClass",
available: "15.0",
note: "[test2] is always `null`."
),
EnumWebPlatform(),
])
class ActionModeMenuItem_ {
final int _value;
const ActionModeMenuItem_._internal(this._value);
///No menu items should be disabled.
static const MENU_ITEM_NONE = const ActionModeMenuItem_._internal(0);
///Disable menu item "Share".
static const MENU_ITEM_SHARE = const ActionModeMenuItem_._internal(1);
///Disable menu item "Web Search".
static const MENU_ITEM_WEB_SEARCH = const ActionModeMenuItem_._internal(2);
///Disable all the action mode menu items for text processing.
@EnumSupportedPlatforms(platforms: [
EnumAndroidPlatform(
apiName: "TestClass",
available: "24",
note: "[test1] is always `null`."
),
EnumIOSPlatform(
apiName: "TestClass",
available: "15.0",
note: "[test2] is always `null`."
),
EnumWebPlatform(),
])
static const MENU_ITEM_PROCESS_TEXT = const ActionModeMenuItem_._internal(4);
}
typedef myString = String;
@ExchangeableEnum()
///Class that represents a type of resource used to ask user's permission.
class PermissionResourceType_ {
final String _value;
final dynamic _nativeValue = null;
const PermissionResourceType_._internal(this._value);
///Resource belongs to audio capture device, like microphone.
@EnumSupportedPlatforms(platforms: [
EnumAndroidPlatform(
apiName: "PermissionRequest.RESOURCE_AUDIO_CAPTURE",
apiUrl: "https://developer.android.com/reference/android/webkit/PermissionRequest#RESOURCE_AUDIO_CAPTURE",
value: 'android.webkit.resource.AUDIO_CAPTURE'
),
EnumIOSPlatform(
available: "15.0",
apiName: "WKMediaCaptureType.microphone",
apiUrl: "https://developer.apple.com/documentation/webkit/wkmediacapturetype/microphone",
value: 1
),
EnumMacOSPlatform(
available: "15.0",
apiName: "WKMediaCaptureType.microphone",
apiUrl: "https://developer.apple.com/documentation/webkit/wkmediacapturetype/microphone",
value: 1
),
])
static const MICROPHONE = PermissionResourceType_._internal('MICROPHONE');
///Resource will allow sysex messages to be sent to or received from MIDI devices.
///These messages are privileged operations, e.g. modifying sound libraries and sampling data, or even updating the MIDI device's firmware.
///Permission may be requested for this resource in API levels 21 and above, if the Android device has been updated to WebView 45 or above.
@EnumSupportedPlatforms(platforms: [
EnumAndroidPlatform(
apiName: "PermissionRequest.RESOURCE_MIDI_SYSEX",
apiUrl: "https://developer.android.com/reference/android/webkit/PermissionRequest#RESOURCE_MIDI_SYSEX",
value: 'android.webkit.resource.RESOURCE_MIDI_SYSEX'
)
])
static const MIDI_SYSEX = PermissionResourceType_._internal('MIDI_SYSEX');
///Resource belongs to protected media identifier. After the user grants this resource, the origin can use EME APIs to generate the license requests.
@EnumSupportedPlatforms(platforms: [
EnumAndroidPlatform(
apiName: "PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID",
apiUrl: "https://developer.android.com/reference/android/webkit/PermissionRequest#RESOURCE_PROTECTED_MEDIA_ID",
value: 'android.webkit.resource.PROTECTED_MEDIA_ID'
)
])
static const PROTECTED_MEDIA_ID = PermissionResourceType_._internal('PROTECTED_MEDIA_ID');
///Resource belongs to video capture device, like camera.
@EnumSupportedPlatforms(platforms: [
EnumAndroidPlatform(
apiName: "PermissionRequest.RESOURCE_VIDEO_CAPTURE",
apiUrl: "https://developer.android.com/reference/android/webkit/PermissionRequest#RESOURCE_VIDEO_CAPTURE",
value: 'android.webkit.resource.VIDEO_CAPTURE'
),
EnumIOSPlatform(
available: "15.0",
apiName: "WKMediaCaptureType.camera",
apiUrl: "https://developer.apple.com/documentation/webkit/wkmediacapturetype/camera",
value: 0
),
EnumMacOSPlatform(
available: "15.0",
apiName: "WKMediaCaptureType.camera",
apiUrl: "https://developer.apple.com/documentation/webkit/wkmediacapturetype/camera",
value: 0
),
])
static const CAMERA = PermissionResourceType_._internal('CAMERA');
///A media device or devices that can capture audio and video.
@EnumSupportedPlatforms(platforms: [
EnumIOSPlatform(
available: "15.0",
apiName: "WKMediaCaptureType.cameraAndMicrophone",
apiUrl: "https://developer.apple.com/documentation/webkit/wkmediacapturetype/cameraandmicrophone",
value: 2
),
EnumMacOSPlatform(
available: "15.0",
apiName: "WKMediaCaptureType.cameraAndMicrophone",
apiUrl: "https://developer.apple.com/documentation/webkit/wkmediacapturetype/cameraandmicrophone",
value: 2
),
])
static const CAMERA_AND_MICROPHONE = PermissionResourceType_._internal('CAMERA_AND_MICROPHONE');
///Resource belongs to the devices orientation and motion.
@EnumSupportedPlatforms(platforms: [
EnumIOSPlatform(
available: "15.0",
value: 'deviceOrientationAndMotion'
),
EnumMacOSPlatform(
available: "15.0",
value: 'deviceOrientationAndMotion'
),
])
static const DEVICE_ORIENTATION_AND_MOTION = PermissionResourceType_._internal('DEVICE_ORIENTATION_AND_MOTION');
}

View File

@ -0,0 +1,10 @@
library test_gen;
import 'package:test_gen/src/types/test_class.dart';
import 'package:test_gen/src/test/test_class_2.dart';
import 'package:test_gen/src/types/test_enum.dart';
void main() {
TestClass a = TestClass(test1: "test1", test2: TestClass2(test1: "test2"), actionModeMenuItem: ActionModeMenuItem.MENU_ITEM_NONE);
a.toMap();
}

View File

@ -0,0 +1,415 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "49.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.1"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.9.0"
build:
dependency: transitive
description:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.1"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.10"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "7.2.4"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "8.4.1"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
code_builder:
dependency: transitive
description:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.16.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
dart_style:
dependency: transitive
description:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.4"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.4"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_inappwebview_internal_annotations:
dependency: "direct main"
description:
path: "../flutter_inappwebview_internal_annotations"
relative: true
source: path
version: "1.0.0"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
generators:
dependency: "direct dev"
description:
path: "../generators"
relative: true
source: path
version: "1.0.0"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.1"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.4"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "4.7.0"
lints:
dependency: "direct dev"
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.5"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
timing:
dependency: transitive
description:
name: timing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
sdks:
dart: ">=2.17.0 <3.0.0"
flutter: ">=2.5.0"

View File

@ -0,0 +1,20 @@
name: test_gen
version: 1.0.0
publish_to: none
environment:
sdk: ">=2.14.0 <3.0.0"
flutter: ">=2.5.0"
dependencies:
flutter:
sdk: flutter
flutter_inappwebview_internal_annotations:
path: ../flutter_inappwebview_internal_annotations/
dev_dependencies:
build_runner: ^2.2.1
generators:
path: ../generators/
lints: ^1.0.1

View File

@ -17,36 +17,6 @@ void initialUrlRequest() {
].contains(defaultTargetPlatform);
group('initial url request', () {
final shouldSkipTest1 = kIsWeb
? false
: ![
TargetPlatform.android,
TargetPlatform.iOS,
TargetPlatform.macOS,
].contains(defaultTargetPlatform);
testWidgets('basic', (WidgetTester tester) async {
final Completer controllerCompleter = Completer<InAppWebViewController>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: InAppWebView(
key: GlobalKey(),
initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1),
onWebViewCreated: (controller) {
controllerCompleter.complete(controller);
},
),
),
);
final InAppWebViewController controller =
await controllerCompleter.future;
final String? currentUrl = (await controller.getUrl())?.toString();
expect(currentUrl, TEST_CROSS_PLATFORM_URL_1.toString());
}, skip: shouldSkipTest1);
final shouldSkipTest2 = kIsWeb
? true
: ![
@ -56,7 +26,9 @@ void initialUrlRequest() {
testWidgets('launches with allowsBackForwardNavigationGestures true',
(WidgetTester tester) async {
final Completer<void> pageLoaded = Completer<void>();
final Completer controllerCompleter = Completer<InAppWebViewController>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
@ -71,14 +43,54 @@ void initialUrlRequest() {
onWebViewCreated: (controller) {
controllerCompleter.complete(controller);
},
onLoadStop: (controller, url) {
pageLoaded.complete();
},
),
),
),
);
await pageLoaded.future;
final InAppWebViewController controller =
await controllerCompleter.future;
final String? currentUrl = (await controller.getUrl())?.toString();
expect(currentUrl, TEST_URL_1.toString());
}, skip: shouldSkipTest2);
final shouldSkipTest1 = kIsWeb
? false
: ![
TargetPlatform.android,
TargetPlatform.iOS,
TargetPlatform.macOS,
].contains(defaultTargetPlatform);
testWidgets('basic', (WidgetTester tester) async {
final Completer<void> pageLoaded = Completer<void>();
final Completer controllerCompleter = Completer<InAppWebViewController>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: InAppWebView(
key: GlobalKey(),
initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1),
onWebViewCreated: (controller) {
controllerCompleter.complete(controller);
},
onLoadStop: (controller, url) {
pageLoaded.complete();
},
),
),
);
await pageLoaded.future;
final InAppWebViewController controller =
await controllerCompleter.future;
final String? currentUrl = (await controller.getUrl())?.toString();
expect(currentUrl, TEST_CROSS_PLATFORM_URL_1.toString());
}, skip: shouldSkipTest1);
}, skip: shouldSkip);
}

View File

@ -19,8 +19,8 @@ void loadUrl() {
testWidgets('loadUrl', (WidgetTester tester) async {
final Completer controllerCompleter = Completer<InAppWebViewController>();
final StreamController<String> pageLoads =
StreamController<String>.broadcast();
final Completer<String> firstUrlLoad = Completer<String>();
final Completer<String> loadedUrl = Completer<String>();
await tester.pumpWidget(
Directionality(
@ -33,21 +33,21 @@ void loadUrl() {
controllerCompleter.complete(controller);
},
onLoadStop: (controller, url) {
pageLoads.add(url!.toString());
if (url.toString() == initialUrl.toString() && !firstUrlLoad.isCompleted) {
firstUrlLoad.complete(url.toString());
} else if (url.toString() == TEST_CROSS_PLATFORM_URL_1.toString() && !loadedUrl.isCompleted) {
loadedUrl.complete(url.toString());
}
},
),
),
);
final InAppWebViewController controller =
await controllerCompleter.future;
var url = await pageLoads.stream.first;
expect(url, initialUrl.toString());
expect(await firstUrlLoad.future, initialUrl.toString());
await controller.loadUrl(
urlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1));
url = await pageLoads.stream.first;
expect(url, TEST_CROSS_PLATFORM_URL_1.toString());
pageLoads.close();
expect(await loadedUrl.future, TEST_CROSS_PLATFORM_URL_1.toString());
}, skip: shouldSkip);
}

View File

@ -28,7 +28,7 @@ void onProgressChanged() {
clearCache: true,
),
onProgressChanged: (controller, progress) {
if (progress == 100) {
if (progress == 100 && !onProgressChangedCompleter.isCompleted) {
onProgressChangedCompleter.complete();
}
},

View File

@ -33,7 +33,9 @@ void onTitleChanged() {
controllerCompleter.complete(controller);
},
onLoadStop: (controller, url) {
pageLoaded.complete();
if (!pageLoaded.isCompleted) {
pageLoaded.complete();
}
},
onTitleChanged: (controller, title) {
if (title == "title test") {

View File

@ -20,8 +20,8 @@ void onUpdateVisitedHistory() {
testWidgets('onUpdateVisitedHistory', (WidgetTester tester) async {
final Completer controllerCompleter = Completer<InAppWebViewController>();
final Completer<void> firstPushCompleter = Completer<void>();
final Completer<void> secondPushCompleter = Completer<void>();
final Completer<String> firstPushCompleter = Completer<String>();
final Completer<String> secondPushCompleter = Completer<String>();
final Completer<void> pageLoaded = Completer<void>();
await tester.pumpWidget(
@ -39,9 +39,9 @@ void onUpdateVisitedHistory() {
},
onUpdateVisitedHistory: (controller, url, androidIsReload) async {
if (url!.toString().endsWith("second-push")) {
secondPushCompleter.complete();
secondPushCompleter.complete(url.toString());
} else if (url.toString().endsWith("first-push")) {
firstPushCompleter.complete();
firstPushCompleter.complete(url.toString());
}
},
),
@ -63,12 +63,12 @@ setTimeout(function() {
}, 500);
""");
await firstPushCompleter.future;
expect((await controller.getUrl())?.toString(),
var firstPushUrl = await firstPushCompleter.future;
expect(firstPushUrl,
'${!kIsWeb ? TEST_CROSS_PLATFORM_URL_1 : TEST_WEB_PLATFORM_BASE_URL}first-push');
await secondPushCompleter.future;
expect((await controller.getUrl())?.toString(),
var secondPushUrl = await secondPushCompleter.future;
expect(secondPushUrl,
'${!kIsWeb ? TEST_CROSS_PLATFORM_URL_1 : TEST_WEB_PLATFORM_BASE_URL}second-push');
}, skip: shouldSkip);
}

View File

@ -68,7 +68,9 @@ void programmaticZoomScale() {
controllerCompleter.complete(controller);
},
onLoadStop: (controller, url) {
pageLoaded.complete();
if (!pageLoaded.isCompleted) {
pageLoaded.complete();
}
},
onZoomScaleChanged: (controller, oldScale, newScale) {
if (listenForScaleChange) {

View File

@ -40,7 +40,9 @@ void reload() {
controllerCompleter.complete(controller);
},
onLoadStop: (controller, url) {
pageLoaded.complete();
if (!pageLoaded.isCompleted) {
pageLoaded.complete();
}
},
),
),

View File

@ -18,6 +18,15 @@ void main() {
InAppWebViewController.setWebContentsDebuggingEnabled(true);
}
WebView.debugLoggingSettings.usePrint = true;
WebView.debugLoggingSettings.maxLogMessageLength = 7000;
InAppBrowser.debugLoggingSettings.usePrint = true;
InAppBrowser.debugLoggingSettings.maxLogMessageLength = 7000;
ChromeSafariBrowser.debugLoggingSettings.usePrint = true;
ChromeSafariBrowser.debugLoggingSettings.maxLogMessageLength = 7000;
WebAuthenticationSession.debugLoggingSettings.usePrint = true;
WebAuthenticationSession.debugLoggingSettings.maxLogMessageLength = 7000;
in_app_webview_tests.main();
service_worker_controller_tests.main();
proxy_controller_tests.main();

View File

@ -3,11 +3,11 @@
export "FLUTTER_ROOT=/Users/lorenzopichilli/fvm/versions/2.10.4"
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart"
export "FLUTTER_TARGET=integration_test/webview_flutter_test.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_DEFINES=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
export "DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"

Binary file not shown.

View File

@ -10,14 +10,17 @@
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
<main role="main" class="inner cover">
<h1 class="cover-heading">InAppWebViewOnLoadResourceCustomSchemeTest</h1>
<img id="image" src="my-special-custom-scheme://images/flutter-logo.svg" alt="flutter logo">
<img id="image" alt="flutter logo">
</main>
</div>
</body>
<script>
var image = document.querySelector("#image");
image.addEventListener('load', function() {
window.flutter_inappwebview.callHandler('imageLoaded');
window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
image.src = "my-special-custom-scheme://images/flutter-logo.svg";
image.addEventListener('load', function() {
window.flutter_inappwebview.callHandler('imageLoaded');
});
});
</script>
</html>

View File

@ -163,7 +163,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
}
}
else if let initialData = initialData {
let baseUrl = URL(string: initialBaseUrl!)!
let baseUrl = URL(string: initialBaseUrl ?? "about:blank")!
var allowingReadAccessToURL: URL? = nil
if let allowingReadAccessTo = webView?.settings?.allowingReadAccessTo, baseUrl.scheme == "file" {
allowingReadAccessToURL = URL(string: allowingReadAccessTo)

View File

@ -95,7 +95,7 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView, Disposable
let windowId = params["windowId"] as? Int64
let initialUrlRequest = params["initialUrlRequest"] as? [String: Any?]
let initialFile = params["initialFile"] as? String
let initialData = params["initialData"] as? [String: String]
let initialData = params["initialData"] as? [String: String?]
if windowId == nil {
if #available(iOS 11.0, *) {
@ -131,7 +131,7 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView, Disposable
}
}
func load(initialUrlRequest: [String:Any?]?, initialFile: String?, initialData: [String: String]?) {
func load(initialUrlRequest: [String:Any?]?, initialFile: String?, initialData: [String: String?]?) {
guard let webView = webView() else {
return
}
@ -144,11 +144,9 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView, Disposable
dump(error)
}
}
else if let initialData = initialData {
let data = initialData["data"]!
let mimeType = initialData["mimeType"]!
let encoding = initialData["encoding"]!
let baseUrl = URL(string: initialData["baseUrl"]!)!
else if let initialData = initialData, let data = initialData["data"]!,
let mimeType = initialData["mimeType"]!, let encoding = initialData["encoding"]!,
let baseUrl = URL(string: initialData["baseUrl"]! ?? "about:blank") {
var allowingReadAccessToURL: URL? = nil
if let allowingReadAccessTo = webView.settings?.allowingReadAccessTo, baseUrl.scheme == "file" {
allowingReadAccessToURL = URL(string: allowingReadAccessTo)
@ -156,7 +154,11 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView, Disposable
allowingReadAccessToURL = nil
}
}
webView.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl, allowingReadAccessTo: allowingReadAccessToURL)
webView.loadData(data: data,
mimeType: mimeType,
encoding: encoding,
baseUrl: baseUrl,
allowingReadAccessTo: allowingReadAccessToURL)
}
else if let initialUrlRequest = initialUrlRequest {
let urlRequest = URLRequest.init(fromPluginMap: initialUrlRequest)

View File

@ -1527,7 +1527,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
}
var result: [String: Any] = [:]
result["history"] = history
result["list"] = history
result["currentIndex"] = currentIndex
return result;
@ -1818,7 +1818,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
}
let webResourceRequest = WebResourceRequest(url: urlError, headers: nil)
let webResourceError = WebResourceError(errorCode: errorCode, errorDescription: errorDescription)
let webResourceError = WebResourceError(type: errorCode, errorDescription: errorDescription)
channelDelegate?.onReceivedError(request: webResourceRequest, error: webResourceError)

View File

@ -760,7 +760,7 @@ public class WebViewChannelDelegate : ChannelDelegate {
"defaultValue": defaultValue,
"isMainFrame": isMainFrame
]
channel?.invokeMethod("onJsConfirm", arguments: arguments, callback: callback)
channel?.invokeMethod("onJsPrompt", arguments: arguments, callback: callback)
}
public class CreateWindowCallback : BaseCallbackResult<Bool> {
@ -828,7 +828,7 @@ public class WebViewChannelDelegate : ChannelDelegate {
override init() {
super.init()
self.decodeResult = { (obj: Any?) in
if let obj = obj as? [String: Any?], let action = obj["action"] as? Int {
if let action = obj as? Int {
return WKNavigationActionPolicy.init(rawValue: action) ?? WKNavigationActionPolicy.cancel
}
return WKNavigationActionPolicy.cancel
@ -987,7 +987,7 @@ public class WebViewChannelDelegate : ChannelDelegate {
override init() {
super.init()
self.decodeResult = { (obj: Any?) in
if let obj = obj as? [String: Any?], let action = obj["action"] as? Int {
if let action = obj as? Int {
return WKNavigationResponsePolicy.init(rawValue: action) ?? WKNavigationResponsePolicy.cancel
}
return WKNavigationResponsePolicy.cancel
@ -1007,7 +1007,7 @@ public class WebViewChannelDelegate : ChannelDelegate {
override init() {
super.init()
self.decodeResult = { (obj: Any?) in
if let obj = obj as? [String: Any?], let action = obj["action"] as? Int {
if let action = obj as? Int {
return action == 1
}
return false

View File

@ -197,7 +197,7 @@ let INTERCEPT_AJAX_REQUEST_JS_SOURCE = """
};
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler('shouldInterceptAjaxRequest', ajaxRequest).then(function(result) {
if (result != null) {
switch (result.action) {
switch (result) {
case 0:
self.abort();
return;

View File

@ -8,10 +8,10 @@
import Foundation
public class PermissionResponse : NSObject {
var resources: [String]
var resources: [Any]
var action: Int?
public init(resources: [String], action: Int? = nil) {
public init(resources: [Any], action: Int? = nil) {
self.resources = resources
self.action = action
}
@ -20,7 +20,7 @@ public class PermissionResponse : NSObject {
guard let map = map else {
return nil
}
let resources = map["resources"] as! [String]
let resources = map["resources"] as! [Any]
let action = map["action"] as? Int
return PermissionResponse(resources: resources, action: action)
}

View File

@ -57,7 +57,6 @@ extension URLProtectionSpace {
"authenticationMethod": authenticationMethod,
"distinguishedNames": distinguishedNames,
"receivesCredentialSecurely": receivesCredentialSecurely,
"isProxy": isProxy(),
"proxyType": proxyType
]
}

View File

@ -8,17 +8,17 @@
import Foundation
public class WebResourceError: NSObject {
var errorCode: Int
var type: Int
var errorDescription: String
public init(errorCode: Int, errorDescription: String) {
self.errorCode = errorCode
public init(type: Int, errorDescription: String) {
self.type = type
self.errorDescription = errorDescription
}
public func toMap () -> [String:Any?] {
return [
"errorCode": errorCode,
"type": type,
"description": errorDescription
]
}

View File

@ -1,3 +1,3 @@
export 'service_worker_controller.dart';
export 'webview_feature.dart';
export 'webview_feature.dart' show WebViewFeature, AndroidWebViewFeature;
export 'proxy_controller.dart';

View File

@ -27,7 +27,14 @@ class ProxyController {
}
static ProxyController _init() {
_channel.setMethodCallHandler(_handleMethod);
_channel.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
_instance = ProxyController();
return _instance!;
}

View File

@ -38,7 +38,14 @@ class ServiceWorkerController {
}
static ServiceWorkerController _init() {
_channel.setMethodCallHandler(_handleMethod);
_channel.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
_instance = ServiceWorkerController();
return _instance!;
}
@ -107,7 +114,7 @@ class ServiceWorkerController {
///**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(
return CacheMode.fromNativeValue(
await _channel.invokeMethod('getCacheMode', args));
}
@ -155,7 +162,7 @@ class ServiceWorkerController {
///**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());
args.putIfAbsent("mode", () => mode.toNativeValue());
await _channel.invokeMethod('setCacheMode', args);
}
}
@ -222,7 +229,14 @@ class AndroidServiceWorkerController {
}
static AndroidServiceWorkerController _init() {
_channel.setMethodCallHandler(_handleMethod);
_channel.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
_instance = AndroidServiceWorkerController();
return _instance!;
}
@ -293,7 +307,7 @@ class AndroidServiceWorkerController {
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getCacheMode()
static Future<AndroidCacheMode?> getCacheMode() async {
Map<String, dynamic> args = <String, dynamic>{};
return AndroidCacheMode.fromValue(
return AndroidCacheMode.fromNativeValue(
await _channel.invokeMethod('getCacheMode', args));
}
@ -341,7 +355,7 @@ class AndroidServiceWorkerController {
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setCacheMode(int)
static Future<void> setCacheMode(AndroidCacheMode mode) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent("mode", () => mode.toValue());
args.putIfAbsent("mode", () => mode.toNativeValue());
await _channel.invokeMethod('setCacheMode', args);
}
}

View File

@ -1,257 +1,200 @@
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import '../in_app_webview/in_app_webview_controller.dart';
import '../in_app_webview/in_app_webview_settings.dart';
import 'proxy_controller.dart';
import 'service_worker_controller.dart';
import '../web_message/main.dart';
part 'webview_feature.g.dart';
///Class that represents an Android-specific utility class for checking which WebView Support Library features are supported on the device.
class WebViewFeature {
@ExchangeableEnum()
class WebViewFeature_ {
@ExchangeableEnumCustomValue()
static const MethodChannel _channel = const MethodChannel(
'com.pichillilorenzo/flutter_inappwebview_webviewfeature');
// ignore: unused_field
final String _value;
const WebViewFeature_._internal(this._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;
@ExchangeableObjectMethod(ignore: true)
String toNativeValue() => _value;
///This feature covers [InAppWebViewController.createWebMessageChannel].
static const CREATE_WEB_MESSAGE_CHANNEL =
const WebViewFeature._internal("CREATE_WEB_MESSAGE_CHANNEL");
const WebViewFeature_._internal("CREATE_WEB_MESSAGE_CHANNEL");
///This feature covers [InAppWebViewSettings.disabledActionModeMenuItems].
static const DISABLED_ACTION_MODE_MENU_ITEMS =
const WebViewFeature._internal("DISABLED_ACTION_MODE_MENU_ITEMS");
const WebViewFeature_._internal("DISABLED_ACTION_MODE_MENU_ITEMS");
///This feature covers [InAppWebViewSettings.forceDark].
static const FORCE_DARK = const WebViewFeature._internal("FORCE_DARK");
static const FORCE_DARK = const WebViewFeature_._internal("FORCE_DARK");
///This feature covers [InAppWebViewSettings.forceDarkStrategy].
static const FORCE_DARK_STRATEGY =
const WebViewFeature._internal("FORCE_DARK_STRATEGY");
const WebViewFeature_._internal("FORCE_DARK_STRATEGY");
///
static const GET_WEB_CHROME_CLIENT =
const WebViewFeature._internal("GET_WEB_CHROME_CLIENT");
const WebViewFeature_._internal("GET_WEB_CHROME_CLIENT");
///
static const GET_WEB_VIEW_CLIENT =
const WebViewFeature._internal("GET_WEB_VIEW_CLIENT");
const WebViewFeature_._internal("GET_WEB_VIEW_CLIENT");
///
static const GET_WEB_VIEW_RENDERER =
const WebViewFeature._internal("GET_WEB_VIEW_RENDERER");
const WebViewFeature_._internal("GET_WEB_VIEW_RENDERER");
///
static const MULTI_PROCESS = const WebViewFeature._internal("MULTI_PROCESS");
static const MULTI_PROCESS = const WebViewFeature_._internal("MULTI_PROCESS");
///This feature covers [InAppWebViewSettings.offscreenPreRaster].
static const OFF_SCREEN_PRERASTER =
const WebViewFeature._internal("OFF_SCREEN_PRERASTER");
const WebViewFeature_._internal("OFF_SCREEN_PRERASTER");
///This feature covers [InAppWebViewController.postWebMessage].
static const POST_WEB_MESSAGE =
const WebViewFeature._internal("POST_WEB_MESSAGE");
const WebViewFeature_._internal("POST_WEB_MESSAGE");
///This feature covers [ProxyController.setProxyOverride] and [ProxyController.clearProxyOverride].
static const PROXY_OVERRIDE =
const WebViewFeature._internal("PROXY_OVERRIDE");
const WebViewFeature_._internal("PROXY_OVERRIDE");
///
static const RECEIVE_HTTP_ERROR =
const WebViewFeature._internal("RECEIVE_HTTP_ERROR");
const WebViewFeature_._internal("RECEIVE_HTTP_ERROR");
///
static const RECEIVE_WEB_RESOURCE_ERROR =
const WebViewFeature._internal("RECEIVE_WEB_RESOURCE_ERROR");
const WebViewFeature_._internal("RECEIVE_WEB_RESOURCE_ERROR");
///This feature covers [InAppWebViewController.setSafeBrowsingAllowlist].
static const SAFE_BROWSING_ALLOWLIST =
const WebViewFeature._internal("SAFE_BROWSING_ALLOWLIST");
const WebViewFeature_._internal("SAFE_BROWSING_ALLOWLIST");
///This feature covers [InAppWebViewSettings.safeBrowsingEnabled].
static const SAFE_BROWSING_ENABLE =
const WebViewFeature._internal("SAFE_BROWSING_ENABLE");
const WebViewFeature_._internal("SAFE_BROWSING_ENABLE");
///
static const SAFE_BROWSING_HIT =
const WebViewFeature._internal("SAFE_BROWSING_HIT");
const WebViewFeature_._internal("SAFE_BROWSING_HIT");
///This feature covers [InAppWebViewController.getSafeBrowsingPrivacyPolicyUrl].
static const SAFE_BROWSING_PRIVACY_POLICY_URL =
const WebViewFeature._internal("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");
const WebViewFeature_._internal("SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY");
///
static const SAFE_BROWSING_RESPONSE_PROCEED =
const WebViewFeature._internal("SAFE_BROWSING_RESPONSE_PROCEED");
const WebViewFeature_._internal("SAFE_BROWSING_RESPONSE_PROCEED");
///
static const SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL =
const WebViewFeature._internal(
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");
const WebViewFeature_._internal("SAFE_BROWSING_WHITELIST");
///This feature covers [ServiceWorkerController].
static const SERVICE_WORKER_BASIC_USAGE =
const WebViewFeature._internal("SERVICE_WORKER_BASIC_USAGE");
const WebViewFeature_._internal("SERVICE_WORKER_BASIC_USAGE");
///This feature covers [ServiceWorkerController.setBlockNetworkLoads] and [ServiceWorkerController.getBlockNetworkLoads].
static const SERVICE_WORKER_BLOCK_NETWORK_LOADS =
const WebViewFeature._internal("SERVICE_WORKER_BLOCK_NETWORK_LOADS");
const WebViewFeature_._internal("SERVICE_WORKER_BLOCK_NETWORK_LOADS");
///This feature covers [ServiceWorkerController.setCacheMode] and [ServiceWorkerController.getCacheMode].
static const SERVICE_WORKER_CACHE_MODE =
const WebViewFeature._internal("SERVICE_WORKER_CACHE_MODE");
const WebViewFeature_._internal("SERVICE_WORKER_CACHE_MODE");
///This feature covers [ServiceWorkerController.setAllowContentAccess] and [ServiceWorkerController.getAllowContentAccess].
static const SERVICE_WORKER_CONTENT_ACCESS =
const WebViewFeature._internal("SERVICE_WORKER_CONTENT_ACCESS");
const WebViewFeature_._internal("SERVICE_WORKER_CONTENT_ACCESS");
///This feature covers [ServiceWorkerController.setAllowFileAccess] and [ServiceWorkerController.getAllowFileAccess].
static const SERVICE_WORKER_FILE_ACCESS =
const WebViewFeature._internal("SERVICE_WORKER_FILE_ACCESS");
const WebViewFeature_._internal("SERVICE_WORKER_FILE_ACCESS");
///This feature covers [ServiceWorkerClient.shouldInterceptRequest].
static const SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST =
const WebViewFeature._internal("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");
const WebViewFeature_._internal("SHOULD_OVERRIDE_WITH_REDIRECTS");
///This feature covers [InAppWebViewController.startSafeBrowsing].
static const START_SAFE_BROWSING =
const WebViewFeature._internal("START_SAFE_BROWSING");
const WebViewFeature_._internal("START_SAFE_BROWSING");
///
static const TRACING_CONTROLLER_BASIC_USAGE =
const WebViewFeature._internal("TRACING_CONTROLLER_BASIC_USAGE");
const WebViewFeature_._internal("TRACING_CONTROLLER_BASIC_USAGE");
///
static const VISUAL_STATE_CALLBACK =
const WebViewFeature._internal("VISUAL_STATE_CALLBACK");
const WebViewFeature_._internal("VISUAL_STATE_CALLBACK");
///
static const WEB_MESSAGE_CALLBACK_ON_MESSAGE =
const WebViewFeature._internal("WEB_MESSAGE_CALLBACK_ON_MESSAGE");
const WebViewFeature_._internal("WEB_MESSAGE_CALLBACK_ON_MESSAGE");
///This feature covers [WebMessageListener].
static const WEB_MESSAGE_LISTENER =
const WebViewFeature._internal("WEB_MESSAGE_LISTENER");
const WebViewFeature_._internal("WEB_MESSAGE_LISTENER");
///
static const WEB_MESSAGE_PORT_CLOSE =
const WebViewFeature._internal("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");
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");
const WebViewFeature_._internal("WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK");
///
static const WEB_RESOURCE_ERROR_GET_CODE =
const WebViewFeature._internal("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");
const WebViewFeature_._internal("WEB_RESOURCE_ERROR_GET_DESCRIPTION");
///
static const WEB_RESOURCE_REQUEST_IS_REDIRECT =
const WebViewFeature._internal("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");
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;
const WebViewFeature_._internal("WEB_VIEW_RENDERER_TERMINATE");
///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 {
static Future<bool> isFeatureSupported(WebViewFeature_ feature) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent("feature", () => feature.toValue());
args.putIfAbsent("feature", () => feature.toNativeValue());
return await _channel.invokeMethod('isFeatureSupported', args);
}
}
@ -259,258 +202,198 @@ class WebViewFeature {
///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 {
@ExchangeableEnum()
class AndroidWebViewFeature_ {
@ExchangeableEnumCustomValue()
static const MethodChannel _channel = const MethodChannel(
'com.pichillilorenzo/flutter_inappwebview_webviewfeature');
// ignore: unused_field
final String _value;
const AndroidWebViewFeature_._internal(this._value);
const AndroidWebViewFeature._internal(this._value);
static final Set<AndroidWebViewFeature> values = [
AndroidWebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
AndroidWebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS,
AndroidWebViewFeature.FORCE_DARK,
AndroidWebViewFeature.FORCE_DARK_STRATEGY,
AndroidWebViewFeature.GET_WEB_CHROME_CLIENT,
AndroidWebViewFeature.GET_WEB_VIEW_CLIENT,
AndroidWebViewFeature.GET_WEB_VIEW_RENDERER,
AndroidWebViewFeature.MULTI_PROCESS,
AndroidWebViewFeature.OFF_SCREEN_PRERASTER,
AndroidWebViewFeature.POST_WEB_MESSAGE,
AndroidWebViewFeature.PROXY_OVERRIDE,
AndroidWebViewFeature.RECEIVE_HTTP_ERROR,
AndroidWebViewFeature.RECEIVE_WEB_RESOURCE_ERROR,
AndroidWebViewFeature.SAFE_BROWSING_ALLOWLIST,
AndroidWebViewFeature.SAFE_BROWSING_ENABLE,
AndroidWebViewFeature.SAFE_BROWSING_HIT,
AndroidWebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL,
AndroidWebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY,
AndroidWebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED,
AndroidWebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL,
AndroidWebViewFeature.SERVICE_WORKER_BASIC_USAGE,
AndroidWebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS,
AndroidWebViewFeature.SERVICE_WORKER_CACHE_MODE,
AndroidWebViewFeature.SERVICE_WORKER_CONTENT_ACCESS,
AndroidWebViewFeature.SERVICE_WORKER_FILE_ACCESS,
AndroidWebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST,
AndroidWebViewFeature.SHOULD_OVERRIDE_WITH_REDIRECTS,
AndroidWebViewFeature.START_SAFE_BROWSING,
AndroidWebViewFeature.TRACING_CONTROLLER_BASIC_USAGE,
AndroidWebViewFeature.VISUAL_STATE_CALLBACK,
AndroidWebViewFeature.WEB_MESSAGE_CALLBACK_ON_MESSAGE,
AndroidWebViewFeature.WEB_MESSAGE_LISTENER,
AndroidWebViewFeature.WEB_MESSAGE_PORT_CLOSE,
AndroidWebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE,
AndroidWebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK,
AndroidWebViewFeature.WEB_RESOURCE_ERROR_GET_CODE,
AndroidWebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION,
AndroidWebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
AndroidWebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE,
AndroidWebViewFeature.WEB_VIEW_RENDERER_TERMINATE,
].toSet();
static AndroidWebViewFeature? fromValue(String? value) {
if (value != null) {
try {
return AndroidWebViewFeature.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
String toValue() => _value;
@override
String toString() => _value;
@ExchangeableObjectMethod(ignore: true)
String toNativeValue() => _value;
///
static const CREATE_WEB_MESSAGE_CHANNEL =
const AndroidWebViewFeature._internal("CREATE_WEB_MESSAGE_CHANNEL");
const AndroidWebViewFeature_._internal("CREATE_WEB_MESSAGE_CHANNEL");
///
static const DISABLED_ACTION_MODE_MENU_ITEMS =
const AndroidWebViewFeature._internal("DISABLED_ACTION_MODE_MENU_ITEMS");
const AndroidWebViewFeature_._internal("DISABLED_ACTION_MODE_MENU_ITEMS");
///
static const FORCE_DARK = const AndroidWebViewFeature._internal("FORCE_DARK");
static const FORCE_DARK = const AndroidWebViewFeature_._internal("FORCE_DARK");
///
static const FORCE_DARK_STRATEGY =
const AndroidWebViewFeature._internal("FORCE_DARK_STRATEGY");
const AndroidWebViewFeature_._internal("FORCE_DARK_STRATEGY");
///
static const GET_WEB_CHROME_CLIENT =
const AndroidWebViewFeature._internal("GET_WEB_CHROME_CLIENT");
const AndroidWebViewFeature_._internal("GET_WEB_CHROME_CLIENT");
///
static const GET_WEB_VIEW_CLIENT =
const AndroidWebViewFeature._internal("GET_WEB_VIEW_CLIENT");
const AndroidWebViewFeature_._internal("GET_WEB_VIEW_CLIENT");
///
static const GET_WEB_VIEW_RENDERER =
const AndroidWebViewFeature._internal("GET_WEB_VIEW_RENDERER");
const AndroidWebViewFeature_._internal("GET_WEB_VIEW_RENDERER");
///
static const MULTI_PROCESS =
const AndroidWebViewFeature._internal("MULTI_PROCESS");
const AndroidWebViewFeature_._internal("MULTI_PROCESS");
///
static const OFF_SCREEN_PRERASTER =
const AndroidWebViewFeature._internal("OFF_SCREEN_PRERASTER");
const AndroidWebViewFeature_._internal("OFF_SCREEN_PRERASTER");
///
static const POST_WEB_MESSAGE =
const AndroidWebViewFeature._internal("POST_WEB_MESSAGE");
const AndroidWebViewFeature_._internal("POST_WEB_MESSAGE");
///
static const PROXY_OVERRIDE =
const AndroidWebViewFeature._internal("PROXY_OVERRIDE");
const AndroidWebViewFeature_._internal("PROXY_OVERRIDE");
///
static const RECEIVE_HTTP_ERROR =
const AndroidWebViewFeature._internal("RECEIVE_HTTP_ERROR");
const AndroidWebViewFeature_._internal("RECEIVE_HTTP_ERROR");
///
static const RECEIVE_WEB_RESOURCE_ERROR =
const AndroidWebViewFeature._internal("RECEIVE_WEB_RESOURCE_ERROR");
const AndroidWebViewFeature_._internal("RECEIVE_WEB_RESOURCE_ERROR");
///
static const SAFE_BROWSING_ALLOWLIST =
const AndroidWebViewFeature._internal("SAFE_BROWSING_ALLOWLIST");
const AndroidWebViewFeature_._internal("SAFE_BROWSING_ALLOWLIST");
///
static const SAFE_BROWSING_ENABLE =
const AndroidWebViewFeature._internal("SAFE_BROWSING_ENABLE");
const AndroidWebViewFeature_._internal("SAFE_BROWSING_ENABLE");
///
static const SAFE_BROWSING_HIT =
const AndroidWebViewFeature._internal("SAFE_BROWSING_HIT");
const AndroidWebViewFeature_._internal("SAFE_BROWSING_HIT");
///
static const SAFE_BROWSING_PRIVACY_POLICY_URL =
const AndroidWebViewFeature._internal("SAFE_BROWSING_PRIVACY_POLICY_URL");
const AndroidWebViewFeature_._internal("SAFE_BROWSING_PRIVACY_POLICY_URL");
///
static const SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY =
const AndroidWebViewFeature._internal(
const AndroidWebViewFeature_._internal(
"SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY");
///
static const SAFE_BROWSING_RESPONSE_PROCEED =
const AndroidWebViewFeature._internal("SAFE_BROWSING_RESPONSE_PROCEED");
const AndroidWebViewFeature_._internal("SAFE_BROWSING_RESPONSE_PROCEED");
///
static const SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL =
const AndroidWebViewFeature._internal(
const AndroidWebViewFeature_._internal(
"SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL");
///Use [SAFE_BROWSING_ALLOWLIST] instead.
@Deprecated('Use SAFE_BROWSING_ALLOWLIST instead')
static const SAFE_BROWSING_WHITELIST =
const AndroidWebViewFeature._internal("SAFE_BROWSING_WHITELIST");
const AndroidWebViewFeature_._internal("SAFE_BROWSING_WHITELIST");
///
static const SERVICE_WORKER_BASIC_USAGE =
const AndroidWebViewFeature._internal("SERVICE_WORKER_BASIC_USAGE");
const AndroidWebViewFeature_._internal("SERVICE_WORKER_BASIC_USAGE");
///
static const SERVICE_WORKER_BLOCK_NETWORK_LOADS =
const AndroidWebViewFeature._internal(
const AndroidWebViewFeature_._internal(
"SERVICE_WORKER_BLOCK_NETWORK_LOADS");
///
static const SERVICE_WORKER_CACHE_MODE =
const AndroidWebViewFeature._internal("SERVICE_WORKER_CACHE_MODE");
const AndroidWebViewFeature_._internal("SERVICE_WORKER_CACHE_MODE");
///
static const SERVICE_WORKER_CONTENT_ACCESS =
const AndroidWebViewFeature._internal("SERVICE_WORKER_CONTENT_ACCESS");
const AndroidWebViewFeature_._internal("SERVICE_WORKER_CONTENT_ACCESS");
///
static const SERVICE_WORKER_FILE_ACCESS =
const AndroidWebViewFeature._internal("SERVICE_WORKER_FILE_ACCESS");
const AndroidWebViewFeature_._internal("SERVICE_WORKER_FILE_ACCESS");
///
static const SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST =
const AndroidWebViewFeature._internal(
const AndroidWebViewFeature_._internal(
"SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST");
///
static const SHOULD_OVERRIDE_WITH_REDIRECTS =
const AndroidWebViewFeature._internal("SHOULD_OVERRIDE_WITH_REDIRECTS");
const AndroidWebViewFeature_._internal("SHOULD_OVERRIDE_WITH_REDIRECTS");
///
static const START_SAFE_BROWSING =
const AndroidWebViewFeature._internal("START_SAFE_BROWSING");
const AndroidWebViewFeature_._internal("START_SAFE_BROWSING");
///
static const TRACING_CONTROLLER_BASIC_USAGE =
const AndroidWebViewFeature._internal("TRACING_CONTROLLER_BASIC_USAGE");
const AndroidWebViewFeature_._internal("TRACING_CONTROLLER_BASIC_USAGE");
///
static const VISUAL_STATE_CALLBACK =
const AndroidWebViewFeature._internal("VISUAL_STATE_CALLBACK");
const AndroidWebViewFeature_._internal("VISUAL_STATE_CALLBACK");
///
static const WEB_MESSAGE_CALLBACK_ON_MESSAGE =
const AndroidWebViewFeature._internal("WEB_MESSAGE_CALLBACK_ON_MESSAGE");
const AndroidWebViewFeature_._internal("WEB_MESSAGE_CALLBACK_ON_MESSAGE");
///
static const WEB_MESSAGE_LISTENER =
const AndroidWebViewFeature._internal("WEB_MESSAGE_LISTENER");
const AndroidWebViewFeature_._internal("WEB_MESSAGE_LISTENER");
///
static const WEB_MESSAGE_PORT_CLOSE =
const AndroidWebViewFeature._internal("WEB_MESSAGE_PORT_CLOSE");
const AndroidWebViewFeature_._internal("WEB_MESSAGE_PORT_CLOSE");
///
static const WEB_MESSAGE_PORT_POST_MESSAGE =
const AndroidWebViewFeature._internal("WEB_MESSAGE_PORT_POST_MESSAGE");
const AndroidWebViewFeature_._internal("WEB_MESSAGE_PORT_POST_MESSAGE");
///
static const WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK =
const AndroidWebViewFeature._internal(
const AndroidWebViewFeature_._internal(
"WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK");
///
static const WEB_RESOURCE_ERROR_GET_CODE =
const AndroidWebViewFeature._internal("WEB_RESOURCE_ERROR_GET_CODE");
const AndroidWebViewFeature_._internal("WEB_RESOURCE_ERROR_GET_CODE");
///
static const WEB_RESOURCE_ERROR_GET_DESCRIPTION =
const AndroidWebViewFeature._internal(
const AndroidWebViewFeature_._internal(
"WEB_RESOURCE_ERROR_GET_DESCRIPTION");
///
static const WEB_RESOURCE_REQUEST_IS_REDIRECT =
const AndroidWebViewFeature._internal("WEB_RESOURCE_REQUEST_IS_REDIRECT");
const AndroidWebViewFeature_._internal("WEB_RESOURCE_REQUEST_IS_REDIRECT");
///
static const WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE =
const AndroidWebViewFeature._internal(
const AndroidWebViewFeature_._internal(
"WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE");
///
static const WEB_VIEW_RENDERER_TERMINATE =
const AndroidWebViewFeature._internal("WEB_VIEW_RENDERER_TERMINATE");
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
const AndroidWebViewFeature_._internal("WEB_VIEW_RENDERER_TERMINATE");
///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(AndroidWebViewFeature feature) async {
static Future<bool> isFeatureSupported(AndroidWebViewFeature_ feature) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent("feature", () => feature.toValue());
args.putIfAbsent("feature", () => feature.toNativeValue());
return await _channel.invokeMethod('isFeatureSupported', args);
}
}

View File

@ -0,0 +1,580 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'webview_feature.dart';
// **************************************************************************
// ExchangeableEnumGenerator
// **************************************************************************
///Class that represents an Android-specific utility class for checking which WebView Support Library features are supported on the device.
class WebViewFeature {
final String _value;
final String _nativeValue;
const WebViewFeature._internal(this._value, this._nativeValue);
// ignore: unused_element
factory WebViewFeature._internalMultiPlatform(
String value, Function nativeValue) =>
WebViewFeature._internal(value, nativeValue());
static const _channel = const MethodChannel(
'com.pichillilorenzo/flutter_inappwebview_webviewfeature');
///This feature covers [InAppWebViewController.createWebMessageChannel].
static const CREATE_WEB_MESSAGE_CHANNEL = WebViewFeature._internal(
'CREATE_WEB_MESSAGE_CHANNEL', 'CREATE_WEB_MESSAGE_CHANNEL');
///This feature covers [InAppWebViewSettings.disabledActionModeMenuItems].
static const DISABLED_ACTION_MODE_MENU_ITEMS = WebViewFeature._internal(
'DISABLED_ACTION_MODE_MENU_ITEMS', 'DISABLED_ACTION_MODE_MENU_ITEMS');
///This feature covers [InAppWebViewSettings.forceDark].
static const FORCE_DARK =
WebViewFeature._internal('FORCE_DARK', 'FORCE_DARK');
///This feature covers [InAppWebViewSettings.forceDarkStrategy].
static const FORCE_DARK_STRATEGY =
WebViewFeature._internal('FORCE_DARK_STRATEGY', 'FORCE_DARK_STRATEGY');
///
static const GET_WEB_CHROME_CLIENT = WebViewFeature._internal(
'GET_WEB_CHROME_CLIENT', 'GET_WEB_CHROME_CLIENT');
///
static const GET_WEB_VIEW_CLIENT =
WebViewFeature._internal('GET_WEB_VIEW_CLIENT', 'GET_WEB_VIEW_CLIENT');
///
static const GET_WEB_VIEW_RENDERER = WebViewFeature._internal(
'GET_WEB_VIEW_RENDERER', 'GET_WEB_VIEW_RENDERER');
///
static const MULTI_PROCESS =
WebViewFeature._internal('MULTI_PROCESS', 'MULTI_PROCESS');
///This feature covers [InAppWebViewSettings.offscreenPreRaster].
static const OFF_SCREEN_PRERASTER =
WebViewFeature._internal('OFF_SCREEN_PRERASTER', 'OFF_SCREEN_PRERASTER');
///This feature covers [InAppWebViewController.postWebMessage].
static const POST_WEB_MESSAGE =
WebViewFeature._internal('POST_WEB_MESSAGE', 'POST_WEB_MESSAGE');
///This feature covers [ProxyController.setProxyOverride] and [ProxyController.clearProxyOverride].
static const PROXY_OVERRIDE =
WebViewFeature._internal('PROXY_OVERRIDE', 'PROXY_OVERRIDE');
///
static const RECEIVE_HTTP_ERROR =
WebViewFeature._internal('RECEIVE_HTTP_ERROR', 'RECEIVE_HTTP_ERROR');
///
static const RECEIVE_WEB_RESOURCE_ERROR = WebViewFeature._internal(
'RECEIVE_WEB_RESOURCE_ERROR', 'RECEIVE_WEB_RESOURCE_ERROR');
///This feature covers [InAppWebViewController.setSafeBrowsingAllowlist].
static const SAFE_BROWSING_ALLOWLIST = WebViewFeature._internal(
'SAFE_BROWSING_ALLOWLIST', 'SAFE_BROWSING_ALLOWLIST');
///This feature covers [InAppWebViewSettings.safeBrowsingEnabled].
static const SAFE_BROWSING_ENABLE =
WebViewFeature._internal('SAFE_BROWSING_ENABLE', 'SAFE_BROWSING_ENABLE');
///
static const SAFE_BROWSING_HIT =
WebViewFeature._internal('SAFE_BROWSING_HIT', 'SAFE_BROWSING_HIT');
///This feature covers [InAppWebViewController.getSafeBrowsingPrivacyPolicyUrl].
static const SAFE_BROWSING_PRIVACY_POLICY_URL = WebViewFeature._internal(
'SAFE_BROWSING_PRIVACY_POLICY_URL', 'SAFE_BROWSING_PRIVACY_POLICY_URL');
///
static const SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = WebViewFeature._internal(
'SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY',
'SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY');
///
static const SAFE_BROWSING_RESPONSE_PROCEED = WebViewFeature._internal(
'SAFE_BROWSING_RESPONSE_PROCEED', 'SAFE_BROWSING_RESPONSE_PROCEED');
///
static const SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL =
WebViewFeature._internal('SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL',
'SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL');
///Use [SAFE_BROWSING_ALLOWLIST] instead.
static const SAFE_BROWSING_WHITELIST = WebViewFeature._internal(
'SAFE_BROWSING_WHITELIST', 'SAFE_BROWSING_WHITELIST');
///This feature covers [ServiceWorkerController].
static const SERVICE_WORKER_BASIC_USAGE = WebViewFeature._internal(
'SERVICE_WORKER_BASIC_USAGE', 'SERVICE_WORKER_BASIC_USAGE');
///This feature covers [ServiceWorkerController.setBlockNetworkLoads] and [ServiceWorkerController.getBlockNetworkLoads].
static const SERVICE_WORKER_BLOCK_NETWORK_LOADS = WebViewFeature._internal(
'SERVICE_WORKER_BLOCK_NETWORK_LOADS',
'SERVICE_WORKER_BLOCK_NETWORK_LOADS');
///This feature covers [ServiceWorkerController.setCacheMode] and [ServiceWorkerController.getCacheMode].
static const SERVICE_WORKER_CACHE_MODE = WebViewFeature._internal(
'SERVICE_WORKER_CACHE_MODE', 'SERVICE_WORKER_CACHE_MODE');
///This feature covers [ServiceWorkerController.setAllowContentAccess] and [ServiceWorkerController.getAllowContentAccess].
static const SERVICE_WORKER_CONTENT_ACCESS = WebViewFeature._internal(
'SERVICE_WORKER_CONTENT_ACCESS', 'SERVICE_WORKER_CONTENT_ACCESS');
///This feature covers [ServiceWorkerController.setAllowFileAccess] and [ServiceWorkerController.getAllowFileAccess].
static const SERVICE_WORKER_FILE_ACCESS = WebViewFeature._internal(
'SERVICE_WORKER_FILE_ACCESS', 'SERVICE_WORKER_FILE_ACCESS');
///This feature covers [ServiceWorkerClient.shouldInterceptRequest].
static const SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST =
WebViewFeature._internal('SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST',
'SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST');
///
static const SHOULD_OVERRIDE_WITH_REDIRECTS = WebViewFeature._internal(
'SHOULD_OVERRIDE_WITH_REDIRECTS', 'SHOULD_OVERRIDE_WITH_REDIRECTS');
///This feature covers [InAppWebViewController.startSafeBrowsing].
static const START_SAFE_BROWSING =
WebViewFeature._internal('START_SAFE_BROWSING', 'START_SAFE_BROWSING');
///
static const TRACING_CONTROLLER_BASIC_USAGE = WebViewFeature._internal(
'TRACING_CONTROLLER_BASIC_USAGE', 'TRACING_CONTROLLER_BASIC_USAGE');
///
static const VISUAL_STATE_CALLBACK = WebViewFeature._internal(
'VISUAL_STATE_CALLBACK', 'VISUAL_STATE_CALLBACK');
///
static const WEB_MESSAGE_CALLBACK_ON_MESSAGE = WebViewFeature._internal(
'WEB_MESSAGE_CALLBACK_ON_MESSAGE', 'WEB_MESSAGE_CALLBACK_ON_MESSAGE');
///This feature covers [WebMessageListener].
static const WEB_MESSAGE_LISTENER =
WebViewFeature._internal('WEB_MESSAGE_LISTENER', 'WEB_MESSAGE_LISTENER');
///
static const WEB_MESSAGE_PORT_CLOSE = WebViewFeature._internal(
'WEB_MESSAGE_PORT_CLOSE', 'WEB_MESSAGE_PORT_CLOSE');
///
static const WEB_MESSAGE_PORT_POST_MESSAGE = WebViewFeature._internal(
'WEB_MESSAGE_PORT_POST_MESSAGE', 'WEB_MESSAGE_PORT_POST_MESSAGE');
///
static const WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = WebViewFeature._internal(
'WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK',
'WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK');
///
static const WEB_RESOURCE_ERROR_GET_CODE = WebViewFeature._internal(
'WEB_RESOURCE_ERROR_GET_CODE', 'WEB_RESOURCE_ERROR_GET_CODE');
///
static const WEB_RESOURCE_ERROR_GET_DESCRIPTION = WebViewFeature._internal(
'WEB_RESOURCE_ERROR_GET_DESCRIPTION',
'WEB_RESOURCE_ERROR_GET_DESCRIPTION');
///
static const WEB_RESOURCE_REQUEST_IS_REDIRECT = WebViewFeature._internal(
'WEB_RESOURCE_REQUEST_IS_REDIRECT', 'WEB_RESOURCE_REQUEST_IS_REDIRECT');
///
static const WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = WebViewFeature._internal(
'WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE',
'WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE');
///
static const WEB_VIEW_RENDERER_TERMINATE = WebViewFeature._internal(
'WEB_VIEW_RENDERER_TERMINATE', 'WEB_VIEW_RENDERER_TERMINATE');
///Set of all values of [WebViewFeature].
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.SAFE_BROWSING_WHITELIST,
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();
///Gets a possible [WebViewFeature] instance from [String] value.
static WebViewFeature? fromValue(String? value) {
if (value != null) {
try {
return WebViewFeature.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets a possible [WebViewFeature] instance from a native value.
static WebViewFeature? fromNativeValue(String? value) {
if (value != null) {
try {
return WebViewFeature.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///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.toNativeValue());
return await _channel.invokeMethod('isFeatureSupported', args);
}
///Gets [String] value.
String toValue() => _value;
///Gets [String] native value.
String toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
@override
String toString() {
return _value;
}
}
///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 {
final String _value;
final String _nativeValue;
const AndroidWebViewFeature._internal(this._value, this._nativeValue);
// ignore: unused_element
factory AndroidWebViewFeature._internalMultiPlatform(
String value, Function nativeValue) =>
AndroidWebViewFeature._internal(value, nativeValue());
static const _channel = const MethodChannel(
'com.pichillilorenzo/flutter_inappwebview_webviewfeature');
///
static const CREATE_WEB_MESSAGE_CHANNEL = AndroidWebViewFeature._internal(
'CREATE_WEB_MESSAGE_CHANNEL', 'CREATE_WEB_MESSAGE_CHANNEL');
///
static const DISABLED_ACTION_MODE_MENU_ITEMS =
AndroidWebViewFeature._internal(
'DISABLED_ACTION_MODE_MENU_ITEMS', 'DISABLED_ACTION_MODE_MENU_ITEMS');
///
static const FORCE_DARK =
AndroidWebViewFeature._internal('FORCE_DARK', 'FORCE_DARK');
///
static const FORCE_DARK_STRATEGY = AndroidWebViewFeature._internal(
'FORCE_DARK_STRATEGY', 'FORCE_DARK_STRATEGY');
///
static const GET_WEB_CHROME_CLIENT = AndroidWebViewFeature._internal(
'GET_WEB_CHROME_CLIENT', 'GET_WEB_CHROME_CLIENT');
///
static const GET_WEB_VIEW_CLIENT = AndroidWebViewFeature._internal(
'GET_WEB_VIEW_CLIENT', 'GET_WEB_VIEW_CLIENT');
///
static const GET_WEB_VIEW_RENDERER = AndroidWebViewFeature._internal(
'GET_WEB_VIEW_RENDERER', 'GET_WEB_VIEW_RENDERER');
///
static const MULTI_PROCESS =
AndroidWebViewFeature._internal('MULTI_PROCESS', 'MULTI_PROCESS');
///
static const OFF_SCREEN_PRERASTER = AndroidWebViewFeature._internal(
'OFF_SCREEN_PRERASTER', 'OFF_SCREEN_PRERASTER');
///
static const POST_WEB_MESSAGE =
AndroidWebViewFeature._internal('POST_WEB_MESSAGE', 'POST_WEB_MESSAGE');
///
static const PROXY_OVERRIDE =
AndroidWebViewFeature._internal('PROXY_OVERRIDE', 'PROXY_OVERRIDE');
///
static const RECEIVE_HTTP_ERROR = AndroidWebViewFeature._internal(
'RECEIVE_HTTP_ERROR', 'RECEIVE_HTTP_ERROR');
///
static const RECEIVE_WEB_RESOURCE_ERROR = AndroidWebViewFeature._internal(
'RECEIVE_WEB_RESOURCE_ERROR', 'RECEIVE_WEB_RESOURCE_ERROR');
///
static const SAFE_BROWSING_ALLOWLIST = AndroidWebViewFeature._internal(
'SAFE_BROWSING_ALLOWLIST', 'SAFE_BROWSING_ALLOWLIST');
///
static const SAFE_BROWSING_ENABLE = AndroidWebViewFeature._internal(
'SAFE_BROWSING_ENABLE', 'SAFE_BROWSING_ENABLE');
///
static const SAFE_BROWSING_HIT =
AndroidWebViewFeature._internal('SAFE_BROWSING_HIT', 'SAFE_BROWSING_HIT');
///
static const SAFE_BROWSING_PRIVACY_POLICY_URL =
AndroidWebViewFeature._internal('SAFE_BROWSING_PRIVACY_POLICY_URL',
'SAFE_BROWSING_PRIVACY_POLICY_URL');
///
static const SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY =
AndroidWebViewFeature._internal('SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY',
'SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY');
///
static const SAFE_BROWSING_RESPONSE_PROCEED = AndroidWebViewFeature._internal(
'SAFE_BROWSING_RESPONSE_PROCEED', 'SAFE_BROWSING_RESPONSE_PROCEED');
///
static const SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL =
AndroidWebViewFeature._internal(
'SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL',
'SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL');
///Use [SAFE_BROWSING_ALLOWLIST] instead.
static const SAFE_BROWSING_WHITELIST = AndroidWebViewFeature._internal(
'SAFE_BROWSING_WHITELIST', 'SAFE_BROWSING_WHITELIST');
///
static const SERVICE_WORKER_BASIC_USAGE = AndroidWebViewFeature._internal(
'SERVICE_WORKER_BASIC_USAGE', 'SERVICE_WORKER_BASIC_USAGE');
///
static const SERVICE_WORKER_BLOCK_NETWORK_LOADS =
AndroidWebViewFeature._internal('SERVICE_WORKER_BLOCK_NETWORK_LOADS',
'SERVICE_WORKER_BLOCK_NETWORK_LOADS');
///
static const SERVICE_WORKER_CACHE_MODE = AndroidWebViewFeature._internal(
'SERVICE_WORKER_CACHE_MODE', 'SERVICE_WORKER_CACHE_MODE');
///
static const SERVICE_WORKER_CONTENT_ACCESS = AndroidWebViewFeature._internal(
'SERVICE_WORKER_CONTENT_ACCESS', 'SERVICE_WORKER_CONTENT_ACCESS');
///
static const SERVICE_WORKER_FILE_ACCESS = AndroidWebViewFeature._internal(
'SERVICE_WORKER_FILE_ACCESS', 'SERVICE_WORKER_FILE_ACCESS');
///
static const SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST =
AndroidWebViewFeature._internal('SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST',
'SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST');
///
static const SHOULD_OVERRIDE_WITH_REDIRECTS = AndroidWebViewFeature._internal(
'SHOULD_OVERRIDE_WITH_REDIRECTS', 'SHOULD_OVERRIDE_WITH_REDIRECTS');
///
static const START_SAFE_BROWSING = AndroidWebViewFeature._internal(
'START_SAFE_BROWSING', 'START_SAFE_BROWSING');
///
static const TRACING_CONTROLLER_BASIC_USAGE = AndroidWebViewFeature._internal(
'TRACING_CONTROLLER_BASIC_USAGE', 'TRACING_CONTROLLER_BASIC_USAGE');
///
static const VISUAL_STATE_CALLBACK = AndroidWebViewFeature._internal(
'VISUAL_STATE_CALLBACK', 'VISUAL_STATE_CALLBACK');
///
static const WEB_MESSAGE_CALLBACK_ON_MESSAGE =
AndroidWebViewFeature._internal(
'WEB_MESSAGE_CALLBACK_ON_MESSAGE', 'WEB_MESSAGE_CALLBACK_ON_MESSAGE');
///
static const WEB_MESSAGE_LISTENER = AndroidWebViewFeature._internal(
'WEB_MESSAGE_LISTENER', 'WEB_MESSAGE_LISTENER');
///
static const WEB_MESSAGE_PORT_CLOSE = AndroidWebViewFeature._internal(
'WEB_MESSAGE_PORT_CLOSE', 'WEB_MESSAGE_PORT_CLOSE');
///
static const WEB_MESSAGE_PORT_POST_MESSAGE = AndroidWebViewFeature._internal(
'WEB_MESSAGE_PORT_POST_MESSAGE', 'WEB_MESSAGE_PORT_POST_MESSAGE');
///
static const WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK =
AndroidWebViewFeature._internal('WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK',
'WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK');
///
static const WEB_RESOURCE_ERROR_GET_CODE = AndroidWebViewFeature._internal(
'WEB_RESOURCE_ERROR_GET_CODE', 'WEB_RESOURCE_ERROR_GET_CODE');
///
static const WEB_RESOURCE_ERROR_GET_DESCRIPTION =
AndroidWebViewFeature._internal('WEB_RESOURCE_ERROR_GET_DESCRIPTION',
'WEB_RESOURCE_ERROR_GET_DESCRIPTION');
///
static const WEB_RESOURCE_REQUEST_IS_REDIRECT =
AndroidWebViewFeature._internal('WEB_RESOURCE_REQUEST_IS_REDIRECT',
'WEB_RESOURCE_REQUEST_IS_REDIRECT');
///
static const WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE =
AndroidWebViewFeature._internal('WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE',
'WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE');
///
static const WEB_VIEW_RENDERER_TERMINATE = AndroidWebViewFeature._internal(
'WEB_VIEW_RENDERER_TERMINATE', 'WEB_VIEW_RENDERER_TERMINATE');
///Set of all values of [AndroidWebViewFeature].
static final Set<AndroidWebViewFeature> values = [
AndroidWebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
AndroidWebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS,
AndroidWebViewFeature.FORCE_DARK,
AndroidWebViewFeature.FORCE_DARK_STRATEGY,
AndroidWebViewFeature.GET_WEB_CHROME_CLIENT,
AndroidWebViewFeature.GET_WEB_VIEW_CLIENT,
AndroidWebViewFeature.GET_WEB_VIEW_RENDERER,
AndroidWebViewFeature.MULTI_PROCESS,
AndroidWebViewFeature.OFF_SCREEN_PRERASTER,
AndroidWebViewFeature.POST_WEB_MESSAGE,
AndroidWebViewFeature.PROXY_OVERRIDE,
AndroidWebViewFeature.RECEIVE_HTTP_ERROR,
AndroidWebViewFeature.RECEIVE_WEB_RESOURCE_ERROR,
AndroidWebViewFeature.SAFE_BROWSING_ALLOWLIST,
AndroidWebViewFeature.SAFE_BROWSING_ENABLE,
AndroidWebViewFeature.SAFE_BROWSING_HIT,
AndroidWebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL,
AndroidWebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY,
AndroidWebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED,
AndroidWebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL,
AndroidWebViewFeature.SAFE_BROWSING_WHITELIST,
AndroidWebViewFeature.SERVICE_WORKER_BASIC_USAGE,
AndroidWebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS,
AndroidWebViewFeature.SERVICE_WORKER_CACHE_MODE,
AndroidWebViewFeature.SERVICE_WORKER_CONTENT_ACCESS,
AndroidWebViewFeature.SERVICE_WORKER_FILE_ACCESS,
AndroidWebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST,
AndroidWebViewFeature.SHOULD_OVERRIDE_WITH_REDIRECTS,
AndroidWebViewFeature.START_SAFE_BROWSING,
AndroidWebViewFeature.TRACING_CONTROLLER_BASIC_USAGE,
AndroidWebViewFeature.VISUAL_STATE_CALLBACK,
AndroidWebViewFeature.WEB_MESSAGE_CALLBACK_ON_MESSAGE,
AndroidWebViewFeature.WEB_MESSAGE_LISTENER,
AndroidWebViewFeature.WEB_MESSAGE_PORT_CLOSE,
AndroidWebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE,
AndroidWebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK,
AndroidWebViewFeature.WEB_RESOURCE_ERROR_GET_CODE,
AndroidWebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION,
AndroidWebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
AndroidWebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE,
AndroidWebViewFeature.WEB_VIEW_RENDERER_TERMINATE,
].toSet();
///Gets a possible [AndroidWebViewFeature] instance from [String] value.
static AndroidWebViewFeature? fromValue(String? value) {
if (value != null) {
try {
return AndroidWebViewFeature.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets a possible [AndroidWebViewFeature] instance from a native value.
static AndroidWebViewFeature? fromNativeValue(String? value) {
if (value != null) {
try {
return AndroidWebViewFeature.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///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(AndroidWebViewFeature feature) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent("feature", () => feature.toNativeValue());
return await _channel.invokeMethod('isFeatureSupported', args);
}
///Gets [String] value.
String toValue() => _value;
///Gets [String] native value.
String toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
@override
String toString() {
return _value;
}
}

View File

@ -95,7 +95,7 @@ class AndroidChromeCustomTabsOptions
return {
// ignore: deprecated_member_use_from_same_package
"addDefaultShareMenuItem": addDefaultShareMenuItem,
"shareState": shareState.toValue(),
"shareState": shareState.toNativeValue(),
"showTitle": showTitle,
"toolbarBackgroundColor": toolbarBackgroundColor?.toHex(),
"enableUrlBarHiding": enableUrlBarHiding,
@ -107,7 +107,7 @@ class AndroidChromeCustomTabsOptions
"isTrustedWebActivity": isTrustedWebActivity,
"additionalTrustedOrigins": additionalTrustedOrigins,
"displayMode": displayMode?.toMap(),
"screenOrientation": screenOrientation.toValue()
"screenOrientation": screenOrientation.toNativeValue()
};
}

View File

@ -53,11 +53,11 @@ class IOSSafariOptions implements ChromeSafariBrowserOptions, IosOptions {
return {
"entersReaderIfAvailable": entersReaderIfAvailable,
"barCollapsingEnabled": barCollapsingEnabled,
"dismissButtonStyle": dismissButtonStyle.toValue(),
"dismissButtonStyle": dismissButtonStyle.toNativeValue(),
"preferredBarTintColor": preferredBarTintColor?.toHex(),
"preferredControlTintColor": preferredControlTintColor?.toHex(),
"presentationStyle": presentationStyle.toValue(),
"transitionStyle": transitionStyle.toValue()
"presentationStyle": presentationStyle.toNativeValue(),
"transitionStyle": transitionStyle.toNativeValue()
};
}
@ -66,15 +66,15 @@ class IOSSafariOptions implements ChromeSafariBrowserOptions, IosOptions {
options.entersReaderIfAvailable = map["entersReaderIfAvailable"];
options.barCollapsingEnabled = map["barCollapsingEnabled"];
options.dismissButtonStyle =
IOSSafariDismissButtonStyle.fromValue(map["dismissButtonStyle"])!;
IOSSafariDismissButtonStyle.fromNativeValue(map["dismissButtonStyle"])!;
options.preferredBarTintColor =
UtilColor.fromHex(map["preferredBarTintColor"]);
options.preferredControlTintColor =
UtilColor.fromHex(map["preferredControlTintColor"]);
options.presentationStyle =
IOSUIModalPresentationStyle.fromValue(map["presentationStyle"])!;
IOSUIModalPresentationStyle.fromNativeValue(map["presentationStyle"])!;
options.transitionStyle =
IOSUIModalTransitionStyle.fromValue(map["transitionStyle"])!;
IOSUIModalTransitionStyle.fromNativeValue(map["transitionStyle"])!;
return options;
}

View File

@ -62,7 +62,14 @@ class ChromeSafariBrowser {
id = IdGenerator.generate();
this._channel =
MethodChannel('com.pichillilorenzo/flutter_chromesafaribrowser_$id');
this._channel.setMethodCallHandler(_handleMethod);
this._channel.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
_isOpened = false;
}
@ -83,7 +90,11 @@ class ChromeSafariBrowser {
if (maxLogMessageLength >= 0 && message.length > maxLogMessageLength) {
message = message.substring(0, maxLogMessageLength) + "...";
}
developer.log(message, name: this.runtimeType.toString());
if (!ChromeSafariBrowser.debugLoggingSettings.usePrint) {
developer.log(message, name: this.runtimeType.toString());
} else {
print("[${this.runtimeType.toString()}] $message");
}
}
}

View File

@ -201,7 +201,7 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
@override
Map<String, dynamic> toMap() {
return {
"shareState": shareState.toValue(),
"shareState": shareState.toNativeValue(),
"showTitle": showTitle,
"toolbarBackgroundColor": toolbarBackgroundColor?.toHex(),
"enableUrlBarHiding": enableUrlBarHiding,
@ -213,14 +213,14 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
"isTrustedWebActivity": isTrustedWebActivity,
"additionalTrustedOrigins": additionalTrustedOrigins,
"displayMode": displayMode?.toMap(),
"screenOrientation": screenOrientation.toValue(),
"screenOrientation": screenOrientation.toNativeValue(),
"entersReaderIfAvailable": entersReaderIfAvailable,
"barCollapsingEnabled": barCollapsingEnabled,
"dismissButtonStyle": dismissButtonStyle.toValue(),
"dismissButtonStyle": dismissButtonStyle.toNativeValue(),
"preferredBarTintColor": preferredBarTintColor?.toHex(),
"preferredControlTintColor": preferredControlTintColor?.toHex(),
"presentationStyle": presentationStyle.toValue(),
"transitionStyle": transitionStyle.toValue()
"presentationStyle": presentationStyle.toNativeValue(),
"transitionStyle": transitionStyle.toNativeValue()
};
}
@ -256,15 +256,15 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
settings.entersReaderIfAvailable = map["entersReaderIfAvailable"];
settings.barCollapsingEnabled = map["barCollapsingEnabled"];
settings.dismissButtonStyle =
DismissButtonStyle.fromValue(map["dismissButtonStyle"])!;
DismissButtonStyle.fromNativeValue(map["dismissButtonStyle"])!;
settings.preferredBarTintColor =
UtilColor.fromHex(map["preferredBarTintColor"]);
settings.preferredControlTintColor =
UtilColor.fromHex(map["preferredControlTintColor"]);
settings.presentationStyle =
ModalPresentationStyle.fromValue(map["presentationStyle"])!;
ModalPresentationStyle.fromNativeValue(map["presentationStyle"])!;
settings.transitionStyle =
ModalTransitionStyle.fromValue(map["transitionStyle"])!;
ModalTransitionStyle.fromNativeValue(map["transitionStyle"])!;
}
return settings;
}

View File

@ -88,11 +88,11 @@ class ContentBlockerTrigger {
Map<String, dynamic> toMap() {
List<String> resourceTypeStringList = [];
resourceType.forEach((type) {
resourceTypeStringList.add(type.toValue());
resourceTypeStringList.add(type.toNativeValue());
});
List<String> loadTypeStringList = [];
loadType.forEach((type) {
loadTypeStringList.add(type.toValue());
loadTypeStringList.add(type.toNativeValue());
});
Map<String, dynamic> map = {
@ -123,7 +123,7 @@ class ContentBlockerTrigger {
List<String> resourceTypeStringList =
List<String>.from(map["resource-type"] ?? []);
resourceTypeStringList.forEach((typeValue) {
var type = ContentBlockerTriggerResourceType.fromValue(typeValue);
var type = ContentBlockerTriggerResourceType.fromNativeValue(typeValue);
if (type != null) {
resourceType.add(type);
}
@ -131,7 +131,7 @@ class ContentBlockerTrigger {
List<String> loadTypeStringList = List<String>.from(map["load-type"] ?? []);
loadTypeStringList.forEach((typeValue) {
var type = ContentBlockerTriggerLoadType.fromValue(typeValue);
var type = ContentBlockerTriggerLoadType.fromNativeValue(typeValue);
if (type != null) {
loadType.add(type);
}
@ -172,7 +172,7 @@ class ContentBlockerAction {
}
Map<String, dynamic> toMap() {
Map<String, dynamic> map = {"type": type.toValue(), "selector": selector};
Map<String, dynamic> map = {"type": type.toNativeValue(), "selector": selector};
map.keys
.where((key) =>
@ -186,7 +186,7 @@ class ContentBlockerAction {
static ContentBlockerAction fromMap(Map<String, dynamic> map) {
return ContentBlockerAction(
type: ContentBlockerActionType.fromValue(map["type"])!,
type: ContentBlockerActionType.fromNativeValue(map["type"])!,
selector: map["selector"]);
}
}

View File

@ -42,7 +42,14 @@ class CookieManager {
}
static CookieManager _init() {
_channel.setMethodCallHandler(_handleMethod);
_channel.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
_instance = CookieManager();
// ignore: deprecated_member_use_from_same_package
_instance!.ios = IOSCookieManager.instance();
@ -128,7 +135,7 @@ class CookieManager {
args.putIfAbsent('maxAge', () => maxAge);
args.putIfAbsent('isSecure', () => isSecure);
args.putIfAbsent('isHttpOnly', () => isHttpOnly);
args.putIfAbsent('sameSite', () => sameSite?.toValue());
args.putIfAbsent('sameSite', () => sameSite?.toNativeValue());
await _channel.invokeMethod('setCookie', args);
}
@ -154,7 +161,7 @@ class CookieManager {
if (isSecure != null && isSecure) cookieValue += "; Secure";
if (sameSite != null) cookieValue += "; SameSite=" + sameSite.toValue();
if (sameSite != null) cookieValue += "; SameSite=" + sameSite.toNativeValue();
cookieValue += ";";
@ -236,7 +243,7 @@ class CookieManager {
expiresDate: cookieMap["expiresDate"],
isSessionOnly: cookieMap["isSessionOnly"],
domain: cookieMap["domain"],
sameSite: HTTPCookieSameSitePolicy.fromValue(cookieMap["sameSite"]),
sameSite: HTTPCookieSameSitePolicy.fromNativeValue(cookieMap["sameSite"]),
isSecure: cookieMap["isSecure"],
isHttpOnly: cookieMap["isHttpOnly"],
path: cookieMap["path"]));
@ -358,7 +365,7 @@ class CookieManager {
isSessionOnly: cookies[i]["isSessionOnly"],
domain: cookies[i]["domain"],
sameSite:
HTTPCookieSameSitePolicy.fromValue(cookies[i]["sameSite"]),
HTTPCookieSameSitePolicy.fromNativeValue(cookies[i]["sameSite"]),
isSecure: cookies[i]["isSecure"],
isHttpOnly: cookies[i]["isHttpOnly"],
path: cookies[i]["path"]);
@ -526,7 +533,7 @@ class CookieManager {
expiresDate: cookieMap["expiresDate"],
isSessionOnly: cookieMap["isSessionOnly"],
domain: cookieMap["domain"],
sameSite: HTTPCookieSameSitePolicy.fromValue(cookieMap["sameSite"]),
sameSite: HTTPCookieSameSitePolicy.fromNativeValue(cookieMap["sameSite"]),
isSecure: cookieMap["isSecure"],
isHttpOnly: cookieMap["isHttpOnly"],
path: cookieMap["path"]));
@ -588,7 +595,7 @@ class IOSCookieManager {
expiresDate: cookieMap["expiresDate"],
isSessionOnly: cookieMap["isSessionOnly"],
domain: cookieMap["domain"],
sameSite: HTTPCookieSameSitePolicy.fromValue(cookieMap["sameSite"]),
sameSite: HTTPCookieSameSitePolicy.fromNativeValue(cookieMap["sameSite"]),
isSecure: cookieMap["isSecure"],
isHttpOnly: cookieMap["isHttpOnly"],
path: cookieMap["path"]));

View File

@ -1,8 +1,9 @@
import 'package:flutter/foundation.dart';
import 'in_app_webview/webview.dart';
import 'chrome_safari_browser/chrome_safari_browser.dart';
import 'in_app_browser/in_app_browser.dart';
///Class that represents the debug logging settings used by [WebView] and [ChromeSafariBrowser].
///Class that represents the debug logging settings used by [WebView], [InAppBrowser] and [ChromeSafariBrowser].
class DebugLoggingSettings {
///Enables debug logging info.
///
@ -20,9 +21,13 @@ class DebugLoggingSettings {
///The default value is `-1`.
int maxLogMessageLength;
///Use [print] instead of `developer.log` to log messages.
bool usePrint;
DebugLoggingSettings({
this.enabled = kDebugMode,
this.excludeFilter = const [],
this.maxLogMessageLength = -1
this.maxLogMessageLength = -1,
this.usePrint = false
});
}

View File

@ -23,7 +23,14 @@ class HttpAuthCredentialDatabase {
}
static HttpAuthCredentialDatabase _init() {
_channel.setMethodCallHandler(_handleMethod);
_channel.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
_instance = HttpAuthCredentialDatabase();
return _instance!;
}

View File

@ -68,8 +68,8 @@ class IOSInAppBrowserOptions implements BrowserOptions, IosOptions {
"toolbarBottomTranslucent": toolbarBottomTranslucent,
"closeButtonCaption": closeButtonCaption,
"closeButtonColor": closeButtonColor?.toHex(),
"presentationStyle": presentationStyle.toValue(),
"transitionStyle": transitionStyle.toValue(),
"presentationStyle": presentationStyle.toNativeValue(),
"transitionStyle": transitionStyle.toNativeValue(),
};
}
@ -87,9 +87,9 @@ class IOSInAppBrowserOptions implements BrowserOptions, IosOptions {
instance.closeButtonCaption = map["closeButtonCaption"];
instance.closeButtonColor = UtilColor.fromHex(map["closeButtonColor"]);
instance.presentationStyle =
IOSUIModalPresentationStyle.fromValue(map["presentationStyle"])!;
IOSUIModalPresentationStyle.fromNativeValue(map["presentationStyle"])!;
instance.transitionStyle =
IOSUIModalTransitionStyle.fromValue(map["transitionStyle"])!;
IOSUIModalTransitionStyle.fromNativeValue(map["transitionStyle"])!;
return instance;
}

View File

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:collection';
import 'dart:typed_data';
import 'dart:developer' as developer;
import 'package:flutter/services.dart';
@ -14,6 +15,7 @@ import '../in_app_webview/in_app_webview_settings.dart';
import '../util.dart';
import '../print_job/main.dart';
import 'in_app_browser_settings.dart';
import '../debug_logging_settings.dart';
class InAppBrowserAlreadyOpenedException implements Exception {
final dynamic message;
@ -46,6 +48,9 @@ class InAppBrowserNotOpenedException implements Exception {
///- Android native WebView
///- iOS
class InAppBrowser {
///Debug settings.
static DebugLoggingSettings debugLoggingSettings = DebugLoggingSettings();
///View ID used internally.
late final String id;
@ -80,20 +85,54 @@ class InAppBrowser {
id = IdGenerator.generate();
this._channel =
MethodChannel('com.pichillilorenzo/flutter_inappbrowser_$id');
this._channel.setMethodCallHandler(_handleMethod);
this._channel.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
_isOpened = false;
webViewController = new InAppWebViewController.fromInAppBrowser(
this._channel, this, this.initialUserScripts);
}
_debugLog(String method, dynamic args) {
if (InAppBrowser.debugLoggingSettings.enabled) {
for (var regExp
in InAppBrowser.debugLoggingSettings.excludeFilter) {
if (regExp.hasMatch(method)) return;
}
var maxLogMessageLength =
InAppBrowser.debugLoggingSettings.maxLogMessageLength;
String message = "InAppBrowser ID " +
id +
" calling \"" +
method.toString() +
"\" using " +
args.toString();
if (maxLogMessageLength >= 0 && message.length > maxLogMessageLength) {
message = message.substring(0, maxLogMessageLength) + "...";
}
if (!InAppBrowser.debugLoggingSettings.usePrint) {
developer.log(message, name: this.runtimeType.toString());
} else {
print("[${this.runtimeType.toString()}] $message");
}
}
}
Future<dynamic> _handleMethod(MethodCall call) async {
switch (call.method) {
case "onBrowserCreated":
_debugLog(call.method, call.arguments);
this._isOpened = true;
this.pullToRefreshController?.initMethodChannel(id);
onBrowserCreated();
break;
case "onExit":
_debugLog(call.method, call.arguments);
this._isOpened = false;
onExit();
break;
@ -133,7 +172,7 @@ class InAppBrowser {
args.putIfAbsent('settings', () => initialSettings);
args.putIfAbsent('contextMenu', () => contextMenu?.toMap() ?? {});
args.putIfAbsent('windowId', () => windowId);
args.putIfAbsent('implementation', () => implementation.toValue());
args.putIfAbsent('implementation', () => implementation.toNativeValue());
args.putIfAbsent('initialUserScripts',
() => initialUserScripts?.map((e) => e.toMap()).toList() ?? []);
args.putIfAbsent('pullToRefreshSettings', () => pullToRefreshSettings);
@ -201,7 +240,7 @@ class InAppBrowser {
args.putIfAbsent('settings', () => initialSettings);
args.putIfAbsent('contextMenu', () => contextMenu?.toMap() ?? {});
args.putIfAbsent('windowId', () => windowId);
args.putIfAbsent('implementation', () => implementation.toValue());
args.putIfAbsent('implementation', () => implementation.toNativeValue());
args.putIfAbsent('initialUserScripts',
() => initialUserScripts?.map((e) => e.toMap()).toList() ?? []);
args.putIfAbsent('pullToRefreshSettings', () => pullToRefreshSettings);
@ -252,7 +291,7 @@ class InAppBrowser {
() => (historyUrl ?? androidHistoryUrl)?.toString() ?? "about:blank");
args.putIfAbsent('contextMenu', () => contextMenu?.toMap() ?? {});
args.putIfAbsent('windowId', () => windowId);
args.putIfAbsent('implementation', () => implementation.toValue());
args.putIfAbsent('implementation', () => implementation.toNativeValue());
args.putIfAbsent('initialUserScripts',
() => initialUserScripts?.map((e) => e.toMap()).toList() ?? []);
args.putIfAbsent('pullToRefreshSettings', () => pullToRefreshSettings);

View File

@ -261,8 +261,8 @@ class InAppBrowserSettings
"toolbarBottomTranslucent": toolbarBottomTranslucent,
"closeButtonCaption": closeButtonCaption,
"closeButtonColor": closeButtonColor?.toHex(),
"presentationStyle": presentationStyle.toValue(),
"transitionStyle": transitionStyle.toValue(),
"presentationStyle": presentationStyle.toNativeValue(),
"transitionStyle": transitionStyle.toNativeValue(),
};
}
@ -296,9 +296,9 @@ class InAppBrowserSettings
settings.closeButtonCaption = map["closeButtonCaption"];
settings.closeButtonColor = UtilColor.fromHex(map["closeButtonColor"]);
settings.presentationStyle =
ModalPresentationStyle.fromValue(map["presentationStyle"])!;
ModalPresentationStyle.fromNativeValue(map["presentationStyle"])!;
settings.transitionStyle =
ModalTransitionStyle.fromValue(map["transitionStyle"])!;
ModalTransitionStyle.fromNativeValue(map["transitionStyle"])!;
}
return settings;
}

View File

@ -307,23 +307,23 @@ class AndroidInAppWebViewOptions
"domStorageEnabled": domStorageEnabled,
"useWideViewPort": useWideViewPort,
"safeBrowsingEnabled": safeBrowsingEnabled,
"mixedContentMode": mixedContentMode?.toValue(),
"mixedContentMode": mixedContentMode?.toNativeValue(),
"allowContentAccess": allowContentAccess,
"allowFileAccess": allowFileAccess,
"appCachePath": appCachePath,
"blockNetworkImage": blockNetworkImage,
"blockNetworkLoads": blockNetworkLoads,
"cacheMode": cacheMode?.toValue(),
"cacheMode": cacheMode?.toNativeValue(),
"cursiveFontFamily": cursiveFontFamily,
"defaultFixedFontSize": defaultFixedFontSize,
"defaultFontSize": defaultFontSize,
"defaultTextEncodingName": defaultTextEncodingName,
"disabledActionModeMenuItems": disabledActionModeMenuItems?.toValue(),
"disabledActionModeMenuItems": disabledActionModeMenuItems?.toNativeValue(),
"fantasyFontFamily": fantasyFontFamily,
"fixedFontFamily": fixedFontFamily,
"forceDark": forceDark?.toValue(),
"forceDark": forceDark?.toNativeValue(),
"geolocationEnabled": geolocationEnabled,
"layoutAlgorithm": layoutAlgorithm?.toValue(),
"layoutAlgorithm": layoutAlgorithm?.toNativeValue(),
"loadWithOverviewMode": loadWithOverviewMode,
"loadsImagesAutomatically": loadsImagesAutomatically,
"minimumLogicalFontSize": minimumLogicalFontSize,
@ -341,10 +341,10 @@ class AndroidInAppWebViewOptions
"regexToCancelSubFramesLoading": regexToCancelSubFramesLoading,
"useShouldInterceptRequest": useShouldInterceptRequest,
"useOnRenderProcessGone": useOnRenderProcessGone,
"overScrollMode": overScrollMode?.toValue(),
"overScrollMode": overScrollMode?.toNativeValue(),
"networkAvailable": networkAvailable,
"scrollBarStyle": scrollBarStyle?.toValue(),
"verticalScrollbarPosition": verticalScrollbarPosition?.toValue(),
"scrollBarStyle": scrollBarStyle?.toNativeValue(),
"verticalScrollbarPosition": verticalScrollbarPosition?.toNativeValue(),
"scrollBarDefaultDelayBeforeFade": scrollBarDefaultDelayBeforeFade,
"scrollbarFadingEnabled": scrollbarFadingEnabled,
"scrollBarFadeDuration": scrollBarFadeDuration,
@ -368,25 +368,25 @@ class AndroidInAppWebViewOptions
instance.useWideViewPort = map["useWideViewPort"];
instance.safeBrowsingEnabled = map["safeBrowsingEnabled"];
instance.mixedContentMode =
AndroidMixedContentMode.fromValue(map["mixedContentMode"]);
AndroidMixedContentMode.fromNativeValue(map["mixedContentMode"]);
instance.allowContentAccess = map["allowContentAccess"];
instance.allowFileAccess = map["allowFileAccess"];
instance.appCachePath = map["appCachePath"];
instance.blockNetworkImage = map["blockNetworkImage"];
instance.blockNetworkLoads = map["blockNetworkLoads"];
instance.cacheMode = AndroidCacheMode.fromValue(map["cacheMode"]);
instance.cacheMode = AndroidCacheMode.fromNativeValue(map["cacheMode"]);
instance.cursiveFontFamily = map["cursiveFontFamily"];
instance.defaultFixedFontSize = map["defaultFixedFontSize"];
instance.defaultFontSize = map["defaultFontSize"];
instance.defaultTextEncodingName = map["defaultTextEncodingName"];
instance.disabledActionModeMenuItems =
AndroidActionModeMenuItem.fromValue(map["disabledActionModeMenuItems"]);
AndroidActionModeMenuItem.fromNativeValue(map["disabledActionModeMenuItems"]);
instance.fantasyFontFamily = map["fantasyFontFamily"];
instance.fixedFontFamily = map["fixedFontFamily"];
instance.forceDark = AndroidForceDark.fromValue(map["forceDark"]);
instance.forceDark = AndroidForceDark.fromNativeValue(map["forceDark"]);
instance.geolocationEnabled = map["geolocationEnabled"];
instance.layoutAlgorithm =
AndroidLayoutAlgorithm.fromValue(map["layoutAlgorithm"]);
AndroidLayoutAlgorithm.fromNativeValue(map["layoutAlgorithm"]);
instance.loadWithOverviewMode = map["loadWithOverviewMode"];
instance.loadsImagesAutomatically = map["loadsImagesAutomatically"];
instance.minimumLogicalFontSize = map["minimumLogicalFontSize"];
@ -406,12 +406,12 @@ class AndroidInAppWebViewOptions
instance.useShouldInterceptRequest = map["useShouldInterceptRequest"];
instance.useOnRenderProcessGone = map["useOnRenderProcessGone"];
instance.overScrollMode =
AndroidOverScrollMode.fromValue(map["overScrollMode"]);
AndroidOverScrollMode.fromNativeValue(map["overScrollMode"]);
instance.networkAvailable = map["networkAvailable"];
instance.scrollBarStyle =
AndroidScrollBarStyle.fromValue(map["scrollBarStyle"]);
AndroidScrollBarStyle.fromNativeValue(map["scrollBarStyle"]);
instance.verticalScrollbarPosition =
AndroidVerticalScrollbarPosition.fromValue(
AndroidVerticalScrollbarPosition.fromNativeValue(
map["verticalScrollbarPosition"]);
instance.scrollBarDefaultDelayBeforeFade =
map["scrollBarDefaultDelayBeforeFade"];

View File

@ -196,8 +196,8 @@ class IOSInAppWebViewOptions
///- [IOSInAppWebViewOptions.enableViewportScale]
///
///Events affected:
///- the `hitTestResult` argument of [WebView.onLongPressHitTestResult] will be empty
///- the `hitTestResult` argument of [ContextMenu.onCreateContextMenu] will be empty
///- the `hitTestResult` argument of [WebView.onLongPressHitTestResult] will be empty
///- the `hitTestResult` argument of [ContextMenu.onCreateContextMenu] will be empty
///- [WebView.onLoadResource]
///- [WebView.shouldInterceptAjaxRequest]
///- [WebView.onAjaxReadyStateChange]
@ -214,7 +214,7 @@ class IOSInAppWebViewOptions
///Used in combination with [WebView.initialUrlRequest] or [WebView.initialData] (using the `file://` scheme), it represents the URL from which to read the web content.
///This URL must be a file-based URL (using the `file://` scheme).
///Specify the same value as the [URLRequest.url] if you are using it with the [WebView.initialUrlRequest] parameter or
///Specify the same value as the [URLRequest.url] if you are using it with the [WebView.initialUrlRequest] parameter or
///the [InAppWebViewInitialData.baseUrl] if you are using it with the [WebView.initialData] parameter to prevent WebView from reading any other content.
///Specify a directory to give WebView permission to read additional files in the specified directory.
Uri? allowingReadAccessTo;
@ -270,7 +270,7 @@ class IOSInAppWebViewOptions
Map<String, dynamic> toMap() {
List<String> dataDetectorTypesList = [];
dataDetectorTypes.forEach((dataDetectorType) {
dataDetectorTypesList.add(dataDetectorType.toValue());
dataDetectorTypesList.add(dataDetectorType.toNativeValue());
});
return {
@ -286,13 +286,13 @@ class IOSInAppWebViewOptions
"allowsPictureInPictureMediaPlayback":
allowsPictureInPictureMediaPlayback,
"isFraudulentWebsiteWarningEnabled": isFraudulentWebsiteWarningEnabled,
"selectionGranularity": selectionGranularity.toValue(),
"selectionGranularity": selectionGranularity.toNativeValue(),
"dataDetectorTypes": dataDetectorTypesList,
"sharedCookiesEnabled": sharedCookiesEnabled,
"automaticallyAdjustsScrollIndicatorInsets":
automaticallyAdjustsScrollIndicatorInsets,
"accessibilityIgnoresInvertColors": accessibilityIgnoresInvertColors,
"decelerationRate": decelerationRate.toValue(),
"decelerationRate": decelerationRate.toNativeValue(),
"alwaysBounceVertical": alwaysBounceVertical,
"alwaysBounceHorizontal": alwaysBounceHorizontal,
"scrollsToTop": scrollsToTop,
@ -300,7 +300,7 @@ class IOSInAppWebViewOptions
"maximumZoomScale": maximumZoomScale,
"minimumZoomScale": minimumZoomScale,
"contentInsetAdjustmentBehavior":
contentInsetAdjustmentBehavior.toValue(),
contentInsetAdjustmentBehavior.toNativeValue(),
"isDirectionalLockEnabled": isDirectionalLockEnabled,
"mediaType": mediaType,
"pageZoom": pageZoom,
@ -319,7 +319,7 @@ class IOSInAppWebViewOptions
List<String>.from(map["dataDetectorTypes"] ?? []);
dataDetectorTypesList.forEach((dataDetectorTypeValue) {
var dataDetectorType =
IOSWKDataDetectorTypes.fromValue(dataDetectorTypeValue);
IOSWKDataDetectorTypes.fromNativeValue(dataDetectorTypeValue);
if (dataDetectorType != null) {
dataDetectorTypes.add(dataDetectorType);
}
@ -342,7 +342,7 @@ class IOSInAppWebViewOptions
instance.isFraudulentWebsiteWarningEnabled =
map["isFraudulentWebsiteWarningEnabled"];
instance.selectionGranularity =
IOSWKSelectionGranularity.fromValue(map["selectionGranularity"])!;
IOSWKSelectionGranularity.fromNativeValue(map["selectionGranularity"])!;
instance.dataDetectorTypes = dataDetectorTypes;
instance.sharedCookiesEnabled = map["sharedCookiesEnabled"];
instance.automaticallyAdjustsScrollIndicatorInsets =
@ -350,7 +350,7 @@ class IOSInAppWebViewOptions
instance.accessibilityIgnoresInvertColors =
map["accessibilityIgnoresInvertColors"];
instance.decelerationRate =
IOSUIScrollViewDecelerationRate.fromValue(map["decelerationRate"])!;
IOSUIScrollViewDecelerationRate.fromNativeValue(map["decelerationRate"])!;
instance.alwaysBounceVertical = map["alwaysBounceVertical"];
instance.alwaysBounceHorizontal = map["alwaysBounceHorizontal"];
instance.scrollsToTop = map["scrollsToTop"];
@ -358,7 +358,7 @@ class IOSInAppWebViewOptions
instance.maximumZoomScale = map["maximumZoomScale"];
instance.minimumZoomScale = map["minimumZoomScale"];
instance.contentInsetAdjustmentBehavior =
IOSUIScrollViewContentInsetAdjustmentBehavior.fromValue(
IOSUIScrollViewContentInsetAdjustmentBehavior.fromNativeValue(
map["contentInsetAdjustmentBehavior"])!;
instance.isDirectionalLockEnabled = map["isDirectionalLockEnabled"];
instance.mediaType = map["mediaType"];

View File

@ -159,7 +159,14 @@ class HeadlessInAppWebView implements WebView, Disposable {
webViewController = new InAppWebViewController(id, this);
this._channel =
MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview_$id');
this._channel.setMethodCallHandler(handleMethod);
this._channel.setMethodCallHandler((call) async {
try {
return await handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
}
Future<dynamic> handleMethod(MethodCall call) async {
@ -212,7 +219,7 @@ class HeadlessInAppWebView implements WebView, Disposable {
'initialSettings': initialSettings,
'contextMenu': this.contextMenu?.toMap() ?? {},
'windowId': this.windowId,
'implementation': this.implementation.toValue(),
'implementation': this.implementation.toNativeValue(),
'initialUserScripts':
this.initialUserScripts?.map((e) => e.toMap()).toList() ?? [],
'pullToRefreshSettings': pullToRefreshSettings,

View File

@ -646,7 +646,7 @@ class _InAppWebViewState extends State<InAppWebView> {
'initialSettings': initialSettings,
'contextMenu': widget.contextMenu?.toMap() ?? {},
'windowId': widget.windowId,
'implementation': widget.implementation.toValue(),
'implementation': widget.implementation.toNativeValue(),
'initialUserScripts':
widget.initialUserScripts?.map((e) => e.toMap()).toList() ??
[],
@ -673,7 +673,7 @@ class _InAppWebViewState extends State<InAppWebView> {
'initialSettings': initialSettings,
'contextMenu': widget.contextMenu?.toMap() ?? {},
'windowId': widget.windowId,
'implementation': widget.implementation.toValue(),
'implementation': widget.implementation.toNativeValue(),
'initialUserScripts':
widget.initialUserScripts?.map((e) => e.toMap()).toList() ?? [],
'pullToRefreshSettings': pullToRefreshSettings
@ -693,7 +693,7 @@ class _InAppWebViewState extends State<InAppWebView> {
'initialSettings': initialSettings,
'contextMenu': widget.contextMenu?.toMap() ?? {},
'windowId': widget.windowId,
'implementation': widget.implementation.toValue(),
'implementation': widget.implementation.toNativeValue(),
'initialUserScripts':
widget.initialUserScripts?.map((e) => e.toMap()).toList() ?? [],
'pullToRefreshSettings': pullToRefreshSettings

View File

@ -78,7 +78,14 @@ class InAppWebViewController {
this._id = id;
this._channel =
MethodChannel('com.pichillilorenzo/flutter_inappwebview_$id');
this._channel.setMethodCallHandler(handleMethod);
this._channel.setMethodCallHandler((call) async {
try {
return await handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
this._webview = webview;
this._userScripts =
List<UserScript>.from(webview.initialUserScripts ?? <UserScript>[]);
@ -123,7 +130,11 @@ class InAppWebViewController {
if (maxLogMessageLength >= 0 && message.length > maxLogMessageLength) {
message = message.substring(0, maxLogMessageLength) + "...";
}
developer.log(message, name: this.runtimeType.toString());
if (!WebView.debugLoggingSettings.usePrint) {
developer.log(message, name: this.runtimeType.toString());
} else {
print("[${this.runtimeType.toString()}] $message");
}
}
}
@ -175,13 +186,13 @@ class InAppWebViewController {
else if (isForMainFrame) {
// ignore: deprecated_member_use_from_same_package
_webview!.onLoadError!(this, request.url,
error.type.toNativeValue(), error.description);
error.type.toNativeValue() ?? -1, error.description);
}
} else {
if (isForMainFrame) {
_inAppBrowser!
// ignore: deprecated_member_use_from_same_package
.onLoadError(request.url, error.type.toNativeValue(),
.onLoadError(request.url, error.type.toNativeValue() ?? -1,
error.description);
}
_inAppBrowser!.onReceivedError(request, error);
@ -243,10 +254,10 @@ class InAppWebViewController {
if (_webview != null && _webview!.shouldOverrideUrlLoading != null)
return (await _webview!.shouldOverrideUrlLoading!(
this, navigationAction))
?.toMap();
?.toNativeValue();
return (await _inAppBrowser!
.shouldOverrideUrlLoading(navigationAction))
?.toMap();
?.toNativeValue();
}
break;
case "onConsoleMessage":
@ -445,19 +456,19 @@ class InAppWebViewController {
if (_webview != null) {
if (_webview!.onRenderProcessUnresponsive != null)
return (await _webview!.onRenderProcessUnresponsive!(this, uri))
?.toMap();
?.toNativeValue();
else {
// ignore: deprecated_member_use_from_same_package
return (await _webview!.androidOnRenderProcessUnresponsive!(
this, uri))
?.toMap();
?.toNativeValue();
}
} else {
return ((await _inAppBrowser!.onRenderProcessUnresponsive(uri)) ??
(await _inAppBrowser!
// ignore: deprecated_member_use_from_same_package
.androidOnRenderProcessUnresponsive(uri)))
?.toMap();
?.toNativeValue();
}
}
break;
@ -473,19 +484,19 @@ class InAppWebViewController {
if (_webview != null) {
if (_webview!.onRenderProcessResponsive != null)
return (await _webview!.onRenderProcessResponsive!(this, uri))
?.toMap();
?.toNativeValue();
else {
// ignore: deprecated_member_use_from_same_package
return (await _webview!.androidOnRenderProcessResponsive!(
this, uri))
?.toMap();
?.toNativeValue();
}
} else {
return ((await _inAppBrowser!.onRenderProcessResponsive(uri)) ??
(await _inAppBrowser!
// ignore: deprecated_member_use_from_same_package
.androidOnRenderProcessResponsive(uri)))
?.toMap();
?.toNativeValue();
}
}
break;
@ -525,17 +536,17 @@ class InAppWebViewController {
if (_webview != null) {
if (_webview!.onFormResubmission != null)
return (await _webview!.onFormResubmission!(this, uri))?.toMap();
return (await _webview!.onFormResubmission!(this, uri))?.toNativeValue();
else {
// ignore: deprecated_member_use_from_same_package
return (await _webview!.androidOnFormResubmission!(this, uri))
?.toMap();
?.toNativeValue();
}
} else {
return ((await _inAppBrowser!.onFormResubmission(uri)) ??
// ignore: deprecated_member_use_from_same_package
(await _inAppBrowser!.androidOnFormResubmission(uri)))
?.toMap();
?.toNativeValue();
}
}
break;
@ -692,7 +703,7 @@ class InAppWebViewController {
_inAppBrowser != null) {
String url = call.arguments["url"];
SafeBrowsingThreat? threatType =
SafeBrowsingThreat.fromValue(call.arguments["threatType"]);
SafeBrowsingThreat.fromNativeValue(call.arguments["threatType"]);
Uri uri = Uri.parse(url);
if (_webview != null) {
@ -924,21 +935,21 @@ class InAppWebViewController {
if (_webview!.onNavigationResponse != null)
return (await _webview!.onNavigationResponse!(
this, navigationResponse))
?.toMap();
?.toNativeValue();
else {
// ignore: deprecated_member_use_from_same_package
return (await _webview!.iosOnNavigationResponse!(
this, iosOnNavigationResponse))
?.toMap();
?.toNativeValue();
}
} else {
return (await _inAppBrowser!
.onNavigationResponse(navigationResponse))
?.toMap() ??
?.toNativeValue() ??
(await _inAppBrowser!
// ignore: deprecated_member_use_from_same_package
.iosOnNavigationResponse(iosOnNavigationResponse))
?.toMap();
?.toNativeValue();
}
}
break;
@ -957,19 +968,19 @@ class InAppWebViewController {
if (_webview!.shouldAllowDeprecatedTLS != null)
return (await _webview!.shouldAllowDeprecatedTLS!(
this, challenge))
?.toMap();
?.toNativeValue();
else {
// ignore: deprecated_member_use_from_same_package
return (await _webview!.iosShouldAllowDeprecatedTLS!(
this, challenge))
?.toMap();
?.toNativeValue();
}
} else {
return (await _inAppBrowser!.shouldAllowDeprecatedTLS(challenge))
?.toMap() ??
?.toNativeValue() ??
// ignore: deprecated_member_use_from_same_package
(await _inAppBrowser!.iosShouldAllowDeprecatedTLS(challenge))
?.toMap();
?.toNativeValue();
}
}
break;
@ -1139,9 +1150,9 @@ class InAppWebViewController {
_webview!.onCameraCaptureStateChanged != null) ||
_inAppBrowser != null) {
var oldState =
MediaCaptureState.fromValue(call.arguments["oldState"]);
MediaCaptureState.fromNativeValue(call.arguments["oldState"]);
var newState =
MediaCaptureState.fromValue(call.arguments["newState"]);
MediaCaptureState.fromNativeValue(call.arguments["newState"]);
if (_webview != null && _webview!.onCameraCaptureStateChanged != null)
_webview!.onCameraCaptureStateChanged!(this, oldState, newState);
@ -1154,9 +1165,9 @@ class InAppWebViewController {
_webview!.onMicrophoneCaptureStateChanged != null) ||
_inAppBrowser != null) {
var oldState =
MediaCaptureState.fromValue(call.arguments["oldState"]);
MediaCaptureState.fromNativeValue(call.arguments["oldState"]);
var newState =
MediaCaptureState.fromValue(call.arguments["newState"]);
MediaCaptureState.fromNativeValue(call.arguments["newState"]);
if (_webview != null &&
_webview!.onMicrophoneCaptureStateChanged != null)
@ -1217,11 +1228,9 @@ class InAppWebViewController {
AjaxRequest request = AjaxRequest.fromMap(arguments)!;
if (_webview != null && _webview!.onAjaxReadyStateChange != null)
return jsonEncode(
await _webview!.onAjaxReadyStateChange!(this, request));
return (await _webview!.onAjaxReadyStateChange!(this, request))?.toNativeValue();
else
return jsonEncode(
await _inAppBrowser!.onAjaxReadyStateChange(request));
return (await _inAppBrowser!.onAjaxReadyStateChange(request))?.toNativeValue();
}
return null;
case "onAjaxProgress":
@ -1231,10 +1240,9 @@ class InAppWebViewController {
AjaxRequest request = AjaxRequest.fromMap(arguments)!;
if (_webview != null && _webview!.onAjaxProgress != null)
return jsonEncode(
await _webview!.onAjaxProgress!(this, request));
return (await _webview!.onAjaxProgress!(this, request))?.toNativeValue();
else
return jsonEncode(await _inAppBrowser!.onAjaxProgress(request));
return (await _inAppBrowser!.onAjaxProgress(request))?.toNativeValue();
}
return null;
case "shouldInterceptFetchRequest":
@ -2281,7 +2289,7 @@ class InAppWebViewController {
///Prints the current page.
///
///To obtain the [PrintJobController], use [settings] argument with [PrintJobSettings.handledByClient] to `true`.
///Otherwise this method will return `null` and the [PrintJobController] will be handled and disposed automatically by the system.
///Otherwise this method will return `null` and the [PrintJobController] will be handled and disposed automatically by the system.
///
///**NOTE**: available on Android 19+.
///
@ -2418,7 +2426,7 @@ class InAppWebViewController {
hitTestResultMap = hitTestResultMap.cast<String, dynamic>();
InAppWebViewHitTestResultType? type =
InAppWebViewHitTestResultType.fromValue(
InAppWebViewHitTestResultType.fromNativeValue(
hitTestResultMap["type"]?.toInt());
String? extra = hitTestResultMap["extra"];
return InAppWebViewHitTestResult(type: type, extra: extra);
@ -2823,9 +2831,9 @@ class InAppWebViewController {
///[autoname] if `false`, takes [filePath] to be a file.
///If `true`, [filePath] is assumed to be a directory in which a filename will be chosen according to the URL of the current page.
///
///**NOTE for iOS**: Available on iOS 14.0+. If [autoname] is `false`, the [filePath] must ends with the [WebArchiveFormat.WEBARCHIVE] file extension.
///**NOTE for iOS**: Available on iOS 14.0+. If [autoname] is `false`, the [filePath] must ends with the [WebArchiveFormat.WEBARCHIVE] file extension.
///
///**NOTE for Android**: if [autoname] is `false`, the [filePath] must ends with the [WebArchiveFormat.MHT] file extension.
///**NOTE for Android**: if [autoname] is `false`, the [filePath] must ends with the [WebArchiveFormat.MHT] file extension.
///
///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebView.saveWebArchive](https://developer.android.com/reference/android/webkit/WebView#saveWebArchive(java.lang.String,%20boolean,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)))
@ -2834,9 +2842,9 @@ class InAppWebViewController {
{required String filePath, bool autoname = false}) async {
if (!autoname) {
if (defaultTargetPlatform == TargetPlatform.android) {
assert(filePath.endsWith("." + WebArchiveFormat.MHT.toValue()));
assert(filePath.endsWith("." + WebArchiveFormat.MHT.toNativeValue()));
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
assert(filePath.endsWith("." + WebArchiveFormat.WEBARCHIVE.toValue()));
assert(filePath.endsWith("." + WebArchiveFormat.WEBARCHIVE.toNativeValue()));
}
}
@ -3303,7 +3311,7 @@ class InAppWebViewController {
///- iOS ([Official API - WKWebView.requestMediaPlaybackState](https://developer.apple.com/documentation/webkit/wkwebview/3752241-requestmediaplaybackstate)).
Future<MediaPlaybackState?> requestMediaPlaybackState() async {
Map<String, dynamic> args = <String, dynamic>{};
return MediaPlaybackState.fromValue(
return MediaPlaybackState.fromNativeValue(
await _channel.invokeMethod('requestMediaPlaybackState', args));
}
@ -3325,7 +3333,7 @@ class InAppWebViewController {
///- iOS ([Official API - WKWebView.cameraCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763093-cameracapturestate)).
Future<MediaCaptureState?> getCameraCaptureState() async {
Map<String, dynamic> args = <String, dynamic>{};
return MediaCaptureState.fromValue(
return MediaCaptureState.fromNativeValue(
await _channel.invokeMethod('getCameraCaptureState', args));
}
@ -3337,7 +3345,7 @@ class InAppWebViewController {
///- iOS ([Official API - WKWebView.setCameraCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763097-setcameracapturestate)).
Future<void> setCameraCaptureState({required MediaCaptureState state}) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('state', () => state.toValue());
args.putIfAbsent('state', () => state.toNativeValue());
await _channel.invokeMethod('setCameraCaptureState', args);
}
@ -3349,7 +3357,7 @@ class InAppWebViewController {
///- iOS ([Official API - WKWebView.microphoneCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763096-microphonecapturestate)).
Future<MediaCaptureState?> getMicrophoneCaptureState() async {
Map<String, dynamic> args = <String, dynamic>{};
return MediaCaptureState.fromValue(
return MediaCaptureState.fromNativeValue(
await _channel.invokeMethod('getMicrophoneCaptureState', args));
}
@ -3362,7 +3370,7 @@ class InAppWebViewController {
Future<void> setMicrophoneCaptureState(
{required MediaCaptureState state}) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('state', () => state.toValue());
args.putIfAbsent('state', () => state.toNativeValue());
await _channel.invokeMethod('setMicrophoneCaptureState', args);
}

View File

@ -916,8 +916,8 @@ class InAppWebViewSettings {
///- [InAppWebViewSettings.enableViewportScale]
///
///Events affected:
///- the `hitTestResult` argument of [WebView.onLongPressHitTestResult] will be empty
///- the `hitTestResult` argument of [ContextMenu.onCreateContextMenu] will be empty
///- the `hitTestResult` argument of [WebView.onLongPressHitTestResult] will be empty
///- the `hitTestResult` argument of [ContextMenu.onCreateContextMenu] will be empty
///- [WebView.onLoadResource]
///- [WebView.shouldInterceptAjaxRequest]
///- [WebView.onAjaxReadyStateChange]
@ -937,7 +937,7 @@ class InAppWebViewSettings {
///Used in combination with [WebView.initialUrlRequest] or [WebView.initialData] (using the `file://` scheme), it represents the URL from which to read the web content.
///This URL must be a file-based URL (using the `file://` scheme).
///Specify the same value as the [URLRequest.url] if you are using it with the [WebView.initialUrlRequest] parameter or
///Specify the same value as the [URLRequest.url] if you are using it with the [WebView.initialUrlRequest] parameter or
///the [InAppWebViewInitialData.baseUrl] if you are using it with the [WebView.initialData] parameter to prevent WebView from reading any other content.
///Specify a directory to give WebView permission to read additional files in the specified directory.
///
@ -1108,7 +1108,7 @@ class InAppWebViewSettings {
this.useHybridComposition = true,
this.useShouldInterceptRequest = false,
this.useOnRenderProcessGone = false,
this.overScrollMode = OverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS,
this.overScrollMode = OverScrollMode.IF_CONTENT_SCROLLS,
this.networkAvailable,
this.scrollBarStyle = ScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY,
this.verticalScrollbarPosition =
@ -1182,7 +1182,7 @@ class InAppWebViewSettings {
});
List<String> dataDetectorTypesList = [];
dataDetectorTypes.forEach((dataDetectorType) {
dataDetectorTypesList.add(dataDetectorType.toValue());
dataDetectorTypesList.add(dataDetectorType.toNativeValue());
});
return {
@ -1200,7 +1200,7 @@ class InAppWebViewSettings {
"horizontalScrollBarEnabled": horizontalScrollBarEnabled,
"resourceCustomSchemes": resourceCustomSchemes,
"contentBlockers": contentBlockersMapList,
"preferredContentMode": preferredContentMode?.toValue(),
"preferredContentMode": preferredContentMode?.toNativeValue(),
"useShouldInterceptAjaxRequest": useShouldInterceptAjaxRequest,
"useShouldInterceptFetchRequest": useShouldInterceptFetchRequest,
"incognito": incognito,
@ -1220,24 +1220,24 @@ class InAppWebViewSettings {
"domStorageEnabled": domStorageEnabled,
"useWideViewPort": useWideViewPort,
"safeBrowsingEnabled": safeBrowsingEnabled,
"mixedContentMode": mixedContentMode?.toValue(),
"mixedContentMode": mixedContentMode?.toNativeValue(),
"allowContentAccess": allowContentAccess,
"allowFileAccess": allowFileAccess,
"appCachePath": appCachePath,
"blockNetworkImage": blockNetworkImage,
"blockNetworkLoads": blockNetworkLoads,
"cacheMode": cacheMode?.toValue(),
"cacheMode": cacheMode?.toNativeValue(),
"cursiveFontFamily": cursiveFontFamily,
"defaultFixedFontSize": defaultFixedFontSize,
"defaultFontSize": defaultFontSize,
"defaultTextEncodingName": defaultTextEncodingName,
"disabledActionModeMenuItems": disabledActionModeMenuItems?.toValue(),
"disabledActionModeMenuItems": disabledActionModeMenuItems?.toNativeValue(),
"fantasyFontFamily": fantasyFontFamily,
"fixedFontFamily": fixedFontFamily,
"forceDark": forceDark?.toValue(),
"forceDarkStrategy": forceDarkStrategy?.toValue(),
"forceDark": forceDark?.toNativeValue(),
"forceDarkStrategy": forceDarkStrategy?.toNativeValue(),
"geolocationEnabled": geolocationEnabled,
"layoutAlgorithm": layoutAlgorithm?.toValue(),
"layoutAlgorithm": layoutAlgorithm?.toNativeValue(),
"loadWithOverviewMode": loadWithOverviewMode,
"loadsImagesAutomatically": loadsImagesAutomatically,
"minimumLogicalFontSize": minimumLogicalFontSize,
@ -1255,10 +1255,10 @@ class InAppWebViewSettings {
"regexToCancelSubFramesLoading": regexToCancelSubFramesLoading,
"useShouldInterceptRequest": useShouldInterceptRequest,
"useOnRenderProcessGone": useOnRenderProcessGone,
"overScrollMode": overScrollMode?.toValue(),
"overScrollMode": overScrollMode?.toNativeValue(),
"networkAvailable": networkAvailable,
"scrollBarStyle": scrollBarStyle?.toValue(),
"verticalScrollbarPosition": verticalScrollbarPosition?.toValue(),
"scrollBarStyle": scrollBarStyle?.toNativeValue(),
"verticalScrollbarPosition": verticalScrollbarPosition?.toNativeValue(),
"scrollBarDefaultDelayBeforeFade": scrollBarDefaultDelayBeforeFade,
"scrollbarFadingEnabled": scrollbarFadingEnabled,
"scrollBarFadeDuration": scrollBarFadeDuration,
@ -1280,13 +1280,13 @@ class InAppWebViewSettings {
"allowsPictureInPictureMediaPlayback":
allowsPictureInPictureMediaPlayback,
"isFraudulentWebsiteWarningEnabled": isFraudulentWebsiteWarningEnabled,
"selectionGranularity": selectionGranularity.toValue(),
"selectionGranularity": selectionGranularity.toNativeValue(),
"dataDetectorTypes": dataDetectorTypesList,
"sharedCookiesEnabled": sharedCookiesEnabled,
"automaticallyAdjustsScrollIndicatorInsets":
automaticallyAdjustsScrollIndicatorInsets,
"accessibilityIgnoresInvertColors": accessibilityIgnoresInvertColors,
"decelerationRate": decelerationRate.toValue(),
"decelerationRate": decelerationRate.toNativeValue(),
"alwaysBounceVertical": alwaysBounceVertical,
"alwaysBounceHorizontal": alwaysBounceHorizontal,
"scrollsToTop": scrollsToTop,
@ -1294,7 +1294,7 @@ class InAppWebViewSettings {
"maximumZoomScale": maximumZoomScale,
"minimumZoomScale": minimumZoomScale,
"contentInsetAdjustmentBehavior":
contentInsetAdjustmentBehavior.toValue(),
contentInsetAdjustmentBehavior.toNativeValue(),
"isDirectionalLockEnabled": isDirectionalLockEnabled,
"mediaType": mediaType,
"pageZoom": pageZoom,
@ -1310,7 +1310,7 @@ class InAppWebViewSettings {
"upgradeKnownHostsToHTTPS": upgradeKnownHostsToHTTPS,
"iframeAllow": iframeAllow,
"iframeAllowFullscreen": iframeAllowFullscreen,
"iframeSandbox": iframeSandbox?.map((e) => e.toValue()).toList(),
"iframeSandbox": iframeSandbox?.map((e) => e.toNativeValue()).toList(),
"iframeReferrerPolicy": iframeReferrerPolicy,
"iframeName": iframeName,
"iframeCsp": iframeCsp,
@ -1332,7 +1332,7 @@ class InAppWebViewSettings {
List<String> dataDetectorTypesList =
List<String>.from(map["dataDetectorTypes"] ?? []);
dataDetectorTypesList.forEach((dataDetectorTypeValue) {
var dataDetectorType = DataDetectorTypes.fromValue(dataDetectorTypeValue);
var dataDetectorType = DataDetectorTypes.fromNativeValue(dataDetectorTypeValue);
if (dataDetectorType != null) {
dataDetectorTypes.add(dataDetectorType);
}
@ -1356,7 +1356,7 @@ class InAppWebViewSettings {
List<String>.from(map["resourceCustomSchemes"] ?? []);
settings.contentBlockers = contentBlockers;
settings.preferredContentMode =
UserPreferredContentMode.fromValue(map["preferredContentMode"]);
UserPreferredContentMode.fromNativeValue(map["preferredContentMode"]);
settings.useShouldInterceptAjaxRequest =
map["useShouldInterceptAjaxRequest"];
settings.useShouldInterceptFetchRequest =
@ -1376,10 +1376,10 @@ class InAppWebViewSettings {
settings.iframeAllowFullscreen = map["iframeAllowFullscreen"];
settings.iframeSandbox = map["iframeSandbox"] != null
? Set.from((map["iframeSandbox"].cast<String>() as List<String>)
.map((e) => Sandbox.fromValue(e)))
.map((e) => Sandbox.fromNativeValue(e)))
: null;
settings.iframeReferrerPolicy =
ReferrerPolicy.fromValue(map["iframeReferrerPolicy"]);
ReferrerPolicy.fromNativeValue(map["iframeReferrerPolicy"]);
settings.iframeName = map["iframeName"];
settings.iframeCsp = map["iframeCsp"];
} else {
@ -1393,26 +1393,26 @@ class InAppWebViewSettings {
settings.useWideViewPort = map["useWideViewPort"];
settings.safeBrowsingEnabled = map["safeBrowsingEnabled"];
settings.mixedContentMode =
MixedContentMode.fromValue(map["mixedContentMode"]);
MixedContentMode.fromNativeValue(map["mixedContentMode"]);
settings.allowContentAccess = map["allowContentAccess"];
settings.allowFileAccess = map["allowFileAccess"];
settings.appCachePath = map["appCachePath"];
settings.blockNetworkImage = map["blockNetworkImage"];
settings.blockNetworkLoads = map["blockNetworkLoads"];
settings.cacheMode = CacheMode.fromValue(map["cacheMode"]);
settings.cacheMode = CacheMode.fromNativeValue(map["cacheMode"]);
settings.cursiveFontFamily = map["cursiveFontFamily"];
settings.defaultFixedFontSize = map["defaultFixedFontSize"];
settings.defaultFontSize = map["defaultFontSize"];
settings.defaultTextEncodingName = map["defaultTextEncodingName"];
settings.disabledActionModeMenuItems =
ActionModeMenuItem.fromValue(map["disabledActionModeMenuItems"]);
ActionModeMenuItem.fromNativeValue(map["disabledActionModeMenuItems"]);
settings.fantasyFontFamily = map["fantasyFontFamily"];
settings.fixedFontFamily = map["fixedFontFamily"];
settings.forceDark = ForceDark.fromValue(map["forceDark"]);
settings.forceDarkStrategy = ForceDarkStrategy.fromValue(map["forceDarkStrategy"]);
settings.forceDark = ForceDark.fromNativeValue(map["forceDark"]);
settings.forceDarkStrategy = ForceDarkStrategy.fromNativeValue(map["forceDarkStrategy"]);
settings.geolocationEnabled = map["geolocationEnabled"];
settings.layoutAlgorithm =
LayoutAlgorithm.fromValue(map["layoutAlgorithm"]);
LayoutAlgorithm.fromNativeValue(map["layoutAlgorithm"]);
settings.loadWithOverviewMode = map["loadWithOverviewMode"];
settings.loadsImagesAutomatically = map["loadsImagesAutomatically"];
settings.minimumLogicalFontSize = map["minimumLogicalFontSize"];
@ -1431,11 +1431,11 @@ class InAppWebViewSettings {
settings.useHybridComposition = map["useHybridComposition"];
settings.useShouldInterceptRequest = map["useShouldInterceptRequest"];
settings.useOnRenderProcessGone = map["useOnRenderProcessGone"];
settings.overScrollMode = OverScrollMode.fromValue(map["overScrollMode"]);
settings.overScrollMode = OverScrollMode.fromNativeValue(map["overScrollMode"]);
settings.networkAvailable = map["networkAvailable"];
settings.scrollBarStyle = ScrollBarStyle.fromValue(map["scrollBarStyle"]);
settings.scrollBarStyle = ScrollBarStyle.fromNativeValue(map["scrollBarStyle"]);
settings.verticalScrollbarPosition =
VerticalScrollbarPosition.fromValue(map["verticalScrollbarPosition"]);
VerticalScrollbarPosition.fromNativeValue(map["verticalScrollbarPosition"]);
settings.scrollBarDefaultDelayBeforeFade =
map["scrollBarDefaultDelayBeforeFade"];
settings.scrollbarFadingEnabled = map["scrollbarFadingEnabled"];
@ -1470,7 +1470,7 @@ class InAppWebViewSettings {
settings.isFraudulentWebsiteWarningEnabled =
map["isFraudulentWebsiteWarningEnabled"];
settings.selectionGranularity =
SelectionGranularity.fromValue(map["selectionGranularity"])!;
SelectionGranularity.fromNativeValue(map["selectionGranularity"])!;
settings.dataDetectorTypes = dataDetectorTypes;
settings.sharedCookiesEnabled = map["sharedCookiesEnabled"];
settings.automaticallyAdjustsScrollIndicatorInsets =
@ -1478,7 +1478,7 @@ class InAppWebViewSettings {
settings.accessibilityIgnoresInvertColors =
map["accessibilityIgnoresInvertColors"];
settings.decelerationRate =
ScrollViewDecelerationRate.fromValue(map["decelerationRate"])!;
ScrollViewDecelerationRate.fromNativeValue(map["decelerationRate"])!;
settings.alwaysBounceVertical = map["alwaysBounceVertical"];
settings.alwaysBounceHorizontal = map["alwaysBounceHorizontal"];
settings.scrollsToTop = map["scrollsToTop"];
@ -1486,7 +1486,7 @@ class InAppWebViewSettings {
settings.maximumZoomScale = map["maximumZoomScale"];
settings.minimumZoomScale = map["minimumZoomScale"];
settings.contentInsetAdjustmentBehavior =
ScrollViewContentInsetAdjustmentBehavior.fromValue(
ScrollViewContentInsetAdjustmentBehavior.fromNativeValue(
map["contentInsetAdjustmentBehavior"])!;
settings.isDirectionalLockEnabled = map["isDirectionalLockEnabled"];
settings.mediaType = map["mediaType"];
@ -1782,7 +1782,7 @@ class InAppWebViewOptions
"horizontalScrollBarEnabled": horizontalScrollBarEnabled,
"resourceCustomSchemes": resourceCustomSchemes,
"contentBlockers": contentBlockersMapList,
"preferredContentMode": preferredContentMode?.toValue(),
"preferredContentMode": preferredContentMode?.toNativeValue(),
"useShouldInterceptAjaxRequest": useShouldInterceptAjaxRequest,
"useShouldInterceptFetchRequest": useShouldInterceptFetchRequest,
"incognito": incognito,
@ -1826,7 +1826,7 @@ class InAppWebViewOptions
List<String>.from(map["resourceCustomSchemes"] ?? []);
instance.contentBlockers = contentBlockers;
instance.preferredContentMode =
UserPreferredContentMode.fromValue(map["preferredContentMode"]);
UserPreferredContentMode.fromNativeValue(map["preferredContentMode"]);
instance.useShouldInterceptAjaxRequest =
map["useShouldInterceptAjaxRequest"];
instance.useShouldInterceptFetchRequest =

View File

@ -12,7 +12,14 @@ class PlatformUtil {
}
static PlatformUtil _init() {
_channel.setMethodCallHandler(_handleMethod);
_channel.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
_instance = PlatformUtil();
return _instance!;
}

View File

@ -23,7 +23,14 @@ class PrintJobController implements Disposable {
{required this.id}) {
this._channel = MethodChannel(
'com.pichillilorenzo/flutter_inappwebview_printjobcontroller_$id');
this._channel.setMethodCallHandler(_handleMethod);
this._channel.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
}
Future<dynamic> _handleMethod(MethodCall call) async {

View File

@ -6,7 +6,7 @@ import 'print_job_controller.dart';
///Class that represents the settings of a [PrintJobController].
class PrintJobSettings {
///Set this to `true` to handle the [PrintJobController].
///Set this to `true` to handle the [PrintJobController].
///Otherwise, it will be handled and disposed automatically by the system.
///The default value is `false`.
///
@ -183,17 +183,17 @@ class PrintJobSettings {
handledByClient: map["handledByClient"],
jobName: map["jobName"],
animated: map["animated"],
orientation: PrintJobOrientation.fromValue(map["orientation"]),
orientation: PrintJobOrientation.fromNativeValue(map["orientation"]),
numberOfPages: map["numberOfPages"],
forceRenderingQuality:
PrintJobRenderingQuality.fromValue(map["forceRenderingQuality"]),
PrintJobRenderingQuality.fromNativeValue(map["forceRenderingQuality"]),
margins:
MapEdgeInsets.fromMap(map["margins"]?.cast<String, dynamic>()),
mediaSize:
PrintJobMediaSize.fromMap(map["mediaSize"]?.cast<String, dynamic>()),
colorMode: PrintJobColorMode.fromValue(map["colorMode"]),
colorMode: PrintJobColorMode.fromNativeValue(map["colorMode"]),
duplexMode: PrintJobDuplexMode.fromNativeValue(map["duplexMode"]),
outputType: PrintJobOutputType.fromValue(map["outputType"]),
outputType: PrintJobOutputType.fromNativeValue(map["outputType"]),
resolution:
PrintJobResolution.fromMap(map["resolution"]?.cast<String, dynamic>()),
showsNumberOfCopies: map["showsNumberOfCopies"],
@ -212,14 +212,14 @@ class PrintJobSettings {
"handledByClient": handledByClient,
"jobName": jobName,
"animated": animated,
"orientation": orientation?.toValue(),
"orientation": orientation?.toNativeValue(),
"numberOfPages": numberOfPages,
"forceRenderingQuality": forceRenderingQuality?.toValue(),
"forceRenderingQuality": forceRenderingQuality?.toNativeValue(),
"margins": margins?.toMap(),
"mediaSize": mediaSize?.toMap(),
"colorMode": colorMode?.toValue(),
"colorMode": colorMode?.toNativeValue(),
"duplexMode": duplexMode?.toNativeValue(),
"outputType": outputType?.toValue(),
"outputType": outputType?.toNativeValue(),
"resolution": resolution?.toMap(),
"showsNumberOfCopies": showsNumberOfCopies,
"showsPaperSelectionForLoadedPapers": showsPaperSelectionForLoadedPapers,

View File

@ -133,7 +133,7 @@ class PullToRefreshController {
@Deprecated("Use setIndicatorSize instead")
Future<void> setSize(AndroidPullToRefreshSize size) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('size', () => size.toValue());
args.putIfAbsent('size', () => size.toNativeValue());
await _channel?.invokeMethod('setSize', args);
}
@ -142,7 +142,7 @@ class PullToRefreshController {
///**NOTE**: Available only on Android.
Future<void> setIndicatorSize(PullToRefreshSize size) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('size', () => size.toValue());
args.putIfAbsent('size', () => size.toNativeValue());
await _channel?.invokeMethod('setSize', args);
}
@ -166,6 +166,13 @@ class PullToRefreshController {
void initMethodChannel(dynamic id) {
this._channel = MethodChannel(
'com.pichillilorenzo/flutter_inappwebview_pull_to_refresh_$id');
this._channel?.setMethodCallHandler(_handleMethod);
this._channel?.setMethodCallHandler((call) async {
try {
return await _handleMethod(call);
} on Error catch (e) {
print(e);
print(e.stackTrace);
}
});
}
}

View File

@ -49,7 +49,7 @@ class PullToRefreshSettings {
"backgroundColor": backgroundColor?.toHex(),
"distanceToTriggerSync": distanceToTriggerSync,
"slingshotDistance": slingshotDistance,
"size": size?.toValue(),
"size": size?.toNativeValue(),
"attributedTitle": attributedTitle?.toMap() ?? {}
};
}
@ -112,7 +112,7 @@ class PullToRefreshOptions {
"backgroundColor": backgroundColor?.toHex(),
"distanceToTriggerSync": distanceToTriggerSync,
"slingshotDistance": slingshotDistance,
"size": size?.toValue(),
"size": size?.toNativeValue(),
"attributedTitle": attributedTitle?.toMap() ?? {}
};
}

View File

@ -1,68 +1,27 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
part 'action_mode_menu_item.g.dart';
///Class used to disable the action mode menu items.
class ActionModeMenuItem {
@ExchangeableEnum(
bitwiseOrOperator: true
)
class ActionModeMenuItem_ {
// ignore: unused_field
final int _value;
const ActionModeMenuItem._internal(this._value);
///Set of all values of [ActionModeMenuItem].
static final Set<ActionModeMenuItem> values = [
ActionModeMenuItem.MENU_ITEM_NONE,
ActionModeMenuItem.MENU_ITEM_SHARE,
ActionModeMenuItem.MENU_ITEM_WEB_SEARCH,
ActionModeMenuItem.MENU_ITEM_PROCESS_TEXT,
].toSet();
///Gets a possible [ActionModeMenuItem] instance from an [int] value.
static ActionModeMenuItem? fromValue(int? value) {
if (value != null) {
try {
return ActionModeMenuItem.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
// maybe coming from a Bitwise OR operator
return ActionModeMenuItem._internal(value);
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
@override
String toString() {
switch (_value) {
case 1:
return "MENU_ITEM_SHARE";
case 2:
return "MENU_ITEM_WEB_SEARCH";
case 4:
return "MENU_ITEM_PROCESS_TEXT";
case 0:
return "MENU_ITEM_NONE";
}
return _value.toString();
}
const ActionModeMenuItem_._internal(this._value);
///No menu items should be disabled.
static const MENU_ITEM_NONE = const ActionModeMenuItem._internal(0);
static const MENU_ITEM_NONE = ActionModeMenuItem_._internal(0);
///Disable menu item "Share".
static const MENU_ITEM_SHARE = const ActionModeMenuItem._internal(1);
static const MENU_ITEM_SHARE = ActionModeMenuItem_._internal(1);
///Disable menu item "Web Search".
static const MENU_ITEM_WEB_SEARCH = const ActionModeMenuItem._internal(2);
static const MENU_ITEM_WEB_SEARCH = ActionModeMenuItem_._internal(2);
///Disable all the action mode menu items for text processing.
static const MENU_ITEM_PROCESS_TEXT = const ActionModeMenuItem._internal(4);
bool operator ==(value) => value == _value;
ActionModeMenuItem operator |(ActionModeMenuItem value) =>
ActionModeMenuItem._internal(value.toValue() | _value);
@override
int get hashCode => _value.hashCode;
static const MENU_ITEM_PROCESS_TEXT = ActionModeMenuItem_._internal(4);
}
///An Android-specific class used to disable the action mode menu items.
@ -71,70 +30,25 @@ class ActionModeMenuItem {
///
///Use [ActionModeMenuItem] instead.
@Deprecated("Use ActionModeMenuItem instead")
class AndroidActionModeMenuItem {
@ExchangeableEnum(
bitwiseOrOperator: true
)
class AndroidActionModeMenuItem_ {
// ignore: unused_field
final int _value;
const AndroidActionModeMenuItem._internal(this._value);
///Set of all values of [AndroidActionModeMenuItem].
static final Set<AndroidActionModeMenuItem> values = [
AndroidActionModeMenuItem.MENU_ITEM_NONE,
AndroidActionModeMenuItem.MENU_ITEM_SHARE,
AndroidActionModeMenuItem.MENU_ITEM_WEB_SEARCH,
AndroidActionModeMenuItem.MENU_ITEM_PROCESS_TEXT,
].toSet();
///Gets a possible [AndroidActionModeMenuItem] instance from an [int] value.
static AndroidActionModeMenuItem? fromValue(int? value) {
if (value != null) {
try {
return AndroidActionModeMenuItem.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
// maybe coming from a Bitwise OR operator
return AndroidActionModeMenuItem._internal(value);
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
@override
String toString() {
switch (_value) {
case 1:
return "MENU_ITEM_SHARE";
case 2:
return "MENU_ITEM_WEB_SEARCH";
case 4:
return "MENU_ITEM_PROCESS_TEXT";
case 0:
return "MENU_ITEM_NONE";
}
return _value.toString();
}
const AndroidActionModeMenuItem_._internal(this._value);
///No menu items should be disabled.
static const MENU_ITEM_NONE = const AndroidActionModeMenuItem._internal(0);
static const MENU_ITEM_NONE = const AndroidActionModeMenuItem_._internal(0);
///Disable menu item "Share".
static const MENU_ITEM_SHARE = const AndroidActionModeMenuItem._internal(1);
static const MENU_ITEM_SHARE = const AndroidActionModeMenuItem_._internal(1);
///Disable menu item "Web Search".
static const MENU_ITEM_WEB_SEARCH =
const AndroidActionModeMenuItem._internal(2);
const AndroidActionModeMenuItem_._internal(2);
///Disable all the action mode menu items for text processing.
static const MENU_ITEM_PROCESS_TEXT =
const AndroidActionModeMenuItem._internal(4);
bool operator ==(value) => value == _value;
AndroidActionModeMenuItem operator |(AndroidActionModeMenuItem value) =>
AndroidActionModeMenuItem._internal(value.toValue() | _value);
@override
int get hashCode => _value.hashCode;
const AndroidActionModeMenuItem_._internal(4);
}

View File

@ -0,0 +1,187 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'action_mode_menu_item.dart';
// **************************************************************************
// ExchangeableEnumGenerator
// **************************************************************************
///Class used to disable the action mode menu items.
class ActionModeMenuItem {
final int _value;
final int _nativeValue;
const ActionModeMenuItem._internal(this._value, this._nativeValue);
// ignore: unused_element
factory ActionModeMenuItem._internalMultiPlatform(
int value, Function nativeValue) =>
ActionModeMenuItem._internal(value, nativeValue());
///No menu items should be disabled.
static const MENU_ITEM_NONE = ActionModeMenuItem._internal(0, 0);
///Disable menu item "Share".
static const MENU_ITEM_SHARE = ActionModeMenuItem._internal(1, 1);
///Disable menu item "Web Search".
static const MENU_ITEM_WEB_SEARCH = ActionModeMenuItem._internal(2, 2);
///Disable all the action mode menu items for text processing.
static const MENU_ITEM_PROCESS_TEXT = ActionModeMenuItem._internal(4, 4);
///Set of all values of [ActionModeMenuItem].
static final Set<ActionModeMenuItem> values = [
ActionModeMenuItem.MENU_ITEM_NONE,
ActionModeMenuItem.MENU_ITEM_SHARE,
ActionModeMenuItem.MENU_ITEM_WEB_SEARCH,
ActionModeMenuItem.MENU_ITEM_PROCESS_TEXT,
].toSet();
///Gets a possible [ActionModeMenuItem] instance from [int] value.
static ActionModeMenuItem? fromValue(int? value) {
if (value != null) {
try {
return ActionModeMenuItem.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return ActionModeMenuItem._internal(value, value);
}
}
return null;
}
///Gets a possible [ActionModeMenuItem] instance from a native value.
static ActionModeMenuItem? fromNativeValue(int? value) {
if (value != null) {
try {
return ActionModeMenuItem.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return ActionModeMenuItem._internal(value, value);
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
///Gets [int] native value.
int toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
ActionModeMenuItem operator |(ActionModeMenuItem value) =>
ActionModeMenuItem._internal(
value.toValue() | _value, value.toNativeValue() | _nativeValue);
@override
String toString() {
switch (_value) {
case 0:
return 'MENU_ITEM_NONE';
case 1:
return 'MENU_ITEM_SHARE';
case 2:
return 'MENU_ITEM_WEB_SEARCH';
case 4:
return 'MENU_ITEM_PROCESS_TEXT';
}
return _value.toString();
}
}
///An Android-specific class used to disable the action mode menu items.
///
///**NOTE**: available on Android 24+.
///
///Use [ActionModeMenuItem] instead.
@Deprecated('Use ActionModeMenuItem instead')
class AndroidActionModeMenuItem {
final int _value;
final int _nativeValue;
const AndroidActionModeMenuItem._internal(this._value, this._nativeValue);
// ignore: unused_element
factory AndroidActionModeMenuItem._internalMultiPlatform(
int value, Function nativeValue) =>
AndroidActionModeMenuItem._internal(value, nativeValue());
///No menu items should be disabled.
static const MENU_ITEM_NONE = AndroidActionModeMenuItem._internal(0, 0);
///Disable menu item "Share".
static const MENU_ITEM_SHARE = AndroidActionModeMenuItem._internal(1, 1);
///Disable menu item "Web Search".
static const MENU_ITEM_WEB_SEARCH = AndroidActionModeMenuItem._internal(2, 2);
///Disable all the action mode menu items for text processing.
static const MENU_ITEM_PROCESS_TEXT =
AndroidActionModeMenuItem._internal(4, 4);
///Set of all values of [AndroidActionModeMenuItem].
static final Set<AndroidActionModeMenuItem> values = [
AndroidActionModeMenuItem.MENU_ITEM_NONE,
AndroidActionModeMenuItem.MENU_ITEM_SHARE,
AndroidActionModeMenuItem.MENU_ITEM_WEB_SEARCH,
AndroidActionModeMenuItem.MENU_ITEM_PROCESS_TEXT,
].toSet();
///Gets a possible [AndroidActionModeMenuItem] instance from [int] value.
static AndroidActionModeMenuItem? fromValue(int? value) {
if (value != null) {
try {
return AndroidActionModeMenuItem.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return AndroidActionModeMenuItem._internal(value, value);
}
}
return null;
}
///Gets a possible [AndroidActionModeMenuItem] instance from a native value.
static AndroidActionModeMenuItem? fromNativeValue(int? value) {
if (value != null) {
try {
return AndroidActionModeMenuItem.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return AndroidActionModeMenuItem._internal(value, value);
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
///Gets [int] native value.
int toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
AndroidActionModeMenuItem operator |(AndroidActionModeMenuItem value) =>
AndroidActionModeMenuItem._internal(
value.toValue() | _value, value.toNativeValue() | _nativeValue);
@override
String toString() {
switch (_value) {
case 0:
return 'MENU_ITEM_NONE';
case 1:
return 'MENU_ITEM_SHARE';
case 2:
return 'MENU_ITEM_WEB_SEARCH';
case 4:
return 'MENU_ITEM_PROCESS_TEXT';
}
return _value.toString();
}
}

View File

@ -1,10 +1,15 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'ajax_request_headers.dart';
import 'ajax_request_ready_state.dart';
import 'ajax_request_event.dart';
import 'ajax_request_action.dart';
part 'ajax_request.g.dart';
///Class that represents a JavaScript [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) object.
class AjaxRequest {
@ExchangeableObject()
class AjaxRequest_ {
///Data passed as a parameter to the `XMLHttpRequest.send()` method.
dynamic data;
@ -30,10 +35,10 @@ class AjaxRequest {
bool? withCredentials;
///The HTTP request headers.
AjaxRequestHeaders? headers;
AjaxRequestHeaders_? headers;
///The state of the `XMLHttpRequest` request.
AjaxRequestReadyState? readyState;
AjaxRequestReadyState_? readyState;
///The numerical HTTP [status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) of the `XMLHttpRequest`'s response.
int? status;
@ -67,12 +72,12 @@ class AjaxRequest {
Map<String, dynamic>? responseHeaders;
///Event type of the `XMLHttpRequest` request.
AjaxRequestEvent? event;
AjaxRequestEvent_? event;
///Indicates the [AjaxRequestAction] that can be used to control the `XMLHttpRequest` request.
AjaxRequestAction? action;
AjaxRequestAction_? action;
AjaxRequest(
AjaxRequest_(
{this.data,
this.method,
this.url,
@ -91,68 +96,6 @@ class AjaxRequest {
this.statusText,
this.responseHeaders,
this.event,
this.action = AjaxRequestAction.PROCEED});
this.action = AjaxRequestAction_.PROCEED});
///Gets a possible [AjaxRequest] instance from a [Map] value.
static AjaxRequest? fromMap(Map<String, dynamic>? map) {
if (map == null) {
return null;
}
return AjaxRequest(
data: map["data"],
method: map["method"],
url: map["url"] != null ? Uri.parse(map["url"]) : null,
isAsync: map["isAsync"],
user: map["user"],
password: map["password"],
withCredentials: map["withCredentials"],
headers:
AjaxRequestHeaders.fromMap(map["headers"]?.cast<String, dynamic>()),
readyState: AjaxRequestReadyState.fromValue(map["readyState"]),
status: map["status"],
responseURL:
map["responseURL"] != null ? Uri.parse(map["responseURL"]) : null,
responseType: map["responseType"],
response: map["response"],
responseText: map["responseText"],
responseXML: map["responseXML"],
statusText: map["statusText"],
responseHeaders: map["responseHeaders"]?.cast<String, dynamic>(),
event: AjaxRequestEvent.fromMap(map["event"]?.cast<String, dynamic>()));
}
///Converts instance to a map.
Map<String, dynamic> toMap() {
return {
"data": data,
"method": method,
"url": url?.toString(),
"isAsync": isAsync,
"user": user,
"password": password,
"withCredentials": withCredentials,
"headers": headers?.toMap(),
"readyState": readyState?.toValue(),
"status": status,
"responseURL": responseURL?.toString(),
"responseType": responseType,
"response": response,
"responseText": responseText,
"responseXML": responseXML,
"statusText": statusText,
"responseHeaders": responseHeaders,
"action": action?.toValue()
};
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
}

View File

@ -0,0 +1,163 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'ajax_request.dart';
// **************************************************************************
// ExchangeableObjectGenerator
// **************************************************************************
///Class that represents a JavaScript [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) object.
class AjaxRequest {
///Data passed as a parameter to the `XMLHttpRequest.send()` method.
dynamic data;
///The HTTP request method of the `XMLHttpRequest` request.
String? method;
///The URL of the `XMLHttpRequest` request.
Uri? url;
///An optional Boolean parameter, defaulting to true, indicating whether or not the request is performed asynchronously.
bool? isAsync;
///The optional user name to use for authentication purposes; by default, this is the null value.
String? user;
///The optional password to use for authentication purposes; by default, this is the null value.
String? password;
///The XMLHttpRequest.withCredentials property is a Boolean that indicates whether or not cross-site Access-Control requests
///should be made using credentials such as cookies, authorization headers or TLS client certificates.
///Setting withCredentials has no effect on same-site requests.
///In addition, this flag is also used to indicate when cookies are to be ignored in the response. The default is false.
bool? withCredentials;
///The HTTP request headers.
AjaxRequestHeaders? headers;
///The state of the `XMLHttpRequest` request.
AjaxRequestReadyState? readyState;
///The numerical HTTP [status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) of the `XMLHttpRequest`'s response.
int? status;
///The serialized URL of the response or the empty string if the URL is null.
///If the URL is returned, any URL fragment present in the URL will be stripped away.
///The value of responseURL will be the final URL obtained after any redirects.
Uri? responseURL;
///It is an enumerated string value specifying the type of data contained in the response.
///It also lets the author change the [response type](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType).
///If an empty string is set as the value of responseType, the default value of text is used.
String? responseType;
///The response's body content. The content-type depends on the [AjaxRequest.reponseType].
dynamic response;
///The text received from a server following a request being sent.
String? responseText;
///The HTML or XML string retrieved by the request or null if the request was unsuccessful, has not yet been sent, or if the data can't be parsed as XML or HTML.
String? responseXML;
///A String containing the response's status message as returned by the HTTP server.
///Unlike [AjaxRequest.status] which indicates a numerical status code, this property contains the text of the response status, such as "OK" or "Not Found".
///If the request's readyState is in [AjaxRequestReadyState.UNSENT] or [AjaxRequestReadyState.OPENED] state, the value of statusText will be an empty string.
///If the server response doesn't explicitly specify a status text, statusText will assume the default value "OK".
String? statusText;
///All the response headers or returns null if no response has been received. If a network error happened, an empty string is returned.
Map<String, dynamic>? responseHeaders;
///Event type of the `XMLHttpRequest` request.
AjaxRequestEvent? event;
///Indicates the [AjaxRequestAction] that can be used to control the `XMLHttpRequest` request.
AjaxRequestAction? action;
AjaxRequest(
{this.data,
this.method,
this.url,
this.isAsync,
this.user,
this.password,
this.withCredentials,
this.headers,
this.readyState,
this.status,
this.responseURL,
this.responseType,
this.response,
this.responseText,
this.responseXML,
this.statusText,
this.responseHeaders,
this.event,
this.action = AjaxRequestAction.PROCEED});
///Gets a possible [AjaxRequest] instance from a [Map] value.
static AjaxRequest? fromMap(Map<String, dynamic>? map) {
if (map == null) {
return null;
}
final instance = AjaxRequest(
data: map['data'],
method: map['method'],
url: map['url'] != null ? Uri.parse(map['url']) : null,
isAsync: map['isAsync'],
user: map['user'],
password: map['password'],
withCredentials: map['withCredentials'],
headers:
AjaxRequestHeaders.fromMap(map['headers']?.cast<String, dynamic>()),
readyState: AjaxRequestReadyState.fromNativeValue(map['readyState']),
status: map['status'],
responseURL:
map['responseURL'] != null ? Uri.parse(map['responseURL']) : null,
responseType: map['responseType'],
response: map['response'],
responseText: map['responseText'],
responseXML: map['responseXML'],
statusText: map['statusText'],
responseHeaders: map['responseHeaders']?.cast<String, dynamic>(),
event: AjaxRequestEvent.fromMap(map['event']?.cast<String, dynamic>()),
);
instance.action = AjaxRequestAction.fromNativeValue(map['action']);
return instance;
}
///Converts instance to a map.
Map<String, dynamic> toMap() {
return {
"data": data,
"method": method,
"url": url?.toString(),
"isAsync": isAsync,
"user": user,
"password": password,
"withCredentials": withCredentials,
"headers": headers?.toMap(),
"readyState": readyState?.toNativeValue(),
"status": status,
"responseURL": responseURL?.toString(),
"responseType": responseType,
"response": response,
"responseText": responseText,
"responseXML": responseXML,
"statusText": statusText,
"responseHeaders": responseHeaders,
"event": event?.toMap(),
"action": action?.toNativeValue(),
};
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return toMap();
}
@override
String toString() {
return 'AjaxRequest{data: $data, method: $method, url: $url, isAsync: $isAsync, user: $user, password: $password, withCredentials: $withCredentials, headers: $headers, readyState: $readyState, status: $status, responseURL: $responseURL, responseType: $responseType, response: $response, responseText: $responseText, responseXML: $responseXML, statusText: $statusText, responseHeaders: $responseHeaders, event: $event, action: $action}';
}
}

View File

@ -1,39 +1,19 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'ajax_request.dart';
part 'ajax_request_action.g.dart';
///Class used by [AjaxRequest] class.
class AjaxRequestAction {
@ExchangeableEnum()
class AjaxRequestAction_ {
// ignore: unused_field
final int _value;
const AjaxRequestAction._internal(this._value);
///Gets [int] value.
int toValue() => _value;
const AjaxRequestAction_._internal(this._value);
///Aborts the current [AjaxRequest].
static const ABORT = const AjaxRequestAction._internal(0);
static const ABORT = const AjaxRequestAction_._internal(0);
///Proceeds with the current [AjaxRequest].
static const PROCEED = const AjaxRequestAction._internal(1);
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
///Converts instance to a map.
Map<String, dynamic> toMap() {
return {
"action": _value,
};
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
static const PROCEED = const AjaxRequestAction_._internal(1);
}

View File

@ -0,0 +1,79 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'ajax_request_action.dart';
// **************************************************************************
// ExchangeableEnumGenerator
// **************************************************************************
///Class used by [AjaxRequest] class.
class AjaxRequestAction {
final int _value;
final int _nativeValue;
const AjaxRequestAction._internal(this._value, this._nativeValue);
// ignore: unused_element
factory AjaxRequestAction._internalMultiPlatform(
int value, Function nativeValue) =>
AjaxRequestAction._internal(value, nativeValue());
///Aborts the current [AjaxRequest].
static const ABORT = AjaxRequestAction._internal(0, 0);
///Proceeds with the current [AjaxRequest].
static const PROCEED = AjaxRequestAction._internal(1, 1);
///Set of all values of [AjaxRequestAction].
static final Set<AjaxRequestAction> values = [
AjaxRequestAction.ABORT,
AjaxRequestAction.PROCEED,
].toSet();
///Gets a possible [AjaxRequestAction] instance from [int] value.
static AjaxRequestAction? fromValue(int? value) {
if (value != null) {
try {
return AjaxRequestAction.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets a possible [AjaxRequestAction] instance from a native value.
static AjaxRequestAction? fromNativeValue(int? value) {
if (value != null) {
try {
return AjaxRequestAction.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
///Gets [int] native value.
int toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
@override
String toString() {
switch (_value) {
case 0:
return 'ABORT';
case 1:
return 'PROCEED';
}
return _value.toString();
}
}

View File

@ -1,10 +1,15 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'ajax_request.dart';
import 'ajax_request_event_type.dart';
part 'ajax_request_event.g.dart';
///Class used by [AjaxRequest] class. It represents events measuring progress of an [AjaxRequest].
class AjaxRequestEvent {
@ExchangeableObject()
class AjaxRequestEvent_ {
///Event type.
AjaxRequestEventType? type;
AjaxRequestEventType_? type;
///Is a Boolean flag indicating if the total work to be done, and the amount of work already done, by the underlying process is calculable.
///In other words, it tells if the progress is measurable or not.
@ -19,38 +24,5 @@ class AjaxRequestEvent {
///When downloading a resource using HTTP, this only represent the content itself, not headers and other overhead.
int? total;
AjaxRequestEvent({this.type, this.lengthComputable, this.loaded, this.total});
///Gets a possible [AjaxRequestEvent] instance from a [Map] value.
static AjaxRequestEvent? fromMap(Map<String, dynamic>? map) {
if (map == null) {
return null;
}
return AjaxRequestEvent(
type: AjaxRequestEventType.fromValue(map["type"]),
lengthComputable: map["lengthComputable"],
loaded: map["loaded"],
total: map["total"]);
}
///Converts instance to a map.
Map<String, dynamic> toMap() {
return {
"type": type?.toValue(),
"lengthComputable": lengthComputable,
"loaded": loaded,
"total": total,
};
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
AjaxRequestEvent_({this.type, this.lengthComputable, this.loaded, this.total});
}

View File

@ -0,0 +1,61 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'ajax_request_event.dart';
// **************************************************************************
// ExchangeableObjectGenerator
// **************************************************************************
///Class used by [AjaxRequest] class. It represents events measuring progress of an [AjaxRequest].
class AjaxRequestEvent {
///Event type.
AjaxRequestEventType? type;
///Is a Boolean flag indicating if the total work to be done, and the amount of work already done, by the underlying process is calculable.
///In other words, it tells if the progress is measurable or not.
bool? lengthComputable;
///Is an integer representing the amount of work already performed by the underlying process.
///The ratio of work done can be calculated with the property and [AjaxRequestEvent.total].
///When downloading a resource using HTTP, this only represent the part of the content itself, not headers and other overhead.
int? loaded;
///Is an integer representing the total amount of work that the underlying process is in the progress of performing.
///When downloading a resource using HTTP, this only represent the content itself, not headers and other overhead.
int? total;
AjaxRequestEvent({this.type, this.lengthComputable, this.loaded, this.total});
///Gets a possible [AjaxRequestEvent] instance from a [Map] value.
static AjaxRequestEvent? fromMap(Map<String, dynamic>? map) {
if (map == null) {
return null;
}
final instance = AjaxRequestEvent(
type: AjaxRequestEventType.fromNativeValue(map['type']),
lengthComputable: map['lengthComputable'],
loaded: map['loaded'],
total: map['total'],
);
return instance;
}
///Converts instance to a map.
Map<String, dynamic> toMap() {
return {
"type": type?.toNativeValue(),
"lengthComputable": lengthComputable,
"loaded": loaded,
"total": total,
};
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return toMap();
}
@override
String toString() {
return 'AjaxRequestEvent{type: $type, lengthComputable: $lengthComputable, loaded: $loaded, total: $total}';
}
}

View File

@ -1,64 +1,34 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'ajax_request_event.dart';
part 'ajax_request_event_type.g.dart';
///Class used by [AjaxRequestEvent] class.
class AjaxRequestEventType {
@ExchangeableEnum()
class AjaxRequestEventType_ {
final String _value;
const AjaxRequestEventType._internal(this._value);
///Set of all values of [AjaxRequestEventType].
static final Set<AjaxRequestEventType> values = [
AjaxRequestEventType.LOADSTART,
AjaxRequestEventType.LOAD,
AjaxRequestEventType.LOADEND,
AjaxRequestEventType.PROGRESS,
AjaxRequestEventType.ERROR,
AjaxRequestEventType.ABORT,
AjaxRequestEventType.TIMEOUT,
].toSet();
///Gets a possible [AjaxRequestEventType] instance from a [String] value.
static AjaxRequestEventType? fromValue(String? value) {
if (value != null) {
try {
return AjaxRequestEventType.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [String] value.
String toValue() => _value;
String toString() => _value;
const AjaxRequestEventType_._internal(this._value);
///The LOADSTART event is fired when a request has started to load data.
static const LOADSTART = const AjaxRequestEventType._internal("loadstart");
static const LOADSTART = const AjaxRequestEventType_._internal("loadstart");
///The LOAD event is fired when an `XMLHttpRequest` transaction completes successfully.
static const LOAD = const AjaxRequestEventType._internal("load");
static const LOAD = const AjaxRequestEventType_._internal("load");
///The LOADEND event is fired when a request has completed, whether successfully (after [AjaxRequestEventType.LOAD]) or
///unsuccessfully (after [AjaxRequestEventType.ABORT] or [AjaxRequestEventType.ERROR]).
static const LOADEND = const AjaxRequestEventType._internal("loadend");
static const LOADEND = const AjaxRequestEventType_._internal("loadend");
///The PROGRESS event is fired periodically when a request receives more data.
static const PROGRESS = const AjaxRequestEventType._internal("progress");
static const PROGRESS = const AjaxRequestEventType_._internal("progress");
///The ERROR event is fired when the request encountered an error.
static const ERROR = const AjaxRequestEventType._internal("error");
static const ERROR = const AjaxRequestEventType_._internal("error");
///The ABORT event is fired when a request has been aborted.
static const ABORT = const AjaxRequestEventType._internal("abort");
static const ABORT = const AjaxRequestEventType_._internal("abort");
///The TIMEOUT event is fired when progression is terminated due to preset time expiring.
static const TIMEOUT = const AjaxRequestEventType._internal("timeout");
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
static const TIMEOUT = const AjaxRequestEventType_._internal("timeout");
}

View File

@ -0,0 +1,96 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'ajax_request_event_type.dart';
// **************************************************************************
// ExchangeableEnumGenerator
// **************************************************************************
///Class used by [AjaxRequestEvent] class.
class AjaxRequestEventType {
final String _value;
final String _nativeValue;
const AjaxRequestEventType._internal(this._value, this._nativeValue);
// ignore: unused_element
factory AjaxRequestEventType._internalMultiPlatform(
String value, Function nativeValue) =>
AjaxRequestEventType._internal(value, nativeValue());
///The LOADSTART event is fired when a request has started to load data.
static const LOADSTART =
AjaxRequestEventType._internal('loadstart', 'loadstart');
///The LOAD event is fired when an `XMLHttpRequest` transaction completes successfully.
static const LOAD = AjaxRequestEventType._internal('load', 'load');
///The LOADEND event is fired when a request has completed, whether successfully (after [AjaxRequestEventType.LOAD]) or
///unsuccessfully (after [AjaxRequestEventType.ABORT] or [AjaxRequestEventType.ERROR]).
static const LOADEND = AjaxRequestEventType._internal('loadend', 'loadend');
///The PROGRESS event is fired periodically when a request receives more data.
static const PROGRESS =
AjaxRequestEventType._internal('progress', 'progress');
///The ERROR event is fired when the request encountered an error.
static const ERROR = AjaxRequestEventType._internal('error', 'error');
///The ABORT event is fired when a request has been aborted.
static const ABORT = AjaxRequestEventType._internal('abort', 'abort');
///The TIMEOUT event is fired when progression is terminated due to preset time expiring.
static const TIMEOUT = AjaxRequestEventType._internal('timeout', 'timeout');
///Set of all values of [AjaxRequestEventType].
static final Set<AjaxRequestEventType> values = [
AjaxRequestEventType.LOADSTART,
AjaxRequestEventType.LOAD,
AjaxRequestEventType.LOADEND,
AjaxRequestEventType.PROGRESS,
AjaxRequestEventType.ERROR,
AjaxRequestEventType.ABORT,
AjaxRequestEventType.TIMEOUT,
].toSet();
///Gets a possible [AjaxRequestEventType] instance from [String] value.
static AjaxRequestEventType? fromValue(String? value) {
if (value != null) {
try {
return AjaxRequestEventType.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets a possible [AjaxRequestEventType] instance from a native value.
static AjaxRequestEventType? fromNativeValue(String? value) {
if (value != null) {
try {
return AjaxRequestEventType.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [String] value.
String toValue() => _value;
///Gets [String] native value.
String toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
@override
String toString() {
return _value;
}
}

View File

@ -1,19 +1,25 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'ajax_request.dart';
part 'ajax_request_headers.g.dart';
///Class that represents the HTTP headers of an [AjaxRequest].
class AjaxRequestHeaders {
@ExchangeableObject()
class AjaxRequestHeaders_ {
Map<String, dynamic> _headers;
Map<String, dynamic> _newHeaders = {};
AjaxRequestHeaders(this._headers);
@ExchangeableObjectConstructor()
AjaxRequestHeaders_(this._headers);
///Gets a possible [AjaxRequestHeaders] instance from a [Map] value.
static AjaxRequestHeaders? fromMap(Map<String, dynamic>? map) {
static AjaxRequestHeaders_? fromMap(Map<String, dynamic>? map) {
if (map == null) {
return null;
}
return AjaxRequestHeaders(map);
return AjaxRequestHeaders_(map);
}
///Gets the HTTP headers of the [AjaxRequest].
@ -34,13 +40,8 @@ class AjaxRequestHeaders {
return _newHeaders;
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return toMap();
}
@override
String toString() {
return toMap().toString();
return 'AjaxRequestHeaders{headers: $_headers, requestHeaders: $_newHeaders}';
}
}

View File

@ -0,0 +1,50 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'ajax_request_headers.dart';
// **************************************************************************
// ExchangeableObjectGenerator
// **************************************************************************
///Class that represents the HTTP headers of an [AjaxRequest].
class AjaxRequestHeaders {
Map<String, dynamic> _headers;
Map<String, dynamic> _newHeaders = {};
AjaxRequestHeaders(this._headers);
///Gets a possible [AjaxRequestHeaders] instance from a [Map] value.
static AjaxRequestHeaders? fromMap(Map<String, dynamic>? map) {
if (map == null) {
return null;
}
return AjaxRequestHeaders(map);
}
///Gets the HTTP headers of the [AjaxRequest].
Map<String, dynamic> getHeaders() {
return this._headers;
}
///Sets/updates an HTTP header of the [AjaxRequest]. If there is already an existing [header] with the same name, the values are merged into one single request header.
///For security reasons, some headers can only be controlled by the user agent.
///These headers include the [forbidden header names](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name)
///and [forbidden response header names](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_response_header_name).
void setRequestHeader(String header, String value) {
_newHeaders[header] = value;
}
///Converts instance to a map.
Map<String, dynamic> toMap() {
return _newHeaders;
}
@override
String toString() {
return 'AjaxRequestHeaders{headers: $_headers, requestHeaders: $_newHeaders}';
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return toMap();
}
}

View File

@ -1,70 +1,28 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import 'ajax_request.dart';
part 'ajax_request_ready_state.g.dart';
///Class used by [AjaxRequest] class. It represents the state of an [AjaxRequest].
class AjaxRequestReadyState {
@ExchangeableEnum()
class AjaxRequestReadyState_ {
// ignore: unused_field
final int _value;
const AjaxRequestReadyState._internal(this._value);
///Set of all values of [AjaxRequestReadyState].
static final Set<AjaxRequestReadyState> values = [
AjaxRequestReadyState.UNSENT,
AjaxRequestReadyState.OPENED,
AjaxRequestReadyState.HEADERS_RECEIVED,
AjaxRequestReadyState.LOADING,
AjaxRequestReadyState.DONE,
].toSet();
///Gets a possible [AjaxRequestReadyState] instance from an [int] value.
static AjaxRequestReadyState? fromValue(int? value) {
if (value != null) {
try {
return AjaxRequestReadyState.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
@override
String toString() {
switch (_value) {
case 1:
return "OPENED";
case 2:
return "HEADERS_RECEIVED";
case 3:
return "LOADING";
case 4:
return "DONE";
case 0:
default:
return "UNSENT";
}
}
const AjaxRequestReadyState_._internal(this._value);
///Client has been created. `XMLHttpRequest.open()` not called yet.
static const UNSENT = const AjaxRequestReadyState._internal(0);
static const UNSENT = const AjaxRequestReadyState_._internal(0);
///`XMLHttpRequest.open()` has been called.
static const OPENED = const AjaxRequestReadyState._internal(1);
static const OPENED = const AjaxRequestReadyState_._internal(1);
///`XMLHttpRequest.send()` has been called, and [AjaxRequest.headers] and [AjaxRequest.status] are available.
static const HEADERS_RECEIVED = const AjaxRequestReadyState._internal(2);
static const HEADERS_RECEIVED = const AjaxRequestReadyState_._internal(2);
///Downloading; [AjaxRequest.responseText] holds partial data.
static const LOADING = const AjaxRequestReadyState._internal(3);
static const LOADING = const AjaxRequestReadyState_._internal(3);
///The operation is complete.
static const DONE = const AjaxRequestReadyState._internal(4);
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
static const DONE = const AjaxRequestReadyState_._internal(4);
}

View File

@ -0,0 +1,97 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'ajax_request_ready_state.dart';
// **************************************************************************
// ExchangeableEnumGenerator
// **************************************************************************
///Class used by [AjaxRequest] class. It represents the state of an [AjaxRequest].
class AjaxRequestReadyState {
final int _value;
final int _nativeValue;
const AjaxRequestReadyState._internal(this._value, this._nativeValue);
// ignore: unused_element
factory AjaxRequestReadyState._internalMultiPlatform(
int value, Function nativeValue) =>
AjaxRequestReadyState._internal(value, nativeValue());
///Client has been created. `XMLHttpRequest.open()` not called yet.
static const UNSENT = AjaxRequestReadyState._internal(0, 0);
///`XMLHttpRequest.open()` has been called.
static const OPENED = AjaxRequestReadyState._internal(1, 1);
///`XMLHttpRequest.send()` has been called, and [AjaxRequest.headers] and [AjaxRequest.status] are available.
static const HEADERS_RECEIVED = AjaxRequestReadyState._internal(2, 2);
///Downloading; [AjaxRequest.responseText] holds partial data.
static const LOADING = AjaxRequestReadyState._internal(3, 3);
///The operation is complete.
static const DONE = AjaxRequestReadyState._internal(4, 4);
///Set of all values of [AjaxRequestReadyState].
static final Set<AjaxRequestReadyState> values = [
AjaxRequestReadyState.UNSENT,
AjaxRequestReadyState.OPENED,
AjaxRequestReadyState.HEADERS_RECEIVED,
AjaxRequestReadyState.LOADING,
AjaxRequestReadyState.DONE,
].toSet();
///Gets a possible [AjaxRequestReadyState] instance from [int] value.
static AjaxRequestReadyState? fromValue(int? value) {
if (value != null) {
try {
return AjaxRequestReadyState.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets a possible [AjaxRequestReadyState] instance from a native value.
static AjaxRequestReadyState? fromNativeValue(int? value) {
if (value != null) {
try {
return AjaxRequestReadyState.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
///Gets [int] native value.
int toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
@override
String toString() {
switch (_value) {
case 0:
return 'UNSENT';
case 1:
return 'OPENED';
case 2:
return 'HEADERS_RECEIVED';
case 3:
return 'LOADING';
case 4:
return 'DONE';
}
return _value.toString();
}
}

View File

@ -1,13 +1,18 @@
import 'dart:ui';
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
import '../pull_to_refresh/main.dart';
import 'underline_style.dart';
import 'attributed_string_text_effect_style.dart';
import '../util.dart';
part 'attributed_string.g.dart';
///Class that represents a string with associated attributes
///used by the [PullToRefreshController] and [PullToRefreshSettings] classes.
class AttributedString {
@ExchangeableObject()
class AttributedString_ {
///The characters for the new object.
String string;
@ -69,7 +74,7 @@ class AttributedString {
///
///This value indicates whether the text has a line through it and corresponds to one of the constants described in [UnderlineStyle].
///The default value for this attribute is [UnderlineStyle.STYLE_NONE].
UnderlineStyle? strikethroughStyle;
UnderlineStyle_? strikethroughStyle;
///The color of the stroke.
///
@ -92,7 +97,7 @@ class AttributedString {
///
///The value of this attribute is a [AttributedStringTextEffectStyle] object.
///The default value of this property is `null`, indicating no text effect.
AttributedStringTextEffectStyle? textEffect;
AttributedStringTextEffectStyle_? textEffect;
///The color of the underline.
///
@ -104,9 +109,9 @@ class AttributedString {
///
///This value indicates whether the text is underlined and corresponds to one of the constants described in [UnderlineStyle].
///The default value for this attribute is [UnderlineStyle.STYLE_NONE].
UnderlineStyle? underlineStyle;
UnderlineStyle_? underlineStyle;
AttributedString({
AttributedString_({
required this.string,
this.backgroundColor,
this.baselineOffset,
@ -123,42 +128,14 @@ class AttributedString {
this.underlineColor,
this.underlineStyle,
});
Map<String, dynamic> toMap() {
return {
"string": this.string,
"backgroundColor": this.backgroundColor?.toHex(),
"baselineOffset": this.baselineOffset,
"expansion": this.expansion,
"foregroundColor": this.foregroundColor?.toHex(),
"kern": this.kern,
"ligature": this.ligature,
"obliqueness": this.obliqueness,
"strikethroughColor": this.strikethroughColor?.toHex(),
"strikethroughStyle": this.strikethroughStyle?.toValue(),
"strokeColor": this.strokeColor?.toHex(),
"strokeWidth": this.strokeWidth,
"textEffect": this.textEffect?.toValue(),
"underlineColor": this.underlineColor?.toHex(),
"underlineStyle": this.underlineStyle?.toValue(),
};
}
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
}
///An iOS-specific class that represents a string with associated attributes
///used by the [PullToRefreshController] and [PullToRefreshOptions] classes.
///Use [AttributedString] instead.
@Deprecated("Use AttributedString instead")
class IOSNSAttributedString {
@ExchangeableObject()
class IOSNSAttributedString_ {
///The characters for the new object.
String string;
@ -220,7 +197,7 @@ class IOSNSAttributedString {
///
///This value indicates whether the text has a line through it and corresponds to one of the constants described in [IOSNSUnderlineStyle].
///The default value for this attribute is [IOSNSUnderlineStyle.STYLE_NONE].
IOSNSUnderlineStyle? strikethroughStyle;
IOSNSUnderlineStyle_? strikethroughStyle;
///The color of the stroke.
///
@ -243,7 +220,7 @@ class IOSNSAttributedString {
///
///The value of this attribute is a [IOSNSAttributedStringTextEffectStyle] object.
///The default value of this property is `null`, indicating no text effect.
IOSNSAttributedStringTextEffectStyle? textEffect;
IOSNSAttributedStringTextEffectStyle_? textEffect;
///The color of the underline.
///
@ -255,9 +232,9 @@ class IOSNSAttributedString {
///
///This value indicates whether the text is underlined and corresponds to one of the constants described in [IOSNSUnderlineStyle].
///The default value for this attribute is [IOSNSUnderlineStyle.STYLE_NONE].
IOSNSUnderlineStyle? underlineStyle;
IOSNSUnderlineStyle_? underlineStyle;
IOSNSAttributedString({
IOSNSAttributedString_({
required this.string,
this.backgroundColor,
this.baselineOffset,
@ -274,35 +251,4 @@ class IOSNSAttributedString {
this.underlineColor,
this.underlineStyle,
});
///Converts instance to a map.
Map<String, dynamic> toMap() {
return {
"string": this.string,
"backgroundColor": this.backgroundColor?.toHex(),
"baselineOffset": this.baselineOffset,
"expansion": this.expansion,
"foregroundColor": this.foregroundColor?.toHex(),
"kern": this.kern,
"ligature": this.ligature,
"obliqueness": this.obliqueness,
"strikethroughColor": this.strikethroughColor?.toHex(),
"strikethroughStyle": this.strikethroughStyle?.toValue(),
"strokeColor": this.strokeColor?.toHex(),
"strokeWidth": this.strokeWidth,
"textEffect": this.textEffect?.toValue(),
"underlineColor": this.underlineColor?.toHex(),
"underlineStyle": this.underlineStyle?.toValue(),
};
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
}

View File

@ -0,0 +1,382 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'attributed_string.dart';
// **************************************************************************
// ExchangeableObjectGenerator
// **************************************************************************
///Class that represents a string with associated attributes
///used by the [PullToRefreshController] and [PullToRefreshSettings] classes.
class AttributedString {
///The characters for the new object.
String string;
///The color of the background behind the text.
///
///The value of this attribute is a [Color] object.
///Use this attribute to specify the color of the background area behind the text.
///If you do not specify this attribute, no background color is drawn.
Color? backgroundColor;
///The vertical offset for the position of the text.
///
///The value of this attribute is a number containing a floating point value indicating the characters offset from the baseline, in points.
///The default value is `0`.
double? baselineOffset;
///The expansion factor of the text.
///
///The value of this attribute is a number containing a floating point value indicating the log of the expansion factor to be applied to glyphs.
///The default value is `0`, indicating no expansion.
double? expansion;
///The color of the text.
///
///The value of this attribute is a [Color] object.
///Use this attribute to specify the color of the text during rendering.
///If you do not specify this attribute, the text is rendered in black.
Color? foregroundColor;
///The kerning of the text.
///
///The value of this attribute is a number containing a floating-point value.
///This value specifies the number of points by which to adjust kern-pair characters.
///Kerning prevents unwanted space from occurring between specific characters and depends on the font.
///The value `0` means kerning is disabled. The default value for this attribute is `0`.
double? kern;
///The ligature of the text.
///
///The value of this attribute is a number containing an integer.
///Ligatures cause specific character combinations to be rendered using a single custom glyph that corresponds to those characters.
///The value `0` indicates no ligatures. The value `1` indicates the use of the default ligatures.
///The value `2` indicates the use of all ligatures.
///The default value for this attribute is `1`. (Value `2` is unsupported on iOS.)
int? ligature;
///The obliqueness of the text.
///
///The value of this attribute is a number containing a floating point value indicating skew to be applied to glyphs.
///The default value is `0`, indicating no skew.
double? obliqueness;
///The color of the strikethrough.
///
///The value of this attribute is a [Color] object. The default value is `null`, indicating same as foreground color.
Color? strikethroughColor;
///The strikethrough style of the text.
///
///This value indicates whether the text has a line through it and corresponds to one of the constants described in [UnderlineStyle].
///The default value for this attribute is [UnderlineStyle.STYLE_NONE].
UnderlineStyle? strikethroughStyle;
///The color of the stroke.
///
///The value of this parameter is a [Color] object.
///If it is not defined (which is the case by default), it is assumed to be the same as the value of foregroundColor;
///otherwise, it describes the outline color.
Color? strokeColor;
///The width of the stroke.
///
///The value of this attribute is a number containing a floating-point value.
///This value represents the amount to change the stroke width and is specified as a percentage of the font point size.
///Specify `0` (the default) for no additional changes.
///Specify positive values to change the stroke width alone.
///Specify negative values to stroke and fill the text.
///For example, a typical value for outlined text would be `3.0`.
double? strokeWidth;
///The text effect.
///
///The value of this attribute is a [AttributedStringTextEffectStyle] object.
///The default value of this property is `null`, indicating no text effect.
AttributedStringTextEffectStyle? textEffect;
///The color of the underline.
///
///The value of this attribute is a [Color] object.
///The default value is `null`, indicating same as foreground color.
Color? underlineColor;
///The underline style of the text.
///
///This value indicates whether the text is underlined and corresponds to one of the constants described in [UnderlineStyle].
///The default value for this attribute is [UnderlineStyle.STYLE_NONE].
UnderlineStyle? underlineStyle;
AttributedString(
{required this.string,
this.backgroundColor,
this.baselineOffset,
this.expansion,
this.foregroundColor,
this.kern,
this.ligature,
this.obliqueness,
this.strikethroughColor,
this.strikethroughStyle,
this.strokeColor,
this.strokeWidth,
this.textEffect,
this.underlineColor,
this.underlineStyle});
///Gets a possible [AttributedString] instance from a [Map] value.
static AttributedString? fromMap(Map<String, dynamic>? map) {
if (map == null) {
return null;
}
final instance = AttributedString(
string: map['string'],
backgroundColor: map['backgroundColor'] != null
? UtilColor.fromStringRepresentation(map['backgroundColor'])
: null,
baselineOffset: map['baselineOffset'],
expansion: map['expansion'],
foregroundColor: map['foregroundColor'] != null
? UtilColor.fromStringRepresentation(map['foregroundColor'])
: null,
kern: map['kern'],
ligature: map['ligature'],
obliqueness: map['obliqueness'],
strikethroughColor: map['strikethroughColor'] != null
? UtilColor.fromStringRepresentation(map['strikethroughColor'])
: null,
strikethroughStyle:
UnderlineStyle.fromNativeValue(map['strikethroughStyle']),
strokeColor: map['strokeColor'] != null
? UtilColor.fromStringRepresentation(map['strokeColor'])
: null,
strokeWidth: map['strokeWidth'],
textEffect:
AttributedStringTextEffectStyle.fromNativeValue(map['textEffect']),
underlineColor: map['underlineColor'] != null
? UtilColor.fromStringRepresentation(map['underlineColor'])
: null,
underlineStyle: UnderlineStyle.fromNativeValue(map['underlineStyle']),
);
return instance;
}
///Converts instance to a map.
Map<String, dynamic> toMap() {
return {
"string": string,
"backgroundColor": backgroundColor?.toHex(),
"baselineOffset": baselineOffset,
"expansion": expansion,
"foregroundColor": foregroundColor?.toHex(),
"kern": kern,
"ligature": ligature,
"obliqueness": obliqueness,
"strikethroughColor": strikethroughColor?.toHex(),
"strikethroughStyle": strikethroughStyle?.toNativeValue(),
"strokeColor": strokeColor?.toHex(),
"strokeWidth": strokeWidth,
"textEffect": textEffect?.toNativeValue(),
"underlineColor": underlineColor?.toHex(),
"underlineStyle": underlineStyle?.toNativeValue(),
};
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return toMap();
}
@override
String toString() {
return 'AttributedString{string: $string, backgroundColor: $backgroundColor, baselineOffset: $baselineOffset, expansion: $expansion, foregroundColor: $foregroundColor, kern: $kern, ligature: $ligature, obliqueness: $obliqueness, strikethroughColor: $strikethroughColor, strikethroughStyle: $strikethroughStyle, strokeColor: $strokeColor, strokeWidth: $strokeWidth, textEffect: $textEffect, underlineColor: $underlineColor, underlineStyle: $underlineStyle}';
}
}
///An iOS-specific class that represents a string with associated attributes
///used by the [PullToRefreshController] and [PullToRefreshOptions] classes.
///Use [AttributedString] instead.
@Deprecated('Use AttributedString instead')
class IOSNSAttributedString {
///The characters for the new object.
String string;
///The color of the background behind the text.
///
///The value of this attribute is a [Color] object.
///Use this attribute to specify the color of the background area behind the text.
///If you do not specify this attribute, no background color is drawn.
Color? backgroundColor;
///The vertical offset for the position of the text.
///
///The value of this attribute is a number containing a floating point value indicating the characters offset from the baseline, in points.
///The default value is `0`.
double? baselineOffset;
///The expansion factor of the text.
///
///The value of this attribute is a number containing a floating point value indicating the log of the expansion factor to be applied to glyphs.
///The default value is `0`, indicating no expansion.
double? expansion;
///The color of the text.
///
///The value of this attribute is a [Color] object.
///Use this attribute to specify the color of the text during rendering.
///If you do not specify this attribute, the text is rendered in black.
Color? foregroundColor;
///The kerning of the text.
///
///The value of this attribute is a number containing a floating-point value.
///This value specifies the number of points by which to adjust kern-pair characters.
///Kerning prevents unwanted space from occurring between specific characters and depends on the font.
///The value `0` means kerning is disabled. The default value for this attribute is `0`.
double? kern;
///The ligature of the text.
///
///The value of this attribute is a number containing an integer.
///Ligatures cause specific character combinations to be rendered using a single custom glyph that corresponds to those characters.
///The value `0` indicates no ligatures. The value `1` indicates the use of the default ligatures.
///The value `2` indicates the use of all ligatures.
///The default value for this attribute is `1`. (Value `2` is unsupported on iOS.)
int? ligature;
///The obliqueness of the text.
///
///The value of this attribute is a number containing a floating point value indicating skew to be applied to glyphs.
///The default value is `0`, indicating no skew.
double? obliqueness;
///The color of the strikethrough.
///
///The value of this attribute is a [Color] object. The default value is `null`, indicating same as foreground color.
Color? strikethroughColor;
///The strikethrough style of the text.
///
///This value indicates whether the text has a line through it and corresponds to one of the constants described in [IOSNSUnderlineStyle].
///The default value for this attribute is [IOSNSUnderlineStyle.STYLE_NONE].
IOSNSUnderlineStyle? strikethroughStyle;
///The color of the stroke.
///
///The value of this parameter is a [Color] object.
///If it is not defined (which is the case by default), it is assumed to be the same as the value of foregroundColor;
///otherwise, it describes the outline color.
Color? strokeColor;
///The width of the stroke.
///
///The value of this attribute is a number containing a floating-point value.
///This value represents the amount to change the stroke width and is specified as a percentage of the font point size.
///Specify `0` (the default) for no additional changes.
///Specify positive values to change the stroke width alone.
///Specify negative values to stroke and fill the text.
///For example, a typical value for outlined text would be `3.0`.
double? strokeWidth;
///The text effect.
///
///The value of this attribute is a [IOSNSAttributedStringTextEffectStyle] object.
///The default value of this property is `null`, indicating no text effect.
IOSNSAttributedStringTextEffectStyle? textEffect;
///The color of the underline.
///
///The value of this attribute is a [Color] object.
///The default value is `null`, indicating same as foreground color.
Color? underlineColor;
///The underline style of the text.
///
///This value indicates whether the text is underlined and corresponds to one of the constants described in [IOSNSUnderlineStyle].
///The default value for this attribute is [IOSNSUnderlineStyle.STYLE_NONE].
IOSNSUnderlineStyle? underlineStyle;
IOSNSAttributedString(
{required this.string,
this.backgroundColor,
this.baselineOffset,
this.expansion,
this.foregroundColor,
this.kern,
this.ligature,
this.obliqueness,
this.strikethroughColor,
this.strikethroughStyle,
this.strokeColor,
this.strokeWidth,
this.textEffect,
this.underlineColor,
this.underlineStyle});
///Gets a possible [IOSNSAttributedString] instance from a [Map] value.
static IOSNSAttributedString? fromMap(Map<String, dynamic>? map) {
if (map == null) {
return null;
}
final instance = IOSNSAttributedString(
string: map['string'],
backgroundColor: map['backgroundColor'] != null
? UtilColor.fromStringRepresentation(map['backgroundColor'])
: null,
baselineOffset: map['baselineOffset'],
expansion: map['expansion'],
foregroundColor: map['foregroundColor'] != null
? UtilColor.fromStringRepresentation(map['foregroundColor'])
: null,
kern: map['kern'],
ligature: map['ligature'],
obliqueness: map['obliqueness'],
strikethroughColor: map['strikethroughColor'] != null
? UtilColor.fromStringRepresentation(map['strikethroughColor'])
: null,
strikethroughStyle:
IOSNSUnderlineStyle.fromNativeValue(map['strikethroughStyle']),
strokeColor: map['strokeColor'] != null
? UtilColor.fromStringRepresentation(map['strokeColor'])
: null,
strokeWidth: map['strokeWidth'],
textEffect: IOSNSAttributedStringTextEffectStyle.fromNativeValue(
map['textEffect']),
underlineColor: map['underlineColor'] != null
? UtilColor.fromStringRepresentation(map['underlineColor'])
: null,
underlineStyle:
IOSNSUnderlineStyle.fromNativeValue(map['underlineStyle']),
);
return instance;
}
///Converts instance to a map.
Map<String, dynamic> toMap() {
return {
"string": string,
"backgroundColor": backgroundColor?.toHex(),
"baselineOffset": baselineOffset,
"expansion": expansion,
"foregroundColor": foregroundColor?.toHex(),
"kern": kern,
"ligature": ligature,
"obliqueness": obliqueness,
"strikethroughColor": strikethroughColor?.toHex(),
"strikethroughStyle": strikethroughStyle?.toNativeValue(),
"strokeColor": strokeColor?.toHex(),
"strokeWidth": strokeWidth,
"textEffect": textEffect?.toNativeValue(),
"underlineColor": underlineColor?.toHex(),
"underlineStyle": underlineStyle?.toNativeValue(),
};
}
///Converts instance to a map.
Map<String, dynamic> toJson() {
return toMap();
}
@override
String toString() {
return 'IOSNSAttributedString{string: $string, backgroundColor: $backgroundColor, baselineOffset: $baselineOffset, expansion: $expansion, foregroundColor: $foregroundColor, kern: $kern, ligature: $ligature, obliqueness: $obliqueness, strikethroughColor: $strikethroughColor, strikethroughStyle: $strikethroughStyle, strokeColor: $strokeColor, strokeWidth: $strokeWidth, textEffect: $textEffect, underlineColor: $underlineColor, underlineStyle: $underlineStyle}';
}
}

View File

@ -1,81 +1,29 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
part 'attributed_string_text_effect_style.g.dart';
///Class that represents the supported proxy types.
class AttributedStringTextEffectStyle {
@ExchangeableEnum()
class AttributedStringTextEffectStyle_ {
// ignore: unused_field
final String _value;
const AttributedStringTextEffectStyle._internal(this._value);
///Set of all values of [AttributedStringTextEffectStyle].
static final Set<AttributedStringTextEffectStyle> values = [
AttributedStringTextEffectStyle.LETTERPRESS_STYLE,
].toSet();
///Gets a possible [AttributedStringTextEffectStyle] instance from a [String] value.
static AttributedStringTextEffectStyle? fromValue(String? value) {
if (value != null) {
try {
return AttributedStringTextEffectStyle.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [String] value.
String toValue() => _value;
@override
String toString() => _value;
const AttributedStringTextEffectStyle_._internal(this._value);
///A graphical text effect that gives glyphs the appearance of letterpress printing, which involves pressing the type into the paper.
static const LETTERPRESS_STYLE =
const AttributedStringTextEffectStyle._internal("letterpressStyle");
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
const AttributedStringTextEffectStyle_._internal("letterpressStyle");
}
///An iOS-specific Class that represents the supported proxy types.
///Use [AttributedStringTextEffectStyle] instead.
@Deprecated("Use AttributedStringTextEffectStyle instead")
class IOSNSAttributedStringTextEffectStyle {
@ExchangeableEnum()
class IOSNSAttributedStringTextEffectStyle_ {
// ignore: unused_field
final String _value;
const IOSNSAttributedStringTextEffectStyle._internal(this._value);
///Set of all values of [IOSNSAttributedStringTextEffectStyle].
static final Set<IOSNSAttributedStringTextEffectStyle> values = [
IOSNSAttributedStringTextEffectStyle.LETTERPRESS_STYLE,
].toSet();
///Gets a possible [IOSNSAttributedStringTextEffectStyle] instance from a [String] value.
static IOSNSAttributedStringTextEffectStyle? fromValue(String? value) {
if (value != null) {
try {
return IOSNSAttributedStringTextEffectStyle.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [String] value.
String toValue() => _value;
@override
String toString() => _value;
const IOSNSAttributedStringTextEffectStyle_._internal(this._value);
///A graphical text effect that gives glyphs the appearance of letterpress printing, which involves pressing the type into the paper.
static const LETTERPRESS_STYLE =
const IOSNSAttributedStringTextEffectStyle._internal("letterpressStyle");
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
const IOSNSAttributedStringTextEffectStyle_._internal("letterpressStyle");
}

View File

@ -0,0 +1,138 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'attributed_string_text_effect_style.dart';
// **************************************************************************
// ExchangeableEnumGenerator
// **************************************************************************
///Class that represents the supported proxy types.
class AttributedStringTextEffectStyle {
final String _value;
final String _nativeValue;
const AttributedStringTextEffectStyle._internal(
this._value, this._nativeValue);
// ignore: unused_element
factory AttributedStringTextEffectStyle._internalMultiPlatform(
String value, Function nativeValue) =>
AttributedStringTextEffectStyle._internal(value, nativeValue());
///A graphical text effect that gives glyphs the appearance of letterpress printing, which involves pressing the type into the paper.
static const LETTERPRESS_STYLE = AttributedStringTextEffectStyle._internal(
'letterpressStyle', 'letterpressStyle');
///Set of all values of [AttributedStringTextEffectStyle].
static final Set<AttributedStringTextEffectStyle> values = [
AttributedStringTextEffectStyle.LETTERPRESS_STYLE,
].toSet();
///Gets a possible [AttributedStringTextEffectStyle] instance from [String] value.
static AttributedStringTextEffectStyle? fromValue(String? value) {
if (value != null) {
try {
return AttributedStringTextEffectStyle.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets a possible [AttributedStringTextEffectStyle] instance from a native value.
static AttributedStringTextEffectStyle? fromNativeValue(String? value) {
if (value != null) {
try {
return AttributedStringTextEffectStyle.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [String] value.
String toValue() => _value;
///Gets [String] native value.
String toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
@override
String toString() {
return _value;
}
}
///An iOS-specific Class that represents the supported proxy types.
///Use [AttributedStringTextEffectStyle] instead.
@Deprecated('Use AttributedStringTextEffectStyle instead')
class IOSNSAttributedStringTextEffectStyle {
final String _value;
final String _nativeValue;
const IOSNSAttributedStringTextEffectStyle._internal(
this._value, this._nativeValue);
// ignore: unused_element
factory IOSNSAttributedStringTextEffectStyle._internalMultiPlatform(
String value, Function nativeValue) =>
IOSNSAttributedStringTextEffectStyle._internal(value, nativeValue());
///A graphical text effect that gives glyphs the appearance of letterpress printing, which involves pressing the type into the paper.
static const LETTERPRESS_STYLE =
IOSNSAttributedStringTextEffectStyle._internal(
'letterpressStyle', 'letterpressStyle');
///Set of all values of [IOSNSAttributedStringTextEffectStyle].
static final Set<IOSNSAttributedStringTextEffectStyle> values = [
IOSNSAttributedStringTextEffectStyle.LETTERPRESS_STYLE,
].toSet();
///Gets a possible [IOSNSAttributedStringTextEffectStyle] instance from [String] value.
static IOSNSAttributedStringTextEffectStyle? fromValue(String? value) {
if (value != null) {
try {
return IOSNSAttributedStringTextEffectStyle.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets a possible [IOSNSAttributedStringTextEffectStyle] instance from a native value.
static IOSNSAttributedStringTextEffectStyle? fromNativeValue(String? value) {
if (value != null) {
try {
return IOSNSAttributedStringTextEffectStyle.values
.firstWhere((element) => element.toNativeValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [String] value.
String toValue() => _value;
///Gets [String] native value.
String toNativeValue() => _nativeValue;
@override
int get hashCode => _value.hashCode;
@override
bool operator ==(value) => value == _value;
@override
String toString() {
return _value;
}
}

View File

@ -1,129 +1,47 @@
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
part 'cache_mode.g.dart';
///Class used to override the way the cache is used.
class CacheMode {
@ExchangeableEnum()
class CacheMode_ {
// ignore: unused_field
final int _value;
const CacheMode._internal(this._value);
///Set of all values of [CacheMode].
static final Set<CacheMode> values = [
CacheMode.LOAD_DEFAULT,
CacheMode.LOAD_CACHE_ELSE_NETWORK,
CacheMode.LOAD_NO_CACHE,
CacheMode.LOAD_CACHE_ONLY,
].toSet();
///Gets a possible [CacheMode] instance from an [int] value.
static CacheMode? fromValue(int? value) {
if (value != null) {
try {
return CacheMode.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
@override
String toString() {
switch (_value) {
case 1:
return "LOAD_CACHE_ELSE_NETWORK";
case 2:
return "LOAD_NO_CACHE";
case 3:
return "LOAD_CACHE_ONLY";
case -1:
default:
return "LOAD_DEFAULT";
}
}
const CacheMode_._internal(this._value);
///Default cache usage mode. If the navigation type doesn't impose any specific behavior,
///use cached resources when they are available and not expired, otherwise load resources from the network.
static const LOAD_DEFAULT = const CacheMode._internal(-1);
static const LOAD_DEFAULT = const CacheMode_._internal(-1);
///Use cached resources when they are available, even if they have expired. Otherwise load resources from the network.
static const LOAD_CACHE_ELSE_NETWORK = const CacheMode._internal(1);
static const LOAD_CACHE_ELSE_NETWORK = const CacheMode_._internal(1);
///Don't use the cache, load from the network.
static const LOAD_NO_CACHE = const CacheMode._internal(2);
static const LOAD_NO_CACHE = const CacheMode_._internal(2);
///Don't use the network, load from the cache.
static const LOAD_CACHE_ONLY = const CacheMode._internal(3);
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
static const LOAD_CACHE_ONLY = const CacheMode_._internal(3);
}
///An Android-specific class used to override the way the cache is used.
///Use [CacheMode] instead.
@Deprecated("Use CacheMode instead")
class AndroidCacheMode {
@ExchangeableEnum()
class AndroidCacheMode_ {
// ignore: unused_field
final int _value;
const AndroidCacheMode._internal(this._value);
///Set of all values of [AndroidCacheMode].
static final Set<AndroidCacheMode> values = [
AndroidCacheMode.LOAD_DEFAULT,
AndroidCacheMode.LOAD_CACHE_ELSE_NETWORK,
AndroidCacheMode.LOAD_NO_CACHE,
AndroidCacheMode.LOAD_CACHE_ONLY,
].toSet();
///Gets a possible [AndroidCacheMode] instance from an [int] value.
static AndroidCacheMode? fromValue(int? value) {
if (value != null) {
try {
return AndroidCacheMode.values
.firstWhere((element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
///Gets [int] value.
int toValue() => _value;
@override
String toString() {
switch (_value) {
case 1:
return "LOAD_CACHE_ELSE_NETWORK";
case 2:
return "LOAD_NO_CACHE";
case 3:
return "LOAD_CACHE_ONLY";
case -1:
default:
return "LOAD_DEFAULT";
}
}
const AndroidCacheMode_._internal(this._value);
///Default cache usage mode. If the navigation type doesn't impose any specific behavior,
///use cached resources when they are available and not expired, otherwise load resources from the network.
static const LOAD_DEFAULT = const AndroidCacheMode._internal(-1);
static const LOAD_DEFAULT = const AndroidCacheMode_._internal(-1);
///Use cached resources when they are available, even if they have expired. Otherwise load resources from the network.
static const LOAD_CACHE_ELSE_NETWORK = const AndroidCacheMode._internal(1);
static const LOAD_CACHE_ELSE_NETWORK = const AndroidCacheMode_._internal(1);
///Don't use the cache, load from the network.
static const LOAD_NO_CACHE = const AndroidCacheMode._internal(2);
static const LOAD_NO_CACHE = const AndroidCacheMode_._internal(2);
///Don't use the network, load from the cache.
static const LOAD_CACHE_ONLY = const AndroidCacheMode._internal(3);
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
static const LOAD_CACHE_ONLY = const AndroidCacheMode_._internal(3);
}

Some files were not shown because too many files have changed in this diff Show More