Skip to content

Commit

Permalink
fix: normlaize @click.right and @click.middle
Browse files Browse the repository at this point in the history
fix #7020
  • Loading branch information
yyx990803 committed Nov 13, 2017
1 parent 7cf188e commit daed1e7
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 24 deletions.
13 changes: 1 addition & 12 deletions src/compiler/codegen/events.js
Expand Up @@ -41,18 +41,7 @@ export function genHandlers (
): string {
let res = isNative ? 'nativeOn:{' : 'on:{'
for (const name in events) {
const handler = events[name]
// #5330: warn click.right, since right clicks do not actually fire click events.
if (process.env.NODE_ENV !== 'production' &&
name === 'click' &&
handler && handler.modifiers && handler.modifiers.right
) {
warn(
`Use "contextmenu" instead of "click.right" since right clicks ` +
`do not actually fire "click" events.`
)
}
res += `"${name}":${genHandler(name, handler)},`
res += `"${name}":${genHandler(name, events[name])},`
}
return res.slice(0, -1) + '}'
}
Expand Down
33 changes: 27 additions & 6 deletions src/compiler/helpers.js
@@ -1,5 +1,6 @@
/* @flow */

import { emptyObject } from 'shared/util'
import { parseFilters } from './parser/filter-parser'

export function baseWarn (msg: string) {
Expand Down Expand Up @@ -42,39 +43,59 @@ export function addHandler (
important?: boolean,
warn?: Function
) {
modifiers = modifiers || emptyObject
// warn prevent and passive modifier
/* istanbul ignore if */
if (
process.env.NODE_ENV !== 'production' && warn &&
modifiers && modifiers.prevent && modifiers.passive
modifiers.prevent && modifiers.passive
) {
warn(
'passive and prevent can\'t be used together. ' +
'Passive handler can\'t prevent default event.'
)
}

// check capture modifier
if (modifiers && modifiers.capture) {
if (modifiers.capture) {
delete modifiers.capture
name = '!' + name // mark the event as captured
}
if (modifiers && modifiers.once) {
if (modifiers.once) {
delete modifiers.once
name = '~' + name // mark the event as once
}
/* istanbul ignore if */
if (modifiers && modifiers.passive) {
if (modifiers.passive) {
delete modifiers.passive
name = '&' + name // mark the event as passive
}

// normalize click.right and click.middle since they don't actually fire
// this is technically browser-specific, but at least for now browsers are
// the only target envs that have right/middle clicks.
if (name === 'click') {
if (modifiers.right) {
name = 'contextmenu'
delete modifiers.right
} else if (modifiers.middle) {
name = 'mouseup'
}
}

let events
if (modifiers && modifiers.native) {
if (modifiers.native) {
delete modifiers.native
events = el.nativeEvents || (el.nativeEvents = {})
} else {
events = el.events || (el.events = {})
}
const newHandler = { value, modifiers }

const newHandler: any = { value }
if (modifiers !== emptyObject) {
newHandler.modifiers = modifiers
}

const handlers = events[name]
/* istanbul ignore if */
if (Array.isArray(handlers)) {
Expand Down
2 changes: 0 additions & 2 deletions src/core/util/lang.js
@@ -1,7 +1,5 @@
/* @flow */

export const emptyObject = Object.freeze({})

/**
* Check if a string starts with $ or _
*/
Expand Down
2 changes: 2 additions & 0 deletions src/shared/util.js
@@ -1,5 +1,7 @@
/* @flow */

export const emptyObject = Object.freeze({})

// these helpers produces better vm code in JS engines due to their
// explicitness and function inlining
export function isUndef (v: any): boolean %checks {
Expand Down
22 changes: 18 additions & 4 deletions test/unit/features/directives/on.spec.js
Expand Up @@ -693,13 +693,27 @@ describe('Directive v-on', () => {
expect(prevented).toBe(true)
})

it('should warn click.right', () => {
new Vue({
it('should transform click.right to contextmenu', () => {
const spy = jasmine.createSpy('click.right')
const vm = new Vue({
template: `<div @click.right="foo"></div>`,
methods: { foo () {} }
methods: { foo: spy }
}).$mount()

expect(`Use "contextmenu" instead`).toHaveBeenWarned()
triggerEvent(vm.$el, 'contextmenu')
expect(spy).toHaveBeenCalled()
})

it('should transform click.middle to mouseup', () => {
const spy = jasmine.createSpy('click.middle')
const vm = new Vue({
template: `<div @click.middle="foo"></div>`,
methods: { foo: spy }
}).$mount()
triggerEvent(vm.$el, 'mouseup', e => { e.button = 0 })
expect(spy).not.toHaveBeenCalled()
triggerEvent(vm.$el, 'mouseup', e => { e.button = 1 })
expect(spy).toHaveBeenCalled()
})

it('object syntax (no argument)', () => {
Expand Down

0 comments on commit daed1e7

Please sign in to comment.