add: preload scripts (#6)
This commit is contained in:
@@ -8,10 +8,11 @@ use bevy::platform::collections::HashMap;
|
||||
use bevy::prelude::*;
|
||||
use bevy_remote::BrpMessage;
|
||||
use cef::{
|
||||
Browser, BrowserHost, BrowserSettings, Client, CompositionUnderline, ImplBrowser,
|
||||
ImplBrowserHost, ImplFrame, ImplListValue, ImplProcessMessage, ImplRequestContext,
|
||||
MouseButtonType, ProcessId, Range, RequestContext, RequestContextSettings, WindowInfo,
|
||||
browser_host_create_browser_sync, process_message_create,
|
||||
Browser, BrowserHost, BrowserSettings, CefString, Client, CompositionUnderline,
|
||||
DictionaryValue, ImplBrowser, ImplBrowserHost, ImplDictionaryValue, ImplFrame, ImplListValue,
|
||||
ImplProcessMessage, ImplRequestContext, MouseButtonType, ProcessId, Range, RequestContext,
|
||||
RequestContextSettings, WindowInfo, browser_host_create_browser_sync, dictionary_value_create,
|
||||
process_message_create,
|
||||
};
|
||||
use cef_dll_sys::{cef_event_flags_t, cef_mouse_button_type_t};
|
||||
#[allow(deprecated)]
|
||||
@@ -62,6 +63,7 @@ impl Browsers {
|
||||
ipc_event_sender: Sender<IpcEventRaw>,
|
||||
brp_sender: Sender<BrpMessage>,
|
||||
system_cursor_icon_sender: SystemCursorIconSenderInner,
|
||||
initialize_scripts: &[String],
|
||||
_window_handle: Option<RawWindowHandle>,
|
||||
) {
|
||||
let mut context = Self::request_context(requester);
|
||||
@@ -93,10 +95,11 @@ impl Browsers {
|
||||
windowless_frame_rate: 60,
|
||||
..Default::default()
|
||||
}),
|
||||
None,
|
||||
Self::create_extra_info(initialize_scripts).as_mut(),
|
||||
context.as_mut(),
|
||||
)
|
||||
.expect("Failed to create browser");
|
||||
|
||||
self.browsers.insert(
|
||||
webview,
|
||||
WebviewBrowser {
|
||||
@@ -415,6 +418,18 @@ impl Browsers {
|
||||
.get(webview)
|
||||
.and_then(|b| b.client.focused_frame().is_some().then_some(b))
|
||||
}
|
||||
|
||||
fn create_extra_info(scripts: &[String]) -> Option<DictionaryValue> {
|
||||
if scripts.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let extra = dictionary_value_create()?;
|
||||
extra.set_string(
|
||||
Some(&CefString::from(INIT_SCRIPT_KEY)),
|
||||
Some(&CefString::from(scripts.join(";").as_str())),
|
||||
);
|
||||
Some(extra)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modifiers_from_mouse_buttons<'a>(buttons: impl IntoIterator<Item = &'a MouseButton>) -> u32 {
|
||||
|
||||
@@ -8,9 +8,10 @@ use bevy::platform::collections::HashMap;
|
||||
use bevy_remote::BrpResult;
|
||||
use cef::rc::{Rc, RcImpl};
|
||||
use cef::{
|
||||
Browser, Frame, ImplFrame, ImplListValue, ImplProcessMessage, ImplRenderProcessHandler,
|
||||
ImplV8Context, ImplV8Value, ProcessId, ProcessMessage, V8Context, V8Propertyattribute, V8Value,
|
||||
WrapRenderProcessHandler, sys, v8_value_create_function, v8_value_create_object,
|
||||
Browser, CefString, DictionaryValue, Frame, ImplBrowser, ImplDictionaryValue, ImplFrame,
|
||||
ImplListValue, ImplProcessMessage, ImplRenderProcessHandler, ImplV8Context, ImplV8Value,
|
||||
ProcessId, ProcessMessage, V8Context, V8Propertyattribute, V8Value, WrapRenderProcessHandler,
|
||||
sys, v8_value_create_function, v8_value_create_object,
|
||||
};
|
||||
use std::os::raw::c_int;
|
||||
use std::sync::Mutex;
|
||||
@@ -18,6 +19,9 @@ use std::sync::Mutex;
|
||||
pub(crate) static BRP_PROMISES: Mutex<HashMap<String, V8Value>> = Mutex::new(HashMap::new());
|
||||
pub(crate) static LISTEN_EVENTS: Mutex<HashMap<String, V8Value>> = Mutex::new(HashMap::new());
|
||||
|
||||
static INIT_SCRIPTS: Mutex<HashMap<c_int, String>> = Mutex::new(HashMap::new());
|
||||
pub const INIT_SCRIPT_KEY: &str = "init_script";
|
||||
|
||||
pub const PROCESS_MESSAGE_BRP: &str = "brp";
|
||||
pub const PROCESS_MESSAGE_HOST_EMIT: &str = "host-emit";
|
||||
pub const PROCESS_MESSAGE_JS_EMIT: &str = "js-emit";
|
||||
@@ -61,52 +65,34 @@ impl Clone for RenderProcessHandlerBuilder {
|
||||
}
|
||||
|
||||
impl ImplRenderProcessHandler for RenderProcessHandlerBuilder {
|
||||
fn on_browser_created(
|
||||
&self,
|
||||
browser: Option<&mut Browser>,
|
||||
extra: Option<&mut DictionaryValue>,
|
||||
) {
|
||||
if let (Some(browser), Some(extra)) = (browser, extra) {
|
||||
let script = extra.string(Some(&INIT_SCRIPT_KEY.into())).into_string();
|
||||
if script.is_empty() {
|
||||
return;
|
||||
}
|
||||
let id = browser.identifier();
|
||||
INIT_SCRIPTS.lock().unwrap().insert(id, script);
|
||||
}
|
||||
}
|
||||
|
||||
fn on_context_created(
|
||||
&self,
|
||||
_browser: Option<&mut Browser>,
|
||||
browser: Option<&mut Browser>,
|
||||
frame: Option<&mut Frame>,
|
||||
context: Option<&mut V8Context>,
|
||||
) {
|
||||
if let Some(g) = context.and_then(|c| c.global())
|
||||
if let Some(context) = context
|
||||
&& let Some(frame) = frame
|
||||
&& let Some(mut cef) = v8_value_create_object(
|
||||
Some(&mut V8DefaultAccessorBuilder::build()),
|
||||
Some(&mut V8DefaultInterceptorBuilder::build()),
|
||||
)
|
||||
&& let Some(mut brp) = v8_value_create_function(
|
||||
Some(&"brp".into()),
|
||||
Some(&mut BrpBuilder::build(frame.clone())),
|
||||
)
|
||||
&& let Some(mut emit) = v8_value_create_function(
|
||||
Some(&"emit".into()),
|
||||
Some(&mut EmitBuilder::build(frame.clone())),
|
||||
)
|
||||
&& let Some(mut listen) = v8_value_create_function(
|
||||
Some(&"listen".into()),
|
||||
Some(&mut ListenBuilder::build(frame.clone())),
|
||||
)
|
||||
&& let Some(browser) = browser
|
||||
{
|
||||
cef.set_value_bykey(
|
||||
Some(&"brp".into()),
|
||||
Some(&mut brp),
|
||||
V8Propertyattribute::default(),
|
||||
);
|
||||
cef.set_value_bykey(
|
||||
Some(&"emit".into()),
|
||||
Some(&mut emit),
|
||||
V8Propertyattribute::default(),
|
||||
);
|
||||
cef.set_value_bykey(
|
||||
Some(&"listen".into()),
|
||||
Some(&mut listen),
|
||||
V8Propertyattribute::default(),
|
||||
);
|
||||
g.set_value_bykey(
|
||||
Some(&"cef".into()),
|
||||
Some(&mut cef),
|
||||
V8Propertyattribute::default(),
|
||||
);
|
||||
};
|
||||
inject_initialize_scripts(browser, context, frame);
|
||||
inject_cef_api(context, frame);
|
||||
}
|
||||
}
|
||||
|
||||
fn on_process_message_received(
|
||||
@@ -139,6 +125,60 @@ impl ImplRenderProcessHandler for RenderProcessHandlerBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_initialize_scripts(browser: &mut Browser, context: &mut V8Context, frame: &mut Frame) {
|
||||
let id = browser.identifier();
|
||||
if let Some(script) = INIT_SCRIPTS.lock().ok().and_then(|scripts| {
|
||||
let script = scripts.get(&id)?;
|
||||
Some(CefString::from(script.as_str()))
|
||||
}) {
|
||||
context.enter();
|
||||
frame.execute_java_script(Some(&script), Some(&(&frame.url()).into()), 0);
|
||||
context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_cef_api(context: &mut V8Context, frame: &mut Frame) {
|
||||
if let Some(g) = context.global()
|
||||
&& let Some(mut cef) = v8_value_create_object(
|
||||
Some(&mut V8DefaultAccessorBuilder::build()),
|
||||
Some(&mut V8DefaultInterceptorBuilder::build()),
|
||||
)
|
||||
&& let Some(mut brp) = v8_value_create_function(
|
||||
Some(&"brp".into()),
|
||||
Some(&mut BrpBuilder::build(frame.clone())),
|
||||
)
|
||||
&& let Some(mut emit) = v8_value_create_function(
|
||||
Some(&"emit".into()),
|
||||
Some(&mut EmitBuilder::build(frame.clone())),
|
||||
)
|
||||
&& let Some(mut listen) = v8_value_create_function(
|
||||
Some(&"listen".into()),
|
||||
Some(&mut ListenBuilder::build(frame.clone())),
|
||||
)
|
||||
{
|
||||
cef.set_value_bykey(
|
||||
Some(&"brp".into()),
|
||||
Some(&mut brp),
|
||||
V8Propertyattribute::default(),
|
||||
);
|
||||
cef.set_value_bykey(
|
||||
Some(&"emit".into()),
|
||||
Some(&mut emit),
|
||||
V8Propertyattribute::default(),
|
||||
);
|
||||
cef.set_value_bykey(
|
||||
Some(&"listen".into()),
|
||||
Some(&mut listen),
|
||||
V8Propertyattribute::default(),
|
||||
);
|
||||
g.set_value_bykey(
|
||||
Some(&"cef".into()),
|
||||
Some(&mut cef),
|
||||
V8Propertyattribute::default(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_brp_message(message: &ProcessMessage, ctx: V8Context) {
|
||||
let Some(argument_list) = message.argument_list() else {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user