blob: 68fb4c2f72f41af43932247186c34a34c2f3c5ac [file] [log] [blame]
{
"version": 3,
"sources": ["keyboard.ts"],
"sourcesContent": ["/*!\n * @license\n * Copyright 2019-2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { track } from '../analytics/analytics';\n\n/**\n * Options are keyhandler callback options.\n */\ninterface Options {\n /**\n * target is the element the key event should filter on. The\n * default target is the document.\n */\n target?: Element;\n\n /**\n * withMeta specifies if the event callback should fire when\n * the key is pressed with a meta key (ctrl, alt, etc). By\n * default meta keypresses are ignored.\n */\n withMeta?: boolean;\n}\n\n/**\n * KeyHandler is the config for a keyboard event callback.\n */\ninterface KeyHandler extends Options {\n description: string;\n callback: (e: KeyboardEvent) => void;\n}\n\n/**\n * KeyboardController controls event callbacks for sitewide\n * keyboard events. Multiple callbacks can be registered for\n * a single key and by default the controller ignores events\n * for text input targets.\n */\nclass KeyboardController {\n handlers: Record<string, Set<KeyHandler>>;\n\n constructor() {\n this.handlers = {};\n document.addEventListener('keydown', e => this.handleKeyPress(e));\n }\n\n /**\n * on registers keyboard event callbacks.\n * @param key the key to register.\n * @param description name of the event.\n * @param callback event callback.\n * @param options set target and withMeta options to override the default behaviors.\n */\n on(key: string, description: string, callback: (e: KeyboardEvent) => void, options?: Options) {\n this.handlers[key] ??= new Set();\n this.handlers[key].add({ description, callback, ...options });\n return this;\n }\n\n private handleKeyPress(e: KeyboardEvent) {\n for (const handler of this.handlers[e.key.toLowerCase()] ?? new Set()) {\n if (handler.target && handler.target !== e.target) {\n return;\n }\n const t = e.target as HTMLElement | null;\n if (\n !handler.target &&\n (t?.tagName === 'INPUT' || t?.tagName === 'SELECT' || t?.tagName === 'TEXTAREA')\n ) {\n return;\n }\n if (t?.isContentEditable) {\n return;\n }\n if (\n (handler.withMeta && !(e.ctrlKey || e.metaKey)) ||\n (!handler.withMeta && (e.ctrlKey || e.metaKey))\n ) {\n return;\n }\n track('keypress', 'hotkeys', `${e.key} pressed`, handler.description);\n handler.callback(e);\n }\n }\n}\n\nexport const keyboard = new KeyboardController();\n"],
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAOA,+CAkCA,OAAyB,CAGvB,aAAc,CACZ,KAAK,SAAW,GAChB,SAAS,iBAAiB,UAAW,GAAK,KAAK,eAAe,IAUhE,GAAG,EAAa,EAAqB,EAAsC,EAAmB,CAC5F,YAAK,SAAS,KAAS,GAAI,KAC3B,KAAK,SAAS,GAAK,IAAI,CAAE,cAAa,cAAa,IAC5C,KAGD,eAAe,EAAkB,CACvC,SAAW,KAAW,MAAK,SAAS,EAAE,IAAI,gBAAkB,GAAI,KAAO,CACrE,GAAI,EAAQ,QAAU,EAAQ,SAAW,EAAE,OACzC,OAEF,KAAM,GAAI,EAAE,OAUZ,GARE,CAAC,EAAQ,QACR,IAAG,UAAY,SAAW,GAAG,UAAY,UAAY,GAAG,UAAY,aAInE,GAAG,mBAIJ,EAAQ,UAAY,CAAE,GAAE,SAAW,EAAE,UACrC,CAAC,EAAQ,UAAa,GAAE,SAAW,EAAE,SAEtC,OAEF,EAAM,WAAY,UAAW,GAAG,EAAE,cAAe,EAAQ,aACzD,EAAQ,SAAS,KAKhB,YAAM,UAAW,GAAI",
"names": []
}