Fix nested rsx expansion by not using template titles (#2799)
* Fix nested rsx expansion by not using template titles * fix writers with nameless templates * fix clippy * dont commit vscode fix * fix release mode, pull out __template_name * fix axum_desktop * Fix core tests * Make most fields of HotReloadedTemplate public for testing * wip: formatting, compare all diff cases * slightly smarter diffing for dynamic nodes * add a comment about generic node diffing * clean up mutations a bit * fix load template * simplify maybe_rebuild * Restore write mutations flag in web * write_mutations -> skip_mutations --------- Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
This commit is contained in:
1 parent
a2180b92e9
commit
0de3bf7aeb
40 files changed
+597
-1038
No files matched your search
@@ -6,7 +6,7 @@
|
||||
//! - tests to ensure dyn_into works for various event types.
|
||||
//! - Partial delegation?
|
||||
|
||||
use dioxus_core::ElementId;
|
||||
use dioxus_core::{ElementId, Template};
|
||||
use dioxus_html::PlatformEventData;
|
||||
use dioxus_interpreter_js::unified_bindings::Interpreter;
|
||||
use futures_channel::mpsc;
|
||||
@@ -20,8 +20,7 @@ pub struct WebsysDom {
|
||||
#[allow(dead_code)]
|
||||
pub(crate) root: Element,
|
||||
pub(crate) document: Document,
|
||||
pub(crate) templates: FxHashMap<String, u16>,
|
||||
pub(crate) max_template_id: u16,
|
||||
pub(crate) templates: FxHashMap<Template, u16>,
|
||||
pub(crate) interpreter: Interpreter,
|
||||
|
||||
#[cfg(feature = "mounted")]
|
||||
@@ -41,10 +40,10 @@ pub struct WebsysDom {
|
||||
// Instead we now store a flag to see if we should be writing templates at all if hydration is enabled.
|
||||
// This has a small overhead, but it avoids dynamic dispatch and reduces the binary size
|
||||
//
|
||||
// NOTE: running the virtual dom with the `only_write_templates` flag set to true is different from running
|
||||
// NOTE: running the virtual dom with the `write_mutations` flag set to true is different from running
|
||||
// it with no mutation writer because it still assigns ids to nodes, but it doesn't write them to the dom
|
||||
#[cfg(feature = "hydrate")]
|
||||
pub(crate) only_write_templates: bool,
|
||||
pub(crate) skip_mutations: bool,
|
||||
|
||||
#[cfg(feature = "hydrate")]
|
||||
pub(crate) suspense_hydration_ids: crate::hydration::SuspenseHydrationIds,
|
||||
@@ -145,13 +144,12 @@ impl WebsysDom {
|
||||
root,
|
||||
interpreter,
|
||||
templates: FxHashMap::default(),
|
||||
max_template_id: 0,
|
||||
#[cfg(feature = "mounted")]
|
||||
event_channel,
|
||||
#[cfg(feature = "mounted")]
|
||||
queued_mounted_events: Default::default(),
|
||||
#[cfg(feature = "hydrate")]
|
||||
only_write_templates: false,
|
||||
skip_mutations: false,
|
||||
#[cfg(feature = "hydrate")]
|
||||
suspense_hydration_ids: Default::default(),
|
||||
}
|
||||
|
||||
@@ -151,11 +151,11 @@ impl WebsysDom {
|
||||
self,
|
||||
|to| {
|
||||
// Switch to only writing templates
|
||||
to.only_write_templates = true;
|
||||
to.skip_mutations = true;
|
||||
},
|
||||
children.len(),
|
||||
);
|
||||
self.only_write_templates = false;
|
||||
self.skip_mutations = false;
|
||||
});
|
||||
|
||||
// Flush the mutations that will swap the placeholder nodes with the resolved nodes
|
||||
|
||||
@@ -25,6 +25,7 @@ use std::{panic, rc::Rc};
|
||||
pub use crate::cfg::Config;
|
||||
use crate::hydration::SuspenseMessage;
|
||||
use dioxus_core::VirtualDom;
|
||||
use dom::WebsysDom;
|
||||
use futures_util::{pin_mut, select, FutureExt, StreamExt};
|
||||
|
||||
mod cfg;
|
||||
@@ -77,7 +78,7 @@ pub async fn run(virtual_dom: VirtualDom, web_config: Config) -> ! {
|
||||
|
||||
let should_hydrate = web_config.hydrate;
|
||||
|
||||
let mut websys_dom = dom::WebsysDom::new(web_config, tx);
|
||||
let mut websys_dom = WebsysDom::new(web_config, tx);
|
||||
|
||||
let mut hydration_receiver: Option<futures_channel::mpsc::UnboundedReceiver<SuspenseMessage>> =
|
||||
None;
|
||||
@@ -85,7 +86,7 @@ pub async fn run(virtual_dom: VirtualDom, web_config: Config) -> ! {
|
||||
if should_hydrate {
|
||||
#[cfg(feature = "hydrate")]
|
||||
{
|
||||
websys_dom.only_write_templates = true;
|
||||
websys_dom.skip_mutations = true;
|
||||
// Get the initial hydration data from the client
|
||||
#[wasm_bindgen::prelude::wasm_bindgen(inline_js = r#"
|
||||
export function get_initial_hydration_data() {
|
||||
@@ -105,7 +106,7 @@ pub async fn run(virtual_dom: VirtualDom, web_config: Config) -> ! {
|
||||
with_server_data(server_data, || {
|
||||
dom.rebuild(&mut websys_dom);
|
||||
});
|
||||
websys_dom.only_write_templates = false;
|
||||
websys_dom.skip_mutations = false;
|
||||
|
||||
let rx = websys_dom.rehydrate(&dom).unwrap();
|
||||
hydration_receiver = Some(rx);
|
||||
|
||||
@@ -79,10 +79,10 @@ impl WebsysDom {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn only_write_templates(&self) -> bool {
|
||||
fn skip_mutations(&self) -> bool {
|
||||
#[cfg(feature = "hydrate")]
|
||||
{
|
||||
self.only_write_templates
|
||||
self.skip_mutations
|
||||
}
|
||||
#[cfg(not(feature = "hydrate"))]
|
||||
{
|
||||
@@ -92,28 +92,15 @@ impl WebsysDom {
|
||||
}
|
||||
|
||||
impl WriteMutations for WebsysDom {
|
||||
fn register_template(&mut self, template: Template) {
|
||||
let mut roots = vec![];
|
||||
for root in template.roots {
|
||||
roots.push(self.create_template_node(root))
|
||||
}
|
||||
self.templates
|
||||
.insert(template.name.to_owned(), self.max_template_id);
|
||||
self.interpreter
|
||||
.base()
|
||||
.save_template(roots, self.max_template_id);
|
||||
self.max_template_id += 1
|
||||
}
|
||||
|
||||
fn append_children(&mut self, id: ElementId, m: usize) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter.append_children(id.0 as u32, m as u16)
|
||||
}
|
||||
|
||||
fn assign_node_id(&mut self, path: &'static [u8], id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter
|
||||
@@ -121,46 +108,47 @@ impl WriteMutations for WebsysDom {
|
||||
}
|
||||
|
||||
fn create_placeholder(&mut self, id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter.create_placeholder(id.0 as u32)
|
||||
}
|
||||
|
||||
fn create_text_node(&mut self, value: &str, id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter.create_text_node(value, id.0 as u32)
|
||||
}
|
||||
|
||||
fn hydrate_text_node(&mut self, path: &'static [u8], value: &str, id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
fn load_template(&mut self, template: Template, index: usize, id: ElementId) {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter
|
||||
.hydrate_text(path.as_ptr() as u32, path.len() as u8, value, id.0 as u32)
|
||||
}
|
||||
let tmpl_id = self.templates.get(&template).cloned().unwrap_or_else(|| {
|
||||
let mut roots = vec![];
|
||||
for root in template.roots {
|
||||
roots.push(self.create_template_node(root))
|
||||
}
|
||||
let id = self.templates.len() as u16;
|
||||
self.templates.insert(template, id);
|
||||
self.interpreter.base().save_template(roots, id);
|
||||
id
|
||||
});
|
||||
|
||||
fn load_template(&mut self, name: &'static str, index: usize, id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
return;
|
||||
}
|
||||
if let Some(tmpl_id) = self.templates.get(name) {
|
||||
self.interpreter
|
||||
.load_template(*tmpl_id, index as u16, id.0 as u32)
|
||||
}
|
||||
self.interpreter
|
||||
.load_template(tmpl_id, index as u16, id.0 as u32)
|
||||
}
|
||||
|
||||
fn replace_node_with(&mut self, id: ElementId, m: usize) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter.replace_with(id.0 as u32, m as u16)
|
||||
}
|
||||
|
||||
fn replace_placeholder_with_nodes(&mut self, path: &'static [u8], m: usize) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter
|
||||
@@ -168,14 +156,14 @@ impl WriteMutations for WebsysDom {
|
||||
}
|
||||
|
||||
fn insert_nodes_after(&mut self, id: ElementId, m: usize) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter.insert_after(id.0 as u32, m as u16)
|
||||
}
|
||||
|
||||
fn insert_nodes_before(&mut self, id: ElementId, m: usize) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter.insert_before(id.0 as u32, m as u16)
|
||||
@@ -188,7 +176,7 @@ impl WriteMutations for WebsysDom {
|
||||
value: &AttributeValue,
|
||||
id: ElementId,
|
||||
) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
match value {
|
||||
@@ -223,14 +211,14 @@ impl WriteMutations for WebsysDom {
|
||||
}
|
||||
|
||||
fn set_node_text(&mut self, value: &str, id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter.set_text(id.0 as u32, value)
|
||||
}
|
||||
|
||||
fn create_event_listener(&mut self, name: &'static str, id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
// mounted events are fired immediately after the element is mounted.
|
||||
@@ -245,7 +233,7 @@ impl WriteMutations for WebsysDom {
|
||||
}
|
||||
|
||||
fn remove_event_listener(&mut self, name: &'static str, id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
if name == "mounted" {
|
||||
@@ -257,14 +245,14 @@ impl WriteMutations for WebsysDom {
|
||||
}
|
||||
|
||||
fn remove_node(&mut self, id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter.remove(id.0 as u32)
|
||||
}
|
||||
|
||||
fn push_root(&mut self, id: ElementId) {
|
||||
if self.only_write_templates() {
|
||||
if self.skip_mutations() {
|
||||
return;
|
||||
}
|
||||
self.interpreter.push_root(id.0 as u32)
|
||||
|
||||
Reference in new issue
Block a user