@remix-run/ui 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -1
- package/dist/accordion/index.js +2 -2
- package/dist/accordion/primitives.d.ts +1 -1
- package/dist/accordion/primitives.js.map +1 -1
- package/dist/anchor/index.js.map +1 -1
- package/dist/animation/animate-layout-mixin.js +1 -1
- package/dist/animation/animate-layout-mixin.js.map +1 -1
- package/dist/animation/animate-mixins.js +2 -2
- package/dist/animation/animate-mixins.js.map +1 -1
- package/dist/animation/demos/color-interpolation.js +1 -1
- package/dist/animation/demos/color-interpolation.js.map +1 -1
- package/dist/animation/demos/drag-release.d.ts +1 -1
- package/dist/animation/demos/hold-to-confirm.d.ts +3 -3
- package/dist/animation/demos/material-ripple.js +1 -3
- package/dist/animation/demos/material-ripple.js.map +1 -1
- package/dist/animation/index.js +4 -4
- package/dist/animation/spring.js.map +1 -1
- package/dist/breadcrumbs/index.js +2 -2
- package/dist/button/index.js +25 -25
- package/dist/button/index.js.map +1 -1
- package/dist/checkbox/index.js +11 -9
- package/dist/checkbox/index.js.map +1 -1
- package/dist/combobox/index.js +4 -4
- package/dist/combobox/index.js.map +1 -1
- package/dist/combobox/primitives.d.ts +1 -1
- package/dist/combobox/primitives.js +5 -5
- package/dist/combobox/primitives.js.map +1 -1
- package/dist/dev/refresh.d.ts +1 -0
- package/dist/dev/refresh.js +2 -0
- package/dist/dev/refresh.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +14 -14
- package/dist/input/index.js +9 -9
- package/dist/input/index.js.map +1 -1
- package/dist/jsx-runtime.js +2 -2
- package/dist/listbox/index.js +2 -2
- package/dist/menu/hover-aim.js.map +1 -1
- package/dist/menu/index.js +3 -3
- package/dist/menu/primitives.d.ts +1 -1
- package/dist/menu/primitives.js +6 -6
- package/dist/menu/primitives.js.map +1 -1
- package/dist/popover/index.js +3 -3
- package/dist/popover/scroll-lock.js.map +1 -1
- package/dist/radio/index.js +7 -7
- package/dist/radio/index.js.map +1 -1
- package/dist/runtime/client-entry-boundary.d.ts +14 -0
- package/dist/runtime/client-entry-boundary.js +29 -0
- package/dist/runtime/client-entry-boundary.js.map +1 -0
- package/dist/runtime/component.d.ts +19 -4
- package/dist/runtime/component.js +39 -9
- package/dist/runtime/component.js.map +1 -1
- package/dist/runtime/core/attributes.js +36 -3
- package/dist/runtime/core/attributes.js.map +1 -1
- package/dist/runtime/core/children.d.ts +2 -0
- package/dist/runtime/core/children.js +26 -2
- package/dist/runtime/core/children.js.map +1 -1
- package/dist/runtime/core/props.js +2 -2
- package/dist/runtime/core/vnode.d.ts +3 -3
- package/dist/runtime/core/vnode.js +22 -1
- package/dist/runtime/core/vnode.js.map +1 -1
- package/dist/runtime/create-element.d.ts +2 -2
- package/dist/runtime/create-element.js +3 -2
- package/dist/runtime/create-element.js.map +1 -1
- package/dist/runtime/diff-dom.js +307 -220
- package/dist/runtime/diff-dom.js.map +1 -1
- package/dist/runtime/diff-props.js +3 -3
- package/dist/runtime/dom.d.ts +12 -0
- package/dist/runtime/element-function.d.ts +3 -0
- package/dist/runtime/element-function.js +2 -0
- package/dist/runtime/element-function.js.map +1 -0
- package/dist/runtime/form-navigation.d.ts +25 -0
- package/dist/runtime/form-navigation.js +132 -0
- package/dist/runtime/form-navigation.js.map +1 -0
- package/dist/runtime/frame-resolution.d.ts +5 -0
- package/dist/runtime/frame-resolution.js +10 -0
- package/dist/runtime/frame-resolution.js.map +1 -0
- package/dist/runtime/frame.d.ts +59 -15
- package/dist/runtime/frame.js +383 -114
- package/dist/runtime/frame.js.map +1 -1
- package/dist/runtime/jsx.d.ts +1 -1
- package/dist/runtime/jsx.js +1 -1
- package/dist/runtime/jsx.js.map +1 -1
- package/dist/runtime/key.d.ts +1 -0
- package/dist/runtime/key.js +2 -0
- package/dist/runtime/key.js.map +1 -0
- package/dist/runtime/mixins/attrs-mixin.js +2 -2
- package/dist/runtime/mixins/link-mixin.js +4 -3
- package/dist/runtime/mixins/link-mixin.js.map +1 -1
- package/dist/runtime/mixins/mixin.d.ts +15 -10
- package/dist/runtime/mixins/mixin.js +4 -4
- package/dist/runtime/mixins/mixin.js.map +1 -1
- package/dist/runtime/mixins/on-mixin.js +1 -1
- package/dist/runtime/mixins/ref-mixin.js +1 -1
- package/dist/runtime/module-preloader.d.ts +8 -0
- package/dist/runtime/module-preloader.js +95 -0
- package/dist/runtime/module-preloader.js.map +1 -0
- package/dist/runtime/navigation.d.ts +4 -1
- package/dist/runtime/navigation.js +157 -32
- package/dist/runtime/navigation.js.map +1 -1
- package/dist/runtime/reconcile.d.ts +11 -10
- package/dist/runtime/reconcile.js +549 -421
- package/dist/runtime/reconcile.js.map +1 -1
- package/dist/runtime/refresh.d.ts +28 -0
- package/dist/runtime/refresh.js +31 -0
- package/dist/runtime/refresh.js.map +1 -0
- package/dist/runtime/render.js +1 -1
- package/dist/runtime/render.js.map +1 -1
- package/dist/runtime/run.d.ts +3 -1
- package/dist/runtime/run.js +15 -7
- package/dist/runtime/run.js.map +1 -1
- package/dist/runtime/scheduler.js +8 -16
- package/dist/runtime/scheduler.js.map +1 -1
- package/dist/runtime/to-vnode.d.ts +2 -2
- package/dist/runtime/to-vnode.js +68 -20
- package/dist/runtime/to-vnode.js.map +1 -1
- package/dist/runtime/vdom.d.ts +4 -2
- package/dist/runtime/vdom.js +87 -42
- package/dist/runtime/vdom.js.map +1 -1
- package/dist/runtime/vnode.d.ts +138 -67
- package/dist/runtime/vnode.js +17 -12
- package/dist/runtime/vnode.js.map +1 -1
- package/dist/select/index.js +11 -11
- package/dist/select/index.js.map +1 -1
- package/dist/select/primitives.d.ts +1 -1
- package/dist/select/primitives.js +6 -6
- package/dist/server/stream.d.ts +2 -0
- package/dist/server/stream.js +74 -29
- package/dist/server/stream.js.map +1 -1
- package/dist/shared/focus-styles.d.ts +1 -1
- package/dist/shared/focus-styles.js +1 -1
- package/dist/shared/focus-styles.js.map +1 -1
- package/dist/shared/listbox-popover-styles.js +1 -1
- package/dist/shared/style-values.js +26 -26
- package/dist/shared/style-values.js.map +1 -1
- package/dist/style/css-mixin.js +3 -3
- package/dist/style/index.js +2 -2
- package/dist/style/style.js +25 -6
- package/dist/style/style.js.map +1 -1
- package/dist/style/stylesheet.d.ts +0 -1
- package/dist/style/stylesheet.js +13 -54
- package/dist/style/stylesheet.js.map +1 -1
- package/dist/tabs/index.js +11 -11
- package/dist/tabs/index.js.map +1 -1
- package/dist/tabs/primitives.d.ts +1 -1
- package/dist/test.js +1 -1
- package/dist/toggle/index.js +9 -9
- package/dist/toggle/index.js.map +1 -1
- package/dist/toggle/primitives.d.ts +1 -1
- package/package.json +10 -7
- package/src/animation/animate-mixins.ts +3 -3
- package/src/animation/demos/color-interpolation.tsx +1 -1
- package/src/button/index.ts +24 -24
- package/src/checkbox/index.ts +10 -8
- package/src/combobox/index.tsx +1 -1
- package/src/dev/refresh.ts +1 -0
- package/src/index.ts +1 -1
- package/src/input/index.ts +8 -8
- package/src/radio/index.ts +6 -5
- package/src/runtime/client-entry-boundary.ts +54 -0
- package/src/runtime/component.ts +65 -16
- package/src/runtime/core/attributes.ts +35 -1
- package/src/runtime/core/children.ts +24 -2
- package/src/runtime/core/vnode.ts +25 -4
- package/src/runtime/create-element.ts +6 -5
- package/src/runtime/demos/readme.demo.tsx +4 -4
- package/src/runtime/diff-dom.ts +370 -244
- package/src/runtime/dom.ts +331 -214
- package/src/runtime/element-function.ts +1 -0
- package/src/runtime/event-listeners.ts +1 -1
- package/src/runtime/form-navigation.ts +184 -0
- package/src/runtime/frame-resolution.ts +13 -0
- package/src/runtime/frame.ts +500 -124
- package/src/runtime/jsx.ts +3 -5
- package/src/runtime/key.ts +1 -0
- package/src/runtime/mixins/link-mixin.ts +1 -0
- package/src/runtime/mixins/mixin.ts +21 -18
- package/src/runtime/module-preloader.ts +115 -0
- package/src/runtime/navigation.ts +204 -30
- package/src/runtime/reconcile.ts +762 -759
- package/src/runtime/refresh.ts +46 -0
- package/src/runtime/run.ts +12 -2
- package/src/runtime/scheduler.ts +9 -29
- package/src/runtime/to-vnode.ts +85 -23
- package/src/runtime/vdom.ts +89 -70
- package/src/runtime/vnode.ts +192 -88
- package/src/select/index.tsx +9 -9
- package/src/server/README.md +13 -0
- package/src/server/stream.ts +93 -30
- package/src/shared/focus-styles.ts +1 -1
- package/src/shared/style-values.ts +26 -26
- package/src/style/style.ts +25 -6
- package/src/style/stylesheet.ts +32 -57
- package/src/tabs/index.tsx +12 -11
- package/src/test/README.md +151 -60
- package/src/toggle/index.tsx +9 -7
package/src/runtime/diff-dom.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { invariant } from './invariant.ts'
|
|
2
2
|
import type { FrameContext } from './frame.ts'
|
|
3
|
+
import { disposeClientEntryBoundary, getClientEntryBoundaryOwner } from './client-entry-boundary.ts'
|
|
3
4
|
|
|
4
|
-
type
|
|
5
|
-
$rmx: {
|
|
6
|
-
dispose(): void
|
|
7
|
-
}
|
|
8
|
-
}
|
|
5
|
+
type MarkerKind = 'frame-start' | 'frame-end' | 'virtual-root-start' | 'virtual-root-end'
|
|
9
6
|
|
|
10
7
|
type CommentMarkerRangeReplacement = {
|
|
11
8
|
currentStart: Comment
|
|
@@ -14,6 +11,25 @@ type CommentMarkerRangeReplacement = {
|
|
|
14
11
|
nextEndIndex: number
|
|
15
12
|
}
|
|
16
13
|
|
|
14
|
+
type NodeSiblingUnit = {
|
|
15
|
+
kind: 'node'
|
|
16
|
+
node: Node
|
|
17
|
+
startIndex: number
|
|
18
|
+
endIndex: number
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type BoundarySiblingUnit = {
|
|
22
|
+
kind: 'frame' | 'hydration'
|
|
23
|
+
start: Comment
|
|
24
|
+
end: Comment
|
|
25
|
+
startIndex: number
|
|
26
|
+
endIndex: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type SiblingUnit = NodeSiblingUnit | BoundarySiblingUnit
|
|
30
|
+
|
|
31
|
+
const REMIX_PRESERVE_DOM_ATTRIBUTE = 'rmx-preserve-dom'
|
|
32
|
+
|
|
17
33
|
export function diffNodes(curr: Node[], next: Node[], context: FrameContext) {
|
|
18
34
|
let parent = curr[0]?.parentNode ?? context.regionParent ?? null
|
|
19
35
|
invariant(parent, 'Parent node not found')
|
|
@@ -24,70 +40,7 @@ export function diffNodes(curr: Node[], next: Node[], context: FrameContext) {
|
|
|
24
40
|
context.regionTailRef ??
|
|
25
41
|
(curr.length > 0 ? (curr[curr.length - 1].nextSibling as ChildNode | null) : null)
|
|
26
42
|
|
|
27
|
-
|
|
28
|
-
let nextIndex = 0
|
|
29
|
-
while (currentIndex < curr.length || nextIndex < next.length) {
|
|
30
|
-
let c = curr[currentIndex]
|
|
31
|
-
let n = next[nextIndex]
|
|
32
|
-
|
|
33
|
-
if (!c && n) {
|
|
34
|
-
if (regionTailRef) {
|
|
35
|
-
parent.insertBefore(n, regionTailRef)
|
|
36
|
-
} else {
|
|
37
|
-
parent.appendChild(n)
|
|
38
|
-
}
|
|
39
|
-
nextIndex++
|
|
40
|
-
} else if (c && !n) {
|
|
41
|
-
removeNode(c, parent, context)
|
|
42
|
-
currentIndex++
|
|
43
|
-
} else if (c && n) {
|
|
44
|
-
let replacement = getCommentMarkerRangeReplacement(
|
|
45
|
-
c,
|
|
46
|
-
n,
|
|
47
|
-
curr,
|
|
48
|
-
next,
|
|
49
|
-
currentIndex,
|
|
50
|
-
nextIndex,
|
|
51
|
-
context,
|
|
52
|
-
)
|
|
53
|
-
if (replacement) {
|
|
54
|
-
replaceCommentMarkerRange(replacement, parent, context)
|
|
55
|
-
currentIndex = replacement.currentEndIndex + 1
|
|
56
|
-
nextIndex = replacement.nextEndIndex + 1
|
|
57
|
-
continue
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Skip hydrated client-entry marker ranges; hydration pass re-renders
|
|
61
|
-
// roots with new props from incoming payload
|
|
62
|
-
if (isVirtualRootStartMarker(c) && isVirtualRootStartMarker(n)) {
|
|
63
|
-
let currentEnd = findHydrationEndMarker(c)
|
|
64
|
-
let nextEnd = findHydrationEndMarker(n)
|
|
65
|
-
let nextData = n.data
|
|
66
|
-
if (c.data !== nextData) c.data = nextData
|
|
67
|
-
|
|
68
|
-
let currentEndIndex = curr.indexOf(currentEnd)
|
|
69
|
-
let nextEndIndex = next.indexOf(nextEnd)
|
|
70
|
-
currentIndex = currentEndIndex + 1
|
|
71
|
-
nextIndex = nextEndIndex + 1
|
|
72
|
-
continue
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
let cursor = diffNode(c, n, context)
|
|
76
|
-
if (cursor) {
|
|
77
|
-
let nextEndIndex = next.indexOf(cursor)
|
|
78
|
-
let currentEndIndex =
|
|
79
|
-
isFrameStartMarker(c) && isFrameEndMarker(cursor)
|
|
80
|
-
? findFrameEndIndex(curr, currentIndex)
|
|
81
|
-
: currentIndex
|
|
82
|
-
currentIndex = currentEndIndex + 1
|
|
83
|
-
nextIndex = nextEndIndex + 1
|
|
84
|
-
continue
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
currentIndex++
|
|
88
|
-
nextIndex++
|
|
89
|
-
}
|
|
90
|
-
}
|
|
43
|
+
diffSiblingUnits(curr, next, parent, regionTailRef, context)
|
|
91
44
|
}
|
|
92
45
|
|
|
93
46
|
function diffNode(current: Node, next: Node, context: FrameContext): ChildNode | undefined {
|
|
@@ -111,45 +64,46 @@ function diffNode(current: Node, next: Node, context: FrameContext): ChildNode |
|
|
|
111
64
|
}
|
|
112
65
|
|
|
113
66
|
// Comment -> Comment
|
|
114
|
-
if (isCommentNode(current) && isCommentNode(next)) {
|
|
67
|
+
if (isCommentNode(current) && isCommentNode(next) && markerKindsMatch(current, next)) {
|
|
115
68
|
let newData = next.data
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
if (
|
|
69
|
+
let updated = false
|
|
70
|
+
if (isFrameStartMarker(current)) {
|
|
71
|
+
if (shouldPreserveFrameStartMarker(current, next, context)) {
|
|
72
|
+
if (current.data !== newData) {
|
|
120
73
|
current.data = newData
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
74
|
+
}
|
|
75
|
+
updated = true
|
|
76
|
+
|
|
77
|
+
let frame = context.frameInstances.get(current)
|
|
78
|
+
let nextMarkerData = getFrameMarkerData(next, context)
|
|
79
|
+
if (frame && nextMarkerData) {
|
|
80
|
+
if (nextMarkerData.status === 'resolved') {
|
|
81
|
+
let nextEnd = findFrameEndMarker(next)
|
|
82
|
+
let nextContent = collectFrameContentFragment(current.ownerDocument, next, nextEnd)
|
|
83
|
+
void frame.renderMarkerContent(
|
|
84
|
+
{ ...nextMarkerData, id: getFrameId(next) },
|
|
85
|
+
nextContent,
|
|
86
|
+
{
|
|
87
|
+
data: context.data,
|
|
88
|
+
signal: context.signal,
|
|
89
|
+
},
|
|
90
|
+
)
|
|
91
|
+
return nextEnd
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (frame.isDisplayingResolvedContent()) {
|
|
95
|
+
return findFrameEndMarker(next)
|
|
142
96
|
}
|
|
143
|
-
} else {
|
|
144
|
-
disposeFrameStartMarker(current, context)
|
|
145
|
-
current.data = newData
|
|
146
|
-
updated = true
|
|
147
97
|
}
|
|
148
|
-
}
|
|
149
|
-
|
|
98
|
+
} else if (current.data !== newData) {
|
|
99
|
+
disposeFrameStartMarker(current, context)
|
|
150
100
|
current.data = newData
|
|
101
|
+
updated = true
|
|
151
102
|
}
|
|
152
103
|
}
|
|
104
|
+
if (!updated && current.data !== newData) {
|
|
105
|
+
current.data = newData
|
|
106
|
+
}
|
|
153
107
|
return
|
|
154
108
|
}
|
|
155
109
|
|
|
@@ -166,6 +120,7 @@ function diffNode(current: Node, next: Node, context: FrameContext): ChildNode |
|
|
|
166
120
|
}
|
|
167
121
|
|
|
168
122
|
// Same tag: update attributes then children
|
|
123
|
+
if (shouldPreserveDomElement(current, next)) return
|
|
169
124
|
diffElementAttributes(current, next)
|
|
170
125
|
if (shouldPreserveElementChildren(current, next)) return
|
|
171
126
|
diffElementChildren(current, next, context)
|
|
@@ -205,6 +160,14 @@ function diffElementAttributes(current: Element, next: Element): void {
|
|
|
205
160
|
}
|
|
206
161
|
}
|
|
207
162
|
|
|
163
|
+
function shouldPreserveDomElement(current: Element, next: Element): boolean {
|
|
164
|
+
if (!next.hasAttribute(REMIX_PRESERVE_DOM_ATTRIBUTE)) return false
|
|
165
|
+
if (!current.hasAttribute(REMIX_PRESERVE_DOM_ATTRIBUTE)) {
|
|
166
|
+
current.setAttribute(REMIX_PRESERVE_DOM_ATTRIBUTE, '')
|
|
167
|
+
}
|
|
168
|
+
return true
|
|
169
|
+
}
|
|
170
|
+
|
|
208
171
|
function shouldPreserveLiveAttribute(current: Element, next: Element, name: string): boolean {
|
|
209
172
|
if (name === 'open') {
|
|
210
173
|
if (current instanceof HTMLDetailsElement && next instanceof HTMLDetailsElement) {
|
|
@@ -274,49 +237,70 @@ function isPopoverOpen(element: Element): boolean {
|
|
|
274
237
|
}
|
|
275
238
|
|
|
276
239
|
function diffElementChildren(current: Element, next: Element, context: FrameContext): void {
|
|
277
|
-
let currentChildren
|
|
240
|
+
let currentChildren: Node[]
|
|
241
|
+
|
|
242
|
+
// Allow actively managed preload link tags in the head to stay in the document
|
|
243
|
+
// during diffing rather than removing them which aborts the preload in Safari
|
|
244
|
+
if (context.isActiveModulePreload && current === current.ownerDocument.head) {
|
|
245
|
+
currentChildren = []
|
|
246
|
+
for (let node of current.childNodes) {
|
|
247
|
+
if (!context.isActiveModulePreload(node)) currentChildren.push(node)
|
|
248
|
+
}
|
|
249
|
+
} else {
|
|
250
|
+
currentChildren = Array.from(current.childNodes)
|
|
251
|
+
}
|
|
278
252
|
let nextChildren = Array.from(next.childNodes)
|
|
253
|
+
diffSiblingUnits(currentChildren, nextChildren, current, null, context)
|
|
254
|
+
}
|
|
279
255
|
|
|
280
|
-
|
|
256
|
+
function diffSiblingUnits(
|
|
257
|
+
currentNodes: Node[],
|
|
258
|
+
nextNodes: Node[],
|
|
259
|
+
parent: ParentNode,
|
|
260
|
+
regionTailRef: ChildNode | null,
|
|
261
|
+
context: FrameContext,
|
|
262
|
+
): void {
|
|
263
|
+
let currentUnits = parseSiblingUnits(currentNodes)
|
|
264
|
+
let nextUnits = parseSiblingUnits(nextNodes)
|
|
281
265
|
let keyToIndex = new Map<string, number>()
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (key != null) keyToIndex.set(key, i)
|
|
287
|
-
}
|
|
266
|
+
|
|
267
|
+
for (let i = 0; i < currentUnits.length; i++) {
|
|
268
|
+
let key = getSiblingUnitKey(currentUnits[i])
|
|
269
|
+
if (key !== undefined) keyToIndex.set(key, i)
|
|
288
270
|
}
|
|
289
271
|
|
|
290
|
-
let used = new Array<boolean>(
|
|
291
|
-
let matchIndexForNext = new Array<number>(
|
|
272
|
+
let used = new Array<boolean>(currentUnits.length).fill(false)
|
|
273
|
+
let matchIndexForNext = new Array<number>(nextUnits.length).fill(-1)
|
|
292
274
|
|
|
293
|
-
|
|
294
|
-
|
|
275
|
+
// Reserve globally matched keyed elements and semantic boundaries before
|
|
276
|
+
// positionally pairing the remaining ordinary siblings.
|
|
277
|
+
for (let i = 0; i < nextUnits.length; i++) {
|
|
278
|
+
let nextUnit = nextUnits[i]
|
|
295
279
|
let matchIndex = -1
|
|
280
|
+
let key = getSiblingUnitKey(nextUnit)
|
|
296
281
|
|
|
297
|
-
if (
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
let key = nextChild.getAttribute('data-key')
|
|
306
|
-
if (key != null && keyToIndex.has(key)) {
|
|
307
|
-
let idx = keyToIndex.get(key)!
|
|
308
|
-
if (!used[idx]) matchIndex = idx
|
|
282
|
+
if (key !== undefined) {
|
|
283
|
+
let keyedIndex = keyToIndex.get(key)
|
|
284
|
+
if (
|
|
285
|
+
keyedIndex !== undefined &&
|
|
286
|
+
!used[keyedIndex] &&
|
|
287
|
+
siblingUnitsComparable(currentUnits[keyedIndex], nextUnit)
|
|
288
|
+
) {
|
|
289
|
+
matchIndex = keyedIndex
|
|
309
290
|
}
|
|
310
291
|
}
|
|
311
292
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
293
|
+
// Boundary identities behave like implicit keys. Repeated boundaries with
|
|
294
|
+
// the same identity are paired in source order because server markers do
|
|
295
|
+
// not carry a separate application key.
|
|
296
|
+
if (matchIndex === -1 && nextUnit.kind !== 'node') {
|
|
297
|
+
for (let j = 0; j < currentUnits.length; j++) {
|
|
298
|
+
let currentUnit = currentUnits[j]
|
|
299
|
+
if (used[j] || currentUnit.kind !== nextUnit.kind) continue
|
|
300
|
+
if (shouldPreserveBoundaryUnit(currentUnit, nextUnit, context)) {
|
|
301
|
+
matchIndex = j
|
|
302
|
+
break
|
|
303
|
+
}
|
|
320
304
|
}
|
|
321
305
|
}
|
|
322
306
|
|
|
@@ -324,136 +308,229 @@ function diffElementChildren(current: Element, next: Element, context: FrameCont
|
|
|
324
308
|
matchIndexForNext[i] = matchIndex
|
|
325
309
|
}
|
|
326
310
|
|
|
327
|
-
|
|
328
|
-
let
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
if (mi !== -1) {
|
|
332
|
-
let curChild = currentChildren[mi]
|
|
333
|
-
let nextChild = nextChildren[i]
|
|
334
|
-
|
|
335
|
-
let replacement = getCommentMarkerRangeReplacement(
|
|
336
|
-
curChild,
|
|
337
|
-
nextChild,
|
|
338
|
-
currentChildren,
|
|
339
|
-
nextChildren,
|
|
340
|
-
mi,
|
|
341
|
-
i,
|
|
342
|
-
context,
|
|
343
|
-
)
|
|
344
|
-
if (replacement) {
|
|
345
|
-
replaceCommentMarkerRange(replacement, current, context)
|
|
311
|
+
let remainingCurrentIndexes: number[] = []
|
|
312
|
+
for (let i = 0; i < currentUnits.length; i++) {
|
|
313
|
+
if (!used[i]) remainingCurrentIndexes.push(i)
|
|
314
|
+
}
|
|
346
315
|
|
|
347
|
-
|
|
316
|
+
let remainingNextIndexes: number[] = []
|
|
317
|
+
for (let i = 0; i < nextUnits.length; i++) {
|
|
318
|
+
if (matchIndexForNext[i] === -1) remainingNextIndexes.push(i)
|
|
319
|
+
}
|
|
348
320
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
321
|
+
let remainingLength = Math.min(remainingCurrentIndexes.length, remainingNextIndexes.length)
|
|
322
|
+
for (let i = 0; i < remainingLength; i++) {
|
|
323
|
+
let currentIndex = remainingCurrentIndexes[i]
|
|
324
|
+
let nextIndex = remainingNextIndexes[i]
|
|
325
|
+
let currentUnit = currentUnits[currentIndex]
|
|
326
|
+
let nextUnit = nextUnits[nextIndex]
|
|
352
327
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
328
|
+
if (
|
|
329
|
+
currentUnit.kind !== 'node' ||
|
|
330
|
+
nextUnit.kind !== 'node' ||
|
|
331
|
+
getSiblingUnitKey(currentUnit) !== undefined ||
|
|
332
|
+
getSiblingUnitKey(nextUnit) !== undefined ||
|
|
333
|
+
!siblingUnitsComparable(currentUnit, nextUnit)
|
|
334
|
+
) {
|
|
335
|
+
continue
|
|
336
|
+
}
|
|
356
337
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
// the next end marker, so skip the owned interior nodes here.
|
|
361
|
-
let nextEndIdx = nextChildren.indexOf(cursor)
|
|
362
|
-
let currEndIdx =
|
|
363
|
-
isFrameStartMarker(curChild) && isFrameEndMarker(cursor)
|
|
364
|
-
? findFrameEndIndex(currentChildren, mi)
|
|
365
|
-
: findHydrationEndIndex(currentChildren, mi)
|
|
366
|
-
|
|
367
|
-
// Adjacent marker ranges can pre-match into the next range and leave an
|
|
368
|
-
// orphaned end marker behind. Clear those stale matches first.
|
|
369
|
-
for (let j = i + 1; j <= nextEndIdx; j++) {
|
|
370
|
-
let matchedIndex = matchIndexForNext[j]
|
|
371
|
-
if (matchedIndex > currEndIdx) {
|
|
372
|
-
used[matchedIndex] = false
|
|
373
|
-
}
|
|
374
|
-
matchIndexForNext[j] = -1
|
|
375
|
-
}
|
|
338
|
+
used[currentIndex] = true
|
|
339
|
+
matchIndexForNext[nextIndex] = currentIndex
|
|
340
|
+
}
|
|
376
341
|
|
|
377
|
-
|
|
378
|
-
|
|
342
|
+
let committed = new Array<SiblingUnit>(nextUnits.length)
|
|
343
|
+
for (let i = 0; i < nextUnits.length; i++) {
|
|
344
|
+
let matchIndex = matchIndexForNext[i]
|
|
345
|
+
let nextUnit = nextUnits[i]
|
|
346
|
+
if (matchIndex === -1) {
|
|
347
|
+
committed[i] = nextUnit
|
|
348
|
+
continue
|
|
349
|
+
}
|
|
379
350
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
351
|
+
let currentUnit = currentUnits[matchIndex]
|
|
352
|
+
if (currentUnit.kind === 'node' && nextUnit.kind === 'node') {
|
|
353
|
+
diffNode(currentUnit.node, nextUnit.node, context)
|
|
354
|
+
committed[i] = currentUnit
|
|
355
|
+
continue
|
|
356
|
+
}
|
|
384
357
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
358
|
+
invariant(currentUnit.kind !== 'node' && nextUnit.kind !== 'node', 'Expected boundaries')
|
|
359
|
+
|
|
360
|
+
let replacement = getCommentMarkerRangeReplacement(
|
|
361
|
+
currentUnit.start,
|
|
362
|
+
nextUnit.start,
|
|
363
|
+
currentNodes,
|
|
364
|
+
nextNodes,
|
|
365
|
+
currentUnit.startIndex,
|
|
366
|
+
nextUnit.startIndex,
|
|
367
|
+
context,
|
|
368
|
+
)
|
|
369
|
+
if (replacement) {
|
|
370
|
+
replaceCommentMarkerRange(replacement, parent, context)
|
|
371
|
+
committed[i] = nextUnit
|
|
372
|
+
continue
|
|
392
373
|
}
|
|
374
|
+
|
|
375
|
+
let cursor = diffNode(currentUnit.start, nextUnit.start, context)
|
|
376
|
+
if (!cursor && currentUnit.kind === 'frame' && nextUnit.kind === 'frame') {
|
|
377
|
+
diffNodes(
|
|
378
|
+
collectNodesBetween(currentUnit.start, currentUnit.end),
|
|
379
|
+
nextNodes.slice(nextUnit.startIndex + 1, nextUnit.endIndex),
|
|
380
|
+
{
|
|
381
|
+
...context,
|
|
382
|
+
regionParent: parent,
|
|
383
|
+
regionTailRef: currentUnit.end,
|
|
384
|
+
},
|
|
385
|
+
)
|
|
386
|
+
}
|
|
387
|
+
committed[i] = currentUnit
|
|
393
388
|
}
|
|
394
389
|
|
|
395
|
-
|
|
396
|
-
let anchor: Node | undefined = undefined
|
|
390
|
+
let anchor: Node | null = regionTailRef
|
|
397
391
|
for (let i = committed.length - 1; i >= 0; i--) {
|
|
398
|
-
let
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
// Use only an anchor that is actually a child of the current parent
|
|
402
|
-
let ref = anchor && anchor.parentNode === current ? anchor : null
|
|
392
|
+
let unit = committed[i]
|
|
393
|
+
let first = getSiblingUnitFirstNode(unit)
|
|
394
|
+
let ref = anchor?.parentNode === parent ? anchor : null
|
|
403
395
|
|
|
404
|
-
// Existing comment markers delimit live ranges, so do not reorder them
|
|
405
|
-
// independently from their contents. New markers still need to be inserted
|
|
406
|
-
// before they can be used as anchors.
|
|
407
396
|
if (
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
isFrameEndMarker(node)
|
|
397
|
+
unit.kind === 'node' &&
|
|
398
|
+
isPreservedDomElement(unit.node) &&
|
|
399
|
+
unit.node.parentNode === parent
|
|
412
400
|
) {
|
|
413
|
-
|
|
414
|
-
current.insertBefore(node, ref)
|
|
415
|
-
}
|
|
416
|
-
anchor = node
|
|
401
|
+
anchor = unit.node
|
|
417
402
|
continue
|
|
418
403
|
}
|
|
419
404
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
405
|
+
placeSiblingUnitBefore(unit, parent, ref)
|
|
406
|
+
if (first.parentNode === parent) anchor = first
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
for (let i = 0; i < currentUnits.length; i++) {
|
|
410
|
+
if (!used[i]) removeSiblingUnit(currentUnits[i], parent, context)
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function parseSiblingUnits(nodes: Node[]): SiblingUnit[] {
|
|
415
|
+
let units: SiblingUnit[] = []
|
|
416
|
+
|
|
417
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
418
|
+
let node = nodes[i]
|
|
419
|
+
if (isVirtualRootStartMarker(node)) {
|
|
420
|
+
let endIndex = findHydrationEndIndex(nodes, i)
|
|
421
|
+
invariant(endIndex > i, 'Hydration end marker not found')
|
|
422
|
+
let end = nodes[endIndex]
|
|
423
|
+
invariant(isVirtualRootEndMarker(end), 'Expected hydration end marker')
|
|
424
|
+
units.push({ kind: 'hydration', start: node, end, startIndex: i, endIndex })
|
|
425
|
+
i = endIndex
|
|
426
|
+
continue
|
|
431
427
|
}
|
|
432
428
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
429
|
+
if (isFrameStartMarker(node)) {
|
|
430
|
+
let endIndex = findFrameEndIndex(nodes, i)
|
|
431
|
+
invariant(endIndex > i, 'Frame end marker not found')
|
|
432
|
+
let end = nodes[endIndex]
|
|
433
|
+
invariant(isFrameEndMarker(end), 'Expected frame end marker')
|
|
434
|
+
units.push({ kind: 'frame', start: node, end, startIndex: i, endIndex })
|
|
435
|
+
i = endIndex
|
|
436
|
+
continue
|
|
436
437
|
}
|
|
438
|
+
|
|
439
|
+
invariant(!isVirtualRootEndMarker(node), 'Unexpected hydration end marker')
|
|
440
|
+
invariant(!isFrameEndMarker(node), 'Unexpected frame end marker')
|
|
441
|
+
units.push({ kind: 'node', node, startIndex: i, endIndex: i })
|
|
437
442
|
}
|
|
438
443
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
+
return units
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function getSiblingUnitKey(unit: SiblingUnit): string | undefined {
|
|
448
|
+
if (unit.kind !== 'node' || !isElement(unit.node)) return
|
|
449
|
+
return unit.node.getAttribute('data-key') ?? undefined
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function siblingUnitsComparable(current: SiblingUnit, next: SiblingUnit): boolean {
|
|
453
|
+
if (current.kind !== next.kind) return false
|
|
454
|
+
if (current.kind !== 'node' || next.kind !== 'node') return true
|
|
455
|
+
return nodeTypesComparable(current.node, next.node)
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function shouldPreserveBoundaryUnit(
|
|
459
|
+
current: BoundarySiblingUnit,
|
|
460
|
+
next: BoundarySiblingUnit,
|
|
461
|
+
context: FrameContext,
|
|
462
|
+
): boolean {
|
|
463
|
+
if (current.kind !== next.kind) return false
|
|
464
|
+
return current.kind === 'frame'
|
|
465
|
+
? shouldPreserveFrameStartMarker(current.start, next.start, context)
|
|
466
|
+
: shouldPreserveHydrationStartMarker(current.start, next.start, context)
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function getSiblingUnitFirstNode(unit: SiblingUnit): Node {
|
|
470
|
+
return unit.kind === 'node' ? unit.node : unit.start
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function placeSiblingUnitBefore(unit: SiblingUnit, parent: ParentNode, ref: Node | null): void {
|
|
474
|
+
if (unit.kind === 'node') {
|
|
475
|
+
if (unit.node.parentNode !== parent || unit.node.nextSibling !== ref) {
|
|
476
|
+
parent.insertBefore(unit.node, ref)
|
|
444
477
|
}
|
|
478
|
+
return
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
let nodes = collectNodeRange(unit.start, unit.end)
|
|
482
|
+
if (unit.start.parentNode === parent && unit.end.nextSibling === ref) return
|
|
483
|
+
|
|
484
|
+
let fragment = unit.start.ownerDocument.createDocumentFragment()
|
|
485
|
+
for (let node of nodes) fragment.appendChild(node)
|
|
486
|
+
parent.insertBefore(fragment, ref)
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function removeSiblingUnit(unit: SiblingUnit, parent: ParentNode, context: FrameContext): void {
|
|
490
|
+
if (unit.kind === 'node') {
|
|
491
|
+
removeNode(unit.node, parent, context)
|
|
492
|
+
return
|
|
445
493
|
}
|
|
494
|
+
|
|
495
|
+
for (let node of collectNodeRange(unit.start, unit.end)) {
|
|
496
|
+
removeNode(node, parent, context)
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function collectNodesBetween(start: Comment, end: Comment): Node[] {
|
|
501
|
+
let nodes: Node[] = []
|
|
502
|
+
let node = start.nextSibling
|
|
503
|
+
while (node && node !== end) {
|
|
504
|
+
nodes.push(node)
|
|
505
|
+
node = node.nextSibling
|
|
506
|
+
}
|
|
507
|
+
return nodes
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function isPreservedDomElement(node: Node): node is Element {
|
|
511
|
+
return isElement(node) && node.hasAttribute(REMIX_PRESERVE_DOM_ATTRIBUTE)
|
|
446
512
|
}
|
|
447
513
|
|
|
448
514
|
function nodeTypesComparable(a: Node, b: Node): boolean {
|
|
449
515
|
if (isTextNode(a) && isTextNode(b)) return true
|
|
450
516
|
if (isElement(a) && isElement(b)) return a.tagName === b.tagName
|
|
451
|
-
if (
|
|
452
|
-
if (isVirtualRootEndMarker(a) && isVirtualRootEndMarker(b)) return true
|
|
453
|
-
if (isCommentNode(a) && isCommentNode(b)) return true
|
|
517
|
+
if (isCommentNode(a) && isCommentNode(b)) return markerKindsMatch(a, b)
|
|
454
518
|
return false
|
|
455
519
|
}
|
|
456
520
|
|
|
521
|
+
function getMarkerKind(node: Node): MarkerKind | undefined {
|
|
522
|
+
if (!isCommentNode(node)) return undefined
|
|
523
|
+
if (isFrameStartMarker(node)) return 'frame-start'
|
|
524
|
+
if (isFrameEndMarker(node)) return 'frame-end'
|
|
525
|
+
if (isVirtualRootStartMarker(node)) return 'virtual-root-start'
|
|
526
|
+
if (isVirtualRootEndMarker(node)) return 'virtual-root-end'
|
|
527
|
+
return undefined
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function markerKindsMatch(a: Node, b: Node): boolean {
|
|
531
|
+
return getMarkerKind(a) === getMarkerKind(b)
|
|
532
|
+
}
|
|
533
|
+
|
|
457
534
|
function isHydrationEndComment(node: Node): node is Comment {
|
|
458
535
|
return isCommentNode(node) && node.data.trim() === '/rmx:h'
|
|
459
536
|
}
|
|
@@ -477,8 +554,15 @@ function findHydrationEndMarker(start: Comment): Comment {
|
|
|
477
554
|
}
|
|
478
555
|
|
|
479
556
|
function findHydrationEndIndex(nodes: Node[], startIdx: number): number {
|
|
557
|
+
let depth = 1
|
|
558
|
+
|
|
480
559
|
for (let j = startIdx + 1; j < nodes.length; j++) {
|
|
481
|
-
|
|
560
|
+
let node = nodes[j]
|
|
561
|
+
if (isVirtualRootStartMarker(node)) depth++
|
|
562
|
+
if (isHydrationEndComment(node)) {
|
|
563
|
+
depth--
|
|
564
|
+
if (depth === 0) return j
|
|
565
|
+
}
|
|
482
566
|
}
|
|
483
567
|
return startIdx
|
|
484
568
|
}
|
|
@@ -541,14 +625,31 @@ function shouldPreserveFrameStartMarker(
|
|
|
541
625
|
): boolean {
|
|
542
626
|
if (!isFrameStartMarker(next)) return false
|
|
543
627
|
|
|
544
|
-
let currentData = getFrameMarkerData(current, context)
|
|
545
628
|
let nextData = getFrameMarkerData(next, context)
|
|
629
|
+
let currentFrame = context.frameInstances.get(current)
|
|
630
|
+
|
|
631
|
+
return (
|
|
632
|
+
currentFrame !== undefined &&
|
|
633
|
+
nextData !== undefined &&
|
|
634
|
+
currentFrame.matchesIdentity(nextData.src, nextData.name)
|
|
635
|
+
)
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function shouldPreserveHydrationStartMarker(
|
|
639
|
+
current: Comment,
|
|
640
|
+
next: Comment,
|
|
641
|
+
context: FrameContext,
|
|
642
|
+
): boolean {
|
|
643
|
+
if (!isVirtualRootStartMarker(next)) return false
|
|
644
|
+
|
|
645
|
+
let currentOwner = getClientEntryBoundaryOwner(current)
|
|
646
|
+
let nextData = getHydrationMarkerData(next, context)
|
|
546
647
|
|
|
547
648
|
return (
|
|
548
|
-
|
|
649
|
+
currentOwner !== undefined &&
|
|
549
650
|
nextData !== undefined &&
|
|
550
|
-
|
|
551
|
-
|
|
651
|
+
currentOwner.identity.moduleUrl === nextData.moduleUrl &&
|
|
652
|
+
currentOwner.identity.exportName === nextData.exportName
|
|
552
653
|
)
|
|
553
654
|
}
|
|
554
655
|
|
|
@@ -576,6 +677,30 @@ function getCommentMarkerRangeReplacement(
|
|
|
576
677
|
nextEndIndex: findFrameEndIndex(nextNodes, nextIndex),
|
|
577
678
|
}
|
|
578
679
|
}
|
|
680
|
+
|
|
681
|
+
if (
|
|
682
|
+
isVirtualRootStartMarker(current) &&
|
|
683
|
+
isVirtualRootStartMarker(next) &&
|
|
684
|
+
!shouldPreserveHydrationStartMarker(current, next, context)
|
|
685
|
+
) {
|
|
686
|
+
return {
|
|
687
|
+
currentStart: current,
|
|
688
|
+
nextStart: next,
|
|
689
|
+
currentEndIndex: findHydrationEndIndex(currentNodes, currentIndex),
|
|
690
|
+
nextEndIndex: findHydrationEndIndex(nextNodes, nextIndex),
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
function getHydrationMarkerData(marker: Comment, context: FrameContext) {
|
|
696
|
+
let id = getHydrationId(marker)
|
|
697
|
+
return context.data.h?.[id]
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
function getHydrationId(marker: Comment): string {
|
|
701
|
+
let trimmed = marker.data.trim()
|
|
702
|
+
invariant(trimmed.startsWith('rmx:h:'), 'Invalid hydration start marker')
|
|
703
|
+
return trimmed.slice('rmx:h:'.length)
|
|
579
704
|
}
|
|
580
705
|
|
|
581
706
|
function getFrameMarkerData(marker: Comment, context: FrameContext) {
|
|
@@ -594,8 +719,8 @@ function replaceCommentMarkerRange(
|
|
|
594
719
|
parent: ParentNode,
|
|
595
720
|
context: FrameContext,
|
|
596
721
|
): void {
|
|
597
|
-
let currentEnd =
|
|
598
|
-
let nextEnd =
|
|
722
|
+
let currentEnd = findCommentMarkerRangeEnd(replacement.currentStart)
|
|
723
|
+
let nextEnd = findCommentMarkerRangeEnd(replacement.nextStart)
|
|
599
724
|
let nextNodes = collectNodeRange(replacement.nextStart, nextEnd)
|
|
600
725
|
let currentNodes = collectNodeRange(replacement.currentStart, currentEnd)
|
|
601
726
|
|
|
@@ -608,6 +733,12 @@ function replaceCommentMarkerRange(
|
|
|
608
733
|
}
|
|
609
734
|
}
|
|
610
735
|
|
|
736
|
+
function findCommentMarkerRangeEnd(start: Comment): Comment {
|
|
737
|
+
if (isFrameStartMarker(start)) return findFrameEndMarker(start)
|
|
738
|
+
if (isVirtualRootStartMarker(start)) return findHydrationEndMarker(start)
|
|
739
|
+
throw new Error('Comment marker range start not found')
|
|
740
|
+
}
|
|
741
|
+
|
|
611
742
|
function collectNodeRange(start: Node, end: Node): Node[] {
|
|
612
743
|
let nodes: Node[] = []
|
|
613
744
|
let node: Node | null = start
|
|
@@ -653,8 +784,7 @@ function disposeRemovedVirtualRoots(node: Node): void {
|
|
|
653
784
|
let next = stack.pop()
|
|
654
785
|
if (!next) continue
|
|
655
786
|
|
|
656
|
-
if (
|
|
657
|
-
next.$rmx.dispose()
|
|
787
|
+
if (isVirtualRootStartMarker(next) && disposeClientEntryBoundary(next)) {
|
|
658
788
|
continue
|
|
659
789
|
}
|
|
660
790
|
|
|
@@ -692,10 +822,6 @@ function isVirtualRootStartMarker(node: Node): node is Comment {
|
|
|
692
822
|
return isCommentNode(node) && node.data.trim().startsWith('rmx:h:')
|
|
693
823
|
}
|
|
694
824
|
|
|
695
|
-
function isHydratedVirtualRootStartMarker(node: Node): node is HydratedVirtualRootStartMarker {
|
|
696
|
-
return isVirtualRootStartMarker(node) && '$rmx' in node
|
|
697
|
-
}
|
|
698
|
-
|
|
699
825
|
function isVirtualRootEndMarker(node: Node): node is Comment {
|
|
700
826
|
return isCommentNode(node) && node.data.trim() === '/rmx:h'
|
|
701
827
|
}
|