@@ -161,20 +161,26 @@ describe('SSR hydration', () => {
161
161
portalContainer . innerHTML = `<span>foo</span><span class="foo"></span><!---->`
162
162
document . body . appendChild ( portalContainer )
163
163
164
- const { vnode, container } = mountWithHydration ( '<!--portal-->' , ( ) =>
165
- h ( Portal , { target : '#portal' } , [
166
- h ( 'span' , msg . value ) ,
167
- h ( 'span' , { class : msg . value , onClick : fn } )
168
- ] )
164
+ const { vnode, container } = mountWithHydration (
165
+ '<!--portal start--><!--portal end-->' ,
166
+ ( ) =>
167
+ h ( Portal , { target : '#portal' } , [
168
+ h ( 'span' , msg . value ) ,
169
+ h ( 'span' , { class : msg . value , onClick : fn } )
170
+ ] )
169
171
)
170
172
171
173
expect ( vnode . el ) . toBe ( container . firstChild )
174
+ expect ( vnode . anchor ) . toBe ( container . lastChild )
175
+
176
+ expect ( vnode . target ) . toBe ( portalContainer )
172
177
expect ( ( vnode . children as VNode [ ] ) [ 0 ] . el ) . toBe (
173
178
portalContainer . childNodes [ 0 ]
174
179
)
175
180
expect ( ( vnode . children as VNode [ ] ) [ 1 ] . el ) . toBe (
176
181
portalContainer . childNodes [ 1 ]
177
182
)
183
+ expect ( vnode . targetAnchor ) . toBe ( portalContainer . childNodes [ 2 ] )
178
184
179
185
// event handler
180
186
triggerEvent ( 'click' , portalContainer . querySelector ( '.foo' ) ! )
@@ -208,7 +214,7 @@ describe('SSR hydration', () => {
208
214
const ctx : SSRContext = { }
209
215
const mainHtml = await renderToString ( h ( Comp ) , ctx )
210
216
expect ( mainHtml ) . toMatchInlineSnapshot (
211
- `"<!--[--><!--portal--><!--portal--><!--]-->"`
217
+ `"<!--[--><!--portal start --><!--portal end--><!--portal start--><!--portal end --><!--]-->"`
212
218
)
213
219
214
220
const portalHtml = ctx . portals ! [ '#portal2' ]
@@ -224,16 +230,21 @@ describe('SSR hydration', () => {
224
230
const portalVnode1 = ( vnode . children as VNode [ ] ) [ 0 ]
225
231
const portalVnode2 = ( vnode . children as VNode [ ] ) [ 1 ]
226
232
expect ( portalVnode1 . el ) . toBe ( container . childNodes [ 1 ] )
227
- expect ( portalVnode2 . el ) . toBe ( container . childNodes [ 2 ] )
233
+ expect ( portalVnode1 . anchor ) . toBe ( container . childNodes [ 2 ] )
234
+ expect ( portalVnode2 . el ) . toBe ( container . childNodes [ 3 ] )
235
+ expect ( portalVnode2 . anchor ) . toBe ( container . childNodes [ 4 ] )
228
236
237
+ expect ( portalVnode1 . target ) . toBe ( portalContainer )
229
238
expect ( ( portalVnode1 as any ) . children [ 0 ] . el ) . toBe (
230
239
portalContainer . childNodes [ 0 ]
231
240
)
232
- expect ( portalVnode1 . anchor ) . toBe ( portalContainer . childNodes [ 2 ] )
241
+ expect ( portalVnode1 . targetAnchor ) . toBe ( portalContainer . childNodes [ 2 ] )
242
+
243
+ expect ( portalVnode2 . target ) . toBe ( portalContainer )
233
244
expect ( ( portalVnode2 as any ) . children [ 0 ] . el ) . toBe (
234
245
portalContainer . childNodes [ 3 ]
235
246
)
236
- expect ( portalVnode2 . anchor ) . toBe ( portalContainer . childNodes [ 5 ] )
247
+ expect ( portalVnode2 . targetAnchor ) . toBe ( portalContainer . childNodes [ 5 ] )
237
248
238
249
// // event handler
239
250
triggerEvent ( 'click' , portalContainer . querySelector ( '.foo' ) ! )
@@ -249,6 +260,68 @@ describe('SSR hydration', () => {
249
260
)
250
261
} )
251
262
263
+ test ( 'Portal (disabled)' , async ( ) => {
264
+ const msg = ref ( 'foo' )
265
+ const fn1 = jest . fn ( )
266
+ const fn2 = jest . fn ( )
267
+
268
+ const Comp = ( ) => [
269
+ h ( 'div' , 'foo' ) ,
270
+ h ( Portal , { target : '#portal3' , disabled : true } , [
271
+ h ( 'span' , msg . value ) ,
272
+ h ( 'span' , { class : msg . value , onClick : fn1 } )
273
+ ] ) ,
274
+ h ( 'div' , { class : msg . value + '2' , onClick : fn2 } , 'bar' )
275
+ ]
276
+
277
+ const portalContainer = document . createElement ( 'div' )
278
+ portalContainer . id = 'portal3'
279
+ const ctx : SSRContext = { }
280
+ const mainHtml = await renderToString ( h ( Comp ) , ctx )
281
+ expect ( mainHtml ) . toMatchInlineSnapshot (
282
+ `"<!--[--><div>foo</div><!--portal start--><span>foo</span><span class=\\"foo\\"></span><!--portal end--><div class=\\"foo2\\">bar</div><!--]-->"`
283
+ )
284
+
285
+ const portalHtml = ctx . portals ! [ '#portal3' ]
286
+ expect ( portalHtml ) . toMatchInlineSnapshot ( `"<!---->"` )
287
+
288
+ portalContainer . innerHTML = portalHtml
289
+ document . body . appendChild ( portalContainer )
290
+
291
+ const { vnode, container } = mountWithHydration ( mainHtml , Comp )
292
+ expect ( vnode . el ) . toBe ( container . firstChild )
293
+ const children = vnode . children as VNode [ ]
294
+
295
+ expect ( children [ 0 ] . el ) . toBe ( container . childNodes [ 1 ] )
296
+
297
+ const portalVnode = children [ 1 ]
298
+ expect ( portalVnode . el ) . toBe ( container . childNodes [ 2 ] )
299
+ expect ( ( portalVnode . children as VNode [ ] ) [ 0 ] . el ) . toBe (
300
+ container . childNodes [ 3 ]
301
+ )
302
+ expect ( ( portalVnode . children as VNode [ ] ) [ 1 ] . el ) . toBe (
303
+ container . childNodes [ 4 ]
304
+ )
305
+ expect ( portalVnode . anchor ) . toBe ( container . childNodes [ 5 ] )
306
+ expect ( children [ 2 ] . el ) . toBe ( container . childNodes [ 6 ] )
307
+
308
+ expect ( portalVnode . target ) . toBe ( portalContainer )
309
+ expect ( portalVnode . targetAnchor ) . toBe ( portalContainer . childNodes [ 0 ] )
310
+
311
+ // // event handler
312
+ triggerEvent ( 'click' , container . querySelector ( '.foo' ) ! )
313
+ expect ( fn1 ) . toHaveBeenCalled ( )
314
+
315
+ triggerEvent ( 'click' , container . querySelector ( '.foo2' ) ! )
316
+ expect ( fn2 ) . toHaveBeenCalled ( )
317
+
318
+ msg . value = 'bar'
319
+ await nextTick ( )
320
+ expect ( container . innerHTML ) . toMatchInlineSnapshot (
321
+ `"<!--[--><div>foo</div><!--portal start--><span>bar</span><span class=\\"bar\\"></span><!--portal end--><div class=\\"bar2\\">bar</div><!--]-->"`
322
+ )
323
+ } )
324
+
252
325
// compile SSR + client render fn from the same template & hydrate
253
326
test ( 'full compiler integration' , async ( ) => {
254
327
const mounted : string [ ] = [ ]
0 commit comments