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:
Jonathan KelleyandEvan Almloff authored and GitHub committed 2024-08-13 01:59:04 +00:00
1 parent a2180b92e9
commit 0de3bf7aeb
40 files changed
+597 -1038

No files matched your search

+5 -34
View File
@@ -126,19 +126,6 @@ mod js {
fn assign_id(ptr: u32, len: u8, id: u32) {
"{this.nodes[$id$] = this.loadChild($ptr$, $len$);}"
}
fn hydrate_text(ptr: u32, len: u8, value: &str, id: u32) {
r#"{
let node = this.loadChild($ptr$, $len$);
if (node.nodeType == node.TEXT_NODE) {
node.textContent = value;
} else {
let text = document.createTextNode(value);
node.replaceWith(text);
node = text;
}
this.nodes[$id$] = node;
}"#
}
fn replace_placeholder(ptr: u32, len: u8, n: u16) {
"{let els = this.stack.splice(this.stack.length - $n$); let node = this.loadChild($ptr$, $len$); node.replaceWith(...els);}"
}
@@ -149,11 +136,11 @@ mod js {
#[cfg(feature = "binary-protocol")]
fn append_children_to_top(many: u16) {
"{
let root = this.stack[this.stack.length-many-1];
let els = this.stack.splice(this.stack.length-many);
for (let k = 0; k < many; k++) {
root.appendChild(els[k]);
}
let root = this.stack[this.stack.length-many-1];
let els = this.stack.splice(this.stack.length-many);
for (let k = 0; k < many; k++) {
root.appendChild(els[k]);
}
}"
}
@@ -218,22 +205,6 @@ mod js {
"{this.nodes[$id$] = this.loadChild($array$);}"
}
/// The coolest ID ever!
#[cfg(feature = "binary-protocol")]
fn hydrate_text_ref(array: &[u8], value: &str, id: u32) {
r#"{
let node = this.loadChild($array$);
if (node.nodeType == node.TEXT_NODE) {
node.textContent = value;
} else {
let text = document.createTextNode(value);
node.replaceWith(text);
node = text;
}
this.nodes[$id$] = node;
}"#
}
#[cfg(feature = "binary-protocol")]
fn replace_placeholder_ref(array: &[u8], n: u16) {
"{let els = this.stack.splice(this.stack.length - $n$); let node = this.loadChild($array$); node.replaceWith(...els);}"
@@ -1,16 +1,13 @@
use crate::unified_bindings::Interpreter as Channel;
use dioxus_core::{TemplateAttribute, TemplateNode, WriteMutations};
use dioxus_core::{Template, TemplateAttribute, TemplateNode, WriteMutations};
use dioxus_html::event_bubbles;
use sledgehammer_utils::rustc_hash::FxHashMap;
/// The state needed to apply mutations to a channel. This state should be kept across all mutations for the app
#[derive(Default)]
pub struct MutationState {
/// The maximum number of templates that we have registered
max_template_count: u16,
/// The currently registered templates with the template ids
templates: FxHashMap<String, u16>,
templates: FxHashMap<Template, u16>,
/// The channel that we are applying mutations to
channel: Channel,
@@ -81,19 +78,6 @@ impl MutationState {
}
impl WriteMutations for MutationState {
fn register_template(&mut self, template: dioxus_core::prelude::Template) {
let current_max_template_count = self.max_template_count;
for root in template.roots.iter() {
self.create_template_node(root);
self.templates
.insert(template.name.to_owned(), current_max_template_count);
}
self.channel
.add_templates(current_max_template_count, template.roots.len() as u16);
self.max_template_count += 1;
}
fn append_children(&mut self, id: dioxus_core::ElementId, m: usize) {
self.channel.append_children(id.0 as u32, m as u16);
}
@@ -110,15 +94,21 @@ impl WriteMutations for MutationState {
self.channel.create_text_node(value, id.0 as u32);
}
fn hydrate_text_node(&mut self, path: &'static [u8], value: &str, id: dioxus_core::ElementId) {
self.channel.hydrate_text_ref(path, value, id.0 as u32);
}
fn load_template(&mut self, template: Template, index: usize, id: dioxus_core::ElementId) {
// Get the template or create it if we haven't seen it before
let tmpl_id = self.templates.get(&template).cloned().unwrap_or_else(|| {
let current_max_template_count = self.templates.len() as u16;
for root in template.roots.iter() {
self.create_template_node(root);
self.templates.insert(template, current_max_template_count);
}
let id = template.roots.len() as u16;
self.channel.add_templates(current_max_template_count, id);
current_max_template_count
});
fn load_template(&mut self, name: &'static str, index: usize, id: dioxus_core::ElementId) {
if let Some(tmpl_id) = self.templates.get(name) {
self.channel
.load_template(*tmpl_id, index as u16, id.0 as u32)
}
self.channel
.load_template(tmpl_id, index as u16, id.0 as u32);
}
fn replace_node_with(&mut self, id: dioxus_core::ElementId, m: usize) {