/* @flow */ import { isDef, isUndef } from 'shared/util' import { updateListeners } from 'core/vdom/helpers/index' import { withMacroTask, isIE, supportsPassive } from 'core/util/index' import { RANGE_TOKEN, CHECKBOX_RADIO_TOKEN } from 'web/compiler/directives/model' // normalize v-model event tokens that can only be determined at runtime. // it's important to place the event as the first in the array because // the whole point is ensuring the v-model callback gets called before // user-attached handlers. function normalizeEvents (on) { /* istanbul ignore if */ if (isDef(on[RANGE_TOKEN])) { // IE input[type=range] only supports `change` event const event = isIE ? 'change' : 'input' on[event] = [].concat(on[RANGE_TOKEN], on[event] || []) delete on[RANGE_TOKEN] } // This was originally intended to fix #4521 but no longer necessary // after 2.5. Keeping it for backwards compat with generated code from < 2.4 /* istanbul ignore if */ if (isDef(on[CHECKBOX_RADIO_TOKEN])) { on.change = [].concat(on[CHECKBOX_RADIO_TOKEN], on.change || []) delete on[CHECKBOX_RADIO_TOKEN] } } let target: any function createOnceHandler (handler, event, capture) { const _target = target // save current target element in closure return function onceHandler () { const res = handler.apply(null, arguments) if (res !== null) { remove(event, onceHandler, capture, _target) } } } function add ( event: string, handler: Function, once: boolean, capture: boolean, passive: boolean ) { handler = withMacroTask(handler) if (once) handler = createOnceHandler(handler, event, capture) target.addEventListener( event, handler, supportsPassive ? { capture, passive } : capture ) } function remove ( event: string, handler: Function, capture: boolean, _target?: HTMLElement ) { (_target || target).removeEventListener( event, handler._withTask || handler, capture ) } function updateDOMListeners (oldVnode: VNodeWithData, vnode: VNodeWithData) { if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) { return } const on = vnode.data.on || {} const oldOn = oldVnode.data.on || {} target = vnode.elm normalizeEvents(on) updateListeners(on, oldOn, add, remove, vnode.context) target = undefined } export default { create: updateDOMListeners, update: updateDOMListeners }