Skip to content

Commit 7e45ae6

Browse files
committed
feat(cursors): migrate to journal
1 parent 6b0a632 commit 7e45ae6

18 files changed

+401
-293
lines changed

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ import {
4848
} from './types';
4949
import { mapArray_get, mapArray_has, mapArray_set } from './util-mapArray';
5050
import {
51-
VNodeJournalOpCode,
5251
vnode_createErrorDiv,
5352
vnode_getProp,
5453
vnode_insertBefore,
@@ -57,6 +56,7 @@ import {
5756
vnode_locate,
5857
vnode_newUnMaterializedElement,
5958
vnode_setProp,
59+
type VNodeJournal,
6060
} from './vnode';
6161
import type { ElementVNode } from '../shared/vnode/element-vnode';
6262
import type { VNode } from '../shared/vnode/vnode';
@@ -168,12 +168,18 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
168168
const vHost = host;
169169
const vHostParent = vHost.parent;
170170
const vHostNextSibling = vHost.nextSibling as VNode | null;
171-
const vErrorDiv = vnode_createErrorDiv(document, vHost, err);
171+
const journal: VNodeJournal = [];
172+
const vErrorDiv = vnode_createErrorDiv(journal, document, vHost, err);
172173
// If the host is an element node, we need to insert the error div into its parent.
173174
const insertHost = vnode_isElementVNode(vHost) ? vHostParent || vHost : vHost;
174175
// If the host is different then we need to insert errored-host in the same position as the host.
175176
const insertBefore = insertHost === vHost ? null : vHostNextSibling;
176-
vnode_insertBefore(insertHost as ElementVNode | VirtualVNode, vErrorDiv, insertBefore);
177+
vnode_insertBefore(
178+
journal,
179+
insertHost as ElementVNode | VirtualVNode,
180+
vErrorDiv,
181+
insertBefore
182+
);
177183
}
178184

179185
if (err && err instanceof Error) {
@@ -260,7 +266,7 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
260266
if (props) {
261267
for (const prop of Object.keys(props)) {
262268
if (isSlotProp(prop)) {
263-
const value = prop;
269+
const value = props[prop];
264270
if (typeof value == 'string') {
265271
const projection = this.vNodeLocate(value);
266272
props[prop] = projection;

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

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ import {
8484
vnode_setText,
8585
vnode_truncate,
8686
vnode_walkVNode,
87+
type VNodeJournal,
8788
} from './vnode';
8889
import { getAttributeNamespace, getNewElementNamespaceData } from './vnode-namespace';
8990
import { cleanupDestroyable } from '../use/utils/destroyable';
@@ -100,6 +101,7 @@ import { _EFFECT_BACK_REF } from '../reactive-primitives/backref';
100101

101102
export const vnode_diff = (
102103
container: ClientContainer,
104+
journal: VNodeJournal,
103105
jsxNode: JSXChildren,
104106
vStartNode: VNode,
105107
scopedStyleIdPrefix: string | null
@@ -498,7 +500,7 @@ export const vnode_diff = (
498500
if (vProjectedNode == null) {
499501
// Nothing to project, so render content of the slot.
500502
vnode_insertBefore(
501-
container,
503+
journal,
502504
vParent as ElementVNode | VirtualVNode,
503505
(vNewNode = vnode_newVirtual()),
504506
vCurrent && getInsertBefore()
@@ -513,7 +515,7 @@ export const vnode_diff = (
513515
} else {
514516
// move from q:template to the target node
515517
vnode_insertBefore(
516-
container,
518+
journal,
517519
vParent as ElementVNode | VirtualVNode,
518520
(vNewNode = vProjectedNode),
519521
vCurrent && getInsertBefore()
@@ -545,8 +547,8 @@ export const vnode_diff = (
545547
if (vNode.flags & VNodeFlags.Deleted) {
546548
continue;
547549
}
548-
cleanup(container, vNode);
549-
vnode_remove(container, vParent, vNode, true);
550+
cleanup(container, journal, vNode);
551+
vnode_remove(journal, vParent, vNode, true);
550552
}
551553
vSideBuffer.clear();
552554
vSideBuffer = null;
@@ -588,10 +590,10 @@ export const vnode_diff = (
588590
if (vFirstChild !== null) {
589591
let vChild: VNode | null = vFirstChild;
590592
while (vChild) {
591-
cleanup(container, vChild);
593+
cleanup(container, journal, vChild);
592594
vChild = vChild.nextSibling as VNode | null;
593595
}
594-
vnode_truncate(container, vCurrent as ElementVNode | VirtualVNode, vFirstChild);
596+
vnode_truncate(container, journal, vCurrent as ElementVNode | VirtualVNode, vFirstChild);
595597
}
596598
}
597599

@@ -603,21 +605,21 @@ export const vnode_diff = (
603605
const toRemove = vCurrent;
604606
advanceToNextSibling();
605607
if (vParent === toRemove.parent) {
606-
cleanup(container, toRemove);
608+
cleanup(container, journal, toRemove);
607609
// If we are diffing projection than the parent is not the parent of the node.
608610
// If that is the case we don't want to remove the node from the parent.
609-
vnode_remove(container, vParent, toRemove, true);
611+
vnode_remove(journal, vParent, toRemove, true);
610612
}
611613
}
612614
}
613615
}
614616

615617
function expectNoMoreTextNodes() {
616618
while (vCurrent !== null && vnode_isTextVNode(vCurrent)) {
617-
cleanup(container, vCurrent);
619+
cleanup(container, journal, vCurrent);
618620
const toRemove = vCurrent;
619621
advanceToNextSibling();
620-
vnode_remove(container, vParent, toRemove, true);
622+
vnode_remove(journal, vParent, toRemove, true);
621623
}
622624
}
623625

@@ -668,7 +670,7 @@ export const vnode_diff = (
668670
vnode_setProp(vNewNode!, HANDLER_PREFIX + ':' + scopedEvent, value);
669671
if (scope) {
670672
// window and document need attrs so qwik loader can find them
671-
vnode_setAttr(container, vNewNode!, key, '');
673+
vnode_setAttr(journal, vNewNode!, key, '');
672674
}
673675
// register an event for qwik loader (window/document prefixed with '-')
674676
registerQwikLoaderEvent(loaderScopedEvent);
@@ -746,7 +748,7 @@ export const vnode_diff = (
746748
}
747749
}
748750

749-
vnode_insertBefore(container, vParent as ElementVNode, vNewNode as ElementVNode, vCurrent);
751+
vnode_insertBefore(journal, vParent as ElementVNode, vNewNode as ElementVNode, vCurrent);
750752

751753
return needsQDispatchEventPatch;
752754
}
@@ -831,7 +833,7 @@ export const vnode_diff = (
831833
const setAttribute = (vnode: ElementVNode, key: string, value: any) => {
832834
const serializedValue =
833835
value != null ? serializeAttribute(key, value, scopedStyleIdPrefix) : null;
834-
vnode_setAttr(container, vnode, key, serializedValue);
836+
vnode_setAttr(journal, vnode, key, serializedValue);
835837
};
836838

837839
const record = (key: string, value: any) => {
@@ -1095,7 +1097,7 @@ export const vnode_diff = (
10951097
}
10961098
}
10971099
vnode_insertBefore(
1098-
container,
1100+
journal,
10991101
parentForInsert as ElementVNode | VirtualVNode,
11001102
buffered,
11011103
vCurrent
@@ -1124,7 +1126,7 @@ export const vnode_diff = (
11241126

11251127
const createNew = () => {
11261128
vnode_insertBefore(
1127-
container,
1129+
journal,
11281130
vParent as VirtualVNode,
11291131
(vNewNode = vnode_newVirtual()),
11301132
vCurrent && getInsertBefore()
@@ -1267,7 +1269,7 @@ export const vnode_diff = (
12671269
clearAllEffects(container, host);
12681270
}
12691271
vnode_insertBefore(
1270-
container,
1272+
journal,
12711273
vParent as VirtualVNode,
12721274
(vNewNode = vnode_newVirtual()),
12731275
vCurrent && getInsertBefore()
@@ -1281,7 +1283,7 @@ export const vnode_diff = (
12811283

12821284
function insertNewInlineComponent() {
12831285
vnode_insertBefore(
1284-
container,
1286+
journal,
12851287
vParent as VirtualVNode,
12861288
(vNewNode = vnode_newVirtual()),
12871289
vCurrent && getInsertBefore()
@@ -1299,14 +1301,14 @@ export const vnode_diff = (
12991301
const type = vnode_getType(vCurrent);
13001302
if (type === 3 /* Text */) {
13011303
if (text !== vnode_getText(vCurrent as TextVNode)) {
1302-
vnode_setText(container, vCurrent as TextVNode, text);
1304+
vnode_setText(journal, vCurrent as TextVNode, text);
13031305
return;
13041306
}
13051307
return;
13061308
}
13071309
}
13081310
vnode_insertBefore(
1309-
container,
1311+
journal,
13101312
vParent as VirtualVNode,
13111313
(vNewNode = vnode_newText(container.document.createTextNode(text), text)),
13121314
vCurrent
@@ -1493,7 +1495,7 @@ function isPropsEmpty(props: Record<string, any> | null | undefined): boolean {
14931495
* - Projection nodes by not recursing into them.
14941496
* - Component nodes by recursing into the component content nodes (which may be projected).
14951497
*/
1496-
export function cleanup(container: ClientContainer, vNode: VNode) {
1498+
export function cleanup(container: ClientContainer, journal: VNodeJournal, vNode: VNode) {
14971499
let vCursor: VNode | null = vNode;
14981500
// Depth first traversal
14991501
if (vnode_isTextVNode(vNode)) {
@@ -1549,11 +1551,11 @@ export function cleanup(container: ClientContainer, vNode: VNode) {
15491551
: (value as unknown as VNode);
15501552
let projectionChild = vnode_getFirstChild(projection);
15511553
while (projectionChild) {
1552-
cleanup(container, projectionChild);
1554+
cleanup(container, journal, projectionChild);
15531555
projectionChild = projectionChild.nextSibling as VNode | null;
15541556
}
15551557

1556-
cleanupStaleUnclaimedProjection(container, projection);
1558+
cleanupStaleUnclaimedProjection(journal, projection);
15571559
}
15581560
}
15591561
}
@@ -1626,7 +1628,7 @@ export function cleanup(container: ClientContainer, vNode: VNode) {
16261628
} while (true as boolean);
16271629
}
16281630

1629-
function cleanupStaleUnclaimedProjection(container: ClientContainer, projection: VNode) {
1631+
function cleanupStaleUnclaimedProjection(journal: VNodeJournal, projection: VNode) {
16301632
// we are removing a node where the projection would go after slot render.
16311633
// This is not needed, so we need to cleanup still unclaimed projection
16321634
const projectionParent = projection.parent;
@@ -1637,7 +1639,7 @@ function cleanupStaleUnclaimedProjection(container: ClientContainer, projection:
16371639
vnode_getElementName(projectionParent as ElementVNode) === QTemplate
16381640
) {
16391641
// if parent is the q:template element then projection is still unclaimed - remove it
1640-
vnode_remove(container, projectionParent as ElementVNode | VirtualVNode, projection, true);
1642+
vnode_remove(journal, projectionParent as ElementVNode | VirtualVNode, projection, true);
16411643
}
16421644
}
16431645
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
vnode_getFirstChild,
2020
vnode_isElementVNode,
2121
vnode_isTextVNode,
22+
type VNodeJournal,
2223
} from './vnode';
2324
import type { ElementVNode } from '../shared/vnode/element-vnode';
2425
import type { VNode } from '../shared/vnode/vnode';
@@ -52,7 +53,7 @@ export const vnode_getElementNamespaceFlags = (element: Element) => {
5253
};
5354

5455
export function vnode_getDomChildrenWithCorrectNamespacesToInsert(
55-
container: Container,
56+
journal: VNodeJournal,
5657
domParentVNode: ElementVNode,
5758
newChild: VNode
5859
): (ElementVNode | TextVNode)[] {
@@ -64,11 +65,11 @@ export function vnode_getDomChildrenWithCorrectNamespacesToInsert(
6465
let domChildren: (ElementVNode | TextVNode)[] = [];
6566
if (elementNamespace === HTML_NS) {
6667
// parent is in the default namespace, so just get the dom children. This is the fast path.
67-
domChildren = vnode_getDOMChildNodes(container, newChild, true);
68+
domChildren = vnode_getDOMChildNodes(journal, newChild, true);
6869
} else {
6970
// parent is in a different namespace, so we need to clone the children with the correct namespace.
7071
// The namespace cannot be changed on nodes, so we need to clone these nodes
71-
const children = vnode_getDOMChildNodes(container, newChild, true);
72+
const children = vnode_getDOMChildNodes(journal, newChild, true);
7273

7374
for (let i = 0; i < children.length; i++) {
7475
const childVNode = children[i];

0 commit comments

Comments
 (0)