All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.src.isHotkeyPressed.ts Maven / Gradle / Ivy

import { isHotkeyModifier, mapKey } from './parseHotkeys'
;(() => {
  if (typeof document !== 'undefined') {
    document.addEventListener('keydown', (e) => {
      if (e.key === undefined) {
        // Synthetic event (e.g., Chrome autofill).  Ignore.
        return
      }

      pushToCurrentlyPressedKeys([mapKey(e.key), mapKey(e.code)])
    })

    document.addEventListener('keyup', (e) => {
      if (e.key === undefined) {
        // Synthetic event (e.g., Chrome autofill).  Ignore.
        return
      }

      removeFromCurrentlyPressedKeys([mapKey(e.key), mapKey(e.code)])
    })
  }

  if (typeof window !== 'undefined') {
    window.addEventListener('blur', () => {
      currentlyPressedKeys.clear()
    })
  }
})()

const currentlyPressedKeys: Set = new Set()

// https://github.com/microsoft/TypeScript/issues/17002
export function isReadonlyArray(value: unknown): value is readonly unknown[] {
  return Array.isArray(value)
}

export function isHotkeyPressed(key: string | readonly string[], splitKey = ','): boolean {
  const hotkeyArray = isReadonlyArray(key) ? key : key.split(splitKey)

  return hotkeyArray.every((hotkey) => currentlyPressedKeys.has(hotkey.trim().toLowerCase()))
}

export function pushToCurrentlyPressedKeys(key: string | string[]): void {
  const hotkeyArray = Array.isArray(key) ? key : [key]

  /*
  Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
  https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
  Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
   */
  if (currentlyPressedKeys.has('meta')) {
    currentlyPressedKeys.forEach((key) => !isHotkeyModifier(key) && currentlyPressedKeys.delete(key.toLowerCase()))
  }

  hotkeyArray.forEach((hotkey) => currentlyPressedKeys.add(hotkey.toLowerCase()))
}

export function removeFromCurrentlyPressedKeys(key: string | string[]): void {
  const hotkeyArray = Array.isArray(key) ? key : [key]

  /*
  Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
  https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
  Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
   */
  if (key === 'meta') {
    currentlyPressedKeys.clear()
  } else {
    hotkeyArray.forEach((hotkey) => currentlyPressedKeys.delete(hotkey.toLowerCase()))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy