All files bindGlobalEventListeners.js

76.36% Statements 42/55
59.57% Branches 28/47
87.5% Functions 7/8
76.36% Lines 42/55

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                  5x 5x 5x 5x 5x 5x   5x 1x       1x   1x       1x 1x       5x 5x                             5x   5x         5x 5x 1x       4x   9x   4x 1x 1x   1x 1x                   3x     5x 1x 1x 1x       5x 1x 1x 1x 1x                 5x 5x 5x 5x   5x       1x      
import { Selectors } from './selectors'
import {
  isBrowser,
  hideAllPoppers,
  closest,
  closestCallback,
  toArray
} from './utils'
 
const nav = isBrowser ? navigator : {}
const win = isBrowser ? window : {}
export let isIE = /MSIE |Trident\//.test(nav.userAgent)
export let isIOS = /iPhone|iPad|iPod/.test(nav.platform) && !win.MSStream
export let supportsTouch = 'ontouchstart' in win
export let isUsingTouch = false
 
export const onDocumentTouch = () => {
  Iif (isUsingTouch) {
    return
  }
 
  isUsingTouch = true
 
  Iif (isIOS) {
    document.body.classList.add('tippy-iOS')
  }
 
  Eif (window.performance) {
    document.addEventListener('mousemove', onDocumentMouseMove)
  }
}
 
let lastMouseMoveTime = 0
export const onDocumentMouseMove = () => {
  const now = performance.now()
 
  // Chrome 60+ is 1 mousemove per animation frame, use 20ms time difference
  if (now - lastMouseMoveTime < 20) {
    isUsingTouch = false
    document.removeEventListener('mousemove', onDocumentMouseMove)
    if (!isIOS) {
      document.body.classList.remove('tippy-iOS')
    }
  }
 
  lastMouseMoveTime = now
}
 
export const onDocumentClick = ({ target }) => {
  // Simulated events dispatched on the document
  Iif (!(target instanceof Element)) {
    return hideAllPoppers()
  }
 
  // Clicked on an interactive popper
  const popper = closest(target, Selectors.POPPER)
  if (popper && popper._tippy && popper._tippy.props.interactive) {
    return
  }
 
  // Clicked on a reference
  const reference = closestCallback(
    target,
    el => el._tippy && el._tippy.reference === el
  )
  if (reference) {
    const tip = reference._tippy
    const isClickTrigger = tip.props.trigger.indexOf('click') > -1
 
    Eif (isUsingTouch || isClickTrigger) {
      return hideAllPoppers(tip)
    }
 
    if (tip.props.hideOnClick !== true || isClickTrigger) {
      return
    }
 
    tip.clearDelayTimeouts()
  }
 
  hideAllPoppers()
}
 
export const onWindowBlur = () => {
  const { activeElement } = document
  Eif (activeElement && activeElement.blur && activeElement._tippy) {
    activeElement.blur()
  }
}
 
export const onWindowResize = () => {
  toArray(document.querySelectorAll(Selectors.POPPER)).forEach(popper => {
    const tippyInstance = popper._tippy
    Eif (!tippyInstance.props.livePlacement) {
      tippyInstance.popperInstance.scheduleUpdate()
    }
  })
}
 
/**
 * Adds the needed global event listeners
 */
export default function bindEventListeners() {
  document.addEventListener('click', onDocumentClick)
  document.addEventListener('touchstart', onDocumentTouch)
  window.addEventListener('blur', onWindowBlur)
  window.addEventListener('resize', onWindowResize)
 
  if (
    !supportsTouch &&
    (navigator.maxTouchPoints || navigator.msMaxTouchPoints)
  ) {
    document.addEventListener('pointerdown', onDocumentTouch)
  }
}