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>[];
|
<DartObject>[];
|
||||||
var hasWebSupport = false;
|
var hasWebSupport = false;
|
||||||
var webSupportValue = null;
|
var webSupportValue = null;
|
||||||
|
var allPlatformsWithoutValue = true;
|
||||||
if (platforms.isNotEmpty) {
|
if (platforms.isNotEmpty) {
|
||||||
for (var platform in platforms) {
|
for (var platform in platforms) {
|
||||||
final targetPlatformName =
|
final targetPlatformName =
|
||||||
|
@ -150,6 +151,9 @@ class ExchangeableEnumGenerator
|
||||||
? platformValueField.toIntValue() ??
|
? platformValueField.toIntValue() ??
|
||||||
"'${platformValueField.toStringValue()}'"
|
"'${platformValueField.toStringValue()}'"
|
||||||
: null;
|
: null;
|
||||||
|
if (allPlatformsWithoutValue && platformValue != null) {
|
||||||
|
allPlatformsWithoutValue = false;
|
||||||
|
}
|
||||||
if (targetPlatformName == "web") {
|
if (targetPlatformName == "web") {
|
||||||
hasWebSupport = true;
|
hasWebSupport = true;
|
||||||
webSupportValue = platformValue;
|
webSupportValue = platformValue;
|
||||||
|
@ -170,8 +174,13 @@ class ExchangeableEnumGenerator
|
||||||
nativeValueBody += "return $defaultValue;";
|
nativeValueBody += "return $defaultValue;";
|
||||||
nativeValueBody += "}";
|
nativeValueBody += "}";
|
||||||
|
|
||||||
|
if (!allPlatformsWithoutValue) {
|
||||||
classBuffer.writeln(
|
classBuffer.writeln(
|
||||||
"static final $fieldName = $extClassName._internalMultiPlatform($constantValue, $nativeValueBody);");
|
"static final $fieldName = $extClassName._internalMultiPlatform($constantValue, $nativeValueBody);");
|
||||||
|
} else {
|
||||||
|
classBuffer.writeln(
|
||||||
|
"static const $fieldName = $extClassName._internal($constantValue, ${defaultValue ?? constantValue});");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
classBuffer.writeln(
|
classBuffer.writeln(
|
||||||
"static const $fieldName = $extClassName._internal($constantValue, $constantValue);");
|
"static const $fieldName = $extClassName._internal($constantValue, $constantValue);");
|
||||||
|
|
|
@ -115,6 +115,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
children: [
|
children: [
|
||||||
InAppWebView(
|
InAppWebView(
|
||||||
key: webViewKey,
|
key: webViewKey,
|
||||||
|
webViewEnvironment: webViewEnvironment,
|
||||||
initialUrlRequest:
|
initialUrlRequest:
|
||||||
URLRequest(url: WebUri('https://flutter.dev')),
|
URLRequest(url: WebUri('https://flutter.dev')),
|
||||||
// initialUrlRequest:
|
// initialUrlRequest:
|
||||||
|
|
|
@ -15,6 +15,7 @@ import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||||
// import 'package:permission_handler/permission_handler.dart';
|
// import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
final localhostServer = InAppLocalhostServer(documentRoot: 'assets');
|
final localhostServer = InAppLocalhostServer(documentRoot: 'assets');
|
||||||
|
WebViewEnvironment? webViewEnvironment;
|
||||||
|
|
||||||
Future main() async {
|
Future main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
@ -22,6 +23,13 @@ Future main() async {
|
||||||
// await Permission.microphone.request();
|
// await Permission.microphone.request();
|
||||||
// await Permission.storage.request();
|
// await Permission.storage.request();
|
||||||
|
|
||||||
|
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.windows) {
|
||||||
|
webViewEnvironment = await WebViewEnvironment.create(settings:
|
||||||
|
WebViewEnvironmentSettings(
|
||||||
|
userDataFolder: 'custom_path'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
|
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
|
||||||
await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
|
await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,10 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import flutter_inappwebview_macos
|
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
|
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,14 +35,14 @@ dependencies:
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
flutter_inappwebview_platform_interface:
|
flutter_inappwebview_platform_interface:
|
||||||
path: ../../flutter_inappwebview_platform_interface
|
path: ../../flutter_inappwebview_platform_interface
|
||||||
flutter_inappwebview_android:
|
#flutter_inappwebview_android:
|
||||||
path: ../../flutter_inappwebview_android
|
# path: ../../flutter_inappwebview_android
|
||||||
flutter_inappwebview_ios:
|
#flutter_inappwebview_ios:
|
||||||
path: ../../flutter_inappwebview_ios
|
# path: ../../flutter_inappwebview_ios
|
||||||
flutter_inappwebview_macos:
|
#flutter_inappwebview_macos:
|
||||||
path: ../../flutter_inappwebview_macos
|
# path: ../../flutter_inappwebview_macos
|
||||||
flutter_inappwebview_web:
|
#flutter_inappwebview_web:
|
||||||
path: ../../flutter_inappwebview_web
|
# path: ../../flutter_inappwebview_web
|
||||||
flutter_inappwebview_windows:
|
flutter_inappwebview_windows:
|
||||||
path: ../../flutter_inappwebview_windows
|
path: ../../flutter_inappwebview_windows
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.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 'headless_in_app_webview.dart';
|
||||||
import 'in_app_webview_controller.dart';
|
import 'in_app_webview_controller.dart';
|
||||||
import '../find_interaction/find_interaction_controller.dart';
|
import '../find_interaction/find_interaction_controller.dart';
|
||||||
|
@ -42,6 +43,7 @@ class InAppWebView extends StatefulWidget {
|
||||||
InAppWebViewKeepAlive? keepAlive,
|
InAppWebViewKeepAlive? keepAlive,
|
||||||
bool? preventGestureDelay,
|
bool? preventGestureDelay,
|
||||||
TextDirection? layoutDirection,
|
TextDirection? layoutDirection,
|
||||||
|
WebViewEnvironment? webViewEnvironment,
|
||||||
@Deprecated('Use onGeolocationPermissionsHidePrompt instead')
|
@Deprecated('Use onGeolocationPermissionsHidePrompt instead')
|
||||||
void Function(InAppWebViewController controller)?
|
void Function(InAppWebViewController controller)?
|
||||||
androidOnGeolocationPermissionsHidePrompt,
|
androidOnGeolocationPermissionsHidePrompt,
|
||||||
|
@ -310,6 +312,7 @@ class InAppWebView extends StatefulWidget {
|
||||||
findInteractionController: findInteractionController?.platform,
|
findInteractionController: findInteractionController?.platform,
|
||||||
contextMenu: contextMenu,
|
contextMenu: contextMenu,
|
||||||
layoutDirection: layoutDirection,
|
layoutDirection: layoutDirection,
|
||||||
|
webViewEnvironment: webViewEnvironment?.platform,
|
||||||
onWebViewCreated: onWebViewCreated != null
|
onWebViewCreated: onWebViewCreated != null
|
||||||
? (controller) => onWebViewCreated.call(controller)
|
? (controller) => onWebViewCreated.call(controller)
|
||||||
: null,
|
: null,
|
||||||
|
|
|
@ -15,3 +15,4 @@ export 'webview_asset_loader.dart';
|
||||||
export 'tracing_controller.dart';
|
export 'tracing_controller.dart';
|
||||||
export 'process_global_config.dart';
|
export 'process_global_config.dart';
|
||||||
export 'in_app_localhost_server.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:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_inappwebview_platform_interface: ^1.0.10
|
flutter_inappwebview_platform_interface: #^1.0.10
|
||||||
flutter_inappwebview_android: ^1.0.12
|
path: ../flutter_inappwebview_platform_interface
|
||||||
flutter_inappwebview_ios: ^1.0.13
|
#flutter_inappwebview_android: ^1.0.12
|
||||||
flutter_inappwebview_macos: ^1.0.11
|
#flutter_inappwebview_ios: ^1.0.13
|
||||||
flutter_inappwebview_web: ^1.0.8
|
#flutter_inappwebview_macos: ^1.0.11
|
||||||
|
#flutter_inappwebview_web: ^1.0.8
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -750,6 +750,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS ([Official API - WKWebView.takeSnapshot](https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshot))
|
///- 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))
|
///- MacOS ([Official API - WKWebView.takeSnapshot](https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshot))
|
||||||
|
///- Windows
|
||||||
///{@endtemplate}
|
///{@endtemplate}
|
||||||
Future<Uint8List?> takeScreenshot(
|
Future<Uint8List?> takeScreenshot(
|
||||||
{ScreenshotConfiguration? screenshotConfiguration}) {
|
{ScreenshotConfiguration? screenshotConfiguration}) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||||
|
|
||||||
import '../inappwebview_platform.dart';
|
import '../inappwebview_platform.dart';
|
||||||
import '../types/disposable.dart';
|
import '../types/disposable.dart';
|
||||||
|
import '../webview_environment/platform_webview_environment.dart';
|
||||||
import 'in_app_webview_keep_alive.dart';
|
import 'in_app_webview_keep_alive.dart';
|
||||||
import 'platform_webview.dart';
|
import 'platform_webview.dart';
|
||||||
import 'platform_headless_in_app_webview.dart';
|
import 'platform_headless_in_app_webview.dart';
|
||||||
|
@ -24,6 +25,7 @@ class PlatformInAppWebViewWidgetCreationParams
|
||||||
this.headlessWebView,
|
this.headlessWebView,
|
||||||
this.keepAlive,
|
this.keepAlive,
|
||||||
this.preventGestureDelay,
|
this.preventGestureDelay,
|
||||||
|
this.webViewEnvironment,
|
||||||
super.controllerFromPlatform,
|
super.controllerFromPlatform,
|
||||||
super.windowId,
|
super.windowId,
|
||||||
super.onWebViewCreated,
|
super.onWebViewCreated,
|
||||||
|
@ -181,6 +183,12 @@ class PlatformInAppWebViewWidgetCreationParams
|
||||||
///**Officially Supported Platforms/Implementations**:
|
///**Officially Supported Platforms/Implementations**:
|
||||||
///- iOS
|
///- iOS
|
||||||
final bool? preventGestureDelay;
|
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.
|
/// 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_asset_loader.dart';
|
||||||
import 'platform_webview_feature.dart';
|
import 'platform_webview_feature.dart';
|
||||||
import 'in_app_localhost_server.dart';
|
import 'in_app_localhost_server.dart';
|
||||||
|
import 'webview_environment/platform_webview_environment.dart';
|
||||||
|
|
||||||
/// Interface for a platform implementation of a WebView.
|
/// Interface for a platform implementation of a WebView.
|
||||||
abstract class InAppWebViewPlatform extends PlatformInterface {
|
abstract class InAppWebViewPlatform extends PlatformInterface {
|
||||||
|
@ -430,4 +431,24 @@ abstract class InAppWebViewPlatform extends PlatformInterface {
|
||||||
throw UnimplementedError(
|
throw UnimplementedError(
|
||||||
'createPlatformChromeSafariBrowserStatic is not implemented on the current platform.');
|
'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 'inappwebview_platform.dart';
|
||||||
export 'types/main.dart';
|
export 'types/main.dart';
|
||||||
|
export 'webview_environment/main.dart';
|
||||||
export 'in_app_webview/main.dart';
|
export 'in_app_webview/main.dart';
|
||||||
export 'in_app_browser/main.dart';
|
export 'in_app_browser/main.dart';
|
||||||
export 'chrome_safari_browser/main.dart';
|
export 'chrome_safari_browser/main.dart';
|
||||||
|
|
|
@ -11,36 +11,48 @@ class CompressFormat_ {
|
||||||
|
|
||||||
///Compress to the `PNG` format.
|
///Compress to the `PNG` format.
|
||||||
///PNG is lossless, so `quality` is ignored.
|
///PNG is lossless, so `quality` is ignored.
|
||||||
|
@EnumSupportedPlatforms(platforms: [
|
||||||
|
EnumAndroidPlatform(),
|
||||||
|
EnumIOSPlatform(),
|
||||||
|
EnumMacOSPlatform(),
|
||||||
|
EnumWindowsPlatform(),
|
||||||
|
])
|
||||||
static const PNG = const CompressFormat_._internal("PNG");
|
static const PNG = const CompressFormat_._internal("PNG");
|
||||||
|
|
||||||
///Compress to the `JPEG` format.
|
///Compress to the `JPEG` format.
|
||||||
///Quality of `0` means compress for the smallest size.
|
///Quality of `0` means compress for the smallest size.
|
||||||
///`100` means compress for max visual quality.
|
///`100` means compress for max visual quality.
|
||||||
|
@EnumSupportedPlatforms(platforms: [
|
||||||
|
EnumAndroidPlatform(),
|
||||||
|
EnumIOSPlatform(),
|
||||||
|
EnumMacOSPlatform(),
|
||||||
|
EnumWindowsPlatform(),
|
||||||
|
])
|
||||||
static const JPEG = const CompressFormat_._internal("JPEG");
|
static const JPEG = const CompressFormat_._internal("JPEG");
|
||||||
|
|
||||||
///Compress to the `WEBP` lossy format.
|
///Compress to the `WEBP` lossy format.
|
||||||
///Quality of `0` means compress for the smallest size.
|
///Quality of `0` means compress for the smallest size.
|
||||||
///`100` means compress for max visual quality.
|
///`100` means compress for max visual quality.
|
||||||
///
|
@EnumSupportedPlatforms(platforms: [
|
||||||
///**NOTE**: available only on Android.
|
EnumAndroidPlatform(),
|
||||||
|
EnumWindowsPlatform(),
|
||||||
|
])
|
||||||
static const WEBP = const CompressFormat_._internal("WEBP");
|
static const WEBP = const CompressFormat_._internal("WEBP");
|
||||||
|
|
||||||
///Compress to the `WEBP` lossy format.
|
///Compress to the `WEBP` lossy format.
|
||||||
///Quality of `0` means compress for the smallest size.
|
///Quality of `0` means compress for the smallest size.
|
||||||
///`100` means compress for max visual quality.
|
///`100` means compress for max visual quality.
|
||||||
///
|
@EnumSupportedPlatforms(platforms: [
|
||||||
///**NOTE**: available only on Android.
|
EnumAndroidPlatform(available: '30'),
|
||||||
///
|
])
|
||||||
///**NOTE for Android**: available on Android 30+.
|
|
||||||
static const WEBP_LOSSY = const CompressFormat_._internal("WEBP_LOSSY");
|
static const WEBP_LOSSY = const CompressFormat_._internal("WEBP_LOSSY");
|
||||||
|
|
||||||
///Compress to the `WEBP` lossless format.
|
///Compress to the `WEBP` lossless format.
|
||||||
///Quality refers to how much effort to put into compression.
|
///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.
|
///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.
|
///`100` means to spend more time compressing, resulting in a smaller file.
|
||||||
///
|
@EnumSupportedPlatforms(platforms: [
|
||||||
///**NOTE**: available only on Android.
|
EnumAndroidPlatform(available: '30'),
|
||||||
///
|
])
|
||||||
///**NOTE for Android**: available on Android 30+.
|
|
||||||
static const WEBP_LOSSLESS = const CompressFormat_._internal("WEBP_LOSSLESS");
|
static const WEBP_LOSSLESS = const CompressFormat_._internal("WEBP_LOSSLESS");
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,17 +19,31 @@ class CompressFormat {
|
||||||
///Compress to the `JPEG` format.
|
///Compress to the `JPEG` format.
|
||||||
///Quality of `0` means compress for the smallest size.
|
///Quality of `0` means compress for the smallest size.
|
||||||
///`100` means compress for max visual quality.
|
///`100` means compress for max visual quality.
|
||||||
|
///
|
||||||
|
///**Officially Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS
|
||||||
|
///- MacOS
|
||||||
|
///- Windows
|
||||||
static const JPEG = CompressFormat._internal('JPEG', 'JPEG');
|
static const JPEG = CompressFormat._internal('JPEG', 'JPEG');
|
||||||
|
|
||||||
///Compress to the `PNG` format.
|
///Compress to the `PNG` format.
|
||||||
///PNG is lossless, so `quality` is ignored.
|
///PNG is lossless, so `quality` is ignored.
|
||||||
|
///
|
||||||
|
///**Officially Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS
|
||||||
|
///- MacOS
|
||||||
|
///- Windows
|
||||||
static const PNG = CompressFormat._internal('PNG', 'PNG');
|
static const PNG = CompressFormat._internal('PNG', 'PNG');
|
||||||
|
|
||||||
///Compress to the `WEBP` lossy format.
|
///Compress to the `WEBP` lossy format.
|
||||||
///Quality of `0` means compress for the smallest size.
|
///Quality of `0` means compress for the smallest size.
|
||||||
///`100` means compress for max visual quality.
|
///`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');
|
static const WEBP = CompressFormat._internal('WEBP', 'WEBP');
|
||||||
|
|
||||||
///Compress to the `WEBP` lossless format.
|
///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.
|
///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.
|
///`100` means to spend more time compressing, resulting in a smaller file.
|
||||||
///
|
///
|
||||||
///**NOTE**: available only on Android.
|
///**Officially Supported Platforms/Implementations**:
|
||||||
///
|
///- Android native WebView 30+
|
||||||
///**NOTE for Android**: available on Android 30+.
|
|
||||||
static const WEBP_LOSSLESS =
|
static const WEBP_LOSSLESS =
|
||||||
CompressFormat._internal('WEBP_LOSSLESS', 'WEBP_LOSSLESS');
|
CompressFormat._internal('WEBP_LOSSLESS', 'WEBP_LOSSLESS');
|
||||||
|
|
||||||
|
@ -47,9 +60,8 @@ class CompressFormat {
|
||||||
///Quality of `0` means compress for the smallest size.
|
///Quality of `0` means compress for the smallest size.
|
||||||
///`100` means compress for max visual quality.
|
///`100` means compress for max visual quality.
|
||||||
///
|
///
|
||||||
///**NOTE**: available only on Android.
|
///**Officially Supported Platforms/Implementations**:
|
||||||
///
|
///- Android native WebView 30+
|
||||||
///**NOTE for Android**: available on Android 30+.
|
|
||||||
static const WEBP_LOSSY =
|
static const WEBP_LOSSY =
|
||||||
CompressFormat._internal('WEBP_LOSSY', '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 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.
|
///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.
|
///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;
|
InAppWebViewRect_? rect;
|
||||||
|
|
||||||
///The width of the captured image, in points.
|
///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 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.
|
///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;
|
double? snapshotWidth;
|
||||||
|
|
||||||
///The compression format of the captured image.
|
///The compression format of the captured image.
|
||||||
///The default value is [CompressFormat.PNG].
|
///The default value is [CompressFormat.PNG].
|
||||||
|
@SupportedPlatforms(platforms: [
|
||||||
|
AndroidPlatform(),
|
||||||
|
IOSPlatform(),
|
||||||
|
MacOSPlatform(),
|
||||||
|
WindowsPlatform()
|
||||||
|
])
|
||||||
CompressFormat_ compressFormat;
|
CompressFormat_ compressFormat;
|
||||||
|
|
||||||
///Hint to the compressor, `0-100`. The value is interpreted differently depending on the [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.
|
///[CompressFormat.PNG] is lossless, so this value is ignored.
|
||||||
|
@SupportedPlatforms(platforms: [
|
||||||
|
AndroidPlatform(),
|
||||||
|
IOSPlatform(),
|
||||||
|
MacOSPlatform(),
|
||||||
|
WindowsPlatform()
|
||||||
|
])
|
||||||
int quality;
|
int quality;
|
||||||
|
|
||||||
///Use [afterScreenUpdates] instead.
|
///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.
|
///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.
|
///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.
|
///If you change the value to `false`, the `WebView` takes the snapshot immediately, and before incorporating any new changes.
|
||||||
///
|
@SupportedPlatforms(platforms: [
|
||||||
///**NOTE**: available only on iOS.
|
IOSPlatform(available: '13.0'),
|
||||||
///
|
MacOSPlatform(available: '10.15'),
|
||||||
///**NOTE for iOS**: Available from iOS 13.0+.
|
])
|
||||||
bool afterScreenUpdates;
|
bool afterScreenUpdates;
|
||||||
|
|
||||||
@ExchangeableObjectConstructor()
|
@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.
|
///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.
|
///If you change the value to `false`, the `WebView` takes the snapshot immediately, and before incorporating any new changes.
|
||||||
///
|
///
|
||||||
///**NOTE**: available only on iOS.
|
///**Officially Supported Platforms/Implementations**:
|
||||||
///
|
///- iOS 13.0+
|
||||||
///**NOTE for iOS**: Available from iOS 13.0+.
|
///- MacOS 10.15+
|
||||||
bool afterScreenUpdates;
|
bool afterScreenUpdates;
|
||||||
|
|
||||||
///The compression format of the captured image.
|
///The compression format of the captured image.
|
||||||
///The default value is [CompressFormat.PNG].
|
///The default value is [CompressFormat.PNG].
|
||||||
|
///
|
||||||
|
///**Officially Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS
|
||||||
|
///- MacOS
|
||||||
|
///- Windows
|
||||||
CompressFormat compressFormat;
|
CompressFormat compressFormat;
|
||||||
|
|
||||||
///Use [afterScreenUpdates] instead.
|
///Use [afterScreenUpdates] instead.
|
||||||
|
@ -27,11 +33,23 @@ class ScreenshotConfiguration {
|
||||||
|
|
||||||
///Hint to the compressor, `0-100`. The value is interpreted differently depending on the [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.
|
///[CompressFormat.PNG] is lossless, so this value is ignored.
|
||||||
|
///
|
||||||
|
///**Officially Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView
|
||||||
|
///- iOS
|
||||||
|
///- MacOS
|
||||||
|
///- Windows
|
||||||
int quality;
|
int quality;
|
||||||
|
|
||||||
///The portion of your web view to capture, specified as a rectangle in the view’s coordinate system.
|
///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.
|
///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.
|
///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;
|
InAppWebViewRect? rect;
|
||||||
|
|
||||||
///The width of the captured image, in points.
|
///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 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.
|
///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;
|
double? snapshotWidth;
|
||||||
ScreenshotConfiguration(
|
ScreenshotConfiguration(
|
||||||
{this.rect,
|
{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
|
name: flutter_inappwebview_platform_interface
|
||||||
description: A common platform interface for the flutter_inappwebview plugin.
|
description: A common platform interface for the flutter_inappwebview plugin.
|
||||||
version: 1.0.10
|
version: 1.0.11
|
||||||
homepage: https://inappwebview.dev/
|
homepage: https://inappwebview.dev/
|
||||||
repository: https://github.com/pichillilorenzo/flutter_inappwebview/tree/master/flutter_inappwebview_platform_interface
|
repository: https://github.com/pichillilorenzo/flutter_inappwebview/tree/master/flutter_inappwebview_platform_interface
|
||||||
issue_tracker: https://github.com/pichillilorenzo/flutter_inappwebview/issues
|
issue_tracker: https://github.com/pichillilorenzo/flutter_inappwebview/issues
|
||||||
|
|
|
@ -86,10 +86,9 @@ packages:
|
||||||
flutter_inappwebview_platform_interface:
|
flutter_inappwebview_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_inappwebview_platform_interface
|
path: "../../flutter_inappwebview_platform_interface"
|
||||||
sha256: "545fd4c25a07d2775f7d5af05a979b2cac4fbf79393b0a7f5d33ba39ba4f6187"
|
relative: true
|
||||||
url: "https://pub.dev"
|
source: path
|
||||||
source: hosted
|
|
||||||
version: "1.0.10"
|
version: "1.0.10"
|
||||||
flutter_inappwebview_windows:
|
flutter_inappwebview_windows:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
|
|
|
@ -5,39 +5,37 @@ import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
||||||
|
|
||||||
import 'in_app_webview/headless_in_app_webview.dart';
|
/// Object specifying creation parameters for creating a [WindowsCookieManager].
|
||||||
import 'platform_util.dart';
|
|
||||||
|
|
||||||
/// Object specifying creation parameters for creating a [MacOSCookieManager].
|
|
||||||
///
|
///
|
||||||
/// When adding additional fields make sure they can be null or have a default
|
/// When adding additional fields make sure they can be null or have a default
|
||||||
/// value to avoid breaking changes. See [PlatformCookieManagerCreationParams] for
|
/// value to avoid breaking changes. See [PlatformCookieManagerCreationParams] for
|
||||||
/// more information.
|
/// more information.
|
||||||
@immutable
|
@immutable
|
||||||
class MacOSCookieManagerCreationParams
|
class WindowsCookieManagerCreationParams
|
||||||
extends PlatformCookieManagerCreationParams {
|
extends PlatformCookieManagerCreationParams {
|
||||||
/// Creates a new [MacOSCookieManagerCreationParams] instance.
|
/// Creates a new [WindowsCookieManagerCreationParams] instance.
|
||||||
const MacOSCookieManagerCreationParams(
|
const WindowsCookieManagerCreationParams(
|
||||||
// This parameter prevents breaking changes later.
|
// This parameter prevents breaking changes later.
|
||||||
// ignore: avoid_unused_constructor_parameters
|
// ignore: avoid_unused_constructor_parameters
|
||||||
PlatformCookieManagerCreationParams params,
|
PlatformCookieManagerCreationParams params,
|
||||||
) : super();
|
) : super();
|
||||||
|
|
||||||
/// Creates a [MacOSCookieManagerCreationParams] instance based on [PlatformCookieManagerCreationParams].
|
/// Creates a [WindowsCookieManagerCreationParams] instance based on [PlatformCookieManagerCreationParams].
|
||||||
factory MacOSCookieManagerCreationParams.fromPlatformCookieManagerCreationParams(
|
factory WindowsCookieManagerCreationParams.fromPlatformCookieManagerCreationParams(
|
||||||
PlatformCookieManagerCreationParams params) {
|
PlatformCookieManagerCreationParams params) {
|
||||||
return MacOSCookieManagerCreationParams(params);
|
return WindowsCookieManagerCreationParams(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///{@macro flutter_inappwebview_platform_interface.PlatformCookieManager}
|
///{@macro flutter_inappwebview_platform_interface.PlatformCookieManager}
|
||||||
class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
class WindowsCookieManager extends PlatformCookieManager
|
||||||
/// Creates a new [MacOSCookieManager].
|
with ChannelController {
|
||||||
MacOSCookieManager(PlatformCookieManagerCreationParams params)
|
/// Creates a new [WindowsCookieManager].
|
||||||
|
WindowsCookieManager(PlatformCookieManagerCreationParams params)
|
||||||
: super.implementation(
|
: super.implementation(
|
||||||
params is MacOSCookieManagerCreationParams
|
params is WindowsCookieManagerCreationParams
|
||||||
? params
|
? params
|
||||||
: MacOSCookieManagerCreationParams
|
: WindowsCookieManagerCreationParams
|
||||||
.fromPlatformCookieManagerCreationParams(params),
|
.fromPlatformCookieManagerCreationParams(params),
|
||||||
) {
|
) {
|
||||||
channel = const MethodChannel(
|
channel = const MethodChannel(
|
||||||
|
@ -46,15 +44,15 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
initMethodCallHandler();
|
initMethodCallHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
static MacOSCookieManager? _instance;
|
static WindowsCookieManager? _instance;
|
||||||
|
|
||||||
///Gets the [MacOSCookieManager] shared instance.
|
///Gets the [WindowsCookieManager] shared instance.
|
||||||
static MacOSCookieManager instance() {
|
static WindowsCookieManager instance() {
|
||||||
return (_instance != null) ? _instance! : _init();
|
return (_instance != null) ? _instance! : _init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static MacOSCookieManager _init() {
|
static WindowsCookieManager _init() {
|
||||||
_instance = MacOSCookieManager(MacOSCookieManagerCreationParams(
|
_instance = WindowsCookieManager(WindowsCookieManagerCreationParams(
|
||||||
const PlatformCookieManagerCreationParams()));
|
const PlatformCookieManagerCreationParams()));
|
||||||
return _instance!;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
@ -76,28 +74,11 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
@Deprecated("Use webViewController instead")
|
@Deprecated("Use webViewController instead")
|
||||||
PlatformInAppWebViewController? iosBelow11WebViewController,
|
PlatformInAppWebViewController? iosBelow11WebViewController,
|
||||||
PlatformInAppWebViewController? webViewController}) async {
|
PlatformInAppWebViewController? webViewController}) async {
|
||||||
webViewController = webViewController ?? iosBelow11WebViewController;
|
|
||||||
|
|
||||||
assert(url.toString().isNotEmpty);
|
assert(url.toString().isNotEmpty);
|
||||||
assert(name.isNotEmpty);
|
assert(name.isNotEmpty);
|
||||||
assert(value.isNotEmpty);
|
assert(value.isNotEmpty);
|
||||||
assert(path.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>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url.toString());
|
args.putIfAbsent('url', () => url.toString());
|
||||||
args.putIfAbsent('name', () => name);
|
args.putIfAbsent('name', () => name);
|
||||||
|
@ -113,57 +94,6 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
return await channel?.invokeMethod<bool>('setCookie', args) ?? false;
|
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
|
@override
|
||||||
Future<List<Cookie>> getCookies(
|
Future<List<Cookie>> getCookies(
|
||||||
{required WebUri url,
|
{required WebUri url,
|
||||||
|
@ -172,13 +102,6 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
PlatformInAppWebViewController? webViewController}) async {
|
PlatformInAppWebViewController? webViewController}) async {
|
||||||
assert(url.toString().isNotEmpty);
|
assert(url.toString().isNotEmpty);
|
||||||
|
|
||||||
webViewController = webViewController ?? iosBelow11WebViewController;
|
|
||||||
|
|
||||||
if (await _shouldUseJavascript()) {
|
|
||||||
return await _getCookiesWithJavaScript(
|
|
||||||
url: url, webViewController: webViewController);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Cookie> cookies = [];
|
List<Cookie> cookies = [];
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -203,64 +126,6 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
return cookies;
|
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
|
@override
|
||||||
Future<Cookie?> getCookie(
|
Future<Cookie?> getCookie(
|
||||||
{required WebUri url,
|
{required WebUri url,
|
||||||
|
@ -271,16 +136,6 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
assert(url.toString().isNotEmpty);
|
assert(url.toString().isNotEmpty);
|
||||||
assert(name.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>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url.toString());
|
args.putIfAbsent('url', () => url.toString());
|
||||||
List<dynamic> cookies =
|
List<dynamic> cookies =
|
||||||
|
@ -316,20 +171,6 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
assert(url.toString().isNotEmpty);
|
assert(url.toString().isNotEmpty);
|
||||||
assert(name.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>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url.toString());
|
args.putIfAbsent('url', () => url.toString());
|
||||||
args.putIfAbsent('name', () => name);
|
args.putIfAbsent('name', () => name);
|
||||||
|
@ -348,24 +189,6 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
PlatformInAppWebViewController? webViewController}) async {
|
PlatformInAppWebViewController? webViewController}) async {
|
||||||
assert(url.toString().isNotEmpty);
|
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>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url.toString());
|
args.putIfAbsent('url', () => url.toString());
|
||||||
args.putIfAbsent('domain', () => domain);
|
args.putIfAbsent('domain', () => domain);
|
||||||
|
@ -380,46 +203,10 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Cookie>> getAllCookies() async {
|
Future<bool> removeSessionCookies() async {
|
||||||
List<Cookie> cookies = [];
|
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
List<dynamic> cookieListMap =
|
return await channel?.invokeMethod<bool>('removeSessionCookies', args) ??
|
||||||
await channel?.invokeMethod<List>('getAllCookies', args) ?? [];
|
false;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -428,6 +215,6 @@ class MacOSCookieManager extends PlatformCookieManager with ChannelController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension InternalCookieManager on MacOSCookieManager {
|
extension InternalCookieManager on WindowsCookieManager {
|
||||||
get handleMethod => _handleMethod;
|
get handleMethod => _handleMethod;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.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
|
/// When adding additional fields make sure they can be null or have a default
|
||||||
/// value to avoid breaking changes. See [PlatformFindInteractionControllerCreationParams] for
|
/// value to avoid breaking changes. See [PlatformFindInteractionControllerCreationParams] for
|
||||||
|
@ -25,10 +25,10 @@ class MacOSFindInteractionControllerCreationParams
|
||||||
}
|
}
|
||||||
|
|
||||||
///{@macro flutter_inappwebview_platform_interface.PlatformFindInteractionController}
|
///{@macro flutter_inappwebview_platform_interface.PlatformFindInteractionController}
|
||||||
class MacOSFindInteractionController extends PlatformFindInteractionController
|
class WindowsFindInteractionController extends PlatformFindInteractionController
|
||||||
with ChannelController {
|
with ChannelController {
|
||||||
/// Constructs a [MacOSFindInteractionController].
|
/// Constructs a [WindowsFindInteractionController].
|
||||||
MacOSFindInteractionController(
|
WindowsFindInteractionController(
|
||||||
PlatformFindInteractionControllerCreationParams params)
|
PlatformFindInteractionControllerCreationParams params)
|
||||||
: super.implementation(
|
: super.implementation(
|
||||||
params is MacOSFindInteractionControllerCreationParams
|
params is MacOSFindInteractionControllerCreationParams
|
||||||
|
@ -114,7 +114,7 @@ class MacOSFindInteractionController extends PlatformFindInteractionController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension InternalFindInteractionController on MacOSFindInteractionController {
|
extension InternalFindInteractionController on WindowsFindInteractionController {
|
||||||
void init(dynamic id) {
|
void init(dynamic id) {
|
||||||
channel = MethodChannel(
|
channel = MethodChannel(
|
||||||
'com.pichillilorenzo/flutter_inappwebview_find_interaction_$id');
|
'com.pichillilorenzo/flutter_inappwebview_find_interaction_$id');
|
||||||
|
|
|
@ -32,13 +32,13 @@ class WindowsInAppBrowserCreationParams
|
||||||
contextMenu: params.contextMenu,
|
contextMenu: params.contextMenu,
|
||||||
pullToRefreshController: params.pullToRefreshController,
|
pullToRefreshController: params.pullToRefreshController,
|
||||||
findInteractionController:
|
findInteractionController:
|
||||||
params.findInteractionController as MacOSFindInteractionController?,
|
params.findInteractionController as WindowsFindInteractionController?,
|
||||||
initialUserScripts: params.initialUserScripts,
|
initialUserScripts: params.initialUserScripts,
|
||||||
windowId: params.windowId);
|
windowId: params.windowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final MacOSFindInteractionController? findInteractionController;
|
final WindowsFindInteractionController? findInteractionController;
|
||||||
}
|
}
|
||||||
|
|
||||||
///{@macro flutter_inappwebview_platform_interface.PlatformInAppBrowser}
|
///{@macro flutter_inappwebview_platform_interface.PlatformInAppBrowser}
|
||||||
|
|
|
@ -238,10 +238,10 @@ class WindowsHeadlessInAppWebViewCreationParams
|
||||||
initialUserScripts: params.initialUserScripts,
|
initialUserScripts: params.initialUserScripts,
|
||||||
pullToRefreshController: params.pullToRefreshController,
|
pullToRefreshController: params.pullToRefreshController,
|
||||||
findInteractionController: params.findInteractionController
|
findInteractionController: params.findInteractionController
|
||||||
as MacOSFindInteractionController?);
|
as WindowsFindInteractionController?);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final MacOSFindInteractionController? findInteractionController;
|
final WindowsFindInteractionController? findInteractionController;
|
||||||
}
|
}
|
||||||
|
|
||||||
///{@macro flutter_inappwebview_platform_interface.PlatformHeadlessInAppWebView}
|
///{@macro flutter_inappwebview_platform_interface.PlatformHeadlessInAppWebView}
|
||||||
|
|
|
@ -23,6 +23,7 @@ class WindowsInAppWebViewWidgetCreationParams
|
||||||
super.keepAlive,
|
super.keepAlive,
|
||||||
super.preventGestureDelay,
|
super.preventGestureDelay,
|
||||||
super.windowId,
|
super.windowId,
|
||||||
|
super.webViewEnvironment,
|
||||||
super.onWebViewCreated,
|
super.onWebViewCreated,
|
||||||
super.onLoadStart,
|
super.onLoadStart,
|
||||||
super.onLoadStop,
|
super.onLoadStop,
|
||||||
|
@ -145,6 +146,7 @@ class WindowsInAppWebViewWidgetCreationParams
|
||||||
keepAlive: params.keepAlive,
|
keepAlive: params.keepAlive,
|
||||||
preventGestureDelay: params.preventGestureDelay,
|
preventGestureDelay: params.preventGestureDelay,
|
||||||
windowId: params.windowId,
|
windowId: params.windowId,
|
||||||
|
webViewEnvironment: params.webViewEnvironment,
|
||||||
onWebViewCreated: params.onWebViewCreated,
|
onWebViewCreated: params.onWebViewCreated,
|
||||||
onLoadStart: params.onLoadStart,
|
onLoadStart: params.onLoadStart,
|
||||||
onLoadStop: params.onLoadStop,
|
onLoadStop: params.onLoadStop,
|
||||||
|
@ -248,10 +250,10 @@ class WindowsInAppWebViewWidgetCreationParams
|
||||||
initialUserScripts: params.initialUserScripts,
|
initialUserScripts: params.initialUserScripts,
|
||||||
pullToRefreshController: params.pullToRefreshController,
|
pullToRefreshController: params.pullToRefreshController,
|
||||||
findInteractionController: params.findInteractionController
|
findInteractionController: params.findInteractionController
|
||||||
as MacOSFindInteractionController?);
|
as WindowsFindInteractionController?);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final MacOSFindInteractionController? findInteractionController;
|
final WindowsFindInteractionController? findInteractionController;
|
||||||
}
|
}
|
||||||
|
|
||||||
///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewWidget}
|
///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewWidget}
|
||||||
|
@ -267,12 +269,12 @@ class WindowsInAppWebViewWidget extends PlatformInAppWebViewWidget {
|
||||||
.fromPlatformInAppWebViewWidgetCreationParams(params),
|
.fromPlatformInAppWebViewWidgetCreationParams(params),
|
||||||
);
|
);
|
||||||
|
|
||||||
WindowsInAppWebViewWidgetCreationParams get _macosParams =>
|
WindowsInAppWebViewWidgetCreationParams get _windowsParams =>
|
||||||
params as WindowsInAppWebViewWidgetCreationParams;
|
params as WindowsInAppWebViewWidgetCreationParams;
|
||||||
|
|
||||||
WindowsInAppWebViewController? _controller;
|
WindowsInAppWebViewController? _controller;
|
||||||
|
|
||||||
WindowsHeadlessInAppWebView? get _macosHeadlessInAppWebView =>
|
WindowsHeadlessInAppWebView? get _windowsHeadlessInAppWebView =>
|
||||||
params.headlessWebView as WindowsHeadlessInAppWebView?;
|
params.headlessWebView as WindowsHeadlessInAppWebView?;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -316,6 +318,7 @@ class WindowsInAppWebViewWidget extends PlatformInAppWebViewWidget {
|
||||||
'initialUserScripts':
|
'initialUserScripts':
|
||||||
params.initialUserScripts?.map((e) => e.toMap()).toList() ?? [],
|
params.initialUserScripts?.map((e) => e.toMap()).toList() ?? [],
|
||||||
'keepAliveId': params.keepAlive?.id,
|
'keepAliveId': params.keepAlive?.id,
|
||||||
|
'webViewEnvironmentId': params.webViewEnvironment?.id,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -326,11 +329,11 @@ class WindowsInAppWebViewWidget extends PlatformInAppWebViewWidget {
|
||||||
viewId = params.headlessWebView?.id;
|
viewId = params.headlessWebView?.id;
|
||||||
}
|
}
|
||||||
viewId = params.keepAlive?.id ?? viewId ?? id;
|
viewId = params.keepAlive?.id ?? viewId ?? id;
|
||||||
_macosHeadlessInAppWebView?.internalDispose();
|
_windowsHeadlessInAppWebView?.internalDispose();
|
||||||
_controller = WindowsInAppWebViewController(
|
_controller = WindowsInAppWebViewController(
|
||||||
PlatformInAppWebViewControllerCreationParams(
|
PlatformInAppWebViewControllerCreationParams(
|
||||||
id: viewId, webviewParams: params));
|
id: viewId, webviewParams: params));
|
||||||
_macosParams.findInteractionController?.init(viewId);
|
_windowsParams.findInteractionController?.init(viewId);
|
||||||
debugLog(
|
debugLog(
|
||||||
className: runtimeType.toString(),
|
className: runtimeType.toString(),
|
||||||
id: viewId?.toString(),
|
id: viewId?.toString(),
|
||||||
|
|
|
@ -74,7 +74,7 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
||||||
};
|
};
|
||||||
Set<String> _webMessageListenerObjNames = Set();
|
Set<String> _webMessageListenerObjNames = Set();
|
||||||
Map<String, ScriptHtmlTagAttributes> _injectedScriptsFromURL = {};
|
Map<String, ScriptHtmlTagAttributes> _injectedScriptsFromURL = {};
|
||||||
Set<MacOSWebMessageChannel> _webMessageChannels = Set();
|
Set<WindowsWebMessageChannel> _webMessageChannels = Set();
|
||||||
Set<MacOSWebMessageListener> _webMessageListeners = Set();
|
Set<MacOSWebMessageListener> _webMessageListeners = Set();
|
||||||
|
|
||||||
// static map that contains the properties to be saved and restored for keep alive feature
|
// 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;
|
_userScripts = props.userScripts;
|
||||||
_webMessageListenerObjNames = props.webMessageListenerObjNames;
|
_webMessageListenerObjNames = props.webMessageListenerObjNames;
|
||||||
_webMessageChannels =
|
_webMessageChannels =
|
||||||
props.webMessageChannels as Set<MacOSWebMessageChannel>;
|
props.webMessageChannels as Set<WindowsWebMessageChannel>;
|
||||||
_webMessageListeners =
|
_webMessageListeners =
|
||||||
props.webMessageListeners as Set<MacOSWebMessageListener>;
|
props.webMessageListeners as Set<MacOSWebMessageListener>;
|
||||||
}
|
}
|
||||||
|
@ -2007,7 +2007,8 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent(
|
args.putIfAbsent(
|
||||||
'screenshotConfiguration', () => screenshotConfiguration?.toMap());
|
'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
|
@override
|
||||||
|
@ -2460,12 +2461,12 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<MacOSWebMessageChannel?> createWebMessageChannel() async {
|
Future<WindowsWebMessageChannel?> createWebMessageChannel() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
Map<String, dynamic>? result =
|
Map<String, dynamic>? result =
|
||||||
(await channel?.invokeMethod('createWebMessageChannel', args))
|
(await channel?.invokeMethod('createWebMessageChannel', args))
|
||||||
?.cast<String, dynamic>();
|
?.cast<String, dynamic>();
|
||||||
final webMessageChannel = MacOSWebMessageChannel.static().fromMap(result);
|
final webMessageChannel = WindowsWebMessageChannel.static().fromMap(result);
|
||||||
if (webMessageChannel != null) {
|
if (webMessageChannel != null) {
|
||||||
_webMessageChannels.add(webMessageChannel);
|
_webMessageChannels.add(webMessageChannel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
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_browser/in_app_browser.dart';
|
||||||
import 'in_app_webview/in_app_webview.dart';
|
import 'in_app_webview/in_app_webview.dart';
|
||||||
import 'in_app_webview/in_app_webview_controller.dart';
|
import 'in_app_webview/in_app_webview_controller.dart';
|
||||||
import 'in_app_webview/headless_in_app_webview.dart';
|
import 'in_app_webview/headless_in_app_webview.dart';
|
||||||
|
import 'webview_environment/webview_environment.dart';
|
||||||
|
|
||||||
/// Implementation of [InAppWebViewPlatform] using the WebKit API.
|
/// Implementation of [InAppWebViewPlatform] using the WebKit API.
|
||||||
class WindowsInAppWebViewPlatform extends InAppWebViewPlatform {
|
class WindowsInAppWebViewPlatform extends InAppWebViewPlatform {
|
||||||
|
@ -12,6 +14,18 @@ class WindowsInAppWebViewPlatform extends InAppWebViewPlatform {
|
||||||
InAppWebViewPlatform.instance = WindowsInAppWebViewPlatform();
|
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].
|
/// Creates a new [WindowsInAppWebViewController].
|
||||||
///
|
///
|
||||||
/// This function should only be called by the app-facing package.
|
/// This function should only be called by the app-facing package.
|
||||||
|
@ -73,4 +87,24 @@ class WindowsInAppWebViewPlatform extends InAppWebViewPlatform {
|
||||||
) {
|
) {
|
||||||
return WindowsHeadlessInAppWebView(params);
|
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 'web_message/main.dart';
|
||||||
export 'print_job/main.dart';
|
export 'print_job/main.dart';
|
||||||
export 'find_interaction/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 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
|
||||||
import 'web_message_port.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
|
/// When adding additional fields make sure they can be null or have a default
|
||||||
/// value to avoid breaking changes. See [PlatformWebMessageChannelCreationParams] for
|
/// value to avoid breaking changes. See [PlatformWebMessageChannelCreationParams] for
|
||||||
|
@ -31,10 +31,10 @@ class MacOSWebMessageChannelCreationParams
|
||||||
}
|
}
|
||||||
|
|
||||||
///{@macro flutter_inappwebview_platform_interface.PlatformWebMessageChannel}
|
///{@macro flutter_inappwebview_platform_interface.PlatformWebMessageChannel}
|
||||||
class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
class WindowsWebMessageChannel extends PlatformWebMessageChannel
|
||||||
with ChannelController {
|
with ChannelController {
|
||||||
/// Constructs a [MacOSWebMessageChannel].
|
/// Constructs a [WindowsWebMessageChannel].
|
||||||
MacOSWebMessageChannel(PlatformWebMessageChannelCreationParams params)
|
WindowsWebMessageChannel(PlatformWebMessageChannelCreationParams params)
|
||||||
: super.implementation(
|
: super.implementation(
|
||||||
params is MacOSWebMessageChannelCreationParams
|
params is MacOSWebMessageChannelCreationParams
|
||||||
? params
|
? params
|
||||||
|
@ -47,7 +47,7 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
||||||
initMethodCallHandler();
|
initMethodCallHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
static final MacOSWebMessageChannel _staticValue = MacOSWebMessageChannel(
|
static final WindowsWebMessageChannel _staticValue = WindowsWebMessageChannel(
|
||||||
MacOSWebMessageChannelCreationParams(
|
MacOSWebMessageChannelCreationParams(
|
||||||
id: '',
|
id: '',
|
||||||
port1:
|
port1:
|
||||||
|
@ -56,7 +56,7 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
||||||
MacOSWebMessagePortCreationParams(index: 1))));
|
MacOSWebMessagePortCreationParams(index: 1))));
|
||||||
|
|
||||||
/// Provide static access.
|
/// Provide static access.
|
||||||
factory MacOSWebMessageChannel.static() {
|
factory WindowsWebMessageChannel.static() {
|
||||||
return _staticValue;
|
return _staticValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,11 +64,11 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
||||||
|
|
||||||
MacOSWebMessagePort get _macosPort2 => port2 as MacOSWebMessagePort;
|
MacOSWebMessagePort get _macosPort2 => port2 as MacOSWebMessagePort;
|
||||||
|
|
||||||
static MacOSWebMessageChannel? _fromMap(Map<String, dynamic>? map) {
|
static WindowsWebMessageChannel? _fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var webMessageChannel = MacOSWebMessageChannel(
|
var webMessageChannel = WindowsWebMessageChannel(
|
||||||
MacOSWebMessageChannelCreationParams(
|
MacOSWebMessageChannelCreationParams(
|
||||||
id: map["id"],
|
id: map["id"],
|
||||||
port1: MacOSWebMessagePort(
|
port1: MacOSWebMessagePort(
|
||||||
|
@ -100,7 +100,7 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MacOSWebMessageChannel? fromMap(Map<String, dynamic>? map) {
|
WindowsWebMessageChannel? fromMap(Map<String, dynamic>? map) {
|
||||||
return _fromMap(map);
|
return _fromMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,6 @@ class MacOSWebMessageChannel extends PlatformWebMessageChannel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension InternalWebMessageChannel on MacOSWebMessageChannel {
|
extension InternalWebMessageChannel on WindowsWebMessageChannel {
|
||||||
MethodChannel? get internalChannel => channel;
|
MethodChannel? get internalChannel => channel;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ class MacOSWebMessagePortCreationParams
|
||||||
///{@macro flutter_inappwebview_platform_interface.PlatformWebMessagePort}
|
///{@macro flutter_inappwebview_platform_interface.PlatformWebMessagePort}
|
||||||
class MacOSWebMessagePort extends PlatformWebMessagePort {
|
class MacOSWebMessagePort extends PlatformWebMessagePort {
|
||||||
WebMessageCallback? _onMessage;
|
WebMessageCallback? _onMessage;
|
||||||
late MacOSWebMessageChannel _webMessageChannel;
|
late WindowsWebMessageChannel _webMessageChannel;
|
||||||
|
|
||||||
/// Constructs a [MacOSWebMessagePort].
|
/// Constructs a [MacOSWebMessagePort].
|
||||||
MacOSWebMessagePort(PlatformWebMessagePortCreationParams params)
|
MacOSWebMessagePort(PlatformWebMessagePortCreationParams params)
|
||||||
|
@ -89,7 +89,7 @@ extension InternalWebMessagePort on MacOSWebMessagePort {
|
||||||
WebMessageCallback? get onMessage => _onMessage;
|
WebMessageCallback? get onMessage => _onMessage;
|
||||||
void set onMessage(WebMessageCallback? value) => _onMessage = value;
|
void set onMessage(WebMessageCallback? value) => _onMessage = value;
|
||||||
|
|
||||||
MacOSWebMessageChannel get webMessageChannel => _webMessageChannel;
|
WindowsWebMessageChannel get webMessageChannel => _webMessageChannel;
|
||||||
void set webMessageChannel(MacOSWebMessageChannel value) =>
|
void set webMessageChannel(WindowsWebMessageChannel value) =>
|
||||||
_webMessageChannel = 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:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_inappwebview_platform_interface: ^1.0.10
|
flutter_inappwebview_platform_interface: #^1.0.10
|
||||||
|
path: ../flutter_inappwebview_platform_interface
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -72,6 +72,10 @@ list(APPEND PLUGIN_SOURCES
|
||||||
"types/plugin_script.h"
|
"types/plugin_script.h"
|
||||||
"types/size_2d.cpp"
|
"types/size_2d.cpp"
|
||||||
"types/size_2d.h"
|
"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.cc"
|
||||||
"custom_platform_view/custom_platform_view.h"
|
"custom_platform_view/custom_platform_view.h"
|
||||||
"custom_platform_view/texture_bridge.cc"
|
"custom_platform_view/texture_bridge.cc"
|
||||||
|
@ -88,6 +92,14 @@ list(APPEND PLUGIN_SOURCES
|
||||||
"plugin_scripts_js/plugin_scripts_util.h"
|
"plugin_scripts_js/plugin_scripts_util.h"
|
||||||
"plugin_scripts_js/javascript_bridge_js.cpp"
|
"plugin_scripts_js/javascript_bridge_js.cpp"
|
||||||
"plugin_scripts_js/javascript_bridge_js.h"
|
"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.cpp"
|
||||||
"in_app_webview/user_content_controller.h"
|
"in_app_webview/user_content_controller.h"
|
||||||
"in_app_webview/in_app_webview_settings.cpp"
|
"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.h"
|
||||||
"in_app_browser/in_app_browser_channel_delegate.cpp"
|
"in_app_browser/in_app_browser_channel_delegate.cpp"
|
||||||
"in_app_browser/in_app_browser_channel_delegate.h"
|
"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
|
# 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 <flutter/plugin_registrar_windows.h>
|
||||||
|
|
||||||
|
#include "cookie_manager.h"
|
||||||
#include "headless_in_app_webview/headless_in_app_webview_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_browser/in_app_browser_manager.h"
|
||||||
#include "in_app_webview/in_app_webview_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, "Shlwapi.lib")
|
||||||
#pragma comment(lib, "dxgi.lib")
|
#pragma comment(lib, "dxgi.lib")
|
||||||
|
@ -23,9 +25,11 @@ namespace flutter_inappwebview_plugin
|
||||||
FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar)
|
FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar)
|
||||||
: registrar(registrar)
|
: registrar(registrar)
|
||||||
{
|
{
|
||||||
|
webViewEnvironmentManager = std::make_unique<WebViewEnvironmentManager>(this);
|
||||||
inAppWebViewManager = std::make_unique<InAppWebViewManager>(this);
|
inAppWebViewManager = std::make_unique<InAppWebViewManager>(this);
|
||||||
inAppBrowserManager = std::make_unique<InAppBrowserManager>(this);
|
inAppBrowserManager = std::make_unique<InAppBrowserManager>(this);
|
||||||
headlessInAppWebViewManager = std::make_unique<HeadlessInAppWebViewManager>(this);
|
headlessInAppWebViewManager = std::make_unique<HeadlessInAppWebViewManager>(this);
|
||||||
|
cookieManager = std::make_unique<CookieManager>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlutterInappwebviewWindowsPlugin::~FlutterInappwebviewWindowsPlugin()
|
FlutterInappwebviewWindowsPlugin::~FlutterInappwebviewWindowsPlugin()
|
||||||
|
|
|
@ -6,16 +6,20 @@
|
||||||
|
|
||||||
namespace flutter_inappwebview_plugin
|
namespace flutter_inappwebview_plugin
|
||||||
{
|
{
|
||||||
|
class WebViewEnvironmentManager;
|
||||||
class InAppWebViewManager;
|
class InAppWebViewManager;
|
||||||
class InAppBrowserManager;
|
class InAppBrowserManager;
|
||||||
class HeadlessInAppWebViewManager;
|
class HeadlessInAppWebViewManager;
|
||||||
|
class CookieManager;
|
||||||
|
|
||||||
class FlutterInappwebviewWindowsPlugin : public flutter::Plugin {
|
class FlutterInappwebviewWindowsPlugin : public flutter::Plugin {
|
||||||
public:
|
public:
|
||||||
flutter::PluginRegistrarWindows* registrar;
|
flutter::PluginRegistrarWindows* registrar;
|
||||||
|
std::unique_ptr<WebViewEnvironmentManager> webViewEnvironmentManager;
|
||||||
std::unique_ptr<InAppWebViewManager> inAppWebViewManager;
|
std::unique_ptr<InAppWebViewManager> inAppWebViewManager;
|
||||||
std::unique_ptr<InAppBrowserManager> inAppBrowserManager;
|
std::unique_ptr<InAppBrowserManager> inAppBrowserManager;
|
||||||
std::unique_ptr<HeadlessInAppWebViewManager> headlessInAppWebViewManager;
|
std::unique_ptr<HeadlessInAppWebViewManager> headlessInAppWebViewManager;
|
||||||
|
std::unique_ptr<CookieManager> cookieManager;
|
||||||
|
|
||||||
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar);
|
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar);
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ namespace flutter_inappwebview_plugin
|
||||||
if (!webView) {
|
if (!webView) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
webView->webViewController->put_IsVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeadlessInAppWebView::setSize(const std::shared_ptr<Size2D> size) const
|
void HeadlessInAppWebView::setSize(const std::shared_ptr<Size2D> size) const
|
||||||
|
@ -48,12 +47,13 @@ namespace flutter_inappwebview_plugin
|
||||||
HeadlessInAppWebView::~HeadlessInAppWebView()
|
HeadlessInAppWebView::~HeadlessInAppWebView()
|
||||||
{
|
{
|
||||||
debugLog("dealloc HeadlessInAppWebView");
|
debugLog("dealloc HeadlessInAppWebView");
|
||||||
|
HWND parentWindow = nullptr;
|
||||||
if (webView && webView->webViewController) {
|
if (webView && webView->webViewController) {
|
||||||
HWND parentWindow;
|
webView->webViewController->get_ParentWindow(&parentWindow);
|
||||||
if (succeededOrLog(webView->webViewController->get_ParentWindow(&parentWindow))) {
|
}
|
||||||
|
webView = nullptr;
|
||||||
|
if (parentWindow) {
|
||||||
DestroyWindow(parentWindow);
|
DestroyWindow(parentWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
webView = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -10,8 +10,10 @@
|
||||||
#include "../types/user_script.h"
|
#include "../types/user_script.h"
|
||||||
#include "../utils/flutter.h"
|
#include "../utils/flutter.h"
|
||||||
#include "../utils/log.h"
|
#include "../utils/log.h"
|
||||||
|
#include "../utils/map.h"
|
||||||
#include "../utils/string.h"
|
#include "../utils/string.h"
|
||||||
#include "../utils/vector.h"
|
#include "../utils/vector.h"
|
||||||
|
#include "../webview_environment/webview_environment_manager.h"
|
||||||
#include "headless_in_app_webview_manager.h"
|
#include "headless_in_app_webview_manager.h"
|
||||||
|
|
||||||
namespace flutter_inappwebview_plugin
|
namespace flutter_inappwebview_plugin
|
||||||
|
@ -54,6 +56,7 @@ namespace flutter_inappwebview_plugin
|
||||||
auto initialFile = get_optional_fl_map_value<std::string>(params, "initialFile");
|
auto initialFile = get_optional_fl_map_value<std::string>(params, "initialFile");
|
||||||
auto initialDataMap = get_optional_fl_map_value<flutter::EncodableMap>(params, "initialData");
|
auto initialDataMap = get_optional_fl_map_value<flutter::EncodableMap>(params, "initialData");
|
||||||
auto initialUserScriptList = get_optional_fl_map_value<flutter::EncodableList>(params, "initialUserScripts");
|
auto initialUserScriptList = get_optional_fl_map_value<flutter::EncodableList>(params, "initialUserScripts");
|
||||||
|
auto webViewEnvironmentId = get_optional_fl_map_value<std::string>(*arguments, "webViewEnvironmentId");
|
||||||
|
|
||||||
RECT bounds;
|
RECT bounds;
|
||||||
GetClientRect(plugin->registrar->GetView()->GetNativeWindow(), &bounds);
|
GetClientRect(plugin->registrar->GetView()->GetNativeWindow(), &bounds);
|
||||||
|
@ -67,7 +70,15 @@ namespace flutter_inappwebview_plugin
|
||||||
nullptr,
|
nullptr,
|
||||||
windowClass_.hInstance, 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<ICoreWebView2Environment> webViewEnv,
|
||||||
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
||||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)
|
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "../utils/log.h"
|
#include "../utils/log.h"
|
||||||
#include "../utils/strconv.h"
|
#include "../utils/strconv.h"
|
||||||
|
#include "../webview_environment/webview_environment_manager.h"
|
||||||
#include "in_app_browser.h"
|
#include "in_app_browser.h"
|
||||||
#include "in_app_browser_manager.h"
|
#include "in_app_browser_manager.h"
|
||||||
|
|
||||||
|
@ -41,13 +42,22 @@ namespace flutter_inappwebview_plugin
|
||||||
|
|
||||||
ShowWindow(m_hWnd, settings->hidden ? SW_HIDE : SW_SHOW);
|
ShowWindow(m_hWnd, settings->hidden ? SW_HIDE : SW_SHOW);
|
||||||
|
|
||||||
|
CreateInAppWebViewEnvParams webViewEnvParams = {
|
||||||
|
m_hWnd,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
InAppWebViewCreationParams webViewParams = {
|
InAppWebViewCreationParams webViewParams = {
|
||||||
id,
|
id,
|
||||||
params.initialWebViewSettings,
|
params.initialWebViewSettings,
|
||||||
params.initialUserScripts
|
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
|
[this, params, webViewParams](wil::com_ptr<ICoreWebView2Environment> webViewEnv, wil::com_ptr<ICoreWebView2Controller> webViewController, wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController) -> void
|
||||||
{
|
{
|
||||||
if (webViewEnv && webViewController) {
|
if (webViewEnv && webViewController) {
|
||||||
|
@ -83,13 +93,11 @@ namespace flutter_inappwebview_plugin
|
||||||
void InAppBrowser::show() const
|
void InAppBrowser::show() const
|
||||||
{
|
{
|
||||||
ShowWindow(m_hWnd, SW_SHOW);
|
ShowWindow(m_hWnd, SW_SHOW);
|
||||||
webView->webViewController->put_IsVisible(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InAppBrowser::hide() const
|
void InAppBrowser::hide() const
|
||||||
{
|
{
|
||||||
ShowWindow(m_hWnd, SW_HIDE);
|
ShowWindow(m_hWnd, SW_HIDE);
|
||||||
webView->webViewController->put_IsVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InAppBrowser::isHidden() const
|
bool InAppBrowser::isHidden() const
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace flutter_inappwebview_plugin
|
||||||
const std::shared_ptr<InAppBrowserSettings> initialSettings;
|
const std::shared_ptr<InAppBrowserSettings> initialSettings;
|
||||||
const std::shared_ptr<InAppWebViewSettings> initialWebViewSettings;
|
const std::shared_ptr<InAppWebViewSettings> initialWebViewSettings;
|
||||||
const std::optional<std::vector<std::shared_ptr<UserScript>>> initialUserScripts;
|
const std::optional<std::vector<std::shared_ptr<UserScript>>> initialUserScripts;
|
||||||
|
const std::optional<std::string> webViewEnvironmentId;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InAppBrowser {
|
class InAppBrowser {
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace flutter_inappwebview_plugin
|
||||||
auto assetFilePath = get_optional_fl_map_value<std::string>(*arguments, "assetFilePath");
|
auto assetFilePath = get_optional_fl_map_value<std::string>(*arguments, "assetFilePath");
|
||||||
auto data = get_optional_fl_map_value<std::string>(*arguments, "data");
|
auto data = get_optional_fl_map_value<std::string>(*arguments, "data");
|
||||||
auto initialUserScriptList = get_optional_fl_map_value<flutter::EncodableList>(*arguments, "initialUserScripts");
|
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>>{};
|
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,
|
data,
|
||||||
std::move(initialSettings),
|
std::move(initialSettings),
|
||||||
std::move(initialWebViewSettings),
|
std::move(initialWebViewSettings),
|
||||||
initialUserScripts
|
initialUserScripts,
|
||||||
|
webViewEnvironmentId
|
||||||
};
|
};
|
||||||
|
|
||||||
auto inAppBrowser = std::make_unique<InAppBrowser>(plugin, params);
|
auto inAppBrowser = std::make_unique<InAppBrowser>(plugin, params);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "../utils/string.h"
|
#include "../utils/string.h"
|
||||||
#include "in_app_webview.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"
|
#include "in_app_webview_manager.h"
|
||||||
|
|
||||||
namespace flutter_inappwebview_plugin
|
namespace flutter_inappwebview_plugin
|
||||||
|
@ -39,6 +40,7 @@ namespace flutter_inappwebview_plugin
|
||||||
registerSurfaceEventHandlers();
|
registerSurfaceEventHandlers();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
this->webViewController->put_IsVisible(true);
|
||||||
// Resize WebView to fit the bounds of the parent window
|
// Resize WebView to fit the bounds of the parent window
|
||||||
RECT bounds;
|
RECT bounds;
|
||||||
GetClientRect(parentWindow, &bounds);
|
GetClientRect(parentWindow, &bounds);
|
||||||
|
@ -56,13 +58,11 @@ namespace flutter_inappwebview_plugin
|
||||||
this->inAppBrowser = inAppBrowser;
|
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<ICoreWebView2Controller> webViewController,
|
||||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)> completionHandler)
|
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)> completionHandler)
|
||||||
{
|
{
|
||||||
failedLog(CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
|
auto callback = [params, completionHandler](HRESULT result, wil::com_ptr<ICoreWebView2Environment> env) -> HRESULT
|
||||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
|
||||||
[parentWindow, completionHandler, willBeSurface](HRESULT result, wil::com_ptr<ICoreWebView2Environment> env) -> HRESULT
|
|
||||||
{
|
{
|
||||||
if (failedAndLog(result) || !env) {
|
if (failedAndLog(result) || !env) {
|
||||||
completionHandler(nullptr, nullptr, nullptr);
|
completionHandler(nullptr, nullptr, nullptr);
|
||||||
|
@ -70,8 +70,8 @@ namespace flutter_inappwebview_plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
wil::com_ptr<ICoreWebView2Environment3> webViewEnv3;
|
wil::com_ptr<ICoreWebView2Environment3> webViewEnv3;
|
||||||
if (willBeSurface && succeededOrLog(env->QueryInterface(IID_PPV_ARGS(&webViewEnv3)))) {
|
if (params.willBeSurface && succeededOrLog(env->QueryInterface(IID_PPV_ARGS(&webViewEnv3)))) {
|
||||||
failedLog(webViewEnv3->CreateCoreWebView2CompositionController(parentWindow, Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(
|
failedLog(webViewEnv3->CreateCoreWebView2CompositionController(params.parentWindow, Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(
|
||||||
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2CompositionController> compositionController) -> HRESULT
|
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2CompositionController> compositionController) -> HRESULT
|
||||||
{
|
{
|
||||||
wil::com_ptr<ICoreWebView2Controller3> webViewController = compositionController.try_query<ICoreWebView2Controller3>();
|
wil::com_ptr<ICoreWebView2Controller3> webViewController = compositionController.try_query<ICoreWebView2Controller3>();
|
||||||
|
@ -94,7 +94,7 @@ namespace flutter_inappwebview_plugin
|
||||||
).Get()));
|
).Get()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
failedLog(env->CreateCoreWebView2Controller(parentWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
|
failedLog(env->CreateCoreWebView2Controller(params.parentWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
|
||||||
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2Controller> controller) -> HRESULT
|
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2Controller> controller) -> HRESULT
|
||||||
{
|
{
|
||||||
if (failedAndLog(result) || !controller) {
|
if (failedAndLog(result) || !controller) {
|
||||||
|
@ -107,7 +107,21 @@ namespace flutter_inappwebview_plugin
|
||||||
}).Get()));
|
}).Get()));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}).Get()));
|
};
|
||||||
|
|
||||||
|
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)
|
void InAppWebView::initChannel(const std::optional<std::variant<std::string, int64_t>> viewId, const std::optional<std::string> channelName)
|
||||||
|
@ -168,11 +182,12 @@ namespace flutter_inappwebview_plugin
|
||||||
}
|
}
|
||||||
).Get()));
|
).Get()));
|
||||||
|
|
||||||
|
if (userContentController) {
|
||||||
userContentController->addPluginScript(std::move(createJavaScriptBridgePluginScript()));
|
userContentController->addPluginScript(std::move(createJavaScriptBridgePluginScript()));
|
||||||
|
|
||||||
if (params.initialUserScripts.has_value()) {
|
if (params.initialUserScripts.has_value()) {
|
||||||
userContentController->addUserOnlyScripts(params.initialUserScripts.value());
|
userContentController->addUserOnlyScripts(params.initialUserScripts.value());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
registerEventHandlers();
|
registerEventHandlers();
|
||||||
}
|
}
|
||||||
|
@ -392,18 +407,6 @@ namespace flutter_inappwebview_plugin
|
||||||
return S_OK;
|
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;
|
wil::unique_cotaskmem_string json;
|
||||||
if (succeededOrLog(args->get_WebMessageAsJson(&json))) {
|
if (succeededOrLog(args->get_WebMessageAsJson(&json))) {
|
||||||
auto message = nlohmann::json::parse(wide_to_utf8(json.get()));
|
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;
|
return webView && succeededOrLog(webView->get_CanGoForward(&canGoForward_)) ? canGoForward_ : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InAppWebView::goBackOrForward(const int& steps)
|
void InAppWebView::goBackOrForward(const int64_t& steps)
|
||||||
{
|
{
|
||||||
getCopyBackForwardList(
|
getCopyBackForwardList(
|
||||||
[this, steps](std::unique_ptr<WebHistory> webHistory)
|
[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(
|
getCopyBackForwardList(
|
||||||
[steps, completionHandler](std::unique_ptr<WebHistory> webHistory)
|
[steps, completionHandler](std::unique_ptr<WebHistory> webHistory)
|
||||||
|
@ -920,6 +923,55 @@ namespace flutter_inappwebview_plugin
|
||||||
userContentController->removeAllUserOnlyScripts();
|
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
|
// flutter_view
|
||||||
void InAppWebView::setSurfaceSize(size_t width, size_t height, float scale_factor)
|
void InAppWebView::setSurfaceSize(size_t width, size_t height, float scale_factor)
|
||||||
{
|
{
|
||||||
|
@ -1187,15 +1239,16 @@ namespace flutter_inappwebview_plugin
|
||||||
InAppWebView::~InAppWebView()
|
InAppWebView::~InAppWebView()
|
||||||
{
|
{
|
||||||
debugLog("dealloc InAppWebView");
|
debugLog("dealloc InAppWebView");
|
||||||
HWND parentWindow = nullptr;
|
userContentController = nullptr;
|
||||||
if (webViewCompositionController && succeededOrLog(webViewController->get_ParentWindow(&parentWindow))) {
|
|
||||||
// if it's an InAppWebView,
|
|
||||||
// then destroy the Window created with it
|
|
||||||
DestroyWindow(parentWindow);
|
|
||||||
}
|
|
||||||
if (webView) {
|
if (webView) {
|
||||||
failedLog(webView->Stop());
|
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) {
|
if (webViewController) {
|
||||||
failedLog(webViewController->Close());
|
failedLog(webViewController->Close());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "../types/navigation_action.h"
|
#include "../types/navigation_action.h"
|
||||||
#include "../types/url_request.h"
|
#include "../types/url_request.h"
|
||||||
#include "../types/web_history.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 "in_app_webview_settings.h"
|
||||||
#include "user_content_controller.h"
|
#include "user_content_controller.h"
|
||||||
#include "webview_channel_delegate.h"
|
#include "webview_channel_delegate.h"
|
||||||
|
@ -81,6 +83,11 @@ namespace flutter_inappwebview_plugin
|
||||||
const std::optional<std::vector<std::shared_ptr<UserScript>>> initialUserScripts;
|
const std::optional<std::vector<std::shared_ptr<UserScript>>> initialUserScripts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CreateInAppWebViewEnvParams {
|
||||||
|
const HWND parentWindow;
|
||||||
|
const bool willBeSurface;
|
||||||
|
};
|
||||||
|
|
||||||
class InAppWebView
|
class InAppWebView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -107,7 +114,7 @@ namespace flutter_inappwebview_plugin
|
||||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController);
|
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController);
|
||||||
~InAppWebView();
|
~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<ICoreWebView2Controller> webViewController,
|
||||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)> completionHandler);
|
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)> completionHandler);
|
||||||
|
|
||||||
|
@ -147,8 +154,8 @@ namespace flutter_inappwebview_plugin
|
||||||
bool canGoBack() const;
|
bool canGoBack() const;
|
||||||
void goForward();
|
void goForward();
|
||||||
bool canGoForward() const;
|
bool canGoForward() const;
|
||||||
void goBackOrForward(const int& steps);
|
void goBackOrForward(const int64_t& steps);
|
||||||
void canGoBackOrForward(const int& steps, std::function<void(bool)> completionHandler) const;
|
void canGoBackOrForward(const int64_t& steps, std::function<void(bool)> completionHandler) const;
|
||||||
bool isLoading() const
|
bool isLoading() const
|
||||||
{
|
{
|
||||||
return isLoading_;
|
return isLoading_;
|
||||||
|
@ -161,6 +168,7 @@ namespace flutter_inappwebview_plugin
|
||||||
void removeUserScript(const int64_t index, const std::shared_ptr<UserScript> userScript) const;
|
void removeUserScript(const int64_t index, const std::shared_ptr<UserScript> userScript) const;
|
||||||
void removeUserScriptsByGroupName(const std::string& groupName) const;
|
void removeUserScriptsByGroupName(const std::string& groupName) const;
|
||||||
void removeAllUserScripts() 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
|
std::string pageFrameId() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "../utils/vector.h"
|
#include "../utils/vector.h"
|
||||||
#include "in_app_webview_manager.h"
|
#include "in_app_webview_manager.h"
|
||||||
|
|
||||||
|
#include ".plugin_symlinks/flutter_inappwebview_windows/windows/webview_environment/webview_environment_manager.h"
|
||||||
|
|
||||||
namespace flutter_inappwebview_plugin
|
namespace flutter_inappwebview_plugin
|
||||||
{
|
{
|
||||||
InAppWebViewManager::InAppWebViewManager(const FlutterInappwebviewWindowsPlugin* 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 initialFile = get_optional_fl_map_value<std::string>(*arguments, "initialFile");
|
||||||
auto initialDataMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "initialData");
|
auto initialDataMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "initialData");
|
||||||
auto initialUserScriptList = get_optional_fl_map_value<flutter::EncodableList>(*arguments, "initialUserScripts");
|
auto initialUserScriptList = get_optional_fl_map_value<flutter::EncodableList>(*arguments, "initialUserScripts");
|
||||||
|
auto webViewEnvironmentId = get_optional_fl_map_value<std::string>(*arguments, "webViewEnvironmentId");
|
||||||
|
|
||||||
RECT bounds;
|
RECT bounds;
|
||||||
GetClientRect(plugin->registrar->GetView()->GetNativeWindow(), &bounds);
|
GetClientRect(plugin->registrar->GetView()->GetNativeWindow(), &bounds);
|
||||||
|
@ -93,7 +96,15 @@ namespace flutter_inappwebview_plugin
|
||||||
nullptr,
|
nullptr,
|
||||||
windowClass_.hInstance, 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<ICoreWebView2Environment> webViewEnv,
|
||||||
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
||||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)
|
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)
|
||||||
|
|
|
@ -159,6 +159,16 @@ namespace flutter_inappwebview_plugin
|
||||||
webView->removeAllUserScripts();
|
webView->removeAllUserScripts();
|
||||||
result->Success(true);
|
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
|
// for inAppBrowser
|
||||||
else if (webView->inAppBrowser && string_equals(methodName, "show")) {
|
else if (webView->inAppBrowser && string_equals(methodName, "show")) {
|
||||||
webView->inAppBrowser->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
|
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)
|
: description(description), type(type)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ namespace flutter_inappwebview_plugin
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const std::string description;
|
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(const flutter::EncodableMap& map);
|
||||||
~WebResourceError() = default;
|
~WebResourceError() = default;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace flutter_inappwebview_plugin
|
namespace flutter_inappwebview_plugin
|
||||||
{
|
{
|
||||||
WebResourceResponse::WebResourceResponse(const std::optional<int>& statusCode)
|
WebResourceResponse::WebResourceResponse(const std::optional<int64_t>& statusCode)
|
||||||
: statusCode(statusCode)
|
: statusCode(statusCode)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ namespace flutter_inappwebview_plugin
|
||||||
class WebResourceResponse
|
class WebResourceResponse
|
||||||
{
|
{
|
||||||
public:
|
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(const flutter::EncodableMap& map);
|
||||||
~WebResourceResponse() = default;
|
~WebResourceResponse() = default;
|
||||||
|
|
||||||
|
|
|
@ -80,23 +80,65 @@ namespace flutter_inappwebview_plugin
|
||||||
return encodableMap;
|
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)
|
static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* key)
|
||||||
{
|
{
|
||||||
return std::get<T>(map.at(make_fl_value(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>
|
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)
|
static inline std::optional<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);
|
auto fl_key = make_fl_value(key);
|
||||||
if (map_contains<flutter::EncodableValue, flutter::EncodableValue>(map, fl_key)) {
|
|
||||||
return make_pointer_optional<T>(std::get_if<T>(&map.at(fl_key)));
|
return make_pointer_optional<T>(std::get_if<T>(&map.at(fl_key)));
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
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>
|
template<typename T>
|
||||||
static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* key, const T& defaultValue)
|
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_
|
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_STRING_H_
|
||||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_STRING_H_
|
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_STRING_H_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -142,6 +143,39 @@ namespace flutter_inappwebview_plugin
|
||||||
res.push_back(s.substr(pos_start));
|
res.push_back(s.substr(pos_start));
|
||||||
return res;
|
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_
|
#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