dioxus-web: Add Config::rootelement

This commit is contained in:
Jan-Mirko Otter committed 2024-01-19 23:35:18 +01:00
1 parent 7a6c8fc9e9
commit baf505e330
2 files changed
+44 -17

No files matched your search

+18 -3
View File
@@ -10,7 +10,7 @@
pub struct Config { pub struct Config {
#[cfg(feature = "hydrate")] #[cfg(feature = "hydrate")]
pub(crate) hydrate: bool, pub(crate) hydrate: bool,
pub(crate) rootname: String, pub(crate) root: ConfigRoot,
pub(crate) cached_strings: Vec<String>, pub(crate) cached_strings: Vec<String>,
pub(crate) default_panic_hook: bool, pub(crate) default_panic_hook: bool,
} }
@@ -20,7 +20,7 @@ impl Default for Config {
Self { Self {
#[cfg(feature = "hydrate")] #[cfg(feature = "hydrate")]
hydrate: false, hydrate: false,
rootname: "main".to_string(), root: ConfigRoot::RootName("main".to_string()),
cached_strings: Vec::new(), cached_strings: Vec::new(),
default_panic_hook: true, default_panic_hook: true,
} }
@@ -50,8 +50,18 @@ impl Config {
/// Set the name of the element that Dioxus will use as the root. /// Set the name of the element that Dioxus will use as the root.
/// ///
/// This is akin to calling React.render() on the element with the specified name. /// This is akin to calling React.render() on the element with the specified name.
/// Note that this only works on the current document, i.e. `window.document`.
/// To use a different document (popup, iframe, ...) use [Self::rootelement] instead.
pub fn rootname(mut self, name: impl Into<String>) -> Self { pub fn rootname(mut self, name: impl Into<String>) -> Self {
self.rootname = name.into(); self.root = ConfigRoot::RootName(name.into());
self
}
/// Set the element that Dioxus will use as root.
///
/// This is akin to calling React.render() on the given element.
pub fn rootelement(mut self, elem: web_sys::Element) -> Self {
self.root = ConfigRoot::RootElement(elem);
self self
} }
@@ -72,3 +82,8 @@ impl Config {
self self
} }
} }
pub(crate) enum ConfigRoot {
RootName(String),
RootElement(web_sys::Element),
}
+26 -14
View File
@@ -37,24 +37,36 @@ pub struct UiEvent {
pub data: PlatformEventData, pub data: PlatformEventData,
} }
//fn get_document(elem: &web_sys::Element) ->
impl WebsysDom { impl WebsysDom {
pub fn new(cfg: Config, event_channel: mpsc::UnboundedSender<UiEvent>) -> Self { pub fn new(cfg: Config, event_channel: mpsc::UnboundedSender<UiEvent>) -> Self {
// eventually, we just want to let the interpreter do all the work of decoding events into our event type let (document, root) = match cfg.root {
// a match here in order to avoid some error during runtime browser test crate::cfg::ConfigRoot::RootName(rootname) => {
let document = load_document(); // eventually, we just want to let the interpreter do all the work of decoding events into our event type
let root = match document.get_element_by_id(&cfg.rootname) { // a match here in order to avoid some error during runtime browser test
Some(root) => root, let document = load_document();
None => { let root = match document.get_element_by_id(&rootname) {
web_sys::console::error_1( Some(root) => root,
&format!( None => {
"element '#{}' not found. mounting to the body.", web_sys::console::error_1(
cfg.rootname &format!("element '#{}' not found. mounting to the body.", rootname)
) .into(),
.into(), );
); document.create_element("body").ok().unwrap()
document.create_element("body").ok().unwrap() }
};
(document, root)
}
crate::cfg::ConfigRoot::RootElement(root) => {
let document = match root.owner_document() {
Some(document) => document,
None => load_document(),
};
(document, root)
} }
}; };
let interpreter = Channel::default(); let interpreter = Channel::default();
let handler: Closure<dyn FnMut(&Event)> = Closure::wrap(Box::new({ let handler: Closure<dyn FnMut(&Event)> = Closure::wrap(Box::new({