windows: fixed dealloc webviews logic, implemented takeScreenshot, added WebViewEnvironment and WebViewEnvironmentSettings classes
This commit is contained in:
parent
7721deb062
commit
ed97928331
|
@ -140,6 +140,7 @@ class ExchangeableEnumGenerator
|
|||
<DartObject>[];
|
||||
var hasWebSupport = false;
|
||||
var webSupportValue = null;
|
||||
var allPlatformsWithoutValue = true;
|
||||
if (platforms.isNotEmpty) {
|
||||
for (var platform in platforms) {
|
||||
final targetPlatformName =
|
||||
|
@ -150,6 +151,9 @@ class ExchangeableEnumGenerator
|
|||
? platformValueField.toIntValue() ??
|
||||
"'${platformValueField.toStringValue()}'"
|
||||
: null;
|
||||
if (allPlatformsWithoutValue && platformValue != null) {
|
||||
allPlatformsWithoutValue = false;
|
||||
}
|
||||
if (targetPlatformName == "web") {
|
||||
hasWebSupport = true;
|
||||
webSupportValue = platformValue;
|
||||
|
@ -170,8 +174,13 @@ class ExchangeableEnumGenerator
|
|||
nativeValueBody += "return $defaultValue;";
|
||||
nativeValueBody += "}";
|
||||
|
||||
classBuffer.writeln(
|
||||
"static final $fieldName = $extClassName._internalMultiPlatform($constantValue, $nativeValueBody);");
|
||||
if (!allPlatformsWithoutValue) {
|
||||
classBuffer.writeln(
|
||||
"static final $fieldName = $extClassName._internalMultiPlatform($constantValue, $nativeValueBody);");
|
||||
} else {
|
||||
classBuffer.writeln(
|
||||
"static const $fieldName = $extClassName._internal($constantValue, ${defaultValue ?? constantValue});");
|
||||
}
|
||||
} else {
|
||||
classBuffer.writeln(
|
||||
"static const $fieldName = $extClassName._internal($constantValue, $constantValue);");
|
||||
|
|
|
@ -115,6 +115,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
children: [
|
||||
InAppWebView(
|
||||
key: webViewKey,
|
||||
webViewEnvironment: webViewEnvironment,
|
||||
initialUrlRequest:
|
||||
URLRequest(url: WebUri('https://flutter.dev')),
|
||||
// initialUrlRequest:
|
||||
|
|
|
@ -15,6 +15,7 @@ import 'package:pointer_interceptor/pointer_interceptor.dart';
|
|||
// import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
final localhostServer = InAppLocalhostServer(documentRoot: 'assets');
|
||||
WebViewEnvironment? webViewEnvironment;
|
||||
|
||||
Future main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
@ -22,6 +23,13 @@ Future main() async {
|
|||
// await Permission.microphone.request();
|
||||
// await Permission.storage.request();
|
||||
|
||||
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.windows) {
|
||||
webViewEnvironment = await WebViewEnvironment.create(settings:
|
||||
WebViewEnvironmentSettings(
|
||||
userDataFolder: 'custom_path'
|
||||
));
|
||||
}
|
||||
|
||||
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
|
||||
await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,10 @@
|
|||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import flutter_inappwebview_macos
|
||||
import path_provider_foundation
|
||||
import url_launcher_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
}
|
||||
|
|
|
@ -35,14 +35,14 @@ dependencies:
|
|||
dependency_overrides:
|
||||
flutter_inappwebview_platform_interface:
|
||||
path: ../../flutter_inappwebview_platform_interface
|
||||
flutter_inappwebview_android:
|
||||
path: ../../flutter_inappwebview_android
|
||||
flutter_inappwebview_ios:
|
||||
path: ../../flutter_inappwebview_ios
|
||||
flutter_inappwebview_macos:
|
||||
path: ../../flutter_inappwebview_macos
|
||||
flutter_inappwebview_web:
|
||||
path: ../../flutter_inappwebview_web
|
||||
#flutter_inappwebview_android:
|
||||
# path: ../../flutter_inappwebview_android
|
||||
#flutter_inappwebview_ios:
|
||||
# path: ../../flutter_inappwebview_ios
|
||||
#flutter_inappwebview_macos:
|
||||
# path: ../../flutter_inappwebview_macos
|
||||
#flutter_inappwebview_web:
|
||||
# path: ../../flutter_inappwebview_web
|
||||
flutter_inappwebview_windows:
|
||||
path: ../../flutter_inappwebview_windows
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:flutter/services.dart';
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
||||
import '../webview_environment/webview_environment.dart';
|
||||
import 'headless_in_app_webview.dart';
|
||||
import 'in_app_webview_controller.dart';
|
||||
import '../find_interaction/find_interaction_controller.dart';
|
||||
|
@ -42,6 +43,7 @@ class InAppWebView extends StatefulWidget {
|
|||
InAppWebViewKeepAlive? keepAlive,
|
||||
bool? preventGestureDelay,
|
||||
TextDirection? layoutDirection,
|
||||
WebViewEnvironment? webViewEnvironment,
|
||||
@Deprecated('Use onGeolocationPermissionsHidePrompt instead')
|
||||
void Function(InAppWebViewController controller)?
|
||||
androidOnGeolocationPermissionsHidePrompt,
|
||||
|
@ -310,6 +312,7 @@ class InAppWebView extends StatefulWidget {
|
|||
findInteractionController: findInteractionController?.platform,
|
||||
contextMenu: contextMenu,
|
||||
layoutDirection: layoutDirection,
|
||||
webViewEnvironment: webViewEnvironment?.platform,
|
||||
onWebViewCreated: onWebViewCreated != null
|
||||
? (controller) => onWebViewCreated.call(controller)
|
||||
: null,
|
||||
|
|
|
@ -15,3 +15,4 @@ export 'webview_asset_loader.dart';
|
|||
export 'tracing_controller.dart';
|
||||
export 'process_global_config.dart';
|
||||
export 'in_app_localhost_server.dart';
|
||||
export 'webview_environment/main.dart';
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export 'webview_environment.dart';
|
|
@ -0,0 +1,35 @@
|
|||
import 'dart:core';
|
||||
|
||||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformWebViewEnvironment}
|
||||
class WebViewEnvironment {
|
||||
/// Constructs a [WebViewEnvironment].
|
||||
///
|
||||
/// See [WebViewEnvironment.fromPlatformCreationParams] for setting parameters for
|
||||
/// a specific platform.
|
||||
WebViewEnvironment.fromPlatformCreationParams({
|
||||
required PlatformWebViewEnvironmentCreationParams params,
|
||||
}) : this.fromPlatform(platform: PlatformWebViewEnvironment(params));
|
||||
|
||||
/// Constructs a [WebViewEnvironment] from a specific platform implementation.
|
||||
WebViewEnvironment.fromPlatform({required this.platform});
|
||||
|
||||
/// Implementation of [PlatformWebViewEnvironment] for the current platform.
|
||||
final PlatformWebViewEnvironment platform;
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformWebViewEnvironment.id}
|
||||
String get id => platform.id;
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformWebViewEnvironment.settings}
|
||||
WebViewEnvironmentSettings? get settings => platform.settings;
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformWebViewEnvironment.create}
|
||||
static Future<WebViewEnvironment> create(
|
||||
{WebViewEnvironmentSettings? settings}) async {
|
||||
return WebViewEnvironment.fromPlatform(platform: await PlatformWebViewEnvironment.static().create(settings: settings));
|
||||
}
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformWebViewEnvironment.dispose}
|
||||
Future<void> dispose() => platform.dispose();
|
||||
}
|
|
@ -18,11 +18,12 @@ environment:
|
|||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_inappwebview_platform_interface: ^1.0.10
|
||||
flutter_inappwebview_android: ^1.0.12
|
||||
flutter_inappwebview_ios: ^1.0.13
|
||||
flutter_inappwebview_macos: ^1.0.11
|
||||
flutter_inappwebview_web: ^1.0.8
|
||||
flutter_inappwebview_platform_interface: #^1.0.10
|
||||
path: ../flutter_inappwebview_platform_interface
|
||||
#flutter_inappwebview_android: ^1.0.12
|
||||
#flutter_inappwebview_ios: ^1.0.13
|
||||
#flutter_inappwebview_macos: ^1.0.11
|
||||
#flutter_inappwebview_web: ^1.0.8
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
@ -750,6 +750,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView
|
||||
///- iOS ([Official API - WKWebView.takeSnapshot](https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshot))
|
||||
///- MacOS ([Official API - WKWebView.takeSnapshot](https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshot))
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<Uint8List?> takeScreenshot(
|
||||
{ScreenshotConfiguration? screenshotConfiguration}) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
|||
|
||||
import '../inappwebview_platform.dart';
|
||||
import '../types/disposable.dart';
|
||||
import '../webview_environment/platform_webview_environment.dart';
|
||||
import 'in_app_webview_keep_alive.dart';
|
||||
import 'platform_webview.dart';
|
||||
import 'platform_headless_in_app_webview.dart';
|
||||
|
@ -24,6 +25,7 @@ class PlatformInAppWebViewWidgetCreationParams
|
|||
this.headlessWebView,
|
||||
this.keepAlive,
|
||||
this.preventGestureDelay,
|
||||
this.webViewEnvironment,
|
||||
super.controllerFromPlatform,
|
||||
super.windowId,
|
||||
super.onWebViewCreated,
|
||||
|
@ -181,6 +183,12 @@ class PlatformInAppWebViewWidgetCreationParams
|
|||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
final bool? preventGestureDelay;
|
||||
|
||||
///Used create the [PlatformInAppWebViewWidget] using the specified environment.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Windows
|
||||
final PlatformWebViewEnvironment? webViewEnvironment;
|
||||
}
|
||||
|
||||
/// Interface for a platform implementation of a web view widget.
|
||||
|
|
|
@ -24,6 +24,7 @@ import 'platform_tracing_controller.dart';
|
|||
import 'platform_webview_asset_loader.dart';
|
||||
import 'platform_webview_feature.dart';
|
||||
import 'in_app_localhost_server.dart';
|
||||
import 'webview_environment/platform_webview_environment.dart';
|
||||
|
||||
/// Interface for a platform implementation of a WebView.
|
||||
abstract class InAppWebViewPlatform extends PlatformInterface {
|
||||
|
@ -430,4 +431,24 @@ abstract class InAppWebViewPlatform extends PlatformInterface {
|
|||
throw UnimplementedError(
|
||||
'createPlatformChromeSafariBrowserStatic is not implemented on the current platform.');
|
||||
}
|
||||
|
||||
/// Creates a new [PlatformWebViewEnvironment].
|
||||
///
|
||||
/// This function should only be called by the app-facing package.
|
||||
/// Look at using [WebViewEnvironment] in `flutter_inappwebview` instead.
|
||||
PlatformWebViewEnvironment createPlatformWebViewEnvironment(
|
||||
PlatformWebViewEnvironmentCreationParams params,
|
||||
) {
|
||||
throw UnimplementedError(
|
||||
'createPlatformWebViewEnvironment is not implemented on the current platform.');
|
||||
}
|
||||
|
||||
/// Creates a new empty [PlatformWebViewEnvironment] to access static methods.
|
||||
///
|
||||
/// This function should only be called by the app-facing package.
|
||||
/// Look at using [WebViewEnvironment] in `flutter_inappwebview` instead.
|
||||
PlatformWebViewEnvironment createPlatformWebViewEnvironmentStatic() {
|
||||
throw UnimplementedError(
|
||||
'createPlatformWebViewEnvironmentStatic is not implemented on the current platform.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export 'inappwebview_platform.dart';
|
||||
export 'types/main.dart';
|
||||
export 'webview_environment/main.dart';
|
||||
export 'in_app_webview/main.dart';
|
||||
export 'in_app_browser/main.dart';
|
||||
export 'chrome_safari_browser/main.dart';
|
||||
|
|
|
@ -11,36 +11,48 @@ class CompressFormat_ {
|
|||
|
||||
///Compress to the `PNG` format.
|
||||
///PNG is lossless, so `quality` is ignored.
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumAndroidPlatform(),
|
||||
EnumIOSPlatform(),
|
||||
EnumMacOSPlatform(),
|
||||
EnumWindowsPlatform(),
|
||||
])
|
||||
static const PNG = const CompressFormat_._internal("PNG");
|
||||
|
||||
///Compress to the `JPEG` format.
|
||||
///Quality of `0` means compress for the smallest size.
|
||||
///`100` means compress for max visual quality.
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumAndroidPlatform(),
|
||||
EnumIOSPlatform(),
|
||||
EnumMacOSPlatform(),
|
||||
EnumWindowsPlatform(),
|
||||
])
|
||||
static const JPEG = const CompressFormat_._internal("JPEG");
|
||||
|
||||
///Compress to the `WEBP` lossy format.
|
||||
///Quality of `0` means compress for the smallest size.
|
||||
///`100` means compress for max visual quality.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumAndroidPlatform(),
|
||||
EnumWindowsPlatform(),
|
||||
])
|
||||
static const WEBP = const CompressFormat_._internal("WEBP");
|
||||
|
||||
///Compress to the `WEBP` lossy format.
|
||||
///Quality of `0` means compress for the smallest size.
|
||||
///`100` means compress for max visual quality.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
///
|
||||
///**NOTE for Android**: available on Android 30+.
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumAndroidPlatform(available: '30'),
|
||||
])
|
||||
static const WEBP_LOSSY = const CompressFormat_._internal("WEBP_LOSSY");
|
||||
|
||||
///Compress to the `WEBP` lossless format.
|
||||
///Quality refers to how much effort to put into compression.
|
||||
///A value of `0` means to compress quickly, resulting in a relatively large file size.
|
||||
///`100` means to spend more time compressing, resulting in a smaller file.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
///
|
||||
///**NOTE for Android**: available on Android 30+.
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumAndroidPlatform(available: '30'),
|
||||
])
|
||||
static const WEBP_LOSSLESS = const CompressFormat_._internal("WEBP_LOSSLESS");
|
||||
}
|
||||
|
|
|
@ -19,17 +19,31 @@ class CompressFormat {
|
|||
///Compress to the `JPEG` format.
|
||||
///Quality of `0` means compress for the smallest size.
|
||||
///`100` means compress for max visual quality.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
static const JPEG = CompressFormat._internal('JPEG', 'JPEG');
|
||||
|
||||
///Compress to the `PNG` format.
|
||||
///PNG is lossless, so `quality` is ignored.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
static const PNG = CompressFormat._internal('PNG', 'PNG');
|
||||
|
||||
///Compress to the `WEBP` lossy format.
|
||||
///Quality of `0` means compress for the smallest size.
|
||||
///`100` means compress for max visual quality.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- Windows
|
||||
static const WEBP = CompressFormat._internal('WEBP', 'WEBP');
|
||||
|
||||
///Compress to the `WEBP` lossless format.
|
||||
|
@ -37,9 +51,8 @@ class CompressFormat {
|
|||
///A value of `0` means to compress quickly, resulting in a relatively large file size.
|
||||
///`100` means to spend more time compressing, resulting in a smaller file.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
///
|
||||
///**NOTE for Android**: available on Android 30+.
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView 30+
|
||||
static const WEBP_LOSSLESS =
|
||||
CompressFormat._internal('WEBP_LOSSLESS', 'WEBP_LOSSLESS');
|
||||
|
||||
|
@ -47,9 +60,8 @@ class CompressFormat {
|
|||
///Quality of `0` means compress for the smallest size.
|
||||
///`100` means compress for max visual quality.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
///
|
||||
///**NOTE for Android**: available on Android 30+.
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView 30+
|
||||
static const WEBP_LOSSY =
|
||||
CompressFormat._internal('WEBP_LOSSY', 'WEBP_LOSSY');
|
||||
|
||||
|
|
|
@ -12,6 +12,12 @@ class ScreenshotConfiguration_ {
|
|||
///The portion of your web view to capture, specified as a rectangle in the view’s coordinate system.
|
||||
///The default value of this property is `null`, which captures everything in the view’s bounds rectangle.
|
||||
///If you specify a custom rectangle, it must lie within the bounds rectangle of the `WebView` object.
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform(),
|
||||
WindowsPlatform()
|
||||
])
|
||||
InAppWebViewRect_? rect;
|
||||
|
||||
///The width of the captured image, in points.
|
||||
|
@ -19,14 +25,31 @@ class ScreenshotConfiguration_ {
|
|||
///The web view maintains the aspect ratio of the captured content, but scales it to match the width you specify.
|
||||
///
|
||||
///The default value of this property is `null`, which returns an image whose size matches the original size of the captured rectangle.
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform()
|
||||
])
|
||||
double? snapshotWidth;
|
||||
|
||||
///The compression format of the captured image.
|
||||
///The default value is [CompressFormat.PNG].
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform(),
|
||||
WindowsPlatform()
|
||||
])
|
||||
CompressFormat_ compressFormat;
|
||||
|
||||
///Hint to the compressor, `0-100`. The value is interpreted differently depending on the [CompressFormat].
|
||||
///[CompressFormat.PNG] is lossless, so this value is ignored.
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform(),
|
||||
WindowsPlatform()
|
||||
])
|
||||
int quality;
|
||||
|
||||
///Use [afterScreenUpdates] instead.
|
||||
|
@ -36,10 +59,10 @@ class ScreenshotConfiguration_ {
|
|||
///A Boolean value that indicates whether to take the snapshot after incorporating any pending screen updates.
|
||||
///The default value of this property is `true`, which causes the web view to incorporate any recent changes to the view’s content and then generate the snapshot.
|
||||
///If you change the value to `false`, the `WebView` takes the snapshot immediately, and before incorporating any new changes.
|
||||
///
|
||||
///**NOTE**: available only on iOS.
|
||||
///
|
||||
///**NOTE for iOS**: Available from iOS 13.0+.
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform(available: '13.0'),
|
||||
MacOSPlatform(available: '10.15'),
|
||||
])
|
||||
bool afterScreenUpdates;
|
||||
|
||||
@ExchangeableObjectConstructor()
|
||||
|
|
|
@ -12,13 +12,19 @@ class ScreenshotConfiguration {
|
|||
///The default value of this property is `true`, which causes the web view to incorporate any recent changes to the view’s content and then generate the snapshot.
|
||||
///If you change the value to `false`, the `WebView` takes the snapshot immediately, and before incorporating any new changes.
|
||||
///
|
||||
///**NOTE**: available only on iOS.
|
||||
///
|
||||
///**NOTE for iOS**: Available from iOS 13.0+.
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS 13.0+
|
||||
///- MacOS 10.15+
|
||||
bool afterScreenUpdates;
|
||||
|
||||
///The compression format of the captured image.
|
||||
///The default value is [CompressFormat.PNG].
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
CompressFormat compressFormat;
|
||||
|
||||
///Use [afterScreenUpdates] instead.
|
||||
|
@ -27,11 +33,23 @@ class ScreenshotConfiguration {
|
|||
|
||||
///Hint to the compressor, `0-100`. The value is interpreted differently depending on the [CompressFormat].
|
||||
///[CompressFormat.PNG] is lossless, so this value is ignored.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
int quality;
|
||||
|
||||
///The portion of your web view to capture, specified as a rectangle in the view’s coordinate system.
|
||||
///The default value of this property is `null`, which captures everything in the view’s bounds rectangle.
|
||||
///If you specify a custom rectangle, it must lie within the bounds rectangle of the `WebView` object.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
InAppWebViewRect? rect;
|
||||
|
||||
///The width of the captured image, in points.
|
||||
|
@ -39,6 +57,11 @@ class ScreenshotConfiguration {
|
|||
///The web view maintains the aspect ratio of the captured content, but scales it to match the width you specify.
|
||||
///
|
||||
///The default value of this property is `null`, which returns an image whose size matches the original size of the captured rectangle.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
double? snapshotWidth;
|
||||
ScreenshotConfiguration(
|
||||
{this.rect,
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export 'platform_webview_environment.dart';
|
||||
export 'webview_environment_settings.dart' show WebViewEnvironmentSettings;
|
|
@ -0,0 +1,106 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||
|
||||
import '../debug_logging_settings.dart';
|
||||
import '../inappwebview_platform.dart';
|
||||
import '../types/disposable.dart';
|
||||
import 'webview_environment_settings.dart';
|
||||
|
||||
/// Object specifying creation parameters for creating a [PlatformWebViewEnvironment].
|
||||
///
|
||||
/// Platform specific implementations can add additional fields by extending
|
||||
/// this class.
|
||||
@immutable
|
||||
class PlatformWebViewEnvironmentCreationParams {
|
||||
/// Used by the platform implementation to create a new [PlatformWebViewEnvironment].
|
||||
const PlatformWebViewEnvironmentCreationParams({this.settings});
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformWebViewEnvironment.settings}
|
||||
final WebViewEnvironmentSettings? settings;
|
||||
}
|
||||
|
||||
///Controls a WebView Environment used by WebView instances.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Windows
|
||||
abstract class PlatformWebViewEnvironment extends PlatformInterface
|
||||
implements Disposable {
|
||||
///Debug settings used by [PlatformWebViewEnvironment].
|
||||
static DebugLoggingSettings debugLoggingSettings = DebugLoggingSettings(
|
||||
maxLogMessageLength: 1000
|
||||
);
|
||||
|
||||
/// Creates a new [PlatformInAppWebViewController]
|
||||
factory PlatformWebViewEnvironment(
|
||||
PlatformWebViewEnvironmentCreationParams params) {
|
||||
assert(
|
||||
InAppWebViewPlatform.instance != null,
|
||||
'A platform implementation for `flutter_inappwebview` has not been set. Please '
|
||||
'ensure that an implementation of `InAppWebViewPlatform` has been set to '
|
||||
'`InAppWebViewPlatform.instance` before use. For unit testing, '
|
||||
'`InAppWebViewPlatform.instance` can be set with your own test implementation.',
|
||||
);
|
||||
final PlatformWebViewEnvironment webViewEnvironment =
|
||||
InAppWebViewPlatform.instance!
|
||||
.createPlatformWebViewEnvironment(params);
|
||||
PlatformInterface.verify(webViewEnvironment, _token);
|
||||
return webViewEnvironment;
|
||||
}
|
||||
|
||||
/// Creates a new [PlatformWebViewEnvironment] to access static methods.
|
||||
factory PlatformWebViewEnvironment.static() {
|
||||
assert(
|
||||
InAppWebViewPlatform.instance != null,
|
||||
'A platform implementation for `flutter_inappwebview` has not been set. Please '
|
||||
'ensure that an implementation of `InAppWebViewPlatform` has been set to '
|
||||
'`InAppWebViewPlatform.instance` before use. For unit testing, '
|
||||
'`InAppWebViewPlatform.instance` can be set with your own test implementation.',
|
||||
);
|
||||
final PlatformWebViewEnvironment webViewEnvironment =
|
||||
InAppWebViewPlatform.instance!
|
||||
.createPlatformWebViewEnvironmentStatic();
|
||||
PlatformInterface.verify(webViewEnvironment, _token);
|
||||
return webViewEnvironment;
|
||||
}
|
||||
|
||||
/// Used by the platform implementation to create a new [PlatformWebViewEnvironment].
|
||||
///
|
||||
/// Should only be used by platform implementations because they can't extend
|
||||
/// a class that only contains a factory constructor.
|
||||
@protected
|
||||
PlatformWebViewEnvironment.implementation(this.params)
|
||||
: super(token: _token);
|
||||
|
||||
static final Object _token = Object();
|
||||
|
||||
/// The parameters used to initialize the [PlatformWebViewEnvironment].
|
||||
final PlatformWebViewEnvironmentCreationParams params;
|
||||
|
||||
///{@template flutter_inappwebview_platform_interface.PlatformWebViewEnvironment.id}
|
||||
/// WebView Environment ID.
|
||||
///{@endtemplate}
|
||||
String get id =>
|
||||
throw UnimplementedError('id is not implemented on the current platform');
|
||||
|
||||
///{@template flutter_inappwebview_platform_interface.PlatformWebViewEnvironment.settings}
|
||||
/// WebView Environment settings.
|
||||
///{@endtemplate}
|
||||
WebViewEnvironmentSettings? get settings => params.settings;
|
||||
|
||||
///{@template flutter_inappwebview_platform_interface.PlatformWebViewEnvironment.create}
|
||||
///Initializes the [PlatformWebViewEnvironment] using [settings].
|
||||
///{@endtemplate}
|
||||
Future<PlatformWebViewEnvironment> create(
|
||||
{WebViewEnvironmentSettings? settings}) {
|
||||
throw UnimplementedError(
|
||||
'create is not implemented on the current platform');
|
||||
}
|
||||
|
||||
///{@template flutter_inappwebview_platform_interface.PlatformWebViewEnvironment.dispose}
|
||||
///Disposes the WebView Environment reference.
|
||||
///{@endtemplate}
|
||||
Future<void> dispose() {
|
||||
throw UnimplementedError(
|
||||
'dispose is not implemented on the current platform');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
|
||||
|
||||
import 'platform_webview_environment.dart';
|
||||
|
||||
part 'webview_environment_settings.g.dart';
|
||||
|
||||
///This class represents all the [PlatformWebViewEnvironment] settings available.
|
||||
@ExchangeableObject(copyMethod: true)
|
||||
class WebViewEnvironmentSettings_ {
|
||||
final String? browserExecutableFolder;
|
||||
final String? userDataFolder;
|
||||
final String? additionalBrowserArguments;
|
||||
final bool? allowSingleSignOnUsingOSPrimaryAccount;
|
||||
final String? language;
|
||||
final String? targetCompatibleBrowserVersion;
|
||||
|
||||
WebViewEnvironmentSettings_({
|
||||
this.browserExecutableFolder,
|
||||
this.userDataFolder,
|
||||
this.additionalBrowserArguments,
|
||||
this.allowSingleSignOnUsingOSPrimaryAccount,
|
||||
this.language,
|
||||
this.targetCompatibleBrowserVersion
|
||||
});
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'webview_environment_settings.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// ExchangeableObjectGenerator
|
||||
// **************************************************************************
|
||||
|
||||
///This class represents all the [PlatformWebViewEnvironment] settings available.
|
||||
class WebViewEnvironmentSettings {
|
||||
final String? additionalBrowserArguments;
|
||||
final bool? allowSingleSignOnUsingOSPrimaryAccount;
|
||||
final String? browserExecutableFolder;
|
||||
final String? language;
|
||||
final String? targetCompatibleBrowserVersion;
|
||||
final String? userDataFolder;
|
||||
WebViewEnvironmentSettings(
|
||||
{this.additionalBrowserArguments,
|
||||
this.allowSingleSignOnUsingOSPrimaryAccount,
|
||||
this.browserExecutableFolder,
|
||||
this.language,
|
||||
this.targetCompatibleBrowserVersion,
|
||||
this.userDataFolder});
|
||||
|
||||
///Gets a possible [WebViewEnvironmentSettings] instance from a [Map] value.
|
||||
static WebViewEnvironmentSettings? fromMap(Map<String, dynamic>? map) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
final instance = WebViewEnvironmentSettings(
|
||||
additionalBrowserArguments: map['additionalBrowserArguments'],
|
||||
allowSingleSignOnUsingOSPrimaryAccount:
|
||||
map['allowSingleSignOnUsingOSPrimaryAccount'],
|
||||
browserExecutableFolder: map['browserExecutableFolder'],
|
||||
language: map['language'],
|
||||
targetCompatibleBrowserVersion: map['targetCompatibleBrowserVersion'],
|
||||
userDataFolder: map['userDataFolder'],
|
||||
);
|
||||
return instance;
|
||||
}
|
||||
|
||||
///Converts instance to a map.
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
"additionalBrowserArguments": additionalBrowserArguments,
|
||||
"allowSingleSignOnUsingOSPrimaryAccount":
|
||||
allowSingleSignOnUsingOSPrimaryAccount,
|
||||
"browserExecutableFolder": browserExecutableFolder,
|
||||
"language": language,
|
||||
"targetCompatibleBrowserVersion": targetCompatibleBrowserVersion,
|
||||
"userDataFolder": userDataFolder,
|
||||
};
|
||||
}
|
||||
|
||||
///Converts instance to a map.
|
||||
Map<String, dynamic> toJson() {
|
||||
return toMap();
|
||||
}
|
||||
|
||||
///Returns a copy of WebViewEnvironmentSettings.
|
||||
WebViewEnvironmentSettings copy() {
|
||||
return WebViewEnvironmentSettings.fromMap(toMap()) ??
|
||||
WebViewEnvironmentSettings();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WebViewEnvironmentSettings{additionalBrowserArguments: $additionalBrowserArguments, allowSingleSignOnUsingOSPrimaryAccount: $allowSingleSignOnUsingOSPrimaryAccount, browserExecutableFolder: $browserExecutableFolder, language: $language, targetCompatibleBrowserVersion: $targetCompatibleBrowserVersion, userDataFolder: $userDataFolder}';
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
name: flutter_inappwebview_platform_interface
|
||||
description: A common platform interface for the flutter_inappwebview plugin.
|
||||
version: 1.0.10
|
||||
version: 1.0.11
|
||||
homepage: https://inappwebview.dev/
|
||||
repository: https://github.com/pichillilorenzo/flutter_inappwebview/tree/master/flutter_inappwebview_platform_interface
|
||||
issue_tracker: https://github.com/pichillilorenzo/flutter_inappwebview/issues
|
||||
|
|
|
@ -86,10 +86,9 @@ packages:
|
|||
flutter_inappwebview_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_inappwebview_platform_interface
|
||||
sha256: "545fd4c25a07d2775f7d5af05a979b2cac4fbf79393b0a7f5d33ba39ba4f6187"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
path: "../../flutter_inappwebview_platform_interface"
|
||||
relative: true
|
||||
source: path
|
||||
version: "1.0.10"
|
||||
flutter_inappwebview_windows:
|
||||
dependency: "direct main"
|
||||
|
|
|
@ -5,56 +5,54 @@ import 'package:flutter/services.dart';
|
|||
|
||||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
||||
|
||||
import 'in_app_webview/headless_in_app_webview.dart';
|
||||
import 'platform_util.dart';
|
||||
|
||||
/// Object specifying creation parameters for creating a [MacOSCookieManager].
|
||||
/// Object specifying creation parameters for creating a [WindowsCookieManager].
|
||||
///
|
||||
/// When adding additional fields make sure they can be null or have a default
|
||||
/// value to avoid breaking changes. See [PlatformCookieManagerCreationParams] for
|
||||
/// more information.
|
||||
@immutable
|
||||
class MacOSCookieManagerCreationParams
|
||||
class WindowsCookieManagerCreationParams
|
||||
extends PlatformCookieManagerCreationParams {
|
||||
/// Creates a new [MacOSCookieManagerCreationParams] instance.
|
||||
const MacOSCookieManagerCreationParams(
|
||||
// This parameter prevents breaking changes later.
|
||||
// ignore: avoid_unused_constructor_parameters
|
||||
PlatformCookieManagerCreationParams params,
|
||||
) : super();
|
||||
/// Creates a new [WindowsCookieManagerCreationParams] instance.
|
||||
const WindowsCookieManagerCreationParams(
|
||||
// This parameter prevents breaking changes later.
|
||||
// ignore: avoid_unused_constructor_parameters
|
||||
PlatformCookieManagerCreationParams params,
|
||||
) : super();
|
||||
|
||||
/// Creates a [MacOSCookieManagerCreationParams] instance based on [PlatformCookieManagerCreationParams].
|
||||
factory MacOSCookieManagerCreationParams.fromPlatformCookieManagerCreationParams(
|
||||
/// Creates a [WindowsCookieManagerCreationParams] instance based on [PlatformCookieManagerCreationParams].
|
||||
factory WindowsCookieManagerCreationParams.fromPlatformCookieManagerCreationParams(
|
||||
PlatformCookieManagerCreationParams params) {
|
||||
return MacOSCookieManagerCreationParams(params);
|
||||
return WindowsCookieManagerCreationParams(params);
|
||||
}
|
||||
}
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformCookieManager}
|
||||
class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||
/// Creates a new [MacOSCookieManager].
|
||||
MacOSCookieManager(PlatformCookieManagerCreationParams params)
|
||||
class WindowsCookieManager extends PlatformCookieManager
|
||||
with ChannelController {
|
||||
/// Creates a new [WindowsCookieManager].
|
||||
WindowsCookieManager(PlatformCookieManagerCreationParams params)
|
||||
: super.implementation(
|
||||
params is MacOSCookieManagerCreationParams
|
||||
? params
|
||||
: MacOSCookieManagerCreationParams
|
||||
.fromPlatformCookieManagerCreationParams(params),
|
||||
) {
|
||||
params is WindowsCookieManagerCreationParams
|
||||
? params
|
||||
: WindowsCookieManagerCreationParams
|
||||
.fromPlatformCookieManagerCreationParams(params),
|
||||
) {
|
||||
channel = const MethodChannel(
|
||||
'com.pichillilorenzo/flutter_inappwebview_cookiemanager');
|
||||
handler = handleMethod;
|
||||
initMethodCallHandler();
|
||||
}
|
||||
|
||||
static MacOSCookieManager? _instance;
|
||||
static WindowsCookieManager? _instance;
|
||||
|
||||
///Gets the [MacOSCookieManager] shared instance.
|
||||
static MacOSCookieManager instance() {
|
||||
///Gets the [WindowsCookieManager] shared instance.
|
||||
static WindowsCookieManager instance() {
|
||||
return (_instance != null) ? _instance! : _init();
|
||||
}
|
||||
|
||||
static MacOSCookieManager _init() {
|
||||
_instance = MacOSCookieManager(MacOSCookieManagerCreationParams(
|
||||
static WindowsCookieManager _init() {
|
||||
_instance = WindowsCookieManager(WindowsCookieManagerCreationParams(
|
||||
const PlatformCookieManagerCreationParams()));
|
||||
return _instance!;
|
||||
}
|
||||
|
@ -64,40 +62,23 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
|||
@override
|
||||
Future<bool> setCookie(
|
||||
{required WebUri url,
|
||||
required String name,
|
||||
required String value,
|
||||
String path = "/",
|
||||
String? domain,
|
||||
int? expiresDate,
|
||||
int? maxAge,
|
||||
bool? isSecure,
|
||||
bool? isHttpOnly,
|
||||
HTTPCookieSameSitePolicy? sameSite,
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
webViewController = webViewController ?? iosBelow11WebViewController;
|
||||
|
||||
required String name,
|
||||
required String value,
|
||||
String path = "/",
|
||||
String? domain,
|
||||
int? expiresDate,
|
||||
int? maxAge,
|
||||
bool? isSecure,
|
||||
bool? isHttpOnly,
|
||||
HTTPCookieSameSitePolicy? sameSite,
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
assert(url.toString().isNotEmpty);
|
||||
assert(name.isNotEmpty);
|
||||
assert(value.isNotEmpty);
|
||||
assert(path.isNotEmpty);
|
||||
|
||||
if (await _shouldUseJavascript()) {
|
||||
await _setCookieWithJavaScript(
|
||||
url: url,
|
||||
name: name,
|
||||
value: value,
|
||||
domain: domain,
|
||||
path: path,
|
||||
expiresDate: expiresDate,
|
||||
maxAge: maxAge,
|
||||
isSecure: isSecure,
|
||||
sameSite: sameSite,
|
||||
webViewController: webViewController);
|
||||
return true;
|
||||
}
|
||||
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('url', () => url.toString());
|
||||
args.putIfAbsent('name', () => name);
|
||||
|
@ -113,72 +94,14 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
|||
return await channel?.invokeMethod<bool>('setCookie', args) ?? false;
|
||||
}
|
||||
|
||||
Future<void> _setCookieWithJavaScript(
|
||||
{required WebUri url,
|
||||
required String name,
|
||||
required String value,
|
||||
String path = "/",
|
||||
String? domain,
|
||||
int? expiresDate,
|
||||
int? maxAge,
|
||||
bool? isSecure,
|
||||
HTTPCookieSameSitePolicy? sameSite,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
var cookieValue = name + "=" + value + "; Path=" + path;
|
||||
|
||||
if (domain != null) cookieValue += "; Domain=" + domain;
|
||||
|
||||
if (expiresDate != null)
|
||||
cookieValue += "; Expires=" + await _getCookieExpirationDate(expiresDate);
|
||||
|
||||
if (maxAge != null) cookieValue += "; Max-Age=" + maxAge.toString();
|
||||
|
||||
if (isSecure != null && isSecure) cookieValue += "; Secure";
|
||||
|
||||
if (sameSite != null)
|
||||
cookieValue += "; SameSite=" + sameSite.toNativeValue();
|
||||
|
||||
cookieValue += ";";
|
||||
|
||||
if (webViewController != null) {
|
||||
final javaScriptEnabled =
|
||||
(await webViewController.getSettings())?.javaScriptEnabled ?? false;
|
||||
if (javaScriptEnabled) {
|
||||
await webViewController.evaluateJavascript(
|
||||
source: 'document.cookie="$cookieValue"');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final setCookieCompleter = Completer<void>();
|
||||
final headlessWebView =
|
||||
WindowsHeadlessInAppWebView(WindowsHeadlessInAppWebViewCreationParams(
|
||||
initialUrlRequest: URLRequest(url: url),
|
||||
onLoadStop: (controller, url) async {
|
||||
await controller.evaluateJavascript(
|
||||
source: 'document.cookie="$cookieValue"');
|
||||
setCookieCompleter.complete();
|
||||
}));
|
||||
await headlessWebView.run();
|
||||
await setCookieCompleter.future;
|
||||
await headlessWebView.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Cookie>> getCookies(
|
||||
{required WebUri url,
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
assert(url.toString().isNotEmpty);
|
||||
|
||||
webViewController = webViewController ?? iosBelow11WebViewController;
|
||||
|
||||
if (await _shouldUseJavascript()) {
|
||||
return await _getCookiesWithJavaScript(
|
||||
url: url, webViewController: webViewController);
|
||||
}
|
||||
|
||||
List<Cookie> cookies = [];
|
||||
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
|
@ -195,7 +118,7 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
|||
isSessionOnly: cookieMap["isSessionOnly"],
|
||||
domain: cookieMap["domain"],
|
||||
sameSite:
|
||||
HTTPCookieSameSitePolicy.fromNativeValue(cookieMap["sameSite"]),
|
||||
HTTPCookieSameSitePolicy.fromNativeValue(cookieMap["sameSite"]),
|
||||
isSecure: cookieMap["isSecure"],
|
||||
isHttpOnly: cookieMap["isHttpOnly"],
|
||||
path: cookieMap["path"]));
|
||||
|
@ -203,84 +126,16 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
|||
return cookies;
|
||||
}
|
||||
|
||||
Future<List<Cookie>> _getCookiesWithJavaScript(
|
||||
{required WebUri url,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
assert(url.toString().isNotEmpty);
|
||||
|
||||
List<Cookie> cookies = [];
|
||||
|
||||
if (webViewController != null) {
|
||||
final javaScriptEnabled =
|
||||
(await webViewController.getSettings())?.javaScriptEnabled ?? false;
|
||||
if (javaScriptEnabled) {
|
||||
List<String> documentCookies = (await webViewController
|
||||
.evaluateJavascript(source: 'document.cookie') as String)
|
||||
.split(';')
|
||||
.map((documentCookie) => documentCookie.trim())
|
||||
.toList();
|
||||
documentCookies.forEach((documentCookie) {
|
||||
List<String> cookie = documentCookie.split('=');
|
||||
if (cookie.length > 1) {
|
||||
cookies.add(Cookie(
|
||||
name: cookie[0],
|
||||
value: cookie[1],
|
||||
));
|
||||
}
|
||||
});
|
||||
return cookies;
|
||||
}
|
||||
}
|
||||
|
||||
final pageLoaded = Completer<void>();
|
||||
final headlessWebView =
|
||||
WindowsHeadlessInAppWebView(WindowsHeadlessInAppWebViewCreationParams(
|
||||
initialUrlRequest: URLRequest(url: url),
|
||||
onLoadStop: (controller, url) async {
|
||||
pageLoaded.complete();
|
||||
},
|
||||
));
|
||||
await headlessWebView.run();
|
||||
await pageLoaded.future;
|
||||
|
||||
List<String> documentCookies = (await headlessWebView.webViewController!
|
||||
.evaluateJavascript(source: 'document.cookie') as String)
|
||||
.split(';')
|
||||
.map((documentCookie) => documentCookie.trim())
|
||||
.toList();
|
||||
documentCookies.forEach((documentCookie) {
|
||||
List<String> cookie = documentCookie.split('=');
|
||||
if (cookie.length > 1) {
|
||||
cookies.add(Cookie(
|
||||
name: cookie[0],
|
||||
value: cookie[1],
|
||||
));
|
||||
}
|
||||
});
|
||||
await headlessWebView.dispose();
|
||||
return cookies;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Cookie?> getCookie(
|
||||
{required WebUri url,
|
||||
required String name,
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
required String name,
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
assert(url.toString().isNotEmpty);
|
||||
assert(name.isNotEmpty);
|
||||
|
||||
webViewController = webViewController ?? iosBelow11WebViewController;
|
||||
|
||||
if (await _shouldUseJavascript()) {
|
||||
List<Cookie> cookies = await _getCookiesWithJavaScript(
|
||||
url: url, webViewController: webViewController);
|
||||
return cookies
|
||||
.cast<Cookie?>()
|
||||
.firstWhere((cookie) => cookie!.name == name, orElse: () => null);
|
||||
}
|
||||
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('url', () => url.toString());
|
||||
List<dynamic> cookies =
|
||||
|
@ -307,29 +162,15 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
|||
@override
|
||||
Future<bool> deleteCookie(
|
||||
{required WebUri url,
|
||||
required String name,
|
||||
String path = "/",
|
||||
String? domain,
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
required String name,
|
||||
String path = "/",
|
||||
String? domain,
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
assert(url.toString().isNotEmpty);
|
||||
assert(name.isNotEmpty);
|
||||
|
||||
webViewController = webViewController ?? iosBelow11WebViewController;
|
||||
|
||||
if (await _shouldUseJavascript()) {
|
||||
await _setCookieWithJavaScript(
|
||||
url: url,
|
||||
name: name,
|
||||
value: "",
|
||||
path: path,
|
||||
domain: domain,
|
||||
maxAge: -1,
|
||||
webViewController: webViewController);
|
||||
return true;
|
||||
}
|
||||
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('url', () => url.toString());
|
||||
args.putIfAbsent('name', () => name);
|
||||
|
@ -341,31 +182,13 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
|||
@override
|
||||
Future<bool> deleteCookies(
|
||||
{required WebUri url,
|
||||
String path = "/",
|
||||
String? domain,
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
String path = "/",
|
||||
String? domain,
|
||||
@Deprecated("Use webViewController instead")
|
||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||
PlatformInAppWebViewController? webViewController}) async {
|
||||
assert(url.toString().isNotEmpty);
|
||||
|
||||
webViewController = webViewController ?? iosBelow11WebViewController;
|
||||
|
||||
if (await _shouldUseJavascript()) {
|
||||
List<Cookie> cookies = await _getCookiesWithJavaScript(
|
||||
url: url, webViewController: webViewController);
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
await _setCookieWithJavaScript(
|
||||
url: url,
|
||||
name: cookies[i].name,
|
||||
value: "",
|
||||
path: path,
|
||||
domain: domain,
|
||||
maxAge: -1,
|
||||
webViewController: webViewController);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('url', () => url.toString());
|
||||
args.putIfAbsent('domain', () => domain);
|
||||
|
@ -380,46 +203,10 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<List<Cookie>> getAllCookies() async {
|
||||
List<Cookie> cookies = [];
|
||||
|
||||
Future<bool> removeSessionCookies() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
List<dynamic> cookieListMap =
|
||||
await channel?.invokeMethod<List>('getAllCookies', args) ?? [];
|
||||
cookieListMap = cookieListMap.cast<Map<dynamic, dynamic>>();
|
||||
|
||||
cookieListMap.forEach((cookieMap) {
|
||||
cookies.add(Cookie(
|
||||
name: cookieMap["name"],
|
||||
value: cookieMap["value"],
|
||||
expiresDate: cookieMap["expiresDate"],
|
||||
isSessionOnly: cookieMap["isSessionOnly"],
|
||||
domain: cookieMap["domain"],
|
||||
sameSite:
|
||||
HTTPCookieSameSitePolicy.fromNativeValue(cookieMap["sameSite"]),
|
||||
isSecure: cookieMap["isSecure"],
|
||||
isHttpOnly: cookieMap["isHttpOnly"],
|
||||
path: cookieMap["path"]));
|
||||
});
|
||||
return cookies;
|
||||
}
|
||||
|
||||
Future<String> _getCookieExpirationDate(int expiresDate) async {
|
||||
var platformUtil = PlatformUtil.instance();
|
||||
var dateTime = DateTime.fromMillisecondsSinceEpoch(expiresDate).toUtc();
|
||||
return !kIsWeb
|
||||
? await platformUtil.formatDate(
|
||||
date: dateTime,
|
||||
format: 'EEE, dd MMM yyyy hh:mm:ss z',
|
||||
locale: 'en_US',
|
||||
timezone: 'GMT')
|
||||
: await platformUtil.getWebCookieExpirationDate(date: dateTime);
|
||||
}
|
||||
|
||||
Future<bool> _shouldUseJavascript() async {
|
||||
final platformUtil = PlatformUtil.instance();
|
||||
final systemVersion = await platformUtil.getSystemVersion();
|
||||
return systemVersion.compareTo("11") == -1;
|
||||
return await channel?.invokeMethod<bool>('removeSessionCookies', args) ??
|
||||
false;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -428,6 +215,6 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
|||
}
|
||||
}
|
||||
|
||||
extension InternalCookieManager on MacOSCookieManager {
|
||||
extension InternalCookieManager on WindowsCookieManager {
|
||||
get handleMethod => _handleMethod;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
||||
|
||||
/// Object specifying creation parameters for creating a [MacOSFindInteractionController].
|
||||
/// Object specifying creation parameters for creating a [WindowsFindInteractionController].
|
||||
///
|
||||
/// When adding additional fields make sure they can be null or have a default
|
||||
/// value to avoid breaking changes. See [PlatformFindInteractionControllerCreationParams] for
|
||||
|
@ -25,10 +25,10 @@ class MacOSFindInteractionControllerCreationParams
|
|||
}
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformFindInteractionController}
|
||||
class MacOSFindInteractionController extends PlatformFindInteractionController
|
||||
class WindowsFindInteractionController extends PlatformFindInteractionController
|
||||
with ChannelController {
|
||||
/// Constructs a [MacOSFindInteractionController].
|
||||
MacOSFindInteractionController(
|
||||
/// Constructs a [WindowsFindInteractionController].
|
||||
WindowsFindInteractionController(
|
||||
PlatformFindInteractionControllerCreationParams params)
|
||||
: super.implementation(
|
||||
params is MacOSFindInteractionControllerCreationParams
|
||||
|
@ -114,7 +114,7 @@ class MacOSFindInteractionController extends PlatformFindInteractionController
|
|||
}
|
||||
}
|
||||
|
||||
extension InternalFindInteractionController on MacOSFindInteractionController {
|
||||
extension InternalFindInteractionController on WindowsFindInteractionController {
|
||||
void init(dynamic id) {
|
||||
channel = MethodChannel(
|
||||
'com.pichillilorenzo/flutter_inappwebview_find_interaction_$id');
|
||||
|
|
|
@ -32,13 +32,13 @@ class WindowsInAppBrowserCreationParams
|
|||
contextMenu: params.contextMenu,
|
||||
pullToRefreshController: params.pullToRefreshController,
|
||||
findInteractionController:
|
||||
params.findInteractionController as MacOSFindInteractionController?,
|
||||
params.findInteractionController as WindowsFindInteractionController?,
|
||||
initialUserScripts: params.initialUserScripts,
|
||||
windowId: params.windowId);
|
||||
}
|
||||
|
||||
@override
|
||||
final MacOSFindInteractionController? findInteractionController;
|
||||
final WindowsFindInteractionController? findInteractionController;
|
||||
}
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformInAppBrowser}
|
||||
|
|
|
@ -238,10 +238,10 @@ class WindowsHeadlessInAppWebViewCreationParams
|
|||
initialUserScripts: params.initialUserScripts,
|
||||
pullToRefreshController: params.pullToRefreshController,
|
||||
findInteractionController: params.findInteractionController
|
||||
as MacOSFindInteractionController?);
|
||||
as WindowsFindInteractionController?);
|
||||
|
||||
@override
|
||||
final MacOSFindInteractionController? findInteractionController;
|
||||
final WindowsFindInteractionController? findInteractionController;
|
||||
}
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformHeadlessInAppWebView}
|
||||
|
|
|
@ -23,6 +23,7 @@ class WindowsInAppWebViewWidgetCreationParams
|
|||
super.keepAlive,
|
||||
super.preventGestureDelay,
|
||||
super.windowId,
|
||||
super.webViewEnvironment,
|
||||
super.onWebViewCreated,
|
||||
super.onLoadStart,
|
||||
super.onLoadStop,
|
||||
|
@ -145,6 +146,7 @@ class WindowsInAppWebViewWidgetCreationParams
|
|||
keepAlive: params.keepAlive,
|
||||
preventGestureDelay: params.preventGestureDelay,
|
||||
windowId: params.windowId,
|
||||
webViewEnvironment: params.webViewEnvironment,
|
||||
onWebViewCreated: params.onWebViewCreated,
|
||||
onLoadStart: params.onLoadStart,
|
||||
onLoadStop: params.onLoadStop,
|
||||
|
@ -248,10 +250,10 @@ class WindowsInAppWebViewWidgetCreationParams
|
|||
initialUserScripts: params.initialUserScripts,
|
||||
pullToRefreshController: params.pullToRefreshController,
|
||||
findInteractionController: params.findInteractionController
|
||||
as MacOSFindInteractionController?);
|
||||
as WindowsFindInteractionController?);
|
||||
|
||||
@override
|
||||
final MacOSFindInteractionController? findInteractionController;
|
||||
final WindowsFindInteractionController? findInteractionController;
|
||||
}
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewWidget}
|
||||
|
@ -267,12 +269,12 @@ class WindowsInAppWebViewWidget extends PlatformInAppWebViewWidget {
|
|||
.fromPlatformInAppWebViewWidgetCreationParams(params),
|
||||
);
|
||||
|
||||
WindowsInAppWebViewWidgetCreationParams get _macosParams =>
|
||||
WindowsInAppWebViewWidgetCreationParams get _windowsParams =>
|
||||
params as WindowsInAppWebViewWidgetCreationParams;
|
||||
|
||||
WindowsInAppWebViewController? _controller;
|
||||
|
||||
WindowsHeadlessInAppWebView? get _macosHeadlessInAppWebView =>
|
||||
WindowsHeadlessInAppWebView? get _windowsHeadlessInAppWebView =>
|
||||
params.headlessWebView as WindowsHeadlessInAppWebView?;
|
||||
|
||||
@override
|
||||
|
@ -316,6 +318,7 @@ class WindowsInAppWebViewWidget extends PlatformInAppWebViewWidget {
|
|||
'initialUserScripts':
|
||||
params.initialUserScripts?.map((e) => e.toMap()).toList() ?? [],
|
||||
'keepAliveId': params.keepAlive?.id,
|
||||
'webViewEnvironmentId': params.webViewEnvironment?.id,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -326,11 +329,11 @@ class WindowsInAppWebViewWidget extends PlatformInAppWebViewWidget {
|
|||
viewId = params.headlessWebView?.id;
|
||||
}
|
||||
viewId = params.keepAlive?.id ?? viewId ?? id;
|
||||
_macosHeadlessInAppWebView?.internalDispose();
|
||||
_windowsHeadlessInAppWebView?.internalDispose();
|
||||
_controller = WindowsInAppWebViewController(
|
||||
PlatformInAppWebViewControllerCreationParams(
|
||||
id: viewId, webviewParams: params));
|
||||
_macosParams.findInteractionController?.init(viewId);
|
||||
_windowsParams.findInteractionController?.init(viewId);
|
||||
debugLog(
|
||||
className: runtimeType.toString(),
|
||||
id: viewId?.toString(),
|
||||
|
|
|
@ -74,7 +74,7 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
};
|
||||
Set<String> _webMessageListenerObjNames = Set();
|
||||
Map<String, ScriptHtmlTagAttributes> _injectedScriptsFromURL = {};
|
||||
Set<MacOSWebMessageChannel> _webMessageChannels = Set();
|
||||
Set<WindowsWebMessageChannel> _webMessageChannels = Set();
|
||||
Set<MacOSWebMessageListener> _webMessageListeners = Set();
|
||||
|
||||
// static map that contains the properties to be saved and restored for keep alive feature
|
||||
|
@ -187,7 +187,7 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
_userScripts = props.userScripts;
|
||||
_webMessageListenerObjNames = props.webMessageListenerObjNames;
|
||||
_webMessageChannels =
|
||||
props.webMessageChannels as Set<MacOSWebMessageChannel>;
|
||||
props.webMessageChannels as Set<WindowsWebMessageChannel>;
|
||||
_webMessageListeners =
|
||||
props.webMessageListeners as Set<MacOSWebMessageListener>;
|
||||
}
|
||||
|
@ -2007,7 +2007,8 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent(
|
||||
'screenshotConfiguration', () => screenshotConfiguration?.toMap());
|
||||
return await channel?.invokeMethod<Uint8List?>('takeScreenshot', args);
|
||||
final base64 = await channel?.invokeMethod<String?>('takeScreenshot', args);
|
||||
return base64 != null ? base64Decode(base64) : null;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -2460,12 +2461,12 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
}
|
||||
|
||||
@override
|
||||
Future<MacOSWebMessageChannel?> createWebMessageChannel() async {
|
||||
Future<WindowsWebMessageChannel?> createWebMessageChannel() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
Map<String, dynamic>? result =
|
||||
(await channel?.invokeMethod('createWebMessageChannel', args))
|
||||
?.cast<String, dynamic>();
|
||||
final webMessageChannel = MacOSWebMessageChannel.static().fromMap(result);
|
||||
final webMessageChannel = WindowsWebMessageChannel.static().fromMap(result);
|
||||
if (webMessageChannel != null) {
|
||||
_webMessageChannels.add(webMessageChannel);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
||||
|
||||
import 'cookie_manager.dart';
|
||||
import 'in_app_browser/in_app_browser.dart';
|
||||
import 'in_app_webview/in_app_webview.dart';
|
||||
import 'in_app_webview/in_app_webview_controller.dart';
|
||||
import 'in_app_webview/headless_in_app_webview.dart';
|
||||
import 'webview_environment/webview_environment.dart';
|
||||
|
||||
/// Implementation of [InAppWebViewPlatform] using the WebKit API.
|
||||
class WindowsInAppWebViewPlatform extends InAppWebViewPlatform {
|
||||
|
@ -12,6 +14,18 @@ class WindowsInAppWebViewPlatform extends InAppWebViewPlatform {
|
|||
InAppWebViewPlatform.instance = WindowsInAppWebViewPlatform();
|
||||
}
|
||||
|
||||
/// Creates a new [WindowsCookieManager].
|
||||
///
|
||||
/// This function should only be called by the app-facing package.
|
||||
/// Look at using [CookieManager] in `flutter_inappwebview` instead.
|
||||
@override
|
||||
WindowsCookieManager createPlatformCookieManager(
|
||||
PlatformCookieManagerCreationParams params,
|
||||
) {
|
||||
return WindowsCookieManager(params);
|
||||
}
|
||||
|
||||
|
||||
/// Creates a new [WindowsInAppWebViewController].
|
||||
///
|
||||
/// This function should only be called by the app-facing package.
|
||||
|
@ -73,4 +87,24 @@ class WindowsInAppWebViewPlatform extends InAppWebViewPlatform {
|
|||
) {
|
||||
return WindowsHeadlessInAppWebView(params);
|
||||
}
|
||||
|
||||
/// Creates a new [WindowsWebViewEnvironment].
|
||||
///
|
||||
/// This function should only be called by the app-facing package.
|
||||
/// Look at using [WebViewEnvironment] in `flutter_inappwebview` instead.
|
||||
@override
|
||||
WindowsWebViewEnvironment createPlatformWebViewEnvironment(
|
||||
PlatformWebViewEnvironmentCreationParams params,
|
||||
) {
|
||||
return WindowsWebViewEnvironment(params);
|
||||
}
|
||||
|
||||
/// Creates a new empty [WindowsWebViewEnvironment] to access static methods.
|
||||
///
|
||||
/// This function should only be called by the app-facing package.
|
||||
/// Look at using [WebViewEnvironment] in `flutter_inappwebview` instead.
|
||||
@override
|
||||
WindowsWebViewEnvironment createPlatformWebViewEnvironmentStatic() {
|
||||
return WindowsWebViewEnvironment.static();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,3 +8,4 @@ export 'http_auth_credentials_database.dart'
|
|||
export 'web_message/main.dart';
|
||||
export 'print_job/main.dart';
|
||||
export 'find_interaction/main.dart';
|
||||
export 'webview_environment/main.dart';
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
|
|||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
||||
import 'web_message_port.dart';
|
||||
|
||||
/// Object specifying creation parameters for creating a [MacOSWebMessageChannel].
|
||||
/// Object specifying creation parameters for creating a [WindowsWebMessageChannel].
|
||||
///
|
||||
/// When adding additional fields make sure they can be null or have a default
|
||||
/// value to avoid breaking changes. See [PlatformWebMessageChannelCreationParams] for
|
||||
|
@ -31,10 +31,10 @@ class MacOSWebMessageChannelCreationParams
|
|||
}
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformWebMessageChannel}
|
||||
class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
||||
class WindowsWebMessageChannel extends PlatformWebMessageChannel
|
||||
with ChannelController {
|
||||
/// Constructs a [MacOSWebMessageChannel].
|
||||
MacOSWebMessageChannel(PlatformWebMessageChannelCreationParams params)
|
||||
/// Constructs a [WindowsWebMessageChannel].
|
||||
WindowsWebMessageChannel(PlatformWebMessageChannelCreationParams params)
|
||||
: super.implementation(
|
||||
params is MacOSWebMessageChannelCreationParams
|
||||
? params
|
||||
|
@ -47,7 +47,7 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
|||
initMethodCallHandler();
|
||||
}
|
||||
|
||||
static final MacOSWebMessageChannel _staticValue = MacOSWebMessageChannel(
|
||||
static final WindowsWebMessageChannel _staticValue = WindowsWebMessageChannel(
|
||||
MacOSWebMessageChannelCreationParams(
|
||||
id: '',
|
||||
port1:
|
||||
|
@ -56,7 +56,7 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
|||
MacOSWebMessagePortCreationParams(index: 1))));
|
||||
|
||||
/// Provide static access.
|
||||
factory MacOSWebMessageChannel.static() {
|
||||
factory WindowsWebMessageChannel.static() {
|
||||
return _staticValue;
|
||||
}
|
||||
|
||||
|
@ -64,11 +64,11 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
|||
|
||||
MacOSWebMessagePort get _macosPort2 => port2 as MacOSWebMessagePort;
|
||||
|
||||
static MacOSWebMessageChannel? _fromMap(Map<String, dynamic>? map) {
|
||||
static WindowsWebMessageChannel? _fromMap(Map<String, dynamic>? map) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
var webMessageChannel = MacOSWebMessageChannel(
|
||||
var webMessageChannel = WindowsWebMessageChannel(
|
||||
MacOSWebMessageChannelCreationParams(
|
||||
id: map["id"],
|
||||
port1: MacOSWebMessagePort(
|
||||
|
@ -100,7 +100,7 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
|||
}
|
||||
|
||||
@override
|
||||
MacOSWebMessageChannel? fromMap(Map<String, dynamic>? map) {
|
||||
WindowsWebMessageChannel? fromMap(Map<String, dynamic>? map) {
|
||||
return _fromMap(map);
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,6 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
|||
}
|
||||
}
|
||||
|
||||
extension InternalWebMessageChannel on MacOSWebMessageChannel {
|
||||
extension InternalWebMessageChannel on WindowsWebMessageChannel {
|
||||
MethodChannel? get internalChannel => channel;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class MacOSWebMessagePortCreationParams
|
|||
///{@macro flutter_inappwebview_platform_interface.PlatformWebMessagePort}
|
||||
class MacOSWebMessagePort extends PlatformWebMessagePort {
|
||||
WebMessageCallback? _onMessage;
|
||||
late MacOSWebMessageChannel _webMessageChannel;
|
||||
late WindowsWebMessageChannel _webMessageChannel;
|
||||
|
||||
/// Constructs a [MacOSWebMessagePort].
|
||||
MacOSWebMessagePort(PlatformWebMessagePortCreationParams params)
|
||||
|
@ -89,7 +89,7 @@ extension InternalWebMessagePort on MacOSWebMessagePort {
|
|||
WebMessageCallback? get onMessage => _onMessage;
|
||||
void set onMessage(WebMessageCallback? value) => _onMessage = value;
|
||||
|
||||
MacOSWebMessageChannel get webMessageChannel => _webMessageChannel;
|
||||
void set webMessageChannel(MacOSWebMessageChannel value) =>
|
||||
WindowsWebMessageChannel get webMessageChannel => _webMessageChannel;
|
||||
void set webMessageChannel(WindowsWebMessageChannel value) =>
|
||||
_webMessageChannel = value;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export 'webview_environment.dart' hide InternalWindowsWebViewEnvironment;
|
|
@ -0,0 +1,102 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
||||
|
||||
/// Object specifying creation parameters for creating a [WindowsWebViewEnvironment].
|
||||
///
|
||||
/// Platform specific implementations can add additional fields by extending
|
||||
/// this class.
|
||||
@immutable
|
||||
class WindowsWebViewEnvironmentCreationParams extends PlatformWebViewEnvironmentCreationParams {
|
||||
/// Creates a new [WindowsInAppWebViewControllerCreationParams] instance.
|
||||
const WindowsWebViewEnvironmentCreationParams({super.settings});
|
||||
|
||||
/// Creates a [WindowsInAppWebViewControllerCreationParams] instance based on [PlatformInAppWebViewControllerCreationParams].
|
||||
factory WindowsWebViewEnvironmentCreationParams.fromPlatformWebViewEnvironmentCreationParams(
|
||||
// Recommended placeholder to prevent being broken by platform interface.
|
||||
// ignore: avoid_unused_constructor_parameters
|
||||
PlatformWebViewEnvironmentCreationParams params) {
|
||||
return WindowsWebViewEnvironmentCreationParams(
|
||||
settings: params.settings
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
///Controls a WebView Environment used by WebView instances.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Windows
|
||||
class WindowsWebViewEnvironment extends PlatformWebViewEnvironment
|
||||
with ChannelController {
|
||||
static final MethodChannel _staticChannel = MethodChannel('com.pichillilorenzo/flutter_webview_environment');
|
||||
|
||||
@override
|
||||
final String id = IdGenerator.generate();
|
||||
|
||||
WindowsWebViewEnvironment(
|
||||
PlatformWebViewEnvironmentCreationParams params)
|
||||
: super.implementation(params is WindowsWebViewEnvironmentCreationParams
|
||||
? params
|
||||
: WindowsWebViewEnvironmentCreationParams
|
||||
.fromPlatformWebViewEnvironmentCreationParams(params));
|
||||
|
||||
static final WindowsWebViewEnvironment _staticValue =
|
||||
WindowsWebViewEnvironment(
|
||||
WindowsWebViewEnvironmentCreationParams());
|
||||
|
||||
factory WindowsWebViewEnvironment.static() {
|
||||
return _staticValue;
|
||||
}
|
||||
|
||||
_debugLog(String method, dynamic args) {
|
||||
debugLog(
|
||||
className: this.runtimeType.toString(),
|
||||
id: id,
|
||||
debugLoggingSettings:
|
||||
PlatformWebViewEnvironment.debugLoggingSettings,
|
||||
method: method,
|
||||
args: args);
|
||||
}
|
||||
|
||||
Future<dynamic> _handleMethod(MethodCall call) async {
|
||||
if (PlatformWebViewEnvironment.debugLoggingSettings.enabled) {
|
||||
_debugLog(call.method, call.arguments);
|
||||
}
|
||||
|
||||
switch (call.method) {
|
||||
default:
|
||||
throw UnimplementedError("Unimplemented ${call.method} method");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<WindowsWebViewEnvironment> create(
|
||||
{WebViewEnvironmentSettings? settings}) async {
|
||||
final env = WindowsWebViewEnvironment(
|
||||
WindowsWebViewEnvironmentCreationParams(settings: settings)
|
||||
);
|
||||
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('id', () => env.id);
|
||||
args.putIfAbsent('settings', () => env.settings?.toMap());
|
||||
await _staticChannel.invokeMethod(
|
||||
'create', args);
|
||||
|
||||
env.channel = MethodChannel('com.pichillilorenzo/flutter_webview_environment_$id');
|
||||
env.handler = env.handleMethod;
|
||||
env.initMethodCallHandler();
|
||||
return env;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
await channel?.invokeMethod('dispose', args);
|
||||
disposeChannel();
|
||||
}
|
||||
}
|
||||
|
||||
extension InternalWindowsWebViewEnvironment on WindowsWebViewEnvironment {
|
||||
get handleMethod => _handleMethod;
|
||||
}
|
|
@ -18,7 +18,8 @@ environment:
|
|||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_inappwebview_platform_interface: ^1.0.10
|
||||
flutter_inappwebview_platform_interface: #^1.0.10
|
||||
path: ../flutter_inappwebview_platform_interface
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
@ -72,6 +72,10 @@ list(APPEND PLUGIN_SOURCES
|
|||
"types/plugin_script.h"
|
||||
"types/size_2d.cpp"
|
||||
"types/size_2d.h"
|
||||
"types/rect.cpp"
|
||||
"types/rect.h"
|
||||
"types/screenshot_configuration.cpp"
|
||||
"types/screenshot_configuration.h"
|
||||
"custom_platform_view/custom_platform_view.cc"
|
||||
"custom_platform_view/custom_platform_view.h"
|
||||
"custom_platform_view/texture_bridge.cc"
|
||||
|
@ -88,6 +92,14 @@ list(APPEND PLUGIN_SOURCES
|
|||
"plugin_scripts_js/plugin_scripts_util.h"
|
||||
"plugin_scripts_js/javascript_bridge_js.cpp"
|
||||
"plugin_scripts_js/javascript_bridge_js.h"
|
||||
"webview_environment/webview_environment_settings.cpp"
|
||||
"webview_environment/webview_environment_settings.h"
|
||||
"webview_environment/webview_environment.cpp"
|
||||
"webview_environment/webview_environment.h"
|
||||
"webview_environment/webview_environment_manager.cpp"
|
||||
"webview_environment/webview_environment_manager.h"
|
||||
"webview_environment/webview_environment_channel_delegate.cpp"
|
||||
"webview_environment/webview_environment_channel_delegate.h"
|
||||
"in_app_webview/user_content_controller.cpp"
|
||||
"in_app_webview/user_content_controller.h"
|
||||
"in_app_webview/in_app_webview_settings.cpp"
|
||||
|
@ -112,6 +124,8 @@ list(APPEND PLUGIN_SOURCES
|
|||
"in_app_browser/in_app_browser.h"
|
||||
"in_app_browser/in_app_browser_channel_delegate.cpp"
|
||||
"in_app_browser/in_app_browser_channel_delegate.h"
|
||||
"cookie_manager.cpp"
|
||||
"cookie_manager.h"
|
||||
)
|
||||
|
||||
# Define the plugin library target. Its name must not be changed (see comment
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <Shlwapi.h>
|
||||
#include <time.h>
|
||||
#include <winrt/base.h>
|
||||
#include <wrl/event.h>
|
||||
|
||||
#include "cookie_manager.h"
|
||||
#include "in_app_webview/in_app_webview.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
CookieManager::CookieManager(const FlutterInappwebviewWindowsPlugin* plugin)
|
||||
: ChannelDelegate(plugin->registrar->messenger(), CookieManager::METHOD_CHANNEL_NAME_PREFIX)
|
||||
{
|
||||
windowClass_.lpszClassName = CookieManager::CLASS_NAME;
|
||||
windowClass_.lpfnWndProc = &DefWindowProc;
|
||||
|
||||
RegisterClass(&windowClass_);
|
||||
|
||||
auto hwnd = CreateWindowEx(0, windowClass_.lpszClassName, L"", 0, 0,
|
||||
0, 0, 0,
|
||||
plugin->registrar->GetView()->GetNativeWindow(),
|
||||
nullptr,
|
||||
windowClass_.hInstance, nullptr);
|
||||
|
||||
CreateInAppWebViewEnvParams webViewEnvParams = {
|
||||
hwnd,
|
||||
false
|
||||
};
|
||||
|
||||
InAppWebView::createInAppWebViewEnv(webViewEnvParams, nullptr,
|
||||
[=](wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)
|
||||
{
|
||||
if (webViewEnv && webViewController) {
|
||||
webViewEnv_ = std::move(webViewEnv);
|
||||
webViewController_ = std::move(webViewController);
|
||||
webViewController_->get_CoreWebView2(&webView_);
|
||||
webViewController_->put_IsVisible(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CookieManager::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
|
||||
{
|
||||
auto& arguments = std::get<flutter::EncodableMap>(*method_call.arguments());
|
||||
auto& methodName = method_call.method_name();
|
||||
|
||||
if (string_equals(methodName, "setCookie")) {
|
||||
if (!webView_) {
|
||||
result->Success(false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto url = get_fl_map_value<std::string>(arguments, "url");
|
||||
auto name = get_fl_map_value<std::string>(arguments, "name");
|
||||
auto value = get_fl_map_value<std::string>(arguments, "value");
|
||||
auto path = get_fl_map_value<std::string>(arguments, "path");
|
||||
auto domain = get_optional_fl_map_value<std::string>(arguments, "domain");
|
||||
auto expiresDate = get_optional_fl_map_value<int64_t>(arguments, "expiresDate");
|
||||
auto maxAge = get_optional_fl_map_value<int64_t>(arguments, "maxAge");
|
||||
auto isSecure = get_optional_fl_map_value<bool>(arguments, "isSecure");
|
||||
auto isHttpOnly = get_optional_fl_map_value<bool>(arguments, "isHttpOnly");
|
||||
auto sameSite = get_optional_fl_map_value<std::string>(arguments, "sameSite");
|
||||
|
||||
nlohmann::json parameters = {
|
||||
{"url", url},
|
||||
{"name", name},
|
||||
{"value", value},
|
||||
{"path", path}
|
||||
};
|
||||
if (domain.has_value()) {
|
||||
parameters["domain"] = domain.value();
|
||||
}
|
||||
if (expiresDate.has_value()) {
|
||||
parameters["expires"] = expiresDate.value() / 1000;
|
||||
}
|
||||
debugLog(maxAge.value());
|
||||
if (maxAge.has_value()) {
|
||||
// time(NULL) represents the current unix timestamp in seconds
|
||||
parameters["expires"] = time(NULL) + maxAge.value();
|
||||
}
|
||||
if (isSecure.has_value()) {
|
||||
parameters["secure"] = isSecure.value();
|
||||
}
|
||||
if (isHttpOnly.has_value()) {
|
||||
parameters["httpOnly"] = isHttpOnly.value();
|
||||
}
|
||||
if (sameSite.has_value()) {
|
||||
parameters["sameSite"] = sameSite.value();
|
||||
}
|
||||
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
auto hr = webView_->CallDevToolsProtocolMethod(L"Network.setCookie", utf8_to_wide(parameters.dump()).c_str(), Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
|
||||
[this, result_](HRESULT errorCode, LPCWSTR returnObjectAsJson)
|
||||
{
|
||||
result_->Success(succeededOrLog(errorCode));
|
||||
return S_OK;
|
||||
}
|
||||
).Get());
|
||||
|
||||
if (failedAndLog(hr)) {
|
||||
result_->Success(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
result->NotImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
CookieManager::~CookieManager()
|
||||
{
|
||||
debugLog("dealloc CookieManager");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_COOKIE_MANAGER_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_COOKIE_MANAGER_H_
|
||||
|
||||
#include <flutter/method_channel.h>
|
||||
#include <flutter/standard_message_codec.h>
|
||||
#include <WebView2.h>
|
||||
#include <wil/com.h>
|
||||
|
||||
#include "flutter_inappwebview_windows_plugin.h"
|
||||
#include "types/channel_delegate.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class CookieManager : public ChannelDelegate
|
||||
{
|
||||
public:
|
||||
static inline const wchar_t* CLASS_NAME = L"CookieManager";
|
||||
static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_cookiemanager";
|
||||
|
||||
const FlutterInappwebviewWindowsPlugin* plugin;
|
||||
|
||||
CookieManager(const FlutterInappwebviewWindowsPlugin* plugin);
|
||||
~CookieManager();
|
||||
|
||||
void HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
private:
|
||||
wil::com_ptr<ICoreWebView2Environment> webViewEnv_;
|
||||
wil::com_ptr<ICoreWebView2Controller> webViewController_;
|
||||
wil::com_ptr<ICoreWebView2> webView_;
|
||||
WNDCLASS windowClass_ = {};
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_COOKIE_MANAGER_H_
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
#include <flutter/plugin_registrar_windows.h>
|
||||
|
||||
#include "cookie_manager.h"
|
||||
#include "headless_in_app_webview/headless_in_app_webview_manager.h"
|
||||
#include "in_app_browser/in_app_browser_manager.h"
|
||||
#include "in_app_webview/in_app_webview_manager.h"
|
||||
#include "webview_environment/webview_environment_manager.h"
|
||||
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
#pragma comment(lib, "dxgi.lib")
|
||||
|
@ -23,9 +25,11 @@ namespace flutter_inappwebview_plugin
|
|||
FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar)
|
||||
: registrar(registrar)
|
||||
{
|
||||
webViewEnvironmentManager = std::make_unique<WebViewEnvironmentManager>(this);
|
||||
inAppWebViewManager = std::make_unique<InAppWebViewManager>(this);
|
||||
inAppBrowserManager = std::make_unique<InAppBrowserManager>(this);
|
||||
headlessInAppWebViewManager = std::make_unique<HeadlessInAppWebViewManager>(this);
|
||||
cookieManager = std::make_unique<CookieManager>(this);
|
||||
}
|
||||
|
||||
FlutterInappwebviewWindowsPlugin::~FlutterInappwebviewWindowsPlugin()
|
||||
|
|
|
@ -6,16 +6,20 @@
|
|||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class WebViewEnvironmentManager;
|
||||
class InAppWebViewManager;
|
||||
class InAppBrowserManager;
|
||||
class HeadlessInAppWebViewManager;
|
||||
class CookieManager;
|
||||
|
||||
class FlutterInappwebviewWindowsPlugin : public flutter::Plugin {
|
||||
public:
|
||||
flutter::PluginRegistrarWindows* registrar;
|
||||
std::unique_ptr<WebViewEnvironmentManager> webViewEnvironmentManager;
|
||||
std::unique_ptr<InAppWebViewManager> inAppWebViewManager;
|
||||
std::unique_ptr<InAppBrowserManager> inAppBrowserManager;
|
||||
std::unique_ptr<HeadlessInAppWebViewManager> headlessInAppWebViewManager;
|
||||
std::unique_ptr<CookieManager> cookieManager;
|
||||
|
||||
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar);
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace flutter_inappwebview_plugin
|
|||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
webView->webViewController->put_IsVisible(false);
|
||||
}
|
||||
|
||||
void HeadlessInAppWebView::setSize(const std::shared_ptr<Size2D> size) const
|
||||
|
@ -48,12 +47,13 @@ namespace flutter_inappwebview_plugin
|
|||
HeadlessInAppWebView::~HeadlessInAppWebView()
|
||||
{
|
||||
debugLog("dealloc HeadlessInAppWebView");
|
||||
HWND parentWindow = nullptr;
|
||||
if (webView && webView->webViewController) {
|
||||
HWND parentWindow;
|
||||
if (succeededOrLog(webView->webViewController->get_ParentWindow(&parentWindow))) {
|
||||
DestroyWindow(parentWindow);
|
||||
}
|
||||
webView->webViewController->get_ParentWindow(&parentWindow);
|
||||
}
|
||||
webView = nullptr;
|
||||
if (parentWindow) {
|
||||
DestroyWindow(parentWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,8 +10,10 @@
|
|||
#include "../types/user_script.h"
|
||||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/map.h"
|
||||
#include "../utils/string.h"
|
||||
#include "../utils/vector.h"
|
||||
#include "../webview_environment/webview_environment_manager.h"
|
||||
#include "headless_in_app_webview_manager.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
|
@ -54,6 +56,7 @@ namespace flutter_inappwebview_plugin
|
|||
auto initialFile = get_optional_fl_map_value<std::string>(params, "initialFile");
|
||||
auto initialDataMap = get_optional_fl_map_value<flutter::EncodableMap>(params, "initialData");
|
||||
auto initialUserScriptList = get_optional_fl_map_value<flutter::EncodableList>(params, "initialUserScripts");
|
||||
auto webViewEnvironmentId = get_optional_fl_map_value<std::string>(*arguments, "webViewEnvironmentId");
|
||||
|
||||
RECT bounds;
|
||||
GetClientRect(plugin->registrar->GetView()->GetNativeWindow(), &bounds);
|
||||
|
@ -67,7 +70,15 @@ namespace flutter_inappwebview_plugin
|
|||
nullptr,
|
||||
windowClass_.hInstance, nullptr);
|
||||
|
||||
InAppWebView::createInAppWebViewEnv(hwnd, false,
|
||||
CreateInAppWebViewEnvParams webViewEnvParams = {
|
||||
hwnd,
|
||||
false
|
||||
};
|
||||
|
||||
auto webViewEnvironment = webViewEnvironmentId.has_value() && map_contains(plugin->webViewEnvironmentManager->webViewEnvironments, webViewEnvironmentId.value())
|
||||
? plugin->webViewEnvironmentManager->webViewEnvironments.at(webViewEnvironmentId.value()).get() : nullptr;
|
||||
|
||||
InAppWebView::createInAppWebViewEnv(webViewEnvParams, webViewEnvironment,
|
||||
[=](wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "../webview_environment/webview_environment_manager.h"
|
||||
#include "in_app_browser.h"
|
||||
#include "in_app_browser_manager.h"
|
||||
|
||||
|
@ -41,13 +42,22 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
ShowWindow(m_hWnd, settings->hidden ? SW_HIDE : SW_SHOW);
|
||||
|
||||
CreateInAppWebViewEnvParams webViewEnvParams = {
|
||||
m_hWnd,
|
||||
false
|
||||
};
|
||||
|
||||
|
||||
InAppWebViewCreationParams webViewParams = {
|
||||
id,
|
||||
params.initialWebViewSettings,
|
||||
params.initialUserScripts
|
||||
};
|
||||
|
||||
InAppWebView::createInAppWebViewEnv(m_hWnd, false,
|
||||
auto webViewEnvironment = params.webViewEnvironmentId.has_value() && map_contains(plugin->webViewEnvironmentManager->webViewEnvironments, params.webViewEnvironmentId.value())
|
||||
? plugin->webViewEnvironmentManager->webViewEnvironments.at(params.webViewEnvironmentId.value()).get() : nullptr;
|
||||
|
||||
InAppWebView::createInAppWebViewEnv(webViewEnvParams, webViewEnvironment,
|
||||
[this, params, webViewParams](wil::com_ptr<ICoreWebView2Environment> webViewEnv, wil::com_ptr<ICoreWebView2Controller> webViewController, wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController) -> void
|
||||
{
|
||||
if (webViewEnv && webViewController) {
|
||||
|
@ -83,13 +93,11 @@ namespace flutter_inappwebview_plugin
|
|||
void InAppBrowser::show() const
|
||||
{
|
||||
ShowWindow(m_hWnd, SW_SHOW);
|
||||
webView->webViewController->put_IsVisible(true);
|
||||
}
|
||||
|
||||
void InAppBrowser::hide() const
|
||||
{
|
||||
ShowWindow(m_hWnd, SW_HIDE);
|
||||
webView->webViewController->put_IsVisible(false);
|
||||
}
|
||||
|
||||
bool InAppBrowser::isHidden() const
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace flutter_inappwebview_plugin
|
|||
const std::shared_ptr<InAppBrowserSettings> initialSettings;
|
||||
const std::shared_ptr<InAppWebViewSettings> initialWebViewSettings;
|
||||
const std::optional<std::vector<std::shared_ptr<UserScript>>> initialUserScripts;
|
||||
const std::optional<std::string> webViewEnvironmentId;
|
||||
};
|
||||
|
||||
class InAppBrowser {
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace flutter_inappwebview_plugin
|
|||
auto assetFilePath = get_optional_fl_map_value<std::string>(*arguments, "assetFilePath");
|
||||
auto data = get_optional_fl_map_value<std::string>(*arguments, "data");
|
||||
auto initialUserScriptList = get_optional_fl_map_value<flutter::EncodableList>(*arguments, "initialUserScripts");
|
||||
auto webViewEnvironmentId = get_optional_fl_map_value<std::string>(*arguments, "webViewEnvironmentId");
|
||||
|
||||
std::optional<std::shared_ptr<URLRequest>> urlRequest = urlRequestMap.has_value() ? std::make_shared<URLRequest>(urlRequestMap.value()) : std::optional<std::shared_ptr<URLRequest>>{};
|
||||
|
||||
|
@ -70,7 +71,8 @@ namespace flutter_inappwebview_plugin
|
|||
data,
|
||||
std::move(initialSettings),
|
||||
std::move(initialWebViewSettings),
|
||||
initialUserScripts
|
||||
initialUserScripts,
|
||||
webViewEnvironmentId
|
||||
};
|
||||
|
||||
auto inAppBrowser = std::make_unique<InAppBrowser>(plugin, params);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "../utils/string.h"
|
||||
#include "in_app_webview.h"
|
||||
|
||||
#include ".plugin_symlinks/flutter_inappwebview_windows/windows/webview_environment/webview_environment_manager.h"
|
||||
#include "in_app_webview_manager.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
|
@ -39,6 +40,7 @@ namespace flutter_inappwebview_plugin
|
|||
registerSurfaceEventHandlers();
|
||||
}
|
||||
else {
|
||||
this->webViewController->put_IsVisible(true);
|
||||
// Resize WebView to fit the bounds of the parent window
|
||||
RECT bounds;
|
||||
GetClientRect(parentWindow, &bounds);
|
||||
|
@ -56,58 +58,70 @@ namespace flutter_inappwebview_plugin
|
|||
this->inAppBrowser = inAppBrowser;
|
||||
}
|
||||
|
||||
void InAppWebView::createInAppWebViewEnv(const HWND parentWindow, const bool willBeSurface, std::function<void(wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
void InAppWebView::createInAppWebViewEnv(const CreateInAppWebViewEnvParams& params, const WebViewEnvironment* webViewEnvironment, std::function<void(wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)> completionHandler)
|
||||
{
|
||||
failedLog(CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
|
||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[parentWindow, completionHandler, willBeSurface](HRESULT result, wil::com_ptr<ICoreWebView2Environment> env) -> HRESULT
|
||||
{
|
||||
if (failedAndLog(result) || !env) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
return E_FAIL;
|
||||
}
|
||||
auto callback = [params, completionHandler](HRESULT result, wil::com_ptr<ICoreWebView2Environment> env) -> HRESULT
|
||||
{
|
||||
if (failedAndLog(result) || !env) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Environment3> webViewEnv3;
|
||||
if (willBeSurface && succeededOrLog(env->QueryInterface(IID_PPV_ARGS(&webViewEnv3)))) {
|
||||
failedLog(webViewEnv3->CreateCoreWebView2CompositionController(parentWindow, Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(
|
||||
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2CompositionController> compositionController) -> HRESULT
|
||||
{
|
||||
wil::com_ptr<ICoreWebView2Controller3> webViewController = compositionController.try_query<ICoreWebView2Controller3>();
|
||||
wil::com_ptr<ICoreWebView2Environment3> webViewEnv3;
|
||||
if (params.willBeSurface && succeededOrLog(env->QueryInterface(IID_PPV_ARGS(&webViewEnv3)))) {
|
||||
failedLog(webViewEnv3->CreateCoreWebView2CompositionController(params.parentWindow, Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(
|
||||
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2CompositionController> compositionController) -> HRESULT
|
||||
{
|
||||
wil::com_ptr<ICoreWebView2Controller3> webViewController = compositionController.try_query<ICoreWebView2Controller3>();
|
||||
|
||||
if (failedAndLog(result) || !webViewController) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
ICoreWebView2Controller3* webViewController3;
|
||||
if (succeededOrLog(webViewController->QueryInterface(IID_PPV_ARGS(&webViewController3)))) {
|
||||
webViewController3->put_BoundsMode(COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS);
|
||||
webViewController3->put_ShouldDetectMonitorScaleChanges(FALSE);
|
||||
webViewController3->put_RasterizationScale(1.0);
|
||||
}
|
||||
|
||||
completionHandler(std::move(env), std::move(webViewController), std::move(compositionController));
|
||||
return S_OK;
|
||||
if (failedAndLog(result) || !webViewController) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
return E_FAIL;
|
||||
}
|
||||
).Get()));
|
||||
}
|
||||
else {
|
||||
failedLog(env->CreateCoreWebView2Controller(parentWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
|
||||
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2Controller> controller) -> HRESULT
|
||||
{
|
||||
if (failedAndLog(result) || !controller) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
completionHandler(std::move(env), std::move(controller), nullptr);
|
||||
return S_OK;
|
||||
}).Get()));
|
||||
}
|
||||
return S_OK;
|
||||
}).Get()));
|
||||
ICoreWebView2Controller3* webViewController3;
|
||||
if (succeededOrLog(webViewController->QueryInterface(IID_PPV_ARGS(&webViewController3)))) {
|
||||
webViewController3->put_BoundsMode(COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS);
|
||||
webViewController3->put_ShouldDetectMonitorScaleChanges(FALSE);
|
||||
webViewController3->put_RasterizationScale(1.0);
|
||||
}
|
||||
|
||||
completionHandler(std::move(env), std::move(webViewController), std::move(compositionController));
|
||||
return S_OK;
|
||||
}
|
||||
).Get()));
|
||||
}
|
||||
else {
|
||||
failedLog(env->CreateCoreWebView2Controller(params.parentWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
|
||||
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2Controller> controller) -> HRESULT
|
||||
{
|
||||
if (failedAndLog(result) || !controller) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
completionHandler(std::move(env), std::move(controller), nullptr);
|
||||
return S_OK;
|
||||
}).Get()));
|
||||
}
|
||||
return S_OK;
|
||||
};
|
||||
|
||||
HRESULT hr;
|
||||
if (webViewEnvironment && webViewEnvironment->env) {
|
||||
hr = callback(S_OK, webViewEnvironment->env);
|
||||
}
|
||||
else {
|
||||
hr = CreateCoreWebView2EnvironmentWithOptions(
|
||||
nullptr, nullptr, nullptr,
|
||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(callback).Get());
|
||||
}
|
||||
|
||||
if (failedAndLog(hr)) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void InAppWebView::initChannel(const std::optional<std::variant<std::string, int64_t>> viewId, const std::optional<std::string> channelName)
|
||||
|
@ -168,10 +182,11 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
).Get()));
|
||||
|
||||
userContentController->addPluginScript(std::move(createJavaScriptBridgePluginScript()));
|
||||
|
||||
if (params.initialUserScripts.has_value()) {
|
||||
userContentController->addUserOnlyScripts(params.initialUserScripts.value());
|
||||
if (userContentController) {
|
||||
userContentController->addPluginScript(std::move(createJavaScriptBridgePluginScript()));
|
||||
if (params.initialUserScripts.has_value()) {
|
||||
userContentController->addUserOnlyScripts(params.initialUserScripts.value());
|
||||
}
|
||||
}
|
||||
|
||||
registerEventHandlers();
|
||||
|
@ -392,18 +407,6 @@ namespace flutter_inappwebview_plugin
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
wil::unique_cotaskmem_string url;
|
||||
args->get_Source(&url);
|
||||
|
||||
wil::com_ptr<IUri> uri;
|
||||
failedLog(CreateUri(
|
||||
url.get(), // NULL terminated URI
|
||||
Uri_CREATE_ALLOW_RELATIVE, // Flags to control behavior
|
||||
0, // Reserved must be 0
|
||||
&uri));
|
||||
*/
|
||||
|
||||
wil::unique_cotaskmem_string json;
|
||||
if (succeededOrLog(args->get_WebMessageAsJson(&json))) {
|
||||
auto message = nlohmann::json::parse(wide_to_utf8(json.get()));
|
||||
|
@ -650,7 +653,7 @@ namespace flutter_inappwebview_plugin
|
|||
return webView && succeededOrLog(webView->get_CanGoForward(&canGoForward_)) ? canGoForward_ : false;
|
||||
}
|
||||
|
||||
void InAppWebView::goBackOrForward(const int& steps)
|
||||
void InAppWebView::goBackOrForward(const int64_t& steps)
|
||||
{
|
||||
getCopyBackForwardList(
|
||||
[this, steps](std::unique_ptr<WebHistory> webHistory)
|
||||
|
@ -682,7 +685,7 @@ namespace flutter_inappwebview_plugin
|
|||
);
|
||||
}
|
||||
|
||||
void InAppWebView::canGoBackOrForward(const int& steps, std::function<void(bool)> completionHandler) const
|
||||
void InAppWebView::canGoBackOrForward(const int64_t& steps, std::function<void(bool)> completionHandler) const
|
||||
{
|
||||
getCopyBackForwardList(
|
||||
[steps, completionHandler](std::unique_ptr<WebHistory> webHistory)
|
||||
|
@ -920,6 +923,55 @@ namespace flutter_inappwebview_plugin
|
|||
userContentController->removeAllUserOnlyScripts();
|
||||
}
|
||||
|
||||
void InAppWebView::takeScreenshot(const std::optional<std::shared_ptr<ScreenshotConfiguration>> screenshotConfiguration, const std::function<void(const std::optional<std::string>)> completionHandler) const
|
||||
{
|
||||
if (!webView) {
|
||||
if (completionHandler) {
|
||||
completionHandler(std::nullopt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
nlohmann::json parameters = {
|
||||
{"captureBeyondViewport", true}
|
||||
};
|
||||
if (screenshotConfiguration.has_value()) {
|
||||
auto& scp = screenshotConfiguration.value();
|
||||
parameters["format"] = to_lowercase_copy(CompressFormatToString(scp->compressFormat));
|
||||
if (scp->compressFormat == CompressFormat::jpeg) {
|
||||
parameters["quality"] = scp->quality;
|
||||
}
|
||||
if (scp->rect.has_value()) {
|
||||
auto& rect = scp->rect.value();
|
||||
parameters["clip"] = {
|
||||
{"x", rect->x},
|
||||
{"y", rect->y},
|
||||
{"width", rect->width},
|
||||
{"height", rect->height},
|
||||
{"scale", scaleFactor_}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
auto hr = webView->CallDevToolsProtocolMethod(L"Page.captureScreenshot", utf8_to_wide(parameters.dump()).c_str(), Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
|
||||
[this, completionHandler](HRESULT errorCode, LPCWSTR returnObjectAsJson)
|
||||
{
|
||||
std::optional<std::string> result = std::nullopt;
|
||||
if (succeededOrLog(errorCode)) {
|
||||
nlohmann::json json = nlohmann::json::parse(wide_to_utf8(returnObjectAsJson));
|
||||
result = json["data"].get<std::string>();
|
||||
}
|
||||
if (completionHandler) {
|
||||
completionHandler(result);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
).Get());
|
||||
if (failedAndLog(hr) && completionHandler) {
|
||||
completionHandler(std::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
// flutter_view
|
||||
void InAppWebView::setSurfaceSize(size_t width, size_t height, float scale_factor)
|
||||
{
|
||||
|
@ -1187,15 +1239,16 @@ namespace flutter_inappwebview_plugin
|
|||
InAppWebView::~InAppWebView()
|
||||
{
|
||||
debugLog("dealloc InAppWebView");
|
||||
HWND parentWindow = nullptr;
|
||||
if (webViewCompositionController && succeededOrLog(webViewController->get_ParentWindow(&parentWindow))) {
|
||||
// if it's an InAppWebView,
|
||||
// then destroy the Window created with it
|
||||
DestroyWindow(parentWindow);
|
||||
}
|
||||
userContentController = nullptr;
|
||||
if (webView) {
|
||||
failedLog(webView->Stop());
|
||||
}
|
||||
HWND parentWindow = nullptr;
|
||||
if (webViewCompositionController && webViewController && succeededOrLog(webViewController->get_ParentWindow(&parentWindow))) {
|
||||
// if it's an InAppWebView (so webViewCompositionController will be not a nullptr!),
|
||||
// then destroy the Window created with it
|
||||
DestroyWindow(parentWindow);
|
||||
}
|
||||
if (webViewController) {
|
||||
failedLog(webViewController->Close());
|
||||
}
|
||||
|
@ -1203,4 +1256,4 @@ namespace flutter_inappwebview_plugin
|
|||
inAppBrowser = nullptr;
|
||||
plugin = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "../types/navigation_action.h"
|
||||
#include "../types/url_request.h"
|
||||
#include "../types/web_history.h"
|
||||
#include "../webview_environment/webview_environment.h"
|
||||
#include ".plugin_symlinks/flutter_inappwebview_windows/windows/types/screenshot_configuration.h"
|
||||
#include "in_app_webview_settings.h"
|
||||
#include "user_content_controller.h"
|
||||
#include "webview_channel_delegate.h"
|
||||
|
@ -81,6 +83,11 @@ namespace flutter_inappwebview_plugin
|
|||
const std::optional<std::vector<std::shared_ptr<UserScript>>> initialUserScripts;
|
||||
};
|
||||
|
||||
struct CreateInAppWebViewEnvParams {
|
||||
const HWND parentWindow;
|
||||
const bool willBeSurface;
|
||||
};
|
||||
|
||||
class InAppWebView
|
||||
{
|
||||
public:
|
||||
|
@ -107,7 +114,7 @@ namespace flutter_inappwebview_plugin
|
|||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController);
|
||||
~InAppWebView();
|
||||
|
||||
static void createInAppWebViewEnv(const HWND parentWindow, const bool willBeSurface, std::function<void(wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
static void createInAppWebViewEnv(const CreateInAppWebViewEnvParams& params, const WebViewEnvironment* webViewEnvironment, std::function<void(wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)> completionHandler);
|
||||
|
||||
|
@ -147,8 +154,8 @@ namespace flutter_inappwebview_plugin
|
|||
bool canGoBack() const;
|
||||
void goForward();
|
||||
bool canGoForward() const;
|
||||
void goBackOrForward(const int& steps);
|
||||
void canGoBackOrForward(const int& steps, std::function<void(bool)> completionHandler) const;
|
||||
void goBackOrForward(const int64_t& steps);
|
||||
void canGoBackOrForward(const int64_t& steps, std::function<void(bool)> completionHandler) const;
|
||||
bool isLoading() const
|
||||
{
|
||||
return isLoading_;
|
||||
|
@ -161,6 +168,7 @@ namespace flutter_inappwebview_plugin
|
|||
void removeUserScript(const int64_t index, const std::shared_ptr<UserScript> userScript) const;
|
||||
void removeUserScriptsByGroupName(const std::string& groupName) const;
|
||||
void removeAllUserScripts() const;
|
||||
void takeScreenshot(const std::optional<std::shared_ptr<ScreenshotConfiguration>> screenshotConfiguration, const std::function<void(const std::optional<std::string>)> completionHandler) const;
|
||||
|
||||
std::string pageFrameId() const
|
||||
{
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "../utils/vector.h"
|
||||
#include "in_app_webview_manager.h"
|
||||
|
||||
#include ".plugin_symlinks/flutter_inappwebview_windows/windows/webview_environment/webview_environment_manager.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
InAppWebViewManager::InAppWebViewManager(const FlutterInappwebviewWindowsPlugin* plugin)
|
||||
|
@ -83,6 +85,7 @@ namespace flutter_inappwebview_plugin
|
|||
auto initialFile = get_optional_fl_map_value<std::string>(*arguments, "initialFile");
|
||||
auto initialDataMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "initialData");
|
||||
auto initialUserScriptList = get_optional_fl_map_value<flutter::EncodableList>(*arguments, "initialUserScripts");
|
||||
auto webViewEnvironmentId = get_optional_fl_map_value<std::string>(*arguments, "webViewEnvironmentId");
|
||||
|
||||
RECT bounds;
|
||||
GetClientRect(plugin->registrar->GetView()->GetNativeWindow(), &bounds);
|
||||
|
@ -93,7 +96,15 @@ namespace flutter_inappwebview_plugin
|
|||
nullptr,
|
||||
windowClass_.hInstance, nullptr);
|
||||
|
||||
InAppWebView::createInAppWebViewEnv(hwnd, true,
|
||||
CreateInAppWebViewEnvParams webViewEnvParams = {
|
||||
hwnd,
|
||||
true
|
||||
};
|
||||
|
||||
auto webViewEnvironment = webViewEnvironmentId.has_value() && map_contains(plugin->webViewEnvironmentManager->webViewEnvironments, webViewEnvironmentId.value())
|
||||
? plugin->webViewEnvironmentManager->webViewEnvironments.at(webViewEnvironmentId.value()).get() : nullptr;
|
||||
|
||||
InAppWebView::createInAppWebViewEnv(webViewEnvParams, webViewEnvironment,
|
||||
[=](wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)
|
||||
|
@ -182,4 +193,4 @@ namespace flutter_inappwebview_plugin
|
|||
UnregisterClass(windowClass_.lpszClassName, nullptr);
|
||||
plugin = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,6 +159,16 @@ namespace flutter_inappwebview_plugin
|
|||
webView->removeAllUserScripts();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (string_equals(methodName, "takeScreenshot")) {
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
auto screenshotConfigurationMap = get_optional_fl_map_value<flutter::EncodableMap>(arguments, "screenshotConfiguration");
|
||||
std::optional<std::unique_ptr<ScreenshotConfiguration>> screenshotConfiguration =
|
||||
screenshotConfigurationMap.has_value() ? std::make_unique<ScreenshotConfiguration>(screenshotConfigurationMap.value()) : std::optional<std::unique_ptr<ScreenshotConfiguration>>{};
|
||||
webView->takeScreenshot(std::move(screenshotConfiguration), [result_ = std::move(result_)](const std::optional<std::string> data)
|
||||
{
|
||||
result_->Success(make_fl_value(data));
|
||||
});
|
||||
}
|
||||
// for inAppBrowser
|
||||
else if (webView->inAppBrowser && string_equals(methodName, "show")) {
|
||||
webView->inAppBrowser->show();
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#include "rect.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
Rect::Rect(const double& x, const double& y, const double& width, const double& height)
|
||||
: x(x), y(y), width(width), height(height)
|
||||
{}
|
||||
|
||||
Rect::Rect(const flutter::EncodableMap& map)
|
||||
: x(get_fl_map_value<double>(map, "x")),
|
||||
y(get_fl_map_value<double>(map, "y")),
|
||||
width(get_fl_map_value<double>(map, "width")),
|
||||
height(get_fl_map_value<double>(map, "height"))
|
||||
{}
|
||||
|
||||
flutter::EncodableMap Rect::toEncodableMap() const
|
||||
{
|
||||
return flutter::EncodableMap{
|
||||
{"x", x},
|
||||
{"y", y},
|
||||
{"width", width},
|
||||
{"height", height}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_RECT_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_RECT_H_
|
||||
|
||||
#include <flutter/standard_method_codec.h>
|
||||
#include <optional>
|
||||
|
||||
#include "../utils/flutter.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class Rect
|
||||
{
|
||||
public:
|
||||
const double x;
|
||||
const double y;
|
||||
const double width;
|
||||
const double height;
|
||||
|
||||
Rect(const double& x, const double& y, const double& width, const double& height);
|
||||
Rect(const flutter::EncodableMap& map);
|
||||
~Rect() = default;
|
||||
|
||||
flutter::EncodableMap toEncodableMap() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_RECT_H_
|
|
@ -0,0 +1,48 @@
|
|||
#include "../utils/flutter.h"
|
||||
#include "../utils/map.h"
|
||||
#include "screenshot_configuration.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
CompressFormat CompressFormatFromString(const std::string& compressFormat)
|
||||
{
|
||||
if (string_equals(compressFormat, "PNG")) {
|
||||
return CompressFormat::png;
|
||||
}
|
||||
else if (string_equals(compressFormat, "JPEG")) {
|
||||
return CompressFormat::jpeg;
|
||||
}
|
||||
else if (string_equals(compressFormat, "WEBP")) {
|
||||
return CompressFormat::webp;
|
||||
}
|
||||
return CompressFormat::png;
|
||||
}
|
||||
|
||||
std::string CompressFormatToString(const CompressFormat& compressFormat)
|
||||
{
|
||||
switch (compressFormat) {
|
||||
case CompressFormat::jpeg:
|
||||
return "JPEG";
|
||||
case CompressFormat::webp:
|
||||
return "WEBP";
|
||||
case CompressFormat::png:
|
||||
default:
|
||||
return "PNG";
|
||||
}
|
||||
}
|
||||
|
||||
ScreenshotConfiguration::ScreenshotConfiguration(
|
||||
const CompressFormat& compressFormat,
|
||||
const int64_t& quality,
|
||||
const std::optional<std::shared_ptr<Rect>> rect
|
||||
) : compressFormat(compressFormat), quality(quality), rect(rect)
|
||||
{}
|
||||
|
||||
ScreenshotConfiguration::ScreenshotConfiguration(const flutter::EncodableMap& map)
|
||||
: compressFormat(CompressFormatFromString(get_fl_map_value<std::string>(map, "compressFormat"))),
|
||||
quality(get_fl_map_value<int>(map, "quality")),
|
||||
rect(fl_map_contains_not_null(map, "rect") ? std::make_shared<Rect>(get_fl_map_value<flutter::EncodableMap>(map, "rect")) : std::optional<std::shared_ptr<Rect>>{})
|
||||
{}
|
||||
|
||||
ScreenshotConfiguration::~ScreenshotConfiguration() {}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_SCREENSHOT_CONFIGURATION_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_SCREENSHOT_CONFIGURATION_H_
|
||||
|
||||
#include <flutter/standard_method_codec.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "../types/rect.h"
|
||||
#include "../utils/string.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
enum CompressFormat {
|
||||
png,
|
||||
jpeg,
|
||||
webp
|
||||
};
|
||||
|
||||
CompressFormat CompressFormatFromString(const std::string& compressFormat);
|
||||
std::string CompressFormatToString(const CompressFormat& compressFormat);
|
||||
|
||||
class ScreenshotConfiguration
|
||||
{
|
||||
public:
|
||||
const CompressFormat compressFormat;
|
||||
const int64_t quality;
|
||||
const std::optional<std::shared_ptr<Rect>> rect;
|
||||
|
||||
ScreenshotConfiguration(
|
||||
const CompressFormat& compressFormat,
|
||||
const int64_t& quality,
|
||||
const std::optional<std::shared_ptr<Rect>> rect
|
||||
);
|
||||
ScreenshotConfiguration(const flutter::EncodableMap& map);
|
||||
~ScreenshotConfiguration();
|
||||
};
|
||||
}
|
||||
#endif //FLUTTER_INAPPWEBVIEW_SCREENSHOT_CONFIGURATION_H_
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
WebResourceError::WebResourceError(const std::string& description, const int type)
|
||||
WebResourceError::WebResourceError(const std::string& description, const int64_t type)
|
||||
: description(description), type(type)
|
||||
{}
|
||||
|
||||
|
|
|
@ -33,9 +33,9 @@ namespace flutter_inappwebview_plugin
|
|||
{
|
||||
public:
|
||||
const std::string description;
|
||||
const int type;
|
||||
const int64_t type;
|
||||
|
||||
WebResourceError(const std::string& description, const int type);
|
||||
WebResourceError(const std::string& description, const int64_t type);
|
||||
WebResourceError(const flutter::EncodableMap& map);
|
||||
~WebResourceError() = default;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
WebResourceResponse::WebResourceResponse(const std::optional<int>& statusCode)
|
||||
WebResourceResponse::WebResourceResponse(const std::optional<int64_t>& statusCode)
|
||||
: statusCode(statusCode)
|
||||
{}
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ namespace flutter_inappwebview_plugin
|
|||
class WebResourceResponse
|
||||
{
|
||||
public:
|
||||
const std::optional<int> statusCode;
|
||||
const std::optional<int64_t> statusCode;
|
||||
|
||||
WebResourceResponse(const std::optional<int>& statusCode);
|
||||
WebResourceResponse(const std::optional<int64_t>& statusCode);
|
||||
WebResourceResponse(const flutter::EncodableMap& map);
|
||||
~WebResourceResponse() = default;
|
||||
|
||||
|
|
|
@ -80,23 +80,65 @@ namespace flutter_inappwebview_plugin
|
|||
return encodableMap;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline bool fl_map_contains(const flutter::EncodableMap& map, const char* key)
|
||||
{
|
||||
return map_contains(map, make_fl_value(key));
|
||||
}
|
||||
|
||||
static inline bool fl_map_contains_not_null(const flutter::EncodableMap& map, const char* key)
|
||||
{
|
||||
return fl_map_contains(map, key) && !map.at(make_fl_value(key)).IsNull();
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<(!std::is_same<T, int32_t>::value && !std::is_same<T, int64_t>::value), bool>::type* = nullptr>
|
||||
static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* key)
|
||||
{
|
||||
return std::get<T>(map.at(make_fl_value(key)));
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<((!is_mappish<T>::value && !is_vector<T>::value) ||
|
||||
template<typename T, typename std::enable_if<std::is_same<T, int32_t>::value, bool>::type* = nullptr>
|
||||
static inline int64_t get_fl_map_value(const flutter::EncodableMap& map, const char* key)
|
||||
{
|
||||
return map.at(make_fl_value(key)).LongValue();
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_same<T, int64_t>::value, bool>::type* = nullptr>
|
||||
static inline int64_t get_fl_map_value(const flutter::EncodableMap& map, const char* key)
|
||||
{
|
||||
return map.at(make_fl_value(key)).LongValue();
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<((!is_mappish<T>::value && !is_vector<T>::value && !std::is_same<T, int32_t>::value && !std::is_same<T, int64_t>::value) ||
|
||||
std::is_same<T, flutter::EncodableMap>::value || std::is_same<T, flutter::EncodableList>::value), int>::type* = nullptr>
|
||||
static inline std::optional<T> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* key)
|
||||
{
|
||||
auto fl_key = make_fl_value(key);
|
||||
if (map_contains<flutter::EncodableValue, flutter::EncodableValue>(map, fl_key)) {
|
||||
if (fl_map_contains_not_null(map, key)) {
|
||||
auto fl_key = make_fl_value(key);
|
||||
return make_pointer_optional<T>(std::get_if<T>(&map.at(fl_key)));
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_same<T, int32_t>::value, bool>::type* = nullptr>
|
||||
static inline std::optional<int64_t> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* key)
|
||||
{
|
||||
if (fl_map_contains_not_null(map, key)) {
|
||||
auto fl_key = make_fl_value(key);
|
||||
return std::make_optional<int64_t>(map.at(fl_key).LongValue());
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_same<T, int64_t>::value, bool>::type* = nullptr>
|
||||
static inline std::optional<int64_t> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* key)
|
||||
{
|
||||
if (fl_map_contains_not_null(map, key)) {
|
||||
auto fl_key = make_fl_value(key);
|
||||
return std::make_optional<int64_t>(map.at(fl_key).LongValue());
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* key, const T& defaultValue)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_STRING_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_STRING_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
@ -142,6 +143,39 @@ namespace flutter_inappwebview_plugin
|
|||
res.push_back(s.substr(pos_start));
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void to_lowercase(const std::basic_string<T>& s)
|
||||
{
|
||||
std::transform(s.begin(), s.end(), s.begin(),
|
||||
[](const T v) { return static_cast<T>(std::tolower(v)); });
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::basic_string<T> to_lowercase_copy(const std::basic_string<T>& s)
|
||||
{
|
||||
std::basic_string<T> s2 = s;
|
||||
std::transform(s2.begin(), s2.end(), s2.begin(),
|
||||
[](const T v) { return static_cast<T>(std::tolower(v)); });
|
||||
return s2;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void to_uppercase(const std::basic_string<T>& s)
|
||||
{
|
||||
std::transform(s.begin(), s.end(), s.begin(),
|
||||
[](const T v) { return static_cast<T>(std::toupper(v)); });
|
||||
return s2;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::basic_string<T> to_uppercase_copy(const std::basic_string<T>& s)
|
||||
{
|
||||
std::basic_string<T> s2 = s;
|
||||
std::transform(s2.begin(), s2.end(), s2.begin(),
|
||||
[](const T v) { return static_cast<T>(std::toupper(v)); });
|
||||
return s2;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_STRING_H_
|
|
@ -0,0 +1,59 @@
|
|||
#include <WebView2EnvironmentOptions.h>
|
||||
#include <wil/wrl.h>
|
||||
|
||||
#include "../utils/log.h"
|
||||
#include "webview_environment.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
WebViewEnvironment::WebViewEnvironment(const FlutterInappwebviewWindowsPlugin* plugin, const std::string& id)
|
||||
: plugin(plugin), id(id),
|
||||
channelDelegate(std::make_unique<WebViewEnvironmentChannelDelegate>(this, plugin->registrar->messenger()))
|
||||
{}
|
||||
|
||||
void WebViewEnvironment::create(const std::unique_ptr<WebViewEnvironmentSettings> settings, const std::function<void(HRESULT)> completionHandler)
|
||||
{
|
||||
auto options = Make<CoreWebView2EnvironmentOptions>();
|
||||
if (settings) {
|
||||
if (settings->additionalBrowserArguments.has_value()) {
|
||||
options->put_AdditionalBrowserArguments(utf8_to_wide(settings->additionalBrowserArguments.value()).c_str());
|
||||
}
|
||||
if (settings->allowSingleSignOnUsingOSPrimaryAccount.has_value()) {
|
||||
options->put_AllowSingleSignOnUsingOSPrimaryAccount(settings->allowSingleSignOnUsingOSPrimaryAccount.value());
|
||||
}
|
||||
if (settings->language.has_value()) {
|
||||
options->put_Language(utf8_to_wide(settings->language.value()).c_str());
|
||||
}
|
||||
if (settings->targetCompatibleBrowserVersion.has_value()) {
|
||||
options->put_TargetCompatibleBrowserVersion(utf8_to_wide(settings->targetCompatibleBrowserVersion.value()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
auto hr = CreateCoreWebView2EnvironmentWithOptions(
|
||||
settings && settings->browserExecutableFolder.has_value() ? utf8_to_wide(settings->browserExecutableFolder.value()).c_str() : nullptr,
|
||||
settings && settings->userDataFolder.has_value() ? utf8_to_wide(settings->userDataFolder.value()).c_str() : nullptr,
|
||||
options.Get(),
|
||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[this, completionHandler](HRESULT result, wil::com_ptr<ICoreWebView2Environment> environment) -> HRESULT
|
||||
{
|
||||
if (succeededOrLog(result)) {
|
||||
env = std::move(environment);
|
||||
}
|
||||
if (completionHandler) {
|
||||
completionHandler(result);
|
||||
}
|
||||
return S_OK;
|
||||
}).Get());
|
||||
|
||||
if (failedAndLog(hr) && completionHandler) {
|
||||
completionHandler(hr);
|
||||
}
|
||||
}
|
||||
|
||||
WebViewEnvironment::~WebViewEnvironment()
|
||||
{
|
||||
debugLog("dealloc WebViewEnvironment");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_H_
|
||||
|
||||
#include <functional>
|
||||
#include <WebView2.h>
|
||||
#include <wil/com.h>
|
||||
|
||||
#include "../flutter_inappwebview_windows_plugin.h"
|
||||
#include "webview_environment_channel_delegate.h"
|
||||
#include "webview_environment_settings.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class WebViewEnvironment
|
||||
{
|
||||
public:
|
||||
static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_webview_environment_";
|
||||
|
||||
const FlutterInappwebviewWindowsPlugin* plugin;
|
||||
std::string id;
|
||||
wil::com_ptr<ICoreWebView2Environment> env;
|
||||
std::unique_ptr<WebViewEnvironmentChannelDelegate> channelDelegate;
|
||||
|
||||
WebViewEnvironment(const FlutterInappwebviewWindowsPlugin* plugin, const std::string& id);
|
||||
~WebViewEnvironment();
|
||||
|
||||
void create(const std::unique_ptr<WebViewEnvironmentSettings> settings, const std::function<void(HRESULT)> completionHandler);
|
||||
};
|
||||
}
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_H_
|
|
@ -0,0 +1,47 @@
|
|||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "../utils/string.h"
|
||||
#include "webview_environment.h"
|
||||
#include "webview_environment_channel_delegate.h"
|
||||
|
||||
#include "webview_environment_manager.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
WebViewEnvironmentChannelDelegate::WebViewEnvironmentChannelDelegate(WebViewEnvironment* webViewEnv, flutter::BinaryMessenger* messenger)
|
||||
: webViewEnvironment(webViewEnv), ChannelDelegate(messenger, WebViewEnvironment::METHOD_CHANNEL_NAME_PREFIX + webViewEnv->id)
|
||||
{}
|
||||
|
||||
void WebViewEnvironmentChannelDelegate::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
|
||||
{
|
||||
if (!webViewEnvironment) {
|
||||
result->Success();
|
||||
return;
|
||||
}
|
||||
|
||||
// auto& arguments = std::get<flutter::EncodableMap>(*method_call.arguments());
|
||||
auto& methodName = method_call.method_name();
|
||||
|
||||
if (string_equals(methodName, "dispose")) {
|
||||
if (webViewEnvironment->plugin && webViewEnvironment->plugin->webViewEnvironmentManager) {
|
||||
std::map<std::string, std::unique_ptr<WebViewEnvironment>>& webViewEnvironments = webViewEnvironment->plugin->webViewEnvironmentManager->webViewEnvironments;
|
||||
auto& id = webViewEnvironment->id;
|
||||
if (map_contains(webViewEnvironments, id)) {
|
||||
webViewEnvironments.erase(id);
|
||||
}
|
||||
}
|
||||
result->Success();
|
||||
}
|
||||
else {
|
||||
result->NotImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
WebViewEnvironmentChannelDelegate::~WebViewEnvironmentChannelDelegate()
|
||||
{
|
||||
debugLog("dealloc WebViewEnvironmentChannelDelegate");
|
||||
webViewEnvironment = nullptr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_CHANNEL_DELEGATE_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_CHANNEL_DELEGATE_H_
|
||||
|
||||
#include "../types/channel_delegate.h"
|
||||
#include <flutter/method_channel.h>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class WebViewEnvironment;
|
||||
|
||||
class WebViewEnvironmentChannelDelegate : public ChannelDelegate
|
||||
{
|
||||
public:
|
||||
WebViewEnvironment* webViewEnvironment;
|
||||
|
||||
WebViewEnvironmentChannelDelegate(WebViewEnvironment* webViewEnv, flutter::BinaryMessenger* messenger);
|
||||
~WebViewEnvironmentChannelDelegate();
|
||||
|
||||
void HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_CHANNEL_DELEGATE_H_
|
|
@ -0,0 +1,63 @@
|
|||
#include <DispatcherQueue.h>
|
||||
#include <flutter/method_channel.h>
|
||||
#include <flutter/standard_method_codec.h>
|
||||
|
||||
#include "../in_app_webview/in_app_webview_settings.h"
|
||||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/string.h"
|
||||
#include "../utils/vector.h"
|
||||
#include "webview_environment_manager.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
WebViewEnvironmentManager::WebViewEnvironmentManager(const FlutterInappwebviewWindowsPlugin* plugin)
|
||||
: plugin(plugin),
|
||||
ChannelDelegate(plugin->registrar->messenger(), WebViewEnvironmentManager::METHOD_CHANNEL_NAME)
|
||||
{}
|
||||
|
||||
void WebViewEnvironmentManager::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
|
||||
{
|
||||
auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
|
||||
auto& methodName = method_call.method_name();
|
||||
|
||||
if (string_equals(methodName, "create")) {
|
||||
auto id = get_fl_map_value<std::string>(*arguments, "id");
|
||||
auto settingsMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "settings");
|
||||
auto settings = settingsMap.has_value() ? std::make_unique<WebViewEnvironmentSettings>(settingsMap.value()) : nullptr;
|
||||
createWebViewEnvironment(id, std::move(settings), std::move(result));
|
||||
}
|
||||
else {
|
||||
result->NotImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
void WebViewEnvironmentManager::createWebViewEnvironment(const std::string& id, std::unique_ptr<WebViewEnvironmentSettings> settings, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
|
||||
{
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
|
||||
auto webViewEnvironment = std::make_unique<WebViewEnvironment>(plugin, id);
|
||||
webViewEnvironment->create(std::move(settings),
|
||||
[this, id, result_](HRESULT errorCode)
|
||||
{
|
||||
if (succeededOrLog(errorCode)) {
|
||||
result_->Success(true);
|
||||
}
|
||||
else {
|
||||
result_->Error("0", "Cannot create WebViewEnvironment: " + getHRMessage(errorCode));
|
||||
if (map_contains(webViewEnvironments, id)) {
|
||||
webViewEnvironments.erase(id);
|
||||
}
|
||||
}
|
||||
});
|
||||
webViewEnvironments.insert({ id, std::move(webViewEnvironment) });
|
||||
}
|
||||
|
||||
WebViewEnvironmentManager::~WebViewEnvironmentManager()
|
||||
{
|
||||
debugLog("dealloc WebViewEnvironmentManager");
|
||||
webViewEnvironments.clear();
|
||||
plugin = nullptr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_MANAGER_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_MANAGER_H_
|
||||
|
||||
#include <flutter/method_channel.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <winrt/base.h>
|
||||
|
||||
#include "../flutter_inappwebview_windows_plugin.h"
|
||||
#include "../types/channel_delegate.h"
|
||||
#include "webview_environment.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class WebViewEnvironmentManager : public ChannelDelegate
|
||||
{
|
||||
public:
|
||||
static inline const std::string METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_webview_environment";
|
||||
|
||||
const FlutterInappwebviewWindowsPlugin* plugin;
|
||||
std::map<std::string, std::unique_ptr<WebViewEnvironment>> webViewEnvironments;
|
||||
|
||||
WebViewEnvironmentManager(const FlutterInappwebviewWindowsPlugin* plugin);
|
||||
~WebViewEnvironmentManager();
|
||||
|
||||
void HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
|
||||
void createWebViewEnvironment(const std::string& id, std::unique_ptr<WebViewEnvironmentSettings> settings, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
};
|
||||
}
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_MANAGER_H_
|
|
@ -0,0 +1,27 @@
|
|||
#include "../utils/flutter.h"
|
||||
#include "webview_environment_settings.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
WebViewEnvironmentSettings::WebViewEnvironmentSettings(const flutter::EncodableMap& map)
|
||||
: browserExecutableFolder(get_optional_fl_map_value<std::string>(map, "browserExecutableFolder")),
|
||||
userDataFolder(get_optional_fl_map_value<std::string>(map, "userDataFolder")),
|
||||
additionalBrowserArguments(get_optional_fl_map_value<std::string>(map, "additionalBrowserArguments")),
|
||||
allowSingleSignOnUsingOSPrimaryAccount(get_optional_fl_map_value<bool>(map, "allowSingleSignOnUsingOSPrimaryAccount")),
|
||||
language(get_optional_fl_map_value<std::string>(map, "language")),
|
||||
targetCompatibleBrowserVersion(get_optional_fl_map_value<std::string>(map, "targetCompatibleBrowserVersion"))
|
||||
{}
|
||||
|
||||
flutter::EncodableMap WebViewEnvironmentSettings::toEncodableMap() const
|
||||
{
|
||||
return flutter::EncodableMap{
|
||||
{"browserExecutableFolder", make_fl_value(browserExecutableFolder)},
|
||||
{"userDataFolder", make_fl_value(userDataFolder)},
|
||||
{"additionalBrowserArguments", make_fl_value(additionalBrowserArguments)},
|
||||
{"allowSingleSignOnUsingOSPrimaryAccount", make_fl_value(allowSingleSignOnUsingOSPrimaryAccount)},
|
||||
{"language", make_fl_value(language)},
|
||||
{"targetCompatibleBrowserVersion", make_fl_value(targetCompatibleBrowserVersion)}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_CREATION_PARAMS_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_CREATION_PARAMS_H_
|
||||
|
||||
#include <flutter/standard_method_codec.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "../flutter_inappwebview_windows_plugin.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class WebViewEnvironmentSettings
|
||||
{
|
||||
public:
|
||||
const std::optional<std::string> browserExecutableFolder;
|
||||
const std::optional<std::string> userDataFolder;
|
||||
const std::optional<std::string> additionalBrowserArguments;
|
||||
const std::optional<bool> allowSingleSignOnUsingOSPrimaryAccount;
|
||||
const std::optional<std::string> language;
|
||||
const std::optional<std::string> targetCompatibleBrowserVersion;
|
||||
|
||||
WebViewEnvironmentSettings() = default;
|
||||
WebViewEnvironmentSettings(const flutter::EncodableMap& map);
|
||||
~WebViewEnvironmentSettings() = default;
|
||||
|
||||
flutter::EncodableMap toEncodableMap() const;
|
||||
};
|
||||
}
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_ENVIRONMENT_CREATION_PARAMS_H_
|
Loading…
Reference in New Issue