windows: added openDevTools, callDevToolsProtocolMethod, addDevToolsProtocolEventListener and removeDevToolsProtocolEventListener methods, added some more inappwebview and inappbrowser basic settings
This commit is contained in:
parent
ade2edfb7d
commit
599e2fd94f
|
@ -484,6 +484,21 @@ class InAppWebViewController {
|
|||
URLResponse? urlResponse}) =>
|
||||
platform.loadSimulatedRequest(urlRequest: urlRequest, data: data);
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewController.openDevTools}
|
||||
Future<void> openDevTools() => platform.openDevTools();
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewController.callDevToolsProtocolMethod}
|
||||
Future<dynamic> callDevToolsProtocolMethod({required String methodName, Map<String, dynamic>? parameters}) =>
|
||||
platform.callDevToolsProtocolMethod(methodName: methodName, parameters: parameters);
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewController.addDevToolsProtocolEventListener}
|
||||
Future<void> addDevToolsProtocolEventListener({required String eventName, required Function(dynamic data) callback}) =>
|
||||
platform.addDevToolsProtocolEventListener(eventName: eventName, callback: callback);
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewController.removeDevToolsProtocolEventListener}
|
||||
Future<void> removeDevToolsProtocolEventListener({required String eventName}) =>
|
||||
platform.removeDevToolsProtocolEventListener(eventName: eventName);
|
||||
|
||||
///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewController.getIFrameId}
|
||||
Future<String?> getIFrameId() => platform.getIFrameId();
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
## 1.0.11
|
||||
|
||||
- Added `PlatformWebViewEnvironment` class
|
||||
|
||||
## 1.0.10
|
||||
|
||||
- Merged "Added == operator and hashCode to WebUri" [#1941](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1941) (thanks to [daisukeueta](https://github.com/daisukeueta))
|
||||
|
|
|
@ -98,194 +98,198 @@ class InAppBrowserSettings_
|
|||
implements BrowserOptions, AndroidOptions, IosOptions {
|
||||
///Set to `true` to create the browser and load the page, but not show it. Omit or set to `false` to have the browser open and load normally.
|
||||
///The default value is `false`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform(),
|
||||
WindowsPlatform()
|
||||
])
|
||||
bool? hidden;
|
||||
|
||||
///Set to `true` to hide the toolbar at the top of the WebView. The default value is `false`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform()
|
||||
])
|
||||
bool? hideToolbarTop;
|
||||
|
||||
///Set the custom background color of the toolbar at the top.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform()
|
||||
])
|
||||
Color_? toolbarTopBackgroundColor;
|
||||
|
||||
///Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform()
|
||||
])
|
||||
bool? hideUrlBar;
|
||||
|
||||
///Set to `true` to hide the progress bar when the WebView is loading a page. The default value is `false`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform()
|
||||
])
|
||||
bool? hideProgressBar;
|
||||
|
||||
///Set to `true` to hide the default menu items. The default value is `false`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform()
|
||||
])
|
||||
bool? hideDefaultMenuItems;
|
||||
|
||||
///Set to `true` if you want the title should be displayed. The default value is `false`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform()
|
||||
])
|
||||
bool? hideTitleBar;
|
||||
|
||||
///Set the action bar's title.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
MacOSPlatform(),
|
||||
WindowsPlatform()
|
||||
])
|
||||
String? toolbarTopFixedTitle;
|
||||
|
||||
///Set to `false` to not close the InAppBrowser when the user click on the Android back button and the WebView cannot go back to the history. The default value is `true`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform()
|
||||
])
|
||||
bool? closeOnCannotGoBack;
|
||||
|
||||
///Set to `false` to block the InAppBrowser WebView going back when the user click on the Android back button. The default value is `true`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform()
|
||||
])
|
||||
bool? allowGoBackWithBackButton;
|
||||
|
||||
///Set to `true` to close the InAppBrowser when the user click on the Android back button. The default value is `false`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform()
|
||||
])
|
||||
bool? shouldCloseOnBackButtonPressed;
|
||||
|
||||
///Set to `true` to set the toolbar at the top translucent. The default value is `true`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
bool? toolbarTopTranslucent;
|
||||
|
||||
///Set the tint color to apply to the navigation bar background.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
Color_? toolbarTopBarTintColor;
|
||||
|
||||
///Set the tint color to apply to the navigation items and bar button items.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
Color_? toolbarTopTintColor;
|
||||
|
||||
///Set to `true` to hide the toolbar at the bottom of the WebView. The default value is `false`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
bool? hideToolbarBottom;
|
||||
|
||||
///Set the custom background color of the toolbar at the bottom.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
Color_? toolbarBottomBackgroundColor;
|
||||
|
||||
///Set the tint color to apply to the bar button items.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
Color_? toolbarBottomTintColor;
|
||||
|
||||
///Set to `true` to set the toolbar at the bottom translucent. The default value is `true`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
bool? toolbarBottomTranslucent;
|
||||
|
||||
///Set the custom text for the close button.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
String? closeButtonCaption;
|
||||
|
||||
///Set the custom color for the close button.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
Color_? closeButtonColor;
|
||||
|
||||
///Set to `true` to hide the close button. The default value is `false`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
bool? hideCloseButton;
|
||||
|
||||
///Set the custom color for the menu button.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
Color_? menuButtonColor;
|
||||
|
||||
///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN].
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
ModalPresentationStyle_? presentationStyle;
|
||||
|
||||
///Set to the custom transition style when presenting the WebView. The default value is [ModalTransitionStyle.COVER_VERTICAL].
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform()
|
||||
])
|
||||
ModalTransitionStyle_? transitionStyle;
|
||||
|
||||
///How the browser window should be added to the main window.
|
||||
///The default value is [WindowType.WINDOW].
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
MacOSPlatform(),
|
||||
WindowsPlatform()
|
||||
])
|
||||
WindowType_? windowType;
|
||||
|
||||
///The window’s alpha value.
|
||||
///The default value is `1.0`.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
MacOSPlatform(),
|
||||
WindowsPlatform()
|
||||
])
|
||||
double? windowAlphaValue;
|
||||
|
||||
///Flags that describe the window’s current style, such as if it’s resizable or in full-screen mode.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
MacOSPlatform()
|
||||
])
|
||||
WindowStyleMask_? windowStyleMask;
|
||||
|
||||
///The type of separator that the app displays between the title bar and content of a window.
|
||||
///
|
||||
///**NOTE for MacOS**: available on MacOS 11.0+.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
MacOSPlatform(available: '11.0')
|
||||
])
|
||||
WindowTitlebarSeparatorStyle_? windowTitlebarSeparatorStyle;
|
||||
|
||||
///Sets the origin and size of the window’s frame rectangle according to a given frame rectangle,
|
||||
///thereby setting its position and size onscreen.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- MacOS
|
||||
@SupportedPlatforms(platforms: [
|
||||
MacOSPlatform(),
|
||||
WindowsPlatform()
|
||||
])
|
||||
InAppWebViewRect_? windowFrame;
|
||||
|
||||
InAppBrowserSettings_(
|
||||
|
|
|
@ -28,6 +28,7 @@ class InAppWebViewControllerKeepAliveProps {
|
|||
Map<String, ScriptHtmlTagAttributes> injectedScriptsFromURL;
|
||||
Set<PlatformWebMessageChannel> webMessageChannels = Set();
|
||||
Set<PlatformWebMessageListener> webMessageListeners = Set();
|
||||
Map<String, Function(dynamic data)> devToolsProtocolEventListenerMap;
|
||||
|
||||
InAppWebViewControllerKeepAliveProps(
|
||||
{required this.javaScriptHandlersMap,
|
||||
|
@ -35,5 +36,7 @@ class InAppWebViewControllerKeepAliveProps {
|
|||
required this.webMessageListenerObjNames,
|
||||
required this.injectedScriptsFromURL,
|
||||
required this.webMessageChannels,
|
||||
required this.webMessageListeners});
|
||||
required this.webMessageListeners,
|
||||
required this.devToolsProtocolEventListenerMap
|
||||
});
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class InAppWebViewSettings_ {
|
|||
///it will be automatically inferred as `true`, otherwise, the default value is `false`.
|
||||
///This logic will not be applied for [PlatformInAppBrowser], where you must set the value manually.
|
||||
@SupportedPlatforms(
|
||||
platforms: [AndroidPlatform(), IOSPlatform(), MacOSPlatform()])
|
||||
platforms: [AndroidPlatform(), IOSPlatform(), MacOSPlatform(), WindowsPlatform()])
|
||||
bool? useShouldOverrideUrlLoading;
|
||||
|
||||
///Set to `true` to be able to listen at the [PlatformWebViewCreationParams.onLoadResource] event.
|
||||
|
@ -98,7 +98,11 @@ class InAppWebViewSettings_ {
|
|||
MacOSPlatform(
|
||||
apiName: "WKWebView.customUserAgent",
|
||||
apiUrl:
|
||||
"https://developer.apple.com/documentation/webkit/wkwebview/1414950-customuseragent")
|
||||
"https://developer.apple.com/documentation/webkit/wkwebview/1414950-customuseragent"),
|
||||
WindowsPlatform(
|
||||
apiName: 'ICoreWebView2Settings2.put_UserAgent',
|
||||
apiUrl: 'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings2?view=webview2-1.0.2210.55#put_useragent'
|
||||
)
|
||||
])
|
||||
String? userAgent;
|
||||
|
||||
|
@ -130,7 +134,12 @@ class InAppWebViewSettings_ {
|
|||
apiName: "WKWebpagePreferences.allowsContentJavaScript",
|
||||
apiUrl:
|
||||
"https://developer.apple.com/documentation/webkit/wkwebpagepreferences/3552422-allowscontentjavascript/"),
|
||||
WebPlatform(requiresSameOrigin: false)
|
||||
WebPlatform(requiresSameOrigin: false),
|
||||
WindowsPlatform(
|
||||
apiName: "ICoreWebView2Settings.put_IsScriptEnabled",
|
||||
apiUrl:
|
||||
"https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings?view=webview2-1.0.2210.55#put_isscriptenabled"
|
||||
)
|
||||
])
|
||||
bool? javaScriptEnabled;
|
||||
|
||||
|
@ -307,7 +316,12 @@ because there isn't any way to make the website data store non-persistent for th
|
|||
@SupportedPlatforms(platforms: [
|
||||
AndroidPlatform(),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform(available: "12.0")
|
||||
MacOSPlatform(available: "12.0"),
|
||||
WindowsPlatform(
|
||||
available: '1.0.774.44',
|
||||
apiName: 'ICoreWebView2Controller2.put_DefaultBackgroundColor',
|
||||
apiUrl: 'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2controller2?view=webview2-1.0.2210.55#put_defaultbackgroundcolor'
|
||||
)
|
||||
])
|
||||
bool? transparentBackground;
|
||||
|
||||
|
@ -323,7 +337,13 @@ because there isn't any way to make the website data store non-persistent for th
|
|||
|
||||
///Set to `true` to disable context menu. The default value is `false`.
|
||||
@SupportedPlatforms(
|
||||
platforms: [AndroidPlatform(), IOSPlatform(), WebPlatform()])
|
||||
platforms: [AndroidPlatform(), IOSPlatform(), WebPlatform(),
|
||||
WindowsPlatform(
|
||||
apiName: "ICoreWebView2Settings.put_AreDefaultContextMenusEnabled",
|
||||
apiUrl:
|
||||
"https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings?view=webview2-1.0.2210.55#put_aredefaultcontextmenusenabled"
|
||||
)
|
||||
])
|
||||
bool? disableContextMenu;
|
||||
|
||||
///Set to `false` if the WebView should not support zooming using its on-screen zoom controls and gestures. The default value is `true`.
|
||||
|
@ -333,7 +353,12 @@ because there isn't any way to make the website data store non-persistent for th
|
|||
apiUrl:
|
||||
"https://developer.android.com/reference/android/webkit/WebSettings?hl=en#setSupportZoom(boolean)"),
|
||||
IOSPlatform(),
|
||||
MacOSPlatform()
|
||||
MacOSPlatform(),
|
||||
WindowsPlatform(
|
||||
apiName: "ICoreWebView2Settings.put_IsZoomControlEnabled",
|
||||
apiUrl:
|
||||
"https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings?view=webview2-1.0.2210.55#put_iszoomcontrolenabled"
|
||||
)
|
||||
])
|
||||
bool? supportZoom;
|
||||
|
||||
|
@ -1537,7 +1562,12 @@ as it can cause framerate drops on animations in Android 9 and lower (see [Hybri
|
|||
available: "13.3",
|
||||
apiName: "WKWebView.isInspectable",
|
||||
apiUrl:
|
||||
"https://developer.apple.com/documentation/webkit/wkwebview/4111163-isinspectable")
|
||||
"https://developer.apple.com/documentation/webkit/wkwebview/4111163-isinspectable"),
|
||||
WindowsPlatform(
|
||||
apiName: "ICoreWebView2Settings.put_AreDevToolsEnabled",
|
||||
apiUrl:
|
||||
"https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings?view=webview2-1.0.2210.55#put_aredevtoolsenabled"
|
||||
)
|
||||
])
|
||||
bool? isInspectable;
|
||||
|
||||
|
|
|
@ -371,6 +371,7 @@ class InAppWebViewSettings {
|
|||
///- Android native WebView
|
||||
///- iOS
|
||||
///- Web but iframe requires same origin
|
||||
///- Windows ([Official API - ICoreWebView2Settings.put_AreDefaultContextMenusEnabled](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings?view=webview2-1.0.2210.55#put_aredefaultcontextmenusenabled))
|
||||
bool? disableContextMenu;
|
||||
|
||||
///Sets whether the default Android WebView’s internal error page should be suppressed or displayed for bad navigations.
|
||||
|
@ -648,6 +649,7 @@ class InAppWebViewSettings {
|
|||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS 16.4+ ([Official API - WKWebView.isInspectable](https://developer.apple.com/documentation/webkit/wkwebview/4111163-isinspectable))
|
||||
///- MacOS 13.3+ ([Official API - WKWebView.isInspectable](https://developer.apple.com/documentation/webkit/wkwebview/4111163-isinspectable))
|
||||
///- Windows ([Official API - ICoreWebView2Settings.put_AreDevToolsEnabled](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings?view=webview2-1.0.2210.55#put_aredevtoolsenabled))
|
||||
bool? isInspectable;
|
||||
|
||||
///A Boolean value that determines whether paging is enabled for the scroll view.
|
||||
|
@ -691,6 +693,7 @@ class InAppWebViewSettings {
|
|||
///- iOS ([Official API - WKWebpagePreferences.allowsContentJavaScript](https://developer.apple.com/documentation/webkit/wkwebpagepreferences/3552422-allowscontentjavascript/))
|
||||
///- MacOS ([Official API - WKWebpagePreferences.allowsContentJavaScript](https://developer.apple.com/documentation/webkit/wkwebpagepreferences/3552422-allowscontentjavascript/))
|
||||
///- Web
|
||||
///- Windows ([Official API - ICoreWebView2Settings.put_IsScriptEnabled](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings?view=webview2-1.0.2210.55#put_isscriptenabled))
|
||||
bool? javaScriptEnabled;
|
||||
|
||||
///Sets the underlying layout algorithm. This will cause a re-layout of the WebView.
|
||||
|
@ -983,6 +986,7 @@ class InAppWebViewSettings {
|
|||
///- Android native WebView ([Official API - WebSettings.setSupportZoom](https://developer.android.com/reference/android/webkit/WebSettings?hl=en#setSupportZoom(boolean)))
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows ([Official API - ICoreWebView2Settings.put_IsZoomControlEnabled](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings?view=webview2-1.0.2210.55#put_iszoomcontrolenabled))
|
||||
bool? supportZoom;
|
||||
|
||||
///Set to `true` if you want the WebView suppresses content rendering until it is fully loaded into memory. The default value is `false`.
|
||||
|
@ -1012,6 +1016,7 @@ class InAppWebViewSettings {
|
|||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS 12.0+
|
||||
///- Windows 1.0.774.44+ ([Official API - ICoreWebView2Controller2.put_DefaultBackgroundColor](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2controller2?view=webview2-1.0.2210.55#put_defaultbackgroundcolor))
|
||||
bool? transparentBackground;
|
||||
|
||||
///The color the web view displays behind the active page, visible when the user scrolls beyond the bounds of the page.
|
||||
|
@ -1137,6 +1142,7 @@ class InAppWebViewSettings {
|
|||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
bool? useShouldOverrideUrlLoading;
|
||||
|
||||
///Set to `true` if the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport.
|
||||
|
@ -1154,6 +1160,7 @@ class InAppWebViewSettings {
|
|||
///- Android native WebView ([Official API - WebSettings.setUserAgentString](https://developer.android.com/reference/android/webkit/WebSettings?hl=en#setUserAgentString(java.lang.String)))
|
||||
///- iOS ([Official API - WKWebView.customUserAgent](https://developer.apple.com/documentation/webkit/wkwebview/1414950-customuseragent))
|
||||
///- MacOS ([Official API - WKWebView.customUserAgent](https://developer.apple.com/documentation/webkit/wkwebview/1414950-customuseragent))
|
||||
///- Windows ([Official API - ICoreWebView2Settings2.put_UserAgent](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2settings2?view=webview2-1.0.2210.55#put_useragent))
|
||||
String? userAgent;
|
||||
|
||||
///Define whether the vertical scrollbar should be drawn or not. The default value is `true`.
|
||||
|
|
|
@ -2040,6 +2040,62 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
'loadSimulatedRequest is not implemented on the current platform');
|
||||
}
|
||||
|
||||
///{@template flutter_inappwebview_platform_interface.PlatformInAppWebViewController.openDevTools}
|
||||
///Opens the DevTools window for the current document in the WebView.
|
||||
///Does nothing if run when the DevTools window is already open.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Windows ([Official API - ICoreWebView2.OpenDevToolsWindow](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#opendevtoolswindow))
|
||||
///{@endtemplate}
|
||||
Future<void> openDevTools() {
|
||||
throw UnimplementedError(
|
||||
'openDevTools is not implemented on the current platform');
|
||||
}
|
||||
|
||||
///{@template flutter_inappwebview_platform_interface.PlatformInAppWebViewController.callDevToolsProtocolMethod}
|
||||
///Runs an asynchronous `DevToolsProtocol` method.
|
||||
///
|
||||
///For more information about available methods, navigate to [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/tot).
|
||||
///The [methodName] parameter is the full name of the method in the `{domain}.{method}` format.
|
||||
///The [parameters] will be a JSON formatted string containing the parameters for the corresponding method.
|
||||
///This function throws an error if the [methodName] is unknown or the [parameters] has an error.
|
||||
///In the case of such an error, the [parameters] parameter of the
|
||||
///handler will include information about the error.
|
||||
///Note even though WebView dispatches the CDP messages in the order called,
|
||||
///CDP method calls may be processed out of order.
|
||||
///If you require CDP methods to run in a particular order, you should wait for
|
||||
///the previous method's completed handler to run before calling the next method.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Windows ([Official API - ICoreWebView2.CallDevToolsProtocolMethod](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#calldevtoolsprotocolmethod))
|
||||
///{@endtemplate}
|
||||
Future<dynamic> callDevToolsProtocolMethod({required String methodName, Map<String, dynamic>? parameters}) {
|
||||
throw UnimplementedError(
|
||||
'callDevToolsProtocolMethod is not implemented on the current platform');
|
||||
}
|
||||
|
||||
///{@template flutter_inappwebview_platform_interface.PlatformInAppWebViewController.addDevToolsProtocolEventListener}
|
||||
///Subscribe to a `DevToolsProtocol` event.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Windows ([Official API - ICoreWebView2DevToolsProtocolEventReceiver.add_DevToolsProtocolEventReceived](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2devtoolsprotocoleventreceiver?view=webview2-1.0.2210.55#add_devtoolsprotocoleventreceived))
|
||||
///{@endtemplate}
|
||||
Future<void> addDevToolsProtocolEventListener({required String eventName, required Function(dynamic data) callback}) {
|
||||
throw UnimplementedError(
|
||||
'addDevToolsProtocolEventListener is not implemented on the current platform');
|
||||
}
|
||||
|
||||
///{@template flutter_inappwebview_platform_interface.PlatformInAppWebViewController.removeDevToolsProtocolEventListener}
|
||||
///Remove an event handler previously added with [addDevToolsProtocolEventListener].
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Windows ([Official API - ICoreWebView2DevToolsProtocolEventReceiver.remove_DevToolsProtocolEventReceived](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2devtoolsprotocoleventreceiver?view=webview2-1.0.2210.55#remove_devtoolsprotocoleventreceived))
|
||||
///{@endtemplate}
|
||||
Future<void> removeDevToolsProtocolEventListener({required String eventName}) {
|
||||
throw UnimplementedError(
|
||||
'removeDevToolsProtocolEventListener is not implemented on the current platform');
|
||||
}
|
||||
|
||||
///{@template flutter_inappwebview_platform_interface.PlatformInAppWebViewController.getIFrameId}
|
||||
///Returns the iframe `id` attribute used on the Web platform.
|
||||
///
|
||||
|
|
|
@ -12,11 +12,11 @@ class WindowType_ {
|
|||
const WindowType_._internal(this._value);
|
||||
|
||||
///Adds the new browser window as a separate new window from the main window.
|
||||
@EnumSupportedPlatforms(platforms: [EnumMacOSPlatform(value: 'WINDOW')])
|
||||
@EnumSupportedPlatforms(platforms: [EnumMacOSPlatform(value: 'WINDOW'), EnumWindowsPlatform(value: 'WINDOW')])
|
||||
static const WINDOW = const WindowType_._internal('WINDOW');
|
||||
|
||||
///Adds the new browser window as a child window of the main window.
|
||||
@EnumSupportedPlatforms(platforms: [EnumMacOSPlatform(value: 'CHILD')])
|
||||
@EnumSupportedPlatforms(platforms: [EnumMacOSPlatform(value: 'CHILD'), EnumWindowsPlatform(value: 'CHILD')])
|
||||
static const CHILD = const WindowType_._internal('CHILD');
|
||||
|
||||
///Adds the new browser window as a new tab in a tabbed window of the main window.
|
||||
|
|
|
@ -20,10 +20,13 @@ class WindowType {
|
|||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- MacOS
|
||||
///- Windows
|
||||
static final CHILD = WindowType._internalMultiPlatform('CHILD', () {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.macOS:
|
||||
return 'CHILD';
|
||||
case TargetPlatform.windows:
|
||||
return 'CHILD';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -48,10 +51,13 @@ class WindowType {
|
|||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- MacOS
|
||||
///- Windows
|
||||
static final WINDOW = WindowType._internalMultiPlatform('WINDOW', () {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.macOS:
|
||||
return 'WINDOW';
|
||||
case TargetPlatform.windows:
|
||||
return 'WINDOW';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
Map<String, ScriptHtmlTagAttributes> _injectedScriptsFromURL = {};
|
||||
Set<WindowsWebMessageChannel> _webMessageChannels = Set();
|
||||
Set<WindowsWebMessageListener> _webMessageListeners = Set();
|
||||
Map<String, Function(dynamic data)> _devToolsProtocolEventListenerMap = HashMap();
|
||||
|
||||
// static map that contains the properties to be saved and restored for keep alive feature
|
||||
static final Map<InAppWebViewKeepAlive, InAppWebViewControllerKeepAliveProps?>
|
||||
|
@ -179,7 +180,9 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
userScripts: _userScripts,
|
||||
webMessageListenerObjNames: _webMessageListenerObjNames,
|
||||
webMessageChannels: _webMessageChannels,
|
||||
webMessageListeners: _webMessageListeners);
|
||||
webMessageListeners: _webMessageListeners,
|
||||
devToolsProtocolEventListenerMap: _devToolsProtocolEventListenerMap
|
||||
);
|
||||
} else {
|
||||
// restore controller properties
|
||||
_injectedScriptsFromURL = props.injectedScriptsFromURL;
|
||||
|
@ -190,6 +193,7 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
props.webMessageChannels as Set<WindowsWebMessageChannel>;
|
||||
_webMessageListeners =
|
||||
props.webMessageListeners as Set<WindowsWebMessageListener>;
|
||||
_devToolsProtocolEventListenerMap = props.devToolsProtocolEventListenerMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1403,6 +1407,14 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
.onContentSizeChanged(oldContentSize, newContentSize);
|
||||
}
|
||||
break;
|
||||
case "onDevToolsProtocolEventReceived":
|
||||
String eventName = call.arguments["eventName"];
|
||||
dynamic data = call.arguments["data"] != null ? jsonDecode(call.arguments["data"]) : null;
|
||||
|
||||
if (this._devToolsProtocolEventListenerMap.containsKey(eventName)) {
|
||||
this._devToolsProtocolEventListenerMap[eventName]!.call(data);
|
||||
}
|
||||
break;
|
||||
case "onCallJsHandler":
|
||||
String handlerName = call.arguments["handlerName"];
|
||||
// decode args to json
|
||||
|
@ -2627,6 +2639,40 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
await channel?.invokeMethod('loadSimulatedRequest', args);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> openDevTools() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
await channel?.invokeMethod('openDevTools', args);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<dynamic> callDevToolsProtocolMethod({required String methodName, Map<String, dynamic>? parameters}) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('methodName', () => methodName);
|
||||
args.putIfAbsent('parametersAsJson', () => parameters != null ? jsonEncode(parameters) : null);
|
||||
final result = await channel?.invokeMethod<String>('callDevToolsProtocolMethod', args);
|
||||
if (result != null) {
|
||||
return jsonDecode(result);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addDevToolsProtocolEventListener({required String eventName, required Function(dynamic data) callback}) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('eventName', () => eventName);
|
||||
await channel?.invokeMethod('addDevToolsProtocolEventListener', args);
|
||||
this._devToolsProtocolEventListenerMap[eventName] = callback;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeDevToolsProtocolEventListener({required String eventName}) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('eventName', () => eventName);
|
||||
await channel?.invokeMethod('removeDevToolsProtocolEventListener', args);
|
||||
this._devToolsProtocolEventListenerMap.remove(eventName);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> getDefaultUserAgent() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
|
@ -2689,6 +2735,7 @@ class WindowsInAppWebViewController extends PlatformInAppWebViewController
|
|||
webMessageListener.dispose();
|
||||
}
|
||||
_webMessageListeners.clear();
|
||||
_devToolsProtocolEventListenerMap.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,25 +21,48 @@ namespace flutter_inappwebview_plugin
|
|||
wndClass.hInstance = m_hInstance;
|
||||
wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
||||
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
||||
wndClass.lpfnWndProc = InAppBrowser::WndProc;
|
||||
|
||||
RegisterClass(&wndClass);
|
||||
|
||||
auto parentWindow = plugin->registrar->GetView()->GetNativeWindow();
|
||||
RECT bounds;
|
||||
GetWindowRect(parentWindow, &bounds);
|
||||
|
||||
auto x = CW_USEDEFAULT;
|
||||
auto y = CW_USEDEFAULT;
|
||||
auto width = bounds.right - bounds.left;
|
||||
auto height = bounds.bottom - bounds.top;
|
||||
|
||||
if (settings->windowFrame) {
|
||||
x = (int)settings->windowFrame->x;
|
||||
y = (int)settings->windowFrame->y;
|
||||
width = (int)settings->windowFrame->width;
|
||||
height = (int)settings->windowFrame->height;
|
||||
}
|
||||
|
||||
m_hWnd = CreateWindowEx(
|
||||
0, // Optional window styles.
|
||||
WS_EX_LAYERED, // Optional window styles.
|
||||
wndClass.lpszClassName, // Window class
|
||||
L"", // Window text
|
||||
WS_OVERLAPPEDWINDOW, // Window style
|
||||
|
||||
// Size and position
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
settings->toolbarTopFixedTitle.empty() ? L"" : utf8_to_wide(settings->toolbarTopFixedTitle).c_str(), // Window text
|
||||
|
||||
NULL, // Parent window
|
||||
NULL, // Menu
|
||||
settings->windowType == InAppBrowserWindowType::window ? WS_OVERLAPPEDWINDOW : (WS_CHILDWINDOW | WS_OVERLAPPEDWINDOW), // Window style
|
||||
|
||||
// Position
|
||||
x, y,
|
||||
// Size
|
||||
width, height,
|
||||
|
||||
settings->windowType == InAppBrowserWindowType::window ? nullptr : parentWindow, // Parent window
|
||||
nullptr, // Menu
|
||||
wndClass.hInstance, // Instance handle
|
||||
this // Additional application data
|
||||
);
|
||||
|
||||
SetLayeredWindowAttributes(m_hWnd, 0, (BYTE)(255 * settings->windowAlphaValue), LWA_ALPHA);
|
||||
|
||||
ShowWindow(m_hWnd, settings->hidden ? SW_HIDE : SW_SHOW);
|
||||
|
||||
InAppWebViewCreationParams webViewParams = {
|
||||
|
@ -99,9 +122,49 @@ namespace flutter_inappwebview_plugin
|
|||
return !IsWindowVisible(m_hWnd);
|
||||
}
|
||||
|
||||
void InAppBrowser::setSettings(const std::shared_ptr<InAppBrowserSettings> newSettings, const flutter::EncodableMap& newSettingsMap)
|
||||
{
|
||||
if (webView) {
|
||||
webView->setSettings(std::make_shared<InAppWebViewSettings>(newSettingsMap), newSettingsMap);
|
||||
}
|
||||
|
||||
if (fl_map_contains_not_null(newSettingsMap, "hidden") && settings->hidden != newSettings->hidden) {
|
||||
newSettings->hidden ? hide() : show();
|
||||
}
|
||||
|
||||
if (fl_map_contains_not_null(newSettingsMap, "toolbarTopFixedTitle") && !string_equals(settings->toolbarTopFixedTitle, newSettings->toolbarTopFixedTitle) && !newSettings->toolbarTopFixedTitle.empty()) {
|
||||
SetWindowText(m_hWnd, utf8_to_wide(newSettings->toolbarTopFixedTitle).c_str());
|
||||
}
|
||||
|
||||
if (fl_map_contains_not_null(newSettingsMap, "windowAlphaValue") && settings->windowAlphaValue != newSettings->windowAlphaValue) {
|
||||
SetLayeredWindowAttributes(m_hWnd, 0, (BYTE)(255 * newSettings->windowAlphaValue), LWA_ALPHA);
|
||||
}
|
||||
|
||||
if (fl_map_contains_not_null(newSettingsMap, "windowFrame")) {
|
||||
auto x = (int)newSettings->windowFrame->x;
|
||||
auto y = (int)newSettings->windowFrame->y;
|
||||
auto width = (int)newSettings->windowFrame->width;
|
||||
auto height = (int)newSettings->windowFrame->height;
|
||||
MoveWindow(m_hWnd, x, y, width, height, true);
|
||||
}
|
||||
|
||||
settings = newSettings;
|
||||
}
|
||||
|
||||
flutter::EncodableValue InAppBrowser::getSettings() const
|
||||
{
|
||||
if (!settings || !webView) {
|
||||
return make_fl_value();
|
||||
}
|
||||
|
||||
auto encodableMap = settings->getRealSettings(this);
|
||||
encodableMap.merge(std::get<flutter::EncodableMap>(webView->getSettings()));
|
||||
return encodableMap;
|
||||
}
|
||||
|
||||
void InAppBrowser::didChangeTitle(const std::optional<std::string>& title) const
|
||||
{
|
||||
if (title.has_value()) {
|
||||
if (title.has_value() && settings->toolbarTopFixedTitle.empty()) {
|
||||
SetWindowText(m_hWnd, utf8_to_wide(title.value()).c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <wil/com.h>
|
||||
#include <Windows.h>
|
||||
|
||||
#include "../flutter_inappwebview_windows_plugin.h"
|
||||
|
@ -41,7 +40,7 @@ namespace flutter_inappwebview_plugin
|
|||
const std::string id;
|
||||
std::unique_ptr<InAppWebView> webView;
|
||||
std::unique_ptr<InAppBrowserChannelDelegate> channelDelegate;
|
||||
const std::shared_ptr<InAppBrowserSettings> settings;
|
||||
std::shared_ptr<InAppBrowserSettings> settings;
|
||||
|
||||
InAppBrowser(const FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params);
|
||||
~InAppBrowser();
|
||||
|
@ -50,9 +49,14 @@ namespace flutter_inappwebview_plugin
|
|||
void show() const;
|
||||
void hide() const;
|
||||
bool isHidden() const;
|
||||
void setSettings(const std::shared_ptr<InAppBrowserSettings> newSettings, const flutter::EncodableMap& newSettingsMap);
|
||||
flutter::EncodableValue getSettings() const;
|
||||
|
||||
void didChangeTitle(const std::optional<std::string>& title) const;
|
||||
|
||||
HWND getHWND() const
|
||||
{
|
||||
return m_hWnd;
|
||||
}
|
||||
private:
|
||||
const HINSTANCE m_hInstance;
|
||||
HWND m_hWnd;
|
||||
|
|
|
@ -1,29 +1,27 @@
|
|||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/string.h"
|
||||
#include "in_app_browser_settings.h"
|
||||
|
||||
#include "in_app_browser.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
namespace
|
||||
{
|
||||
InAppBrowserWindowType inAppBrowserWindowTypeFromString(const std::string& s)
|
||||
{
|
||||
if (s.compare("CHILD") == 0) {
|
||||
return child;
|
||||
if (string_equals(s, "CHILD")) {
|
||||
return InAppBrowserWindowType::child;
|
||||
}
|
||||
else if (s.compare("TABBED") == 0) {
|
||||
return tabbed;
|
||||
}
|
||||
return window;
|
||||
return InAppBrowserWindowType::window;
|
||||
}
|
||||
|
||||
std::string inAppBrowserWindowTypeToString(const InAppBrowserWindowType& t)
|
||||
{
|
||||
switch (t) {
|
||||
case child:
|
||||
case InAppBrowserWindowType::child:
|
||||
return "CHILD";
|
||||
case tabbed:
|
||||
return "TABBED";
|
||||
default:
|
||||
return "WINDOW";
|
||||
}
|
||||
|
@ -35,8 +33,40 @@ namespace flutter_inappwebview_plugin
|
|||
InAppBrowserSettings::InAppBrowserSettings(const flutter::EncodableMap& encodableMap)
|
||||
{
|
||||
hidden = get_fl_map_value(encodableMap, "hidden", hidden);
|
||||
windowType = inAppBrowserWindowTypeFromString(get_fl_map_value<std::string>(encodableMap, "windowType", inAppBrowserWindowTypeToString(window)));
|
||||
windowType = inAppBrowserWindowTypeFromString(get_fl_map_value<std::string>(encodableMap, "windowType", inAppBrowserWindowTypeToString(InAppBrowserWindowType::window)));
|
||||
toolbarTopFixedTitle = get_fl_map_value(encodableMap, "toolbarTopFixedTitle", toolbarTopFixedTitle);
|
||||
windowAlphaValue = get_fl_map_value(encodableMap, "windowAlphaValue", windowAlphaValue);
|
||||
auto windowFrameMap = get_optional_fl_map_value<flutter::EncodableMap>(encodableMap, "windowFrame");
|
||||
if (windowFrameMap.has_value()) {
|
||||
windowFrame = std::make_shared<Rect>(windowFrameMap.value());
|
||||
}
|
||||
}
|
||||
|
||||
flutter::EncodableMap InAppBrowserSettings::toEncodableMap() const
|
||||
{
|
||||
return flutter::EncodableMap{
|
||||
{"hidden", hidden},
|
||||
{"windowType", inAppBrowserWindowTypeToString(windowType)},
|
||||
{"toolbarTopFixedTitle", toolbarTopFixedTitle},
|
||||
{"windowAlphaValue", windowAlphaValue},
|
||||
{"windowFrame", windowFrame ? windowFrame->toEncodableMap() : make_fl_value()},
|
||||
};
|
||||
}
|
||||
|
||||
flutter::EncodableMap InAppBrowserSettings::getRealSettings(const InAppBrowser* inAppBrowser) const
|
||||
{
|
||||
auto settingsMap = toEncodableMap();
|
||||
settingsMap["hidden"] = inAppBrowser->isHidden();
|
||||
|
||||
BYTE alphaValue = 0;
|
||||
GetLayeredWindowAttributes(inAppBrowser->getHWND(), nullptr, &alphaValue, nullptr);
|
||||
settingsMap["windowAlphaValue"] = (double)alphaValue;
|
||||
|
||||
RECT position;
|
||||
GetWindowRect(inAppBrowser->getHWND(), &position);
|
||||
settingsMap["windowFrame"] = std::make_unique<Rect>(position.left, position.top, position.right - position.left, position.bottom - position.top)->toEncodableMap();
|
||||
|
||||
return settingsMap;
|
||||
}
|
||||
|
||||
InAppBrowserSettings::~InAppBrowserSettings()
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_SETTINGS_H_
|
||||
|
||||
#include <flutter/standard_message_codec.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "../types/rect.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class InAppBrowser;
|
||||
|
||||
enum InAppBrowserWindowType {
|
||||
window,
|
||||
child,
|
||||
tabbed
|
||||
child
|
||||
};
|
||||
|
||||
class InAppBrowserSettings
|
||||
|
@ -17,11 +21,16 @@ namespace flutter_inappwebview_plugin
|
|||
public:
|
||||
bool hidden = false;
|
||||
InAppBrowserWindowType windowType = window;
|
||||
std::string toolbarTopFixedTitle;
|
||||
double windowAlphaValue = 1.0;
|
||||
std::shared_ptr<Rect> windowFrame;
|
||||
|
||||
InAppBrowserSettings();
|
||||
InAppBrowserSettings(const flutter::EncodableMap& encodableMap);
|
||||
~InAppBrowserSettings();
|
||||
|
||||
flutter::EncodableMap toEncodableMap() const;
|
||||
flutter::EncodableMap getRealSettings(const InAppBrowser* inAppBrowser) const;
|
||||
};
|
||||
}
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_SETTINGS_H_
|
|
@ -143,6 +143,8 @@ namespace flutter_inappwebview_plugin
|
|||
if (succeededOrLog(hrWebView2Settings)) {
|
||||
webView2Settings->put_IsScriptEnabled(settings->javaScriptEnabled);
|
||||
webView2Settings->put_IsZoomControlEnabled(settings->supportZoom);
|
||||
webView2Settings->put_AreDevToolsEnabled(settings->isInspectable);
|
||||
webView2Settings->put_AreDefaultContextMenusEnabled(!settings->disableContextMenu);
|
||||
|
||||
wil::com_ptr<ICoreWebView2Settings2> webView2Settings2;
|
||||
if (succeededOrLog(webView2Settings->QueryInterface(IID_PPV_ARGS(&webView2Settings2)))) {
|
||||
|
@ -152,6 +154,13 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Controller2> webViewController2;
|
||||
if (succeededOrLog(webViewController->QueryInterface(IID_PPV_ARGS(&webViewController2)))) {
|
||||
if (!settings->transparentBackground) {
|
||||
webViewController2->put_DefaultBackgroundColor({ 0, 255, 255, 255 });
|
||||
}
|
||||
}
|
||||
|
||||
// required to make Runtime events work
|
||||
failedLog(webView->CallDevToolsProtocolMethod(L"Runtime.enable", L"{}", Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
|
||||
[this](HRESULT errorCode, LPCWSTR returnObjectAsJson)
|
||||
|
@ -971,6 +980,137 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
}
|
||||
|
||||
void InAppWebView::setSettings(const std::shared_ptr<InAppWebViewSettings> newSettings, const flutter::EncodableMap& newSettingsMap)
|
||||
{
|
||||
wil::com_ptr<ICoreWebView2Settings> webView2Settings;
|
||||
if (succeededOrLog(webView->get_Settings(&webView2Settings))) {
|
||||
if (fl_map_contains_not_null(newSettingsMap, "javaScriptEnabled") && settings->javaScriptEnabled != newSettings->javaScriptEnabled) {
|
||||
webView2Settings->put_IsScriptEnabled(newSettings->javaScriptEnabled);
|
||||
}
|
||||
|
||||
if (fl_map_contains_not_null(newSettingsMap, "supportZoom") && settings->supportZoom != newSettings->supportZoom) {
|
||||
webView2Settings->put_IsZoomControlEnabled(newSettings->supportZoom);
|
||||
}
|
||||
|
||||
if (fl_map_contains_not_null(newSettingsMap, "isInspectable") && settings->isInspectable != newSettings->isInspectable) {
|
||||
webView2Settings->put_AreDevToolsEnabled(newSettings->isInspectable);
|
||||
}
|
||||
|
||||
if (fl_map_contains_not_null(newSettingsMap, "disableContextMenu") && settings->disableContextMenu != newSettings->disableContextMenu) {
|
||||
webView2Settings->put_AreDefaultContextMenusEnabled(!newSettings->disableContextMenu);
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Settings2> webView2Settings2;
|
||||
if (succeededOrLog(webView2Settings->QueryInterface(IID_PPV_ARGS(&webView2Settings2)))) {
|
||||
if (fl_map_contains_not_null(newSettingsMap, "userAgent") && !string_equals(settings->userAgent, newSettings->userAgent)) {
|
||||
webView2Settings2->put_UserAgent(utf8_to_wide(newSettings->userAgent).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Controller2> webViewController2;
|
||||
if (succeededOrLog(webViewController->QueryInterface(IID_PPV_ARGS(&webViewController2)))) {
|
||||
if (fl_map_contains_not_null(newSettingsMap, "transparentBackground") && settings->transparentBackground != newSettings->transparentBackground) {
|
||||
BYTE alpha = newSettings->transparentBackground ? 0 : 255;
|
||||
webViewController2->put_DefaultBackgroundColor({ alpha, 255, 255, 255 });
|
||||
}
|
||||
}
|
||||
|
||||
settings = newSettings;
|
||||
}
|
||||
|
||||
flutter::EncodableValue InAppWebView::getSettings() const
|
||||
{
|
||||
if (!settings || !webView) {
|
||||
return make_fl_value();
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Settings> webView2Settings;
|
||||
if (succeededOrLog(webView->get_Settings(&webView2Settings))) {
|
||||
return settings->getRealSettings(webView2Settings.get());
|
||||
}
|
||||
return settings->toEncodableMap();
|
||||
}
|
||||
|
||||
void InAppWebView::openDevTools() const
|
||||
{
|
||||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
|
||||
failedLog(webView->OpenDevToolsWindow());
|
||||
}
|
||||
|
||||
void InAppWebView::callDevToolsProtocolMethod(const std::string& methodName, const std::optional<std::string>& parametersAsJson, const std::function<void(const HRESULT& errorCode, const std::optional<std::string>&)> completionHandler) const
|
||||
{
|
||||
if (!webView) {
|
||||
if (completionHandler) {
|
||||
completionHandler(S_OK, std::nullopt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto hr = webView->CallDevToolsProtocolMethod(
|
||||
utf8_to_wide(methodName).c_str(),
|
||||
!parametersAsJson.has_value() || parametersAsJson.value().empty() ? L"{}" : utf8_to_wide(parametersAsJson.value()).c_str(),
|
||||
Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
|
||||
[completionHandler](HRESULT errorCode, LPCWSTR returnObjectAsJson)
|
||||
{
|
||||
failedLog(errorCode);
|
||||
if (completionHandler) {
|
||||
completionHandler(errorCode, wide_to_utf8(returnObjectAsJson));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
).Get());
|
||||
|
||||
if (failedAndLog(hr) && completionHandler) {
|
||||
completionHandler(hr, std::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
void InAppWebView::addDevToolsProtocolEventListener(const std::string& eventName)
|
||||
{
|
||||
if (map_contains(devToolsProtocolEventListener_, eventName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2DevToolsProtocolEventReceiver> eventReceiver;
|
||||
if (succeededOrLog(webView->GetDevToolsProtocolEventReceiver(utf8_to_wide(eventName).c_str(), &eventReceiver))) {
|
||||
EventRegistrationToken token = {};
|
||||
auto hr = eventReceiver->add_DevToolsProtocolEventReceived(
|
||||
Callback<ICoreWebView2DevToolsProtocolEventReceivedEventHandler>(
|
||||
[this, eventName](
|
||||
ICoreWebView2* sender,
|
||||
ICoreWebView2DevToolsProtocolEventReceivedEventArgs* args) -> HRESULT
|
||||
{
|
||||
if (!channelDelegate) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
wil::unique_cotaskmem_string json;
|
||||
failedLog(args->get_ParameterObjectAsJson(&json));
|
||||
channelDelegate->onDevToolsProtocolEventReceived(eventName, wide_to_utf8(json.get()));
|
||||
|
||||
return S_OK;
|
||||
})
|
||||
.Get(), &token);
|
||||
if (succeededOrLog(hr)) {
|
||||
devToolsProtocolEventListener_.insert({ eventName, std::make_pair(std::move(eventReceiver), token) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InAppWebView::removeDevToolsProtocolEventListener(const std::string& eventName)
|
||||
{
|
||||
if (map_contains(devToolsProtocolEventListener_, eventName)) {
|
||||
auto eventReceiver = devToolsProtocolEventListener_.at(eventName).first;
|
||||
auto token = devToolsProtocolEventListener_.at(eventName).second;
|
||||
eventReceiver->remove_DevToolsProtocolEventReceived(token);
|
||||
devToolsProtocolEventListener_.erase(eventName);
|
||||
}
|
||||
}
|
||||
|
||||
// flutter_view
|
||||
void InAppWebView::setSurfaceSize(size_t width, size_t height, float scale_factor)
|
||||
{
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace flutter_inappwebview_plugin
|
|||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController;
|
||||
wil::com_ptr<ICoreWebView2> webView;
|
||||
std::unique_ptr<WebViewChannelDelegate> channelDelegate;
|
||||
const std::shared_ptr<InAppWebViewSettings> settings;
|
||||
std::shared_ptr<InAppWebViewSettings> settings;
|
||||
InAppBrowser* inAppBrowser = nullptr;
|
||||
std::unique_ptr<UserContentController> userContentController;
|
||||
|
||||
|
@ -164,6 +164,12 @@ namespace flutter_inappwebview_plugin
|
|||
void removeUserScriptsByGroupName(const std::string& groupName) const;
|
||||
void removeAllUserScripts() const;
|
||||
void takeScreenshot(const std::optional<std::shared_ptr<ScreenshotConfiguration>> screenshotConfiguration, const std::function<void(const std::optional<std::string>)> completionHandler) const;
|
||||
void setSettings(const std::shared_ptr<InAppWebViewSettings> newSettings, const flutter::EncodableMap& newSettingsMap);
|
||||
flutter::EncodableValue getSettings() const;
|
||||
void openDevTools() const;
|
||||
void callDevToolsProtocolMethod(const std::string& methodName, const std::optional<std::string>& parametersAsJson, const std::function<void(const HRESULT& errorCode, const std::optional<std::string>&)> completionHandler) const;
|
||||
void addDevToolsProtocolEventListener(const std::string& eventName);
|
||||
void removeDevToolsProtocolEventListener(const std::string& eventName);
|
||||
|
||||
std::string pageFrameId() const
|
||||
{
|
||||
|
@ -185,6 +191,7 @@ namespace flutter_inappwebview_plugin
|
|||
std::shared_ptr<NavigationAction> lastNavigationAction_;
|
||||
bool isLoading_ = false;
|
||||
std::string pageFrameId_;
|
||||
std::map<std::string, std::pair<wil::com_ptr<ICoreWebView2DevToolsProtocolEventReceiver>, EventRegistrationToken>> devToolsProtocolEventListener_ = {};
|
||||
|
||||
void registerEventHandlers();
|
||||
void registerSurfaceEventHandlers();
|
||||
|
|
|
@ -2,8 +2,12 @@
|
|||
#include "../utils/log.h"
|
||||
#include "in_app_webview_settings.h"
|
||||
|
||||
#include <wil/com.h>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
InAppWebViewSettings::InAppWebViewSettings() {};
|
||||
|
||||
InAppWebViewSettings::InAppWebViewSettings(const flutter::EncodableMap& encodableMap)
|
||||
|
@ -16,6 +20,56 @@ namespace flutter_inappwebview_plugin
|
|||
resourceCustomSchemes = get_fl_map_value(encodableMap, "resourceCustomSchemes", resourceCustomSchemes);
|
||||
transparentBackground = get_fl_map_value(encodableMap, "transparentBackground", transparentBackground);
|
||||
supportZoom = get_fl_map_value(encodableMap, "supportZoom", supportZoom);
|
||||
isInspectable = get_fl_map_value(encodableMap, "isInspectable", isInspectable);
|
||||
disableContextMenu = get_fl_map_value(encodableMap, "disableContextMenu", disableContextMenu);
|
||||
}
|
||||
|
||||
flutter::EncodableMap InAppWebViewSettings::toEncodableMap() const
|
||||
{
|
||||
return flutter::EncodableMap{
|
||||
{"useShouldOverrideUrlLoading", useShouldOverrideUrlLoading},
|
||||
{"useOnLoadResource", useOnLoadResource},
|
||||
{"useOnDownloadStart", useOnDownloadStart},
|
||||
{"userAgent", userAgent},
|
||||
{"javaScriptEnabled", javaScriptEnabled},
|
||||
{"resourceCustomSchemes", make_fl_value(resourceCustomSchemes)},
|
||||
{"transparentBackground", transparentBackground},
|
||||
{"supportZoom", supportZoom},
|
||||
{"isInspectable", isInspectable},
|
||||
{"disableContextMenu", disableContextMenu},
|
||||
};
|
||||
}
|
||||
|
||||
flutter::EncodableMap InAppWebViewSettings::getRealSettings(ICoreWebView2Settings* settings) const
|
||||
{
|
||||
auto settingsMap = toEncodableMap();
|
||||
if (settings) {
|
||||
BOOL realJavaScriptEnabled;
|
||||
if (SUCCEEDED(settings->get_IsScriptEnabled(&realJavaScriptEnabled))) {
|
||||
settingsMap["javaScriptEnabled"] = (bool)realJavaScriptEnabled;
|
||||
}
|
||||
BOOL realSupportZoom;
|
||||
if (SUCCEEDED(settings->get_IsZoomControlEnabled(&realSupportZoom))) {
|
||||
settingsMap["supportZoom"] = (bool)realSupportZoom;
|
||||
}
|
||||
BOOL realIsInspectable;
|
||||
if (SUCCEEDED(settings->get_AreDevToolsEnabled(&realIsInspectable))) {
|
||||
settingsMap["isInspectable"] = (bool)realIsInspectable;
|
||||
}
|
||||
BOOL areDefaultContextMenusEnabled;
|
||||
if (SUCCEEDED(settings->get_AreDefaultContextMenusEnabled(&areDefaultContextMenusEnabled))) {
|
||||
settingsMap["disableContextMenu"] = !(bool)areDefaultContextMenusEnabled;
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Settings2> settings2;
|
||||
if (SUCCEEDED(settings->QueryInterface(IID_PPV_ARGS(&settings2)))) {
|
||||
wil::unique_cotaskmem_string realUserAgent;
|
||||
if (SUCCEEDED(settings2->get_UserAgent(&realUserAgent))) {
|
||||
settingsMap["userAgent"] = wide_to_utf8(realUserAgent.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return settingsMap;
|
||||
}
|
||||
|
||||
InAppWebViewSettings::~InAppWebViewSettings()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <flutter/standard_message_codec.h>
|
||||
#include <string>
|
||||
#include <WebView2.h>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
|
@ -17,10 +18,15 @@ namespace flutter_inappwebview_plugin
|
|||
std::vector<std::string> resourceCustomSchemes;
|
||||
bool transparentBackground = false;
|
||||
bool supportZoom = true;
|
||||
bool isInspectable = true;
|
||||
bool disableContextMenu = false;
|
||||
|
||||
InAppWebViewSettings();
|
||||
InAppWebViewSettings(const flutter::EncodableMap& encodableMap);
|
||||
~InAppWebViewSettings();
|
||||
|
||||
flutter::EncodableMap toEncodableMap() const;
|
||||
flutter::EncodableMap getRealSettings(ICoreWebView2Settings* settings) const;
|
||||
};
|
||||
}
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_WEBVIEW_SETTINGS_H_
|
|
@ -169,6 +169,55 @@ namespace flutter_inappwebview_plugin
|
|||
result_->Success(make_fl_value(data));
|
||||
});
|
||||
}
|
||||
else if (string_equals(methodName, "setSettings")) {
|
||||
if (webView->inAppBrowser) {
|
||||
auto settingsMap = get_fl_map_value<flutter::EncodableMap>(arguments, "settings");
|
||||
auto settings = std::make_unique<InAppBrowserSettings>(settingsMap);
|
||||
webView->inAppBrowser->setSettings(std::move(settings), settingsMap);
|
||||
}
|
||||
else {
|
||||
auto settingsMap = get_fl_map_value<flutter::EncodableMap>(arguments, "settings");
|
||||
auto settings = std::make_unique<InAppWebViewSettings>(settingsMap);
|
||||
webView->setSettings(std::move(settings), settingsMap);
|
||||
}
|
||||
result->Success(true);
|
||||
}
|
||||
else if (string_equals(methodName, "getSettings")) {
|
||||
if (webView->inAppBrowser) {
|
||||
result->Success(webView->inAppBrowser->getSettings());
|
||||
}
|
||||
else {
|
||||
result->Success(webView->getSettings());
|
||||
}
|
||||
}
|
||||
else if (string_equals(methodName, "openDevTools")) {
|
||||
webView->openDevTools();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (string_equals(methodName, "callDevToolsProtocolMethod")) {
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
auto cdpMethodName = get_fl_map_value<std::string>(arguments, "methodName");
|
||||
auto parametersAsJson = get_optional_fl_map_value<std::string>(arguments, "parametersAsJson");
|
||||
webView->callDevToolsProtocolMethod(cdpMethodName, parametersAsJson, [result_ = std::move(result_)](const HRESULT& errorCode, const std::optional<std::string>& data)
|
||||
{
|
||||
if (SUCCEEDED(errorCode)) {
|
||||
result_->Success(make_fl_value(data));
|
||||
}
|
||||
else {
|
||||
result_->Error(std::to_string(errorCode), getHRMessage(errorCode));
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (string_equals(methodName, "addDevToolsProtocolEventListener")) {
|
||||
auto eventName = get_fl_map_value<std::string>(arguments, "eventName");
|
||||
webView->addDevToolsProtocolEventListener(eventName);
|
||||
result->Success(true);
|
||||
}
|
||||
else if (string_equals(methodName, "removeDevToolsProtocolEventListener")) {
|
||||
auto eventName = get_fl_map_value<std::string>(arguments, "eventName");
|
||||
webView->removeDevToolsProtocolEventListener(eventName);
|
||||
result->Success(true);
|
||||
}
|
||||
// for inAppBrowser
|
||||
else if (webView->inAppBrowser && string_equals(methodName, "show")) {
|
||||
webView->inAppBrowser->show();
|
||||
|
@ -302,6 +351,20 @@ namespace flutter_inappwebview_plugin
|
|||
channel->InvokeMethod("onConsoleMessage", std::move(arguments));
|
||||
}
|
||||
|
||||
|
||||
void WebViewChannelDelegate::onDevToolsProtocolEventReceived(const std::string& eventName, const std::string& data) const
|
||||
{
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
|
||||
{"eventName", eventName},
|
||||
{"data", data}
|
||||
});
|
||||
channel->InvokeMethod("onDevToolsProtocolEventReceived", std::move(arguments));
|
||||
}
|
||||
|
||||
WebViewChannelDelegate::~WebViewChannelDelegate()
|
||||
{
|
||||
debugLog("dealloc WebViewChannelDelegate");
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace flutter_inappwebview_plugin
|
|||
void onUpdateVisitedHistory(const std::optional<std::string>& url, const std::optional<bool>& isReload) const;
|
||||
void onCallJsHandler(const std::string& handlerName, const std::string& args, std::unique_ptr<CallJsHandlerCallback> callback) const;
|
||||
void onConsoleMessage(const std::string& message, const int64_t& messageLevel) const;
|
||||
void onDevToolsProtocolEventReceived(const std::string& eventName, const std::string& data) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,15 @@ namespace flutter_inappwebview_plugin
|
|||
Rect(const flutter::EncodableMap& map);
|
||||
~Rect() = default;
|
||||
|
||||
bool Rect::operator==(const Rect& other)
|
||||
{
|
||||
return x == other.x && y == other.y && width == other.width && height == other.height;
|
||||
}
|
||||
bool Rect::operator!=(const Rect& other)
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
flutter::EncodableMap toEncodableMap() const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,6 +18,15 @@ namespace flutter_inappwebview_plugin
|
|||
Size2D(const flutter::EncodableMap& map);
|
||||
~Size2D() = default;
|
||||
|
||||
bool Size2D::operator==(const Size2D& other)
|
||||
{
|
||||
return width == other.width && height == other.height;
|
||||
}
|
||||
bool Size2D::operator!=(const Size2D& other)
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
flutter::EncodableMap toEncodableMap() const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
|
@ -26,6 +27,12 @@ namespace flutter_inappwebview_plugin
|
|||
static_assert(always_false_v<T>, "non-exhaustive visitor!");
|
||||
}, var);
|
||||
}
|
||||
|
||||
static inline float get_current_scale_factor(HWND hwnd)
|
||||
{
|
||||
auto dpi = GetDpiForWindow(hwnd);
|
||||
return dpi > 0 ? dpi / 96.0f : 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_
|
Loading…
Reference in New Issue