Skip to content

Commit 01177c8

Browse files
committed
fix: support for .passive modifier
1 parent 27149ca commit 01177c8

File tree

2 files changed

+117
-5
lines changed

2 files changed

+117
-5
lines changed

Diff for: packages/babel-sugar-v-on/src/index.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -183,17 +183,29 @@ export default function(babel) {
183183
.reduce((acc, item) => (acc ? or(acc, item) : item)),
184184
),
185185
)
186-
} else if (key === 'capture') {
187-
event = '!' + event
188-
} else if (key === 'once') {
189-
event = '~' + event
186+
} else if (key === 'capture' || key === 'once' || key === 'passive') {
187+
continue
190188
} else if (key === 'native') {
191189
isNative = true
192190
} else {
193191
keys.push(key)
194192
}
195193
}
196194

195+
// vue has special order of capture/once/passive with
196+
// modifier markers
197+
// SEE
198+
// https://github.com/vuejs/vue/blob/4c98f9de39e18703ec3dbd05b596a1bbc3d0c8e3/src/compiler/helpers.js#L111
199+
if (modifiers.indexOf('capture') > -1) {
200+
event = '!' + event
201+
}
202+
if (modifiers.indexOf('once') > -1) {
203+
event = '~' + event
204+
}
205+
if (modifiers.indexOf('passive') > -1) {
206+
event = '&' + event
207+
}
208+
197209
if (keys.length) {
198210
code.push(genKeyFilter(keys))
199211
}
@@ -251,7 +263,7 @@ export default function(babel) {
251263
}
252264

253265
function addEvent(event, expression, isNative, attributes) {
254-
if (event[0] !== '~' && event[0] !== '!') {
266+
if (event[0] !== '~' && event[0] !== '!' && event[0] !== '&') {
255267
attributes.push(
256268
t.jSXAttribute(
257269
t.jSXIdentifier(`${isNative ? 'nativeOn' : 'on'}-${event}`),

Diff for: packages/babel-sugar-v-on/test/functional.js

+100
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,106 @@ test('should support once and other modifiers', t => {
209209
t.is(stub.calls.length, 1)
210210
})
211211

212+
test('should support passive', t => {
213+
const arr = []
214+
const wrapper = mount({
215+
methods: {
216+
foo(e) {
217+
arr.push(e.defaultPrevented) // will be false
218+
e.preventDefault()
219+
arr.push(e.defaultPrevented) // will be true
220+
},
221+
bar(e) {
222+
arr.push(e.defaultPrevented) // will be false
223+
e.preventDefault() // does nothing since the listener is passive
224+
arr.push(e.defaultPrevented) // still false
225+
},
226+
},
227+
render(h) {
228+
return (
229+
<section>
230+
<div vOn:click={this.foo} />
231+
<div vOn:click_passive={this.bar} />
232+
</section>
233+
)
234+
},
235+
})
236+
const divs = wrapper.findAll('div')
237+
divs.at(0).trigger('click')
238+
divs.at(1).trigger('click')
239+
t.deepEqual(arr, [false, true, false, false])
240+
})
241+
242+
test('should support passive and once', t => {
243+
const arr = []
244+
const wrapper = mount({
245+
methods: {
246+
bar(e) {
247+
arr.push(e.defaultPrevented) // will be false
248+
e.preventDefault() // does nothing since the listener is passive
249+
arr.push(e.defaultPrevented) // still false
250+
},
251+
},
252+
render(h) {
253+
return <div vOn:click_passive_once={this.bar} />
254+
},
255+
})
256+
257+
wrapper.trigger('click')
258+
t.deepEqual(arr, [false, false])
259+
260+
wrapper.trigger('click')
261+
t.deepEqual(arr, [false, false])
262+
})
263+
264+
test('should support passive and other modifiers', t => {
265+
const arr = []
266+
const wrapper = mount({
267+
methods: {
268+
bar(e) {
269+
arr.push(e.defaultPrevented) // will be false
270+
e.preventDefault() // does nothing since the listener is passive
271+
arr.push(e.defaultPrevented) // still false
272+
},
273+
},
274+
render(h) {
275+
return (
276+
<section vOn:click_passive_self={this.bar}>
277+
<div />
278+
</section>
279+
)
280+
},
281+
})
282+
283+
wrapper.trigger('click')
284+
t.deepEqual(arr, [false, false])
285+
286+
wrapper.find('div').trigger('click')
287+
t.deepEqual(arr, [false, false])
288+
})
289+
290+
test("should respect vue' order on special modifer markers", t => {
291+
// This test is especially for `.passive` working with other modifiers
292+
const fn = t.context.stub()
293+
const FC = h => (
294+
<section>
295+
<div vOn:click_once_passive={fn} />
296+
<div vOn:click_passive_once={fn} />
297+
<div vOn:click_passive_capture={fn} />
298+
<div vOn:click_capture_passive={fn} />
299+
</section>
300+
)
301+
302+
const mockCreateElement = (tag, props, children) => {
303+
if (tag === 'div') {
304+
// `&` is always the first if `.passive` present
305+
t.is(Object.keys(props.on)[0].indexOf('&'), 0)
306+
}
307+
}
308+
309+
FC(mockCreateElement)
310+
})
311+
212312
test('should support keyCode', t => {
213313
const stub = t.context.stub()
214314
const wrapper = mount({

0 commit comments

Comments
 (0)