<commit_before>import Platform from '../plugins/Platform.js'
import { position, leftClick, stopAndPrevent, prevent, listenOpts } from '../utils/event.js'
import { setObserver, removeObserver } from '../utils/touch.js'
import { clearSelection } from '../utils/selection.js'

const
  keyCodes = {
    esc: 27,
    tab: 9,
    enter: 13,
    space: 32,
    up: 38,
    left: 37,
    right: 39,
    down: 40,
    'delete': [8, 46]
  },
  keyRegex = new RegExp(`^([\\d+]+|${Object.keys(keyCodes).join('|')})$`, 'i')

function shouldEnd (evt, origin) {
  const { top, left } = position(evt)

  return Math.abs(left - origin.left) >= 7 ||
    Math.abs(top - origin.top) >= 7
}

const docEvtOpts = listenOpts.notPassiveCapture

export default {
  name: 'touch-repeat',

  bind (el, { modifiers, value, arg }) {
    if (el.__qtouchrepeat) {
      el.__qtouchrepeat_old = el.__qtouchrepeat
    }

    const keyboard = Object.keys(modifiers).reduce((acc, key) => {
      if (keyRegex.test(key)) {
        const keyCode = parseInt(key, 10)
        acc.push(keyCode || keyCodes[key.toLowerCase()])
      }

      return acc
    }, [])

    // early return, we don't need to do anything
    if (
      modifiers.mouse !== true &&
      Platform.has.touch !== true &&
      keyboard.length === 0
    ) {
      return
    }

    const durations = typeof arg === 'string' && arg.length
      ? arg.split(':').map(val => parseInt(val, 10))
      : [0, 600, 300]

    const durationsLast = durations.length - 1

    let ctx = {
      keyboard,
      handler: value,

      mouseStart (evt) {
        if (leftClick(evt)) {
          document.addEventListener('mousemove', ctx.mouseMove, docEvtOpts)
          document.addEventListener('mouseup', ctx.mouseEnd, docEvtOpts)
          document.addEventListener('click', ctx.mouseEnd, docEvtOpts)

          ctx.start(evt, true)
        }
      },

      mouseMove (evt) {
        ctx.event !== void 0 && shouldEnd(evt, ctx.origin) === true && setTimeout(() => {
          ctx.mouseEnd(evt)
        })
      },

      mouseEnd (evt) {
        document.removeEventListener('mousemove', ctx.mouseMove, docEvtOpts)
        document.removeEventListener('mouseup', ctx.mouseEnd, docEvtOpts)
        document.removeEventListener('click', ctx.mouseEnd, docEvtOpts)

        ctx.end(evt)
      },

      keyboardStart (evt) {
        if (keyboard.includes(evt.keyCode)) {
          if (durations[0] === 0 || ctx.event !== void 0) {
            stopAndPrevent(evt)
            el.focus()
            if (ctx.event !== void 0) {
              return
            }
          }

          document.addEventListener('keyup', ctx.keyboardEnd, docEvtOpts)
          ctx.start(evt, false, true)
        }
      },
<commit_msg>fix(quasar): setTimeout on mousemove in touch-repeat is no longer required (#4180)<commit_after>import Platform from '../plugins/Platform.js'
import { position, leftClick, stopAndPrevent, prevent, listenOpts } from '../utils/event.js'
import { setObserver, removeObserver } from '../utils/touch.js'
import { clearSelection } from '../utils/selection.js'

const
  keyCodes = {
    esc: 27,
    tab: 9,
    enter: 13,
    space: 32,
    up: 38,
    left: 37,
    right: 39,
    down: 40,
    'delete': [8, 46]
  },
  keyRegex = new RegExp(`^([\\d+]+|${Object.keys(keyCodes).join('|')})$`, 'i')

function shouldEnd (evt, origin) {
  const { top, left } = position(evt)

  return Math.abs(left - origin.left) >= 7 ||
    Math.abs(top - origin.top) >= 7
}

const docEvtOpts = listenOpts.notPassiveCapture

export default {
  name: 'touch-repeat',

  bind (el, { modifiers, value, arg }) {
    if (el.__qtouchrepeat) {
      el.__qtouchrepeat_old = el.__qtouchrepeat
    }

    const keyboard = Object.keys(modifiers).reduce((acc, key) => {
      if (keyRegex.test(key)) {
        const keyCode = parseInt(key, 10)
        acc.push(keyCode || keyCodes[key.toLowerCase()])
      }

      return acc
    }, [])

    // early return, we don't need to do anything
    if (
      modifiers.mouse !== true &&
      Platform.has.touch !== true &&
      keyboard.length === 0
    ) {
      return
    }

    const durations = typeof arg === 'string' && arg.length
      ? arg.split(':').map(val => parseInt(val, 10))
      : [0, 600, 300]

    const durationsLast = durations.length - 1

    let ctx = {
      keyboard,
      handler: value,

      mouseStart (evt) {
        if (leftClick(evt)) {
          document.addEventListener('mousemove', ctx.mouseMove, docEvtOpts)
          document.addEventListener('mouseup', ctx.mouseEnd, docEvtOpts)
          document.addEventListener('click', ctx.mouseEnd, docEvtOpts)

          ctx.start(evt, true)
        }
      },

      mouseMove (evt) {
        ctx.event !== void 0 && shouldEnd(evt, ctx.origin) === true && ctx.mouseEnd(evt)
      },

      mouseEnd (evt) {
        document.removeEventListener('mousemove', ctx.mouseMove, docEvtOpts)
        document.removeEventListener('mouseup', ctx.mouseEnd, docEvtOpts)
        document.removeEventListener('click', ctx.mouseEnd, docEvtOpts)

        ctx.end(evt)
      },

      keyboardStart (evt) {
        if (keyboard.includes(evt.keyCode)) {
          if (durations[0] === 0 || ctx.event !== void 0) {
            stopAndPrevent(evt)
            el.focus()
            if (ctx.event !== void 0) {
              return
            }
          }

          document.addEventListener('keyup', ctx.keyboardEnd, docEvtOpts)
          ctx.start(evt, false, true)
        }
      },

{'fraction_non_alphanumeric': 0.1474277404108344, 'fraction_numerical': 0.014542810398109434, 'mean_word_length': 2.322463768115942, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5542895', 'n_tokens_mistral': 1800, 'n_tokens_neox': 1761, 'n_words': 385}