diff --git a/packages/babel-sugar-v-on/src/index.js b/packages/babel-sugar-v-on/src/index.js index d654bcd..f713437 100644 --- a/packages/babel-sugar-v-on/src/index.js +++ b/packages/babel-sugar-v-on/src/index.js @@ -183,10 +183,8 @@ export default function(babel) { .reduce((acc, item) => (acc ? or(acc, item) : item)), ), ) - } else if (key === 'capture') { - event = '!' + event - } else if (key === 'once') { - event = '~' + event + } else if (key === 'capture' || key === 'once' || key === 'passive') { + continue } else if (key === 'native') { isNative = true } else { @@ -194,6 +192,20 @@ export default function(babel) { } } + // vue has special order of capture/once/passive with + // modifier markers + // SEE + // https://github.com/vuejs/vue/blob/4c98f9de39e18703ec3dbd05b596a1bbc3d0c8e3/src/compiler/helpers.js#L111 + if (modifiers.indexOf('capture') > -1) { + event = '!' + event + } + if (modifiers.indexOf('once') > -1) { + event = '~' + event + } + if (modifiers.indexOf('passive') > -1) { + event = '&' + event + } + if (keys.length) { code.push(genKeyFilter(keys)) } @@ -251,7 +263,7 @@ export default function(babel) { } function addEvent(event, expression, isNative, attributes) { - if (event[0] !== '~' && event[0] !== '!') { + if (event[0] !== '~' && event[0] !== '!' && event[0] !== '&') { attributes.push( t.jSXAttribute( t.jSXIdentifier(`${isNative ? 'nativeOn' : 'on'}-${event}`), diff --git a/packages/babel-sugar-v-on/test/functional.js b/packages/babel-sugar-v-on/test/functional.js index 3007e12..49de229 100644 --- a/packages/babel-sugar-v-on/test/functional.js +++ b/packages/babel-sugar-v-on/test/functional.js @@ -209,6 +209,106 @@ test('should support once and other modifiers', t => { t.is(stub.calls.length, 1) }) +test('should support passive', t => { + const arr = [] + const wrapper = mount({ + methods: { + foo(e) { + arr.push(e.defaultPrevented) // will be false + e.preventDefault() + arr.push(e.defaultPrevented) // will be true + }, + bar(e) { + arr.push(e.defaultPrevented) // will be false + e.preventDefault() // does nothing since the listener is passive + arr.push(e.defaultPrevented) // still false + }, + }, + render(h) { + return ( +
+
+
+
+ ) + }, + }) + const divs = wrapper.findAll('div') + divs.at(0).trigger('click') + divs.at(1).trigger('click') + t.deepEqual(arr, [false, true, false, false]) +}) + +test('should support passive and once', t => { + const arr = [] + const wrapper = mount({ + methods: { + bar(e) { + arr.push(e.defaultPrevented) // will be false + e.preventDefault() // does nothing since the listener is passive + arr.push(e.defaultPrevented) // still false + }, + }, + render(h) { + return
+ }, + }) + + wrapper.trigger('click') + t.deepEqual(arr, [false, false]) + + wrapper.trigger('click') + t.deepEqual(arr, [false, false]) +}) + +test('should support passive and other modifiers', t => { + const arr = [] + const wrapper = mount({ + methods: { + bar(e) { + arr.push(e.defaultPrevented) // will be false + e.preventDefault() // does nothing since the listener is passive + arr.push(e.defaultPrevented) // still false + }, + }, + render(h) { + return ( +
+
+
+ ) + }, + }) + + wrapper.trigger('click') + t.deepEqual(arr, [false, false]) + + wrapper.find('div').trigger('click') + t.deepEqual(arr, [false, false]) +}) + +test("should respect vue' order on special modifer markers", t => { + // This test is especially for `.passive` working with other modifiers + const fn = t.context.stub() + const FC = h => ( +
+
+
+
+
+
+ ) + + const mockCreateElement = (tag, props, children) => { + if (tag === 'div') { + // `&` is always the first if `.passive` present + t.is(Object.keys(props.on)[0].indexOf('&'), 0) + } + } + + FC(mockCreateElement) +}) + test('should support keyCode', t => { const stub = t.context.stub() const wrapper = mount({