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

+19 -5
View File
@@ -31,7 +31,7 @@ export class BaseInterpreter {
// sledgehammer is generating this...
m: any;
constructor() { }
constructor() {}
initialize(root: HTMLElement, handler: EventListener | null = null) {
this.global = {};
@@ -45,7 +45,7 @@ export class BaseInterpreter {
this.handler = handler;
// make sure to set the root element's ID so it still registers events
root.setAttribute('data-dioxus-id', "0");
root.setAttribute("data-dioxus-id", "0");
}
handleResizeEvent(entry: ResizeObserverEntry) {
@@ -241,6 +241,18 @@ export class BaseInterpreter {
NodeFilter.SHOW_COMMENT
);
let nextSibling = under.nextSibling;
// Continue to the next node. Returns false if we should stop traversing because we've reached the end of the children
// of the root
let continueToNextNode = () => {
// stop traversing if there are no more nodes
if (!treeWalker.nextNode()) {
return false;
}
// stop traversing if we have reached the next sibling of the root node
return treeWalker.currentNode !== nextSibling;
};
while (treeWalker.currentNode) {
const currentNode = treeWalker.currentNode as ChildNode;
if (currentNode.nodeType === Node.COMMENT_NODE) {
@@ -251,7 +263,7 @@ export class BaseInterpreter {
if (placeholderSplit.length > 1) {
this.nodes[ids[parseInt(placeholderSplit[1])]] = currentNode;
if (!treeWalker.nextNode()) {
if (!continueToNextNode()) {
break;
}
continue;
@@ -284,7 +296,9 @@ export class BaseInterpreter {
}
treeWalker.currentNode = commentAfterText;
this.nodes[ids[parseInt(textNodeSplit[1])]] = textNode;
let exit = !treeWalker.nextNode();
// Stop traversing if we started on a comment node (which has no children)
// or the next sibling stops the walk
let exit = currentNode === under || !continueToNextNode();
// remove the comment node after the text node
commentAfterText.remove();
if (exit) {
@@ -293,7 +307,7 @@ export class BaseInterpreter {
continue;
}
}
if (!treeWalker.nextNode()) {
if (!continueToNextNode()) {
break;
}
}