use super::*;
use windows_core::implement_decl;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum ScrollBarStyle {
#[default]
Default,
FluentOverlay,
}
impl ScrollBarStyle {
fn to_raw(self) -> COREWEBVIEW2_SCROLLBAR_STYLE {
match self {
Self::Default => 0,
Self::FluentOverlay => 1,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct EnvironmentOptions {
browser_executable_folder: Option<String>,
user_data_folder: Option<String>,
additional_browser_arguments: Option<String>,
language: Option<String>,
target_compatible_browser_version: Option<String>,
allow_single_sign_on_using_os_primary_account: bool,
are_browser_extensions_enabled: bool,
scrollbar_style: ScrollBarStyle,
}
impl EnvironmentOptions {
pub fn new() -> Self {
Self::default()
}
pub fn browser_executable_folder(mut self, value: impl Into<String>) -> Self {
self.browser_executable_folder = Some(value.into());
self
}
pub fn user_data_folder(mut self, value: impl Into<String>) -> Self {
self.user_data_folder = Some(value.into());
self
}
pub fn additional_browser_arguments(mut self, value: impl Into<String>) -> Self {
self.additional_browser_arguments = Some(value.into());
self
}
pub fn language(mut self, value: impl Into<String>) -> Self {
self.language = Some(value.into());
self
}
pub fn target_compatible_browser_version(mut self, value: impl Into<String>) -> Self {
self.target_compatible_browser_version = Some(value.into());
self
}
pub fn allow_single_sign_on_using_os_primary_account(mut self, value: bool) -> Self {
self.allow_single_sign_on_using_os_primary_account = value;
self
}
pub fn are_browser_extensions_enabled(mut self, value: bool) -> Self {
self.are_browser_extensions_enabled = value;
self
}
pub fn scrollbar_style(mut self, value: ScrollBarStyle) -> Self {
self.scrollbar_style = value;
self
}
pub(crate) fn create_environment<F: FnOnce(Result<Environment>) + 'static>(
&self,
handler: F,
) -> Result<()> {
let handler = handler::EnvironmentCompleted::create(handler);
let options: ICoreWebView2EnvironmentOptions = OptionsObject::new(self).into();
let browser = self.browser_executable_folder.as_deref().map(HSTRING::from);
let user_data = self.user_data_folder.as_deref().map(HSTRING::from);
let browser = browser
.as_ref()
.map_or(PCWSTR::null(), |value| PCWSTR::from_raw(value.as_ptr()));
let user_data = user_data
.as_ref()
.map_or(PCWSTR::null(), |value| PCWSTR::from_raw(value.as_ptr()));
unsafe {
CreateCoreWebView2EnvironmentWithOptions(
browser,
user_data,
Interface::as_raw(&options),
Interface::as_raw(&handler),
)
.ok()
}
}
}
pub(crate) struct OptionsObject {
additional_browser_arguments: String,
language: String,
target_compatible_browser_version: String,
allow_single_sign_on_using_os_primary_account: BOOL,
are_browser_extensions_enabled: BOOL,
scrollbar_style: COREWEBVIEW2_SCROLLBAR_STYLE,
}
implement_decl! {
impl OptionsObject as pub(crate) OptionsObject_Impl:
[ICoreWebView2EnvironmentOptions, ICoreWebView2EnvironmentOptions6, ICoreWebView2EnvironmentOptions8]
}
const DEFAULT_TARGET_COMPATIBLE_BROWSER_VERSION: &str = "86.0.616.0";
impl OptionsObject {
fn new(options: &EnvironmentOptions) -> Self {
Self {
additional_browser_arguments: options
.additional_browser_arguments
.clone()
.unwrap_or_default(),
language: options.language.clone().unwrap_or_default(),
target_compatible_browser_version: options
.target_compatible_browser_version
.clone()
.unwrap_or_else(|| DEFAULT_TARGET_COMPATIBLE_BROWSER_VERSION.to_string()),
allow_single_sign_on_using_os_primary_account: options
.allow_single_sign_on_using_os_primary_account
.into(),
are_browser_extensions_enabled: options.are_browser_extensions_enabled.into(),
scrollbar_style: options.scrollbar_style.to_raw(),
}
}
}
impl ICoreWebView2EnvironmentOptions_Impl for OptionsObject_Impl {
fn AdditionalBrowserArguments(&self) -> Result<LPWSTR> {
unsafe { string::allocate(&self.additional_browser_arguments) }
}
fn SetAdditionalBrowserArguments(&self, _value: &PCWSTR) -> Result<()> {
Ok(())
}
fn Language(&self) -> Result<LPWSTR> {
unsafe { string::allocate(&self.language) }
}
fn SetLanguage(&self, _value: &PCWSTR) -> Result<()> {
Ok(())
}
fn TargetCompatibleBrowserVersion(&self) -> Result<LPWSTR> {
unsafe { string::allocate(&self.target_compatible_browser_version) }
}
fn SetTargetCompatibleBrowserVersion(&self, _value: &PCWSTR) -> Result<()> {
Ok(())
}
fn AllowSingleSignOnUsingOSPrimaryAccount(&self) -> Result<BOOL> {
Ok(self.allow_single_sign_on_using_os_primary_account)
}
fn SetAllowSingleSignOnUsingOSPrimaryAccount(&self, _allow: BOOL) -> Result<()> {
Ok(())
}
}
impl ICoreWebView2EnvironmentOptions6_Impl for OptionsObject_Impl {
fn AreBrowserExtensionsEnabled(&self) -> Result<BOOL> {
Ok(self.are_browser_extensions_enabled)
}
fn SetAreBrowserExtensionsEnabled(&self, _value: BOOL) -> Result<()> {
Ok(())
}
}
impl ICoreWebView2EnvironmentOptions8_Impl for OptionsObject_Impl {
fn ScrollBarStyle(&self) -> Result<COREWEBVIEW2_SCROLLBAR_STYLE> {
Ok(self.scrollbar_style)
}
fn SetScrollBarStyle(&self, _value: COREWEBVIEW2_SCROLLBAR_STYLE) -> Result<()> {
Ok(())
}
}