Skip to content

Commit 172fcb6

Browse files
committed
fix: inserting new node edge case and creating error overlay
1 parent f640012 commit 172fcb6

File tree

7 files changed

+2069
-31
lines changed

7 files changed

+2069
-31
lines changed

.changeset/cyan-bottles-speak.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/core': patch
3+
---
4+
5+
fix: creating error overlay

.changeset/tame-glasses-explain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/core': patch
3+
---
4+
5+
fix: inserting new node edge case

packages/qwik/src/core/client/dom-container.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,15 +200,19 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
200200
}
201201
errorDiv.setAttribute('q:key', '_error_');
202202
const journal: VNodeJournal = [];
203-
vnode_getDOMChildNodes(journal, vHost).forEach((child) => errorDiv.appendChild(child));
204-
const vErrorDiv = vnode_newElement(errorDiv, 'error-host');
203+
204+
const vErrorDiv = vnode_newElement(errorDiv, 'errored-host');
205+
206+
vnode_getDOMChildNodes(journal, vHost, true).forEach((child) => {
207+
vnode_insertBefore(journal, vErrorDiv, child, null);
208+
});
205209
vnode_insertBefore(journal, vHost, vErrorDiv, null);
206210
vnode_applyJournal(journal);
207211
}
208212

209213
if (err && err instanceof Error) {
210214
if (!('hostElement' in err)) {
211-
(err as any)['hostElement'] = host;
215+
(err as any)['hostElement'] = String(host);
212216
}
213217
}
214218
if (!isRecoverable(err)) {

packages/qwik/src/core/client/vnode-diff.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -491,21 +491,6 @@ export const vnode_diff = (
491491
// All is good.
492492
// console.log(' NOOP', String(vCurrent));
493493
} else {
494-
const parent = vnode_getParent(vProjectedNode);
495-
const isAlreadyProjected =
496-
!!parent && !(vnode_isElementVNode(parent) && vnode_getElementName(parent) === QTemplate);
497-
if (isAlreadyProjected && vParent !== parent) {
498-
/**
499-
* The node is already projected, but structure has been changed. In next steps we will
500-
* insert the vProjectedNode at the end. However we will find existing projection elements
501-
* (from already projected THE SAME projection as vProjectedNode!) during
502-
* vnode_insertBefore. We need to remove vnode from the vnode tree to avoid referencing it
503-
* to self and cause infinite loop. Don't remove it from DOM to avoid additional operations
504-
* and flickering.
505-
*/
506-
vnode_remove(journal, parent, vProjectedNode, false);
507-
}
508-
509494
// move from q:template to the target node
510495
vnode_insertBefore(
511496
journal,

packages/qwik/src/core/client/vnode.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -965,11 +965,29 @@ export const vnode_insertBefore = (
965965
if (vnode_isElementVNode(parent)) {
966966
ensureMaterialized(parent);
967967
}
968+
const newChildCurrentParent = newChild[VNodeProps.parent];
968969
if (newChild === insertBefore) {
969970
// invalid insertBefore. We can't insert before self reference
970971
// prevent infinity loop and putting self reference to next sibling
971-
insertBefore = null;
972+
if (newChildCurrentParent) {
973+
// early return, as the newChild is already in the tree and we are already in the correct position
974+
return;
975+
} else {
976+
// if the newChild is not in the tree, than we insert it at the end of the list
977+
insertBefore = null;
978+
}
979+
}
980+
981+
// ensure that the previous node is unlinked.
982+
if (
983+
newChildCurrentParent &&
984+
(newChild[VNodeProps.previousSibling] ||
985+
newChild[VNodeProps.nextSibling] ||
986+
newChildCurrentParent !== parent)
987+
) {
988+
vnode_remove(journal, newChildCurrentParent, newChild, false);
972989
}
990+
973991
let adjustedInsertBefore: VNode | null = null;
974992
if (insertBefore == null) {
975993
if (vnode_isVirtualVNode(parent)) {
@@ -1013,17 +1031,6 @@ export const vnode_insertBefore = (
10131031
);
10141032
}
10151033

1016-
// ensure that the previous node is unlinked.
1017-
const newChildCurrentParent = newChild[VNodeProps.parent];
1018-
if (
1019-
newChildCurrentParent &&
1020-
(newChild[VNodeProps.previousSibling] ||
1021-
newChild[VNodeProps.nextSibling] ||
1022-
(vnode_isElementVNode(newChildCurrentParent) && newChildCurrentParent !== parent))
1023-
) {
1024-
vnode_remove(journal, newChildCurrentParent, newChild, false);
1025-
}
1026-
10271034
// link newChild into the previous/next list
10281035
const vNext = insertBefore;
10291036
const vPrevious = vNext

0 commit comments

Comments
 (0)