it('should support multiple modifiers and event options w/ prefixIdentifiers: true', () => {
const {
props: [prop]
- } = parseWithVOn(`<div @click.stop.capture.passive="test"/>`, {
+ } = parseWithVOn(`<div @click.stop.capture.once="test"/>`, {
prefixIdentifiers: true
})
expect(prop).toMatchObject({
type: NodeTypes.JS_PROPERTY,
key: {
- content: `onClick.capture.passive`
+ content: `onClickCaptureOnce`
},
value: {
callee: V_ON_WITH_MODIFIERS,
expect(prop).toMatchObject({
type: NodeTypes.JS_PROPERTY,
key: {
- content: `onKeydown.capture`
+ content: `onKeydownCapture`
},
value: {
callee: V_ON_WITH_KEYS,
)
expect(prop).toMatchObject({
key: {
- content: `onKeyup.capture`
+ content: `onKeyupCapture`
},
value: {
type: NodeTypes.JS_CACHE_EXPRESSION,
isStaticExp
} from '@vue/compiler-core'
import { V_ON_WITH_MODIFIERS, V_ON_WITH_KEYS } from '../runtimeHelpers'
-import { makeMap } from '@vue/shared'
+import { makeMap, capitalize } from '@vue/shared'
const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`)
const isNonKeyModifier = /*#__PURE__*/ makeMap(
const modifier = modifiers[i]
if (isEventOptionModifier(modifier)) {
- // eventOptionModifiers: modifiers for addEventListener() options, e.g. .passive & .capture
+ // eventOptionModifiers: modifiers for addEventListener() options,
+ // e.g. .passive & .capture
eventOptionModifiers.push(modifier)
} else {
// runtimeModifiers: modifiers that needs runtime guards
}
if (eventOptionModifiers.length) {
+ const modifierPostfix = eventOptionModifiers.map(capitalize).join('')
key = isStaticExp(key)
- ? createSimpleExpression(
- `${key.content}.${eventOptionModifiers.join(`.`)}`,
- true
- )
- : createCompoundExpression([
- `(`,
- key,
- `) + ".${eventOptionModifiers.join(`.`)}"`
- ])
+ ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
+ : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`])
}
return {
const fn = jest.fn()
render(
h(Foo, {
- 'onFoo.once': fn
+ onFooOnce: fn
}),
nodeOps.createElement('div')
)
test('.once listeners', () => {
const def2 = { emits: { click: null } }
- expect(isEmitListener(def2, 'onClick.once')).toBe(true)
- expect(isEmitListener(def2, 'onclick.once')).toBe(false)
+ expect(isEmitListener(def2, 'onClickOnce')).toBe(true)
+ expect(isEmitListener(def2, 'onclickOnce')).toBe(false)
})
})
})
handler = props[handlerName]
}
if (!handler) {
- handler = props[handlerName + `.once`]
+ handler = props[handlerName + `Once`]
if (!instance.emitted) {
;(instance.emitted = {} as Record<string, boolean>)[handlerName] = true
} else if (instance.emitted[handlerName]) {
if (!isOn(key) || !(emits = normalizeEmitsOptions(comp))) {
return false
}
- key = key.replace(/\.once$/, '')
+ key = key.replace(/Once$/, '')
return (
hasOwn(emits, key[2].toLowerCase() + key.slice(3)) ||
hasOwn(emits, key.slice(2))
const el = document.createElement('div')
const event = new Event('click')
const fn = jest.fn()
- patchProp(el, 'onClick.once.capture', null, fn)
+ patchProp(el, 'onClickOnceCapture', null, fn)
el.dispatchEvent(event)
await timeout()
el.dispatchEvent(event)
const el = document.createElement('div')
const event = new Event('click')
const fn = jest.fn()
- patchProp(el, 'onClick.capture', null, fn)
- patchProp(el, 'onClick.capture', fn, null)
+ patchProp(el, 'onClickCapture', null, fn)
el.dispatchEvent(event)
await timeout()
+ expect(fn).toHaveBeenCalledTimes(1)
+
+ patchProp(el, 'onClickCapture', fn, null)
el.dispatchEvent(event)
await timeout()
- expect(fn).not.toHaveBeenCalled()
+ el.dispatchEvent(event)
+ await timeout()
+ expect(fn).toHaveBeenCalledTimes(1)
})
it('should support native onclick', async () => {
}
}
-const optionsModifierRE = /\.(once|passive|capture)\b/g
+const optionsModifierRE = /(?:Once|Passive|Capture)$/
function parseName(name: string): [string, EventListenerOptions | undefined] {
- name = name.slice(2).toLowerCase()
+ let options: EventListenerOptions | undefined
if (optionsModifierRE.test(name)) {
- const options: EventListenerOptions = {}
- name = name.replace(
- optionsModifierRE,
- (_, key: keyof EventListenerOptions) => {
- options[key] = true
- return ''
- }
- )
- return [name, options]
- } else {
- return [name, undefined]
+ options = {}
+ let m
+ while ((m = name.match(optionsModifierRE))) {
+ name = name.slice(0, name.length - m[0].length)
+ ;(options as any)[m[0].toLowerCase()] = true
+ options
+ }
}
+ return [name.slice(2).toLowerCase(), options]
}
function createInvoker(