Fix hydration of suspense fragments that contain text nodes (#3287)

* Fix hydration of suspense fragments that contain text nodes

* fix release builds

* disable link deduplication

* restore meta tag deduplication

* Add a test for the failed hydration case

* make changes to the document trait non-breaking

* remove info log from server future hook

* restore default implementation - this was also a breaking change

* fix semver breakage

* clean up server_future

* Cleanup unused code

* fix clippy

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2025-01-07 19:47:23 -08:00
1 parent 57d637184f
commit d41ab3a756
33 files changed
+644 -222

No files matched your search

+54 -1
View File
@@ -1,5 +1,9 @@
use dioxus_core::prelude::queue_effect;
use dioxus_core::ScopeId;
use dioxus_document::{Document, Eval, EvalError, Evaluator};
use dioxus_document::{
create_element_in_head, Document, Eval, EvalError, Evaluator, LinkProps, MetaProps,
ScriptProps, StyleProps,
};
use dioxus_history::History;
use generational_box::{AnyStorage, GenerationalBox, UnsyncStorage};
use std::rc::Rc;
@@ -75,6 +79,7 @@ pub fn init_document() {
}
/// Reprints the liveview-target's provider of evaluators.
#[derive(Clone)]
pub struct LiveviewDocument {
query: QueryEngine,
}
@@ -83,4 +88,52 @@ impl Document for LiveviewDocument {
fn eval(&self, js: String) -> Eval {
Eval::new(LiveviewEvaluator::create(self.query.clone(), js))
}
/// Set the title of the document
fn set_title(&self, title: String) {
let myself = self.clone();
queue_effect(move || {
myself.eval(format!("document.title = {title:?};"));
});
}
/// Create a new meta tag in the head
fn create_meta(&self, props: MetaProps) {
let myself = self.clone();
queue_effect(move || {
myself.eval(create_element_in_head("meta", &props.attributes(), None));
});
}
/// Create a new script tag in the head
fn create_script(&self, props: ScriptProps) {
let myself = self.clone();
queue_effect(move || {
myself.eval(create_element_in_head(
"script",
&props.attributes(),
props.script_contents().ok(),
));
});
}
/// Create a new style tag in the head
fn create_style(&self, props: StyleProps) {
let myself = self.clone();
queue_effect(move || {
myself.eval(create_element_in_head(
"style",
&props.attributes(),
props.style_contents().ok(),
));
});
}
/// Create a new link tag in the head
fn create_link(&self, props: LinkProps) {
let myself = self.clone();
queue_effect(move || {
myself.eval(create_element_in_head("link", &props.attributes(), None));
});
}
}