Skip to content

Commit 888c9ea

Browse files
author
Dillen Meijboom
committed
feat: naive implementation for vraw hydration
1 parent 7ec8d2a commit 888c9ea

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed

packages/yew/src/dom_bundle/bnode.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,7 @@ mod feat_hydration {
267267
VNode::VSuspense(vsuspense) => vsuspense
268268
.hydrate(root, parent_scope, parent, fragment)
269269
.into(),
270-
VNode::VRaw(_) => {
271-
panic!("VRaw is not hydratable (raw HTML string cannot be hydrated)")
272-
}
270+
VNode::VRaw(vraw) => vraw.hydrate(root, parent_scope, parent, fragment).into(),
273271
}
274272
}
275273
}

packages/yew/src/dom_bundle/braw.rs

+45
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,51 @@ impl Reconcilable for VRaw {
128128
}
129129
}
130130

131+
#[cfg(feature = "hydration")]
132+
mod feat_hydration {
133+
use gloo::utils::document;
134+
135+
use super::*;
136+
use crate::{
137+
dom_bundle::{Fragment, Hydratable},
138+
virtual_dom::Collectable,
139+
};
140+
141+
impl Hydratable for VRaw {
142+
fn hydrate(
143+
self,
144+
_root: &BSubtree,
145+
_parent_scope: &AnyScope,
146+
parent: &Element,
147+
fragment: &mut Fragment,
148+
) -> Self::Bundle {
149+
let detached_parent = document()
150+
.create_element("div")
151+
.expect("failed to create detached element");
152+
153+
let collectable = Collectable::Raw;
154+
let fallback_fragment = Fragment::collect_between(fragment, &collectable, parent);
155+
156+
let mut nodes = fallback_fragment.deep_clone();
157+
158+
for node in nodes.iter() {
159+
detached_parent.append_child(node).unwrap();
160+
}
161+
162+
// We trim all leading text nodes before checking as it's likely these are whitespaces.
163+
nodes.trim_start_text_nodes();
164+
165+
let Self { html } = self;
166+
167+
BRaw {
168+
reference: None,
169+
children_count: nodes.len(),
170+
html,
171+
}
172+
}
173+
}
174+
}
175+
131176
#[cfg(target_arch = "wasm32")]
132177
#[cfg(test)]
133178
mod tests {

packages/yew/src/virtual_dom/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ mod feat_ssr_hydration {
6464
/// This indicates a kind that can be collected from fragment to be processed at a later time
6565
pub enum Collectable {
6666
Component(ComponentName),
67+
Raw,
6768
Suspense,
6869
}
6970

@@ -79,20 +80,23 @@ mod feat_ssr_hydration {
7980
pub fn open_start_mark(&self) -> &'static str {
8081
match self {
8182
Self::Component(_) => "<[",
83+
Self::Raw => "<#",
8284
Self::Suspense => "<?",
8385
}
8486
}
8587

8688
pub fn close_start_mark(&self) -> &'static str {
8789
match self {
8890
Self::Component(_) => "</[",
91+
Self::Raw => "</#",
8992
Self::Suspense => "</?",
9093
}
9194
}
9295

9396
pub fn end_mark(&self) -> &'static str {
9497
match self {
9598
Self::Component(_) => "]>",
99+
Self::Raw => "#>",
96100
Self::Suspense => ">",
97101
}
98102
}
@@ -104,6 +108,7 @@ mod feat_ssr_hydration {
104108
Self::Component(m) => format!("Component({m})").into(),
105109
#[cfg(not(debug_assertions))]
106110
Self::Component(_) => "Component".into(),
111+
Self::Raw => "Raw".into(),
107112
Self::Suspense => "Suspense".into(),
108113
}
109114
}
@@ -130,6 +135,7 @@ mod feat_ssr {
130135
Self::Component(type_name) => {
131136
let _ = w.write_str(type_name);
132137
}
138+
Self::Raw => {}
133139
Self::Suspense => {}
134140
}
135141

@@ -146,6 +152,7 @@ mod feat_ssr {
146152
Self::Component(type_name) => {
147153
let _ = w.write_str(type_name);
148154
}
155+
Self::Raw => {}
149156
Self::Suspense => {}
150157
}
151158

packages/yew/src/virtual_dom/vraw.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,26 @@ mod feat_ssr {
1919
use super::*;
2020
use crate::html::AnyScope;
2121
use crate::platform::fmt::BufWriter;
22+
use crate::virtual_dom::Collectable;
2223

2324
impl VRaw {
2425
pub(crate) async fn render_into_stream(
2526
&self,
2627
w: &mut BufWriter,
2728
_parent_scope: &AnyScope,
28-
_hydratable: bool,
29+
hydratable: bool,
2930
) {
31+
let collectable = Collectable::Raw;
32+
33+
if hydratable {
34+
collectable.write_open_tag(w);
35+
}
36+
3037
let _ = w.write_str(self.html.as_ref());
38+
39+
if hydratable {
40+
collectable.write_close_tag(w);
41+
}
3142
}
3243
}
3344
}

0 commit comments

Comments
 (0)