fix: improve marker-node filtering when using islands router (closes #4443) (#4446)

This commit is contained in:
Greg Johnston
2025-11-19 19:56:44 -05:00
committed by GitHub
parent 4f3a26ce88
commit 61571ed24b
4 changed files with 38 additions and 76 deletions

View File

@@ -7,6 +7,9 @@ use std::cell::Cell;
use std::{cell::RefCell, panic::Location, rc::Rc};
use web_sys::{Comment, Element, Node, Text};
#[cfg(feature = "mark_branches")]
const COMMENT_NODE: u16 = 8;
/// Hydration works by walking over the DOM, adding interactivity as needed.
///
/// This cursor tracks the location in the DOM that is currently being hydrated. Each that type
@@ -43,13 +46,27 @@ where
///
/// Does nothing if there is no child.
pub fn child(&self) {
//crate::log("advancing to next child of ");
//Rndr::log_node(&self.current());
let mut inner = self.0.borrow_mut();
if let Some(node) = Rndr::first_child(&inner) {
*inner = node;
}
//drop(inner);
#[cfg(feature = "mark_branches")]
{
while inner.node_type() == COMMENT_NODE {
if let Some(content) = inner.text_content() {
if content.starts_with("bo") || content.starts_with("bc") {
if let Some(sibling) = Rndr::next_sibling(&inner) {
*inner = sibling;
continue;
}
}
}
break;
}
}
// //drop(inner);
//crate::log(">> which is ");
//Rndr::log_node(&self.current());
}
@@ -58,12 +75,25 @@ where
///
/// Does nothing if there is no sibling.
pub fn sibling(&self) {
//crate::log("advancing to next sibling of ");
//Rndr::log_node(&self.current());
let mut inner = self.0.borrow_mut();
if let Some(node) = Rndr::next_sibling(&inner) {
*inner = node;
}
#[cfg(feature = "mark_branches")]
{
while inner.node_type() == COMMENT_NODE {
if let Some(content) = inner.text_content() {
if content.starts_with("bo") || content.starts_with("bc") {
if let Some(sibling) = Rndr::next_sibling(&inner) {
*inner = sibling;
continue;
}
}
}
break;
}
}
//drop(inner);
//crate::log(">> which is ");
//Rndr::log_node(&self.current());

View File

@@ -575,15 +575,7 @@ impl RenderHtml for AnyView {
#[cfg(feature = "hydrate")]
{
if FROM_SERVER {
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
let state =
(self.hydrate_from_server)(self.value, cursor, position);
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
state
(self.hydrate_from_server)(self.value, cursor, position)
} else {
panic!(
"hydrating AnyView from inside a ViewTemplate is not \
@@ -609,14 +601,8 @@ impl RenderHtml for AnyView {
) -> Self::State {
#[cfg(feature = "hydrate")]
{
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
let state =
(self.hydrate_async)(self.value, cursor, position).await;
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
state
}
#[cfg(not(feature = "hydrate"))]

View File

@@ -411,21 +411,14 @@ where
cursor: &Cursor,
position: &PositionState,
) -> Self::State {
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
let state = match self {
match self {
Either::Left(left) => {
Either::Left(left.hydrate::<FROM_SERVER>(cursor, position))
}
Either::Right(right) => {
Either::Right(right.hydrate::<FROM_SERVER>(cursor, position))
}
};
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
state
}
async fn hydrate_async(
@@ -433,21 +426,14 @@ where
cursor: &Cursor,
position: &PositionState,
) -> Self::State {
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
let state = match self {
match self {
Either::Left(left) => {
Either::Left(left.hydrate_async(cursor, position).await)
}
Either::Right(right) => {
Either::Right(right.hydrate_async(cursor, position).await)
}
};
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
state
}
fn into_owned(self) -> Self::Owned {
@@ -973,17 +959,11 @@ macro_rules! tuples {
cursor: &Cursor,
position: &PositionState,
) -> Self::State {
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
let state = match self {
$([<EitherOf $num>]::$ty(this) => {
[<EitherOf $num>]::$ty(this.hydrate::<FROM_SERVER>(cursor, position))
})*
};
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
Self::State { state }
}
@@ -993,17 +973,11 @@ macro_rules! tuples {
cursor: &Cursor,
position: &PositionState,
) -> Self::State {
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
let state = match self {
$([<EitherOf $num>]::$ty(this) => {
[<EitherOf $num>]::$ty(this.hydrate_async(cursor, position).await)
})*
};
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
Self::State { state }
}

View File

@@ -322,10 +322,6 @@ where
cursor: &Cursor,
position: &PositionState,
) -> Self::State {
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
// get parent and position
let current = cursor.current();
let parent = if position.get() == Position::FirstChild {
@@ -346,22 +342,12 @@ where
for (index, item) in items.enumerate() {
hashed_items.insert((self.key_fn)(&item));
let (set_index, view) = (self.view_fn)(index, item);
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
let item = view.hydrate::<FROM_SERVER>(cursor, position);
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
rendered_items.push(Some((set_index, item)));
}
let marker = cursor.next_placeholder(position);
position.set(Position::NextChild);
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
KeyedState {
parent: Some(parent),
marker,
@@ -375,10 +361,6 @@ where
cursor: &Cursor,
position: &PositionState,
) -> Self::State {
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
// get parent and position
let current = cursor.current();
let parent = if position.get() == Position::FirstChild {
@@ -399,22 +381,12 @@ where
for (index, item) in items.enumerate() {
hashed_items.insert((self.key_fn)(&item));
let (set_index, view) = (self.view_fn)(index, item);
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
let item = view.hydrate_async(cursor, position).await;
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
rendered_items.push(Some((set_index, item)));
}
let marker = cursor.next_placeholder(position);
position.set(Position::NextChild);
if cfg!(feature = "mark_branches") {
cursor.advance_to_placeholder(position);
}
KeyedState {
parent: Some(parent),
marker,