@@ -15,7 +15,7 @@ import { mockWarn } from '@vue/shared'
15
15
describe ( 'attribute fallthrough' , ( ) => {
16
16
mockWarn ( )
17
17
18
- it ( 'everything should be in props when component has no declared props ' , async ( ) => {
18
+ it ( 'should allow whitelisted attrs to fallthrough ' , async ( ) => {
19
19
const click = jest . fn ( )
20
20
const childUpdated = jest . fn ( )
21
21
@@ -42,113 +42,42 @@ describe('attribute fallthrough', () => {
42
42
43
43
const Child = {
44
44
setup ( props : any ) {
45
- onUpdated ( childUpdated )
46
- return ( ) =>
47
- h (
48
- 'div' ,
49
- mergeProps (
50
- {
51
- class : 'c2' ,
52
- style : { fontWeight : 'bold' }
53
- } ,
54
- props
55
- ) ,
56
- props . foo
57
- )
58
- }
59
- }
60
-
61
- const root = document . createElement ( 'div' )
62
- document . body . appendChild ( root )
63
- render ( h ( Hello ) , root )
64
-
65
- const node = root . children [ 0 ] as HTMLElement
66
-
67
- expect ( node . getAttribute ( 'id' ) ) . toBe ( 'test' )
68
- expect ( node . getAttribute ( 'foo' ) ) . toBe ( '1' )
69
- expect ( node . getAttribute ( 'class' ) ) . toBe ( 'c2 c0' )
70
- expect ( node . style . color ) . toBe ( 'green' )
71
- expect ( node . style . fontWeight ) . toBe ( 'bold' )
72
- expect ( node . dataset . id ) . toBe ( '1' )
73
- node . dispatchEvent ( new CustomEvent ( 'click' ) )
74
- expect ( click ) . toHaveBeenCalled ( )
75
-
76
- await nextTick ( )
77
- expect ( childUpdated ) . toHaveBeenCalled ( )
78
- expect ( node . getAttribute ( 'id' ) ) . toBe ( 'test' )
79
- expect ( node . getAttribute ( 'foo' ) ) . toBe ( '1' )
80
- expect ( node . getAttribute ( 'class' ) ) . toBe ( 'c2 c1' )
81
- expect ( node . style . color ) . toBe ( 'red' )
82
- expect ( node . style . fontWeight ) . toBe ( 'bold' )
83
- } )
84
-
85
- it ( 'should implicitly fallthrough on single root nodes' , async ( ) => {
86
- const click = jest . fn ( )
87
- const childUpdated = jest . fn ( )
88
-
89
- const Hello = {
90
- setup ( ) {
91
- const count = ref ( 0 )
92
-
93
- function inc ( ) {
94
- count . value ++
95
- click ( )
96
- }
97
-
98
- return ( ) =>
99
- h ( Child , {
100
- foo : 1 ,
101
- id : 'test' ,
102
- class : 'c' + count . value ,
103
- style : { color : count . value ? 'red' : 'green' } ,
104
- onClick : inc
105
- } )
106
- }
107
- }
108
-
109
- const Child = defineComponent ( {
110
- props : {
111
- foo : Number
112
- } ,
113
- setup ( props ) {
114
45
onUpdated ( childUpdated )
115
46
return ( ) =>
116
47
h (
117
48
'div' ,
118
49
{
50
+ id : props . id , // id is not whitelisted
119
51
class : 'c2' ,
120
52
style : { fontWeight : 'bold' }
121
53
} ,
122
54
props . foo
123
55
)
124
56
}
125
- } )
57
+ }
126
58
127
59
const root = document . createElement ( 'div' )
128
60
document . body . appendChild ( root )
129
61
render ( h ( Hello ) , root )
130
62
131
63
const node = root . children [ 0 ] as HTMLElement
132
64
133
- // with declared props, any parent attr that isn't a prop falls through
134
- expect ( node . getAttribute ( 'id ' ) ) . toBe ( 'test' )
65
+ expect ( node . getAttribute ( 'id' ) ) . toBe ( 'test' ) // id is not whitelisted, but explicitly bound
66
+ expect ( node . getAttribute ( 'foo ' ) ) . toBe ( null ) // foo is not whitelisted
135
67
expect ( node . getAttribute ( 'class' ) ) . toBe ( 'c2 c0' )
136
68
expect ( node . style . color ) . toBe ( 'green' )
137
69
expect ( node . style . fontWeight ) . toBe ( 'bold' )
70
+ expect ( node . dataset . id ) . toBe ( '1' )
138
71
node . dispatchEvent ( new CustomEvent ( 'click' ) )
139
72
expect ( click ) . toHaveBeenCalled ( )
140
73
141
- // ...while declared ones remain props
142
- expect ( node . hasAttribute ( 'foo' ) ) . toBe ( false )
143
-
144
74
await nextTick ( )
145
75
expect ( childUpdated ) . toHaveBeenCalled ( )
146
76
expect ( node . getAttribute ( 'id' ) ) . toBe ( 'test' )
77
+ expect ( node . getAttribute ( 'foo' ) ) . toBe ( null )
147
78
expect ( node . getAttribute ( 'class' ) ) . toBe ( 'c2 c1' )
148
79
expect ( node . style . color ) . toBe ( 'red' )
149
80
expect ( node . style . fontWeight ) . toBe ( 'bold' )
150
-
151
- expect ( node . hasAttribute ( 'foo' ) ) . toBe ( false )
152
81
} )
153
82
154
83
it ( 'should fallthrough for nested components' , async ( ) => {
@@ -179,12 +108,16 @@ describe('attribute fallthrough', () => {
179
108
const Child = {
180
109
setup ( props : any ) {
181
110
onUpdated ( childUpdated )
111
+ // HOC simply passing props down.
112
+ // this will result in merging the same attrs, but should be deduped by
113
+ // `mergeProps`.
182
114
return ( ) => h ( GrandChild , props )
183
115
}
184
116
}
185
117
186
118
const GrandChild = defineComponent ( {
187
119
props : {
120
+ id : String ,
188
121
foo : Number
189
122
} ,
190
123
setup ( props ) {
@@ -193,6 +126,7 @@ describe('attribute fallthrough', () => {
193
126
h (
194
127
'div' ,
195
128
{
129
+ id : props . id ,
196
130
class : 'c2' ,
197
131
style : { fontWeight : 'bold' }
198
132
} ,
@@ -351,11 +285,11 @@ describe('attribute fallthrough', () => {
351
285
352
286
// #677
353
287
it ( 'should update merged dynamic attrs on optimized child root' , async ( ) => {
354
- const id = ref ( 'foo ' )
288
+ const aria = ref ( 'true ' )
355
289
const cls = ref ( 'bar' )
356
290
const Parent = {
357
291
render ( ) {
358
- return h ( Child , { id : id . value , class : cls . value } )
292
+ return h ( Child , { 'aria-hidden' : aria . value , class : cls . value } )
359
293
}
360
294
}
361
295
@@ -370,14 +304,14 @@ describe('attribute fallthrough', () => {
370
304
document . body . appendChild ( root )
371
305
render ( h ( Parent ) , root )
372
306
373
- expect ( root . innerHTML ) . toBe ( `<div id="foo " class="bar"></div>` )
307
+ expect ( root . innerHTML ) . toBe ( `<div aria-hidden="true " class="bar"></div>` )
374
308
375
- id . value = 'fooo '
309
+ aria . value = 'false '
376
310
await nextTick ( )
377
- expect ( root . innerHTML ) . toBe ( `<div id="fooo " class="bar"></div>` )
311
+ expect ( root . innerHTML ) . toBe ( `<div aria-hidden="false " class="bar"></div>` )
378
312
379
313
cls . value = 'barr'
380
314
await nextTick ( )
381
- expect ( root . innerHTML ) . toBe ( `<div id="fooo " class="barr"></div>` )
315
+ expect ( root . innerHTML ) . toBe ( `<div aria-hidden="false " class="barr"></div>` )
382
316
} )
383
317
} )
0 commit comments