UNPKG

quasar

Version:

Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time

192 lines (158 loc) 5.78 kB
import { client } from '../../plugins/platform/Platform.js' import { createDirective } from '../../utils/private.create/create.js' import { addEvt, cleanEvt, position, leftClick, stopAndPrevent, noop } from '../../utils/event/event.js' import { clearSelection } from '../../utils/private.selection/selection.js' import getSSRProps from '../../utils/private.noop-ssr-directive-transform/noop-ssr-directive-transform.js' export default createDirective( __QUASAR_SSR_SERVER__ ? { name: 'touch-hold', getSSRProps } : { name: 'touch-hold', beforeMount(el, binding) { const { modifiers } = binding // early return, we don't need to do anything if (modifiers.mouse !== true && client.has.touch !== true) return const ctx = { handler: binding.value, noop, mouseStart(evt) { if ( typeof ctx.handler === 'function' && leftClick(evt) === true ) { addEvt(ctx, 'temp', [ [document, 'mousemove', 'move', 'passiveCapture'], [document, 'click', 'end', 'notPassiveCapture'] ]) ctx.start(evt, true) } }, touchStart(evt) { if (evt.target !== void 0 && typeof ctx.handler === 'function') { const target = evt.target addEvt(ctx, 'temp', [ [target, 'touchmove', 'move', 'passiveCapture'], [target, 'touchcancel', 'end', 'notPassiveCapture'], [target, 'touchend', 'end', 'notPassiveCapture'] ]) ctx.start(evt) } }, start(evt, mouseEvent) { ctx.origin = position(evt) const startTime = Date.now() if (client.is.mobile === true) { document.body.classList.add('non-selectable') clearSelection() ctx.styleCleanup = withDelay => { ctx.styleCleanup = void 0 const remove = () => { document.body.classList.remove('non-selectable') } if (withDelay === true) { clearSelection() setTimeout(remove, 10) } else { remove() } } } ctx.triggered = false ctx.sensitivity = mouseEvent === true ? ctx.mouseSensitivity : ctx.touchSensitivity ctx.timer = setTimeout(() => { ctx.timer = void 0 clearSelection() ctx.triggered = true ctx.handler({ evt, touch: mouseEvent !== true, mouse: mouseEvent === true, position: ctx.origin, duration: Date.now() - startTime }) }, ctx.duration) }, move(evt) { const { top, left } = position(evt) if ( ctx.timer !== void 0 && (Math.abs(left - ctx.origin.left) >= ctx.sensitivity || Math.abs(top - ctx.origin.top) >= ctx.sensitivity) ) { clearTimeout(ctx.timer) ctx.timer = void 0 } }, end(evt) { cleanEvt(ctx, 'temp') // delay needed otherwise selection still occurs ctx.styleCleanup?.(ctx.triggered) if (ctx.triggered === true) { if (evt !== void 0) stopAndPrevent(evt) } else if (ctx.timer !== void 0) { clearTimeout(ctx.timer) ctx.timer = void 0 } } } // duration in ms, touch in pixels, mouse in pixels const data = [600, 5, 7] if (typeof binding.arg === 'string' && binding.arg.length !== 0) { binding.arg.split(':').forEach((val, index) => { const v = parseInt(val, 10) if (v) data[index] = v }) } ;[ctx.duration, ctx.touchSensitivity, ctx.mouseSensitivity] = data el.__qtouchhold = ctx if (modifiers.mouse === true) { // account for UMD too where modifiers will be lowercased to work const capture = modifiers.mouseCapture === true || modifiers.mousecapture === true ? 'Capture' : '' addEvt(ctx, 'main', [ [el, 'mousedown', 'mouseStart', `passive${capture}`] ]) } if (client.has.touch === true) { addEvt(ctx, 'main', [ [ el, 'touchstart', 'touchStart', `passive${modifiers.capture === true ? 'Capture' : ''}` ], [el, 'touchend', 'noop', 'notPassiveCapture'] ]) } }, updated(el, binding) { const ctx = el.__qtouchhold if (ctx !== void 0 && binding.oldValue !== binding.value) { if (typeof binding.value !== 'function') ctx.end() ctx.handler = binding.value } }, beforeUnmount(el) { const ctx = el.__qtouchhold if (ctx !== void 0) { cleanEvt(ctx, 'main') cleanEvt(ctx, 'temp') if (ctx.timer !== void 0) clearTimeout(ctx.timer) ctx.styleCleanup?.() delete el.__qtouchhold } } } )