Skip to content

Commit 99a8c6d

Browse files
authored
fix(runtime-vapor): reset insertion state to avoid duplicate block inserts during non-hydration (#13220)
1 parent 99482a4 commit 99a8c6d

File tree

8 files changed

+1533
-1585
lines changed

8 files changed

+1533
-1585
lines changed

packages/compiler-sfc/__tests__/compileStyle.spec.ts

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -211,38 +211,42 @@ color: red
211211
expect(
212212
compileScoped(`.div { color: red; } .div:where(:hover) { color: blue; }`),
213213
).toMatchInlineSnapshot(`
214-
".div[data-v-test] { color: red;
215-
}
216-
.div[data-v-test]:where(:hover) { color: blue;
217-
}"`)
214+
".div[data-v-test] { color: red;
215+
}
216+
.div[data-v-test]:where(:hover) { color: blue;
217+
}"
218+
`)
218219

219220
expect(
220221
compileScoped(`.div { color: red; } .div:is(:hover) { color: blue; }`),
221222
).toMatchInlineSnapshot(`
222-
".div[data-v-test] { color: red;
223-
}
224-
.div[data-v-test]:is(:hover) { color: blue;
225-
}"`)
223+
".div[data-v-test] { color: red;
224+
}
225+
.div[data-v-test]:is(:hover) { color: blue;
226+
}"
227+
`)
226228

227229
expect(
228230
compileScoped(
229231
`.div { color: red; } .div:where(.foo:hover) { color: blue; }`,
230232
),
231233
).toMatchInlineSnapshot(`
232-
".div[data-v-test] { color: red;
233-
}
234-
.div[data-v-test]:where(.foo:hover) { color: blue;
235-
}"`)
234+
".div[data-v-test] { color: red;
235+
}
236+
.div[data-v-test]:where(.foo:hover) { color: blue;
237+
}"
238+
`)
236239

237240
expect(
238241
compileScoped(
239242
`.div { color: red; } .div:is(.foo:hover) { color: blue; }`,
240243
),
241244
).toMatchInlineSnapshot(`
242-
".div[data-v-test] { color: red;
243-
}
244-
.div[data-v-test]:is(.foo:hover) { color: blue;
245-
}"`)
245+
".div[data-v-test] { color: red;
246+
}
247+
.div[data-v-test]:is(.foo:hover) { color: blue;
248+
}"
249+
`)
246250
})
247251

248252
test('media query', () => {

packages/compiler-vapor/src/generators/operation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export function genOperationWithInsertionState(
4444
): CodeFragment[] {
4545
const [frag, push] = buildCodeFragment()
4646
if (isBlockOperation(oper) && oper.parent) {
47-
push(...genInsertionstate(oper, context))
47+
push(...genInsertionState(oper, context))
4848
}
4949
push(...genOperation(oper, context))
5050
return frag
@@ -152,7 +152,7 @@ export function genEffect(
152152
return frag
153153
}
154154

155-
function genInsertionstate(
155+
function genInsertionState(
156156
operation: InsertionStateTypes,
157157
context: CodegenContext,
158158
): CodeFragment[] {

packages/runtime-vapor/src/apiCreateFor.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ import type { DynamicSlot } from './componentSlots'
2323
import { renderEffect } from './renderEffect'
2424
import { VaporVForFlags } from '../../shared/src/vaporFlags'
2525
import { isHydrating, locateHydrationNode } from './dom/hydration'
26-
import { insertionAnchor, insertionParent } from './insertionState'
26+
import {
27+
insertionAnchor,
28+
insertionParent,
29+
resetInsertionState,
30+
} from './insertionState'
2731

2832
class ForBlock extends VaporFragment {
2933
scope: EffectScope | undefined
@@ -72,6 +76,8 @@ export const createFor = (
7276
const _insertionAnchor = insertionAnchor
7377
if (isHydrating) {
7478
locateHydrationNode()
79+
} else {
80+
resetInsertionState()
7581
}
7682

7783
let isMounted = false

packages/runtime-vapor/src/apiCreateIf.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { type Block, type BlockFn, DynamicFragment, insert } from './block'
22
import { isHydrating, locateHydrationNode } from './dom/hydration'
3-
import { insertionAnchor, insertionParent } from './insertionState'
3+
import {
4+
insertionAnchor,
5+
insertionParent,
6+
resetInsertionState,
7+
} from './insertionState'
48
import { renderEffect } from './renderEffect'
59

610
export function createIf(
@@ -13,6 +17,8 @@ export function createIf(
1317
const _insertionAnchor = insertionAnchor
1418
if (isHydrating) {
1519
locateHydrationNode()
20+
} else {
21+
resetInsertionState()
1622
}
1723

1824
let frag: Block

packages/runtime-vapor/src/component.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ import {
5959
} from './componentSlots'
6060
import { hmrReload, hmrRerender } from './hmr'
6161
import { isHydrating, locateHydrationNode } from './dom/hydration'
62-
import { insertionAnchor, insertionParent } from './insertionState'
62+
import {
63+
insertionAnchor,
64+
insertionParent,
65+
resetInsertionState,
66+
} from './insertionState'
6367

6468
export { currentInstance } from '@vue/runtime-dom'
6569

@@ -142,6 +146,8 @@ export function createComponent(
142146
const _insertionAnchor = insertionAnchor
143147
if (isHydrating) {
144148
locateHydrationNode()
149+
} else {
150+
resetInsertionState()
145151
}
146152

147153
// vdom interop enabled and component is not an explicit vapor component

packages/runtime-vapor/src/componentSlots.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import { rawPropsProxyHandlers } from './componentProps'
44
import { currentInstance, isRef } from '@vue/runtime-dom'
55
import type { LooseRawProps, VaporComponentInstance } from './component'
66
import { renderEffect } from './renderEffect'
7-
import { insertionAnchor, insertionParent } from './insertionState'
7+
import {
8+
insertionAnchor,
9+
insertionParent,
10+
resetInsertionState,
11+
} from './insertionState'
812
import { isHydrating, locateHydrationNode } from './dom/hydration'
913

1014
export type RawSlots = Record<string, VaporSlot> & {
@@ -96,6 +100,8 @@ export function createSlot(
96100
const _insertionAnchor = insertionAnchor
97101
if (isHydrating) {
98102
locateHydrationNode()
103+
} else {
104+
resetInsertionState()
99105
}
100106

101107
const instance = currentInstance as VaporComponentInstance

packages/server-renderer/__tests__/webStream.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ test('pipeToWebWritable', async () => {
4949
}
5050

5151
const { readable, writable } = new TransformStream()
52-
pipeToWebWritable(createApp(App), {}, writable)
52+
pipeToWebWritable(createApp(App), {}, writable as any)
5353

5454
const reader = readable.getReader()
5555
const decoder = new TextDecoder()

0 commit comments

Comments
 (0)