{"version":3,"file":"useHotKey.cjs","sources":["../../src/composables/useHotKey/index.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { onKeyStroke } from '@vueuse/core'\n\nconst disableKeyboardShortcuts = window.OCP?.Accessibility?.disableKeyboardShortcuts?.()\nconst isMac = /mac|ipad|iphone|darwin/i.test(navigator.userAgent)\n\n/**\n * Check if event target (active element) is editable (allows input from keyboard) or NcModal is open\n * If true, a hot key should not trigger the callback\n * TODO discuss if we should abort on another interactive elements (button, a, e.t.c)\n *\n * @param {KeyboardEvent} event keyboard event\n * @return {boolean} whether it should prevent callback\n */\nfunction shouldIgnoreEvent(event) {\n\tif (event.target instanceof HTMLInputElement\n\t\t|| event.target instanceof HTMLTextAreaElement\n\t\t|| event.target instanceof HTMLSelectElement\n\t\t|| event.target?.isContentEditable) {\n\t\treturn true\n\t}\n\t/** Abort if any modal/dialog opened */\n\treturn document.getElementsByClassName('modal-mask').length !== 0\n}\n\nconst eventHandler = (callback, options) => (event) => {\n\tconst ctrlKeyPressed = isMac ? event.metaKey : event.ctrlKey\n\tif (ctrlKeyPressed !== Boolean(options.ctrl)) {\n\t\t/**\n\t\t * Ctrl is required and not pressed, or the opposite\n\t\t * As on macOS 'cmd' key is used instead of 'ctrl' key for most key combinations,\n\t\t * 'event.metaKey' should be checked\n\t\t */\n\t\treturn\n\t} else if (event.altKey !== Boolean(options.alt)) {\n\t\t// Alt is required and not pressed, or the opposite\n\t\treturn\n\t} else if (options.shift !== undefined && event.shiftKey !== Boolean(options.shift)) {\n\t\t/**\n\t\t * Shift is required and not pressed, or the opposite\n\t\t * As shift key is used to type capital letters and alternate characters,\n\t\t * option should be explicitly defined\n\t\t */\n\t\treturn\n\t} else if (shouldIgnoreEvent(event)) {\n\t\t// Keyboard shortcuts are disabled, because active element assumes input\n\t\treturn\n\t}\n\n\tif (options.prevent) {\n\t\tevent.preventDefault()\n\t}\n\tif (options.stop) {\n\t\tevent.stopPropagation()\n\t}\n\tcallback(event)\n}\n\n/**\n * @param {true|string|string[]|Function} keysOrFilter - keyboard key or keys to listen to, or filter function\n * @param {Function} callback - callback function\n * @param {object} options - composable options\n * @see docs/composables/usekeystroke.md\n */\nexport function useHotKey(keysOrFilter, callback = () => {}, options = {}) {\n\tif (disableKeyboardShortcuts) {\n\t\t// Keyboard shortcuts are disabled\n\t\treturn () => {}\n\t}\n\n\t/**\n\t * Validates event key to expected key\n\t * FIXME should support any languages / key codes\n\t *\n\t * @param {KeyboardEvent} event keyboard event\n\t * @param {string} key expected key\n\t * @return {boolean} whether it satisfies expected value or not\n\t */\n\tconst validateKeyEvent = (event, key) => {\n\t\tif (options.caseSensitive) {\n\t\t\treturn event.key === key\n\t\t}\n\t\treturn event.key.toLowerCase() === key.toLowerCase()\n\t}\n\n\t/**\n\t * Filter function for the listener\n\t * see https://github.com/vueuse/vueuse/blob/v11.3.0/packages/core/onKeyStroke/index.ts#L21-L32\n\t *\n\t * @param {KeyboardEvent} event keyboard event\n\t * @return {boolean} whether it satisfies expected value or not\n\t */\n\tconst keyFilter = (event) => {\n\t\tif (typeof keysOrFilter === 'function') {\n\t\t\treturn keysOrFilter(event)\n\t\t} else if (typeof keysOrFilter === 'string') {\n\t\t\treturn validateKeyEvent(event, keysOrFilter)\n\t\t} else if (Array.isArray(keysOrFilter)) {\n\t\t\treturn keysOrFilter.some(key => validateKeyEvent(event, key))\n\t\t} else {\n\t\t\treturn true\n\t\t}\n\t}\n\n\tconst stopKeyDown = onKeyStroke(keyFilter, eventHandler(callback, options), {\n\t\teventName: 'keydown',\n\t\tdedupe: true,\n\t\tpassive: !options.prevent,\n\t})\n\n\tconst stopKeyUp = options.push\n\t\t? onKeyStroke(keyFilter, eventHandler(callback, options), {\n\t\t\teventName: 'keyup',\n\t\t\tpassive: !options.prevent,\n\t\t})\n\t\t: () => {}\n\n\treturn () => {\n\t\tstopKeyDown()\n\t\tstopKeyUp()\n\t}\n}\n"],"names":["onKeyStroke"],"mappings":";;;AAMA,MAAM,2BAA2B,OAAO,KAAK,eAAe,2BAA4B;AACxF,MAAM,QAAQ,0BAA0B,KAAK,UAAU,SAAS;AAUhE,SAAS,kBAAkB,OAAO;AACjC,MAAI,MAAM,kBAAkB,oBACxB,MAAM,kBAAkB,uBACxB,MAAM,kBAAkB,qBACxB,MAAM,QAAQ,mBAAmB;AACpC,WAAO;AAAA,EACP;AAED,SAAO,SAAS,uBAAuB,YAAY,EAAE,WAAW;AACjE;AAEA,MAAM,eAAe,CAAC,UAAU,YAAY,CAAC,UAAU;AACtD,QAAM,iBAAiB,QAAQ,MAAM,UAAU,MAAM;AACrD,MAAI,mBAAmB,QAAQ,QAAQ,IAAI,GAAG;AAM7C;AAAA,EACF,WAAY,MAAM,WAAW,QAAQ,QAAQ,GAAG,GAAG;AAEjD;AAAA,EACF,WAAY,QAAQ,UAAU,UAAa,MAAM,aAAa,QAAQ,QAAQ,KAAK,GAAG;AAMpF;AAAA,EACF,WAAY,kBAAkB,KAAK,GAAG;AAEpC;AAAA,EACA;AAED,MAAI,QAAQ,SAAS;AACpB,UAAM,eAAgB;AAAA,EACtB;AACD,MAAI,QAAQ,MAAM;AACjB,UAAM,gBAAiB;AAAA,EACvB;AACD,WAAS,KAAK;AACf;AAQO,SAAS,UAAU,cAAc,WAAW,MAAM;AAAA,GAAI,UAAU,CAAA,GAAI;AAC1E,MAAI,0BAA0B;AAE7B,WAAO,MAAM;AAAA,IAAE;AAAA,EACf;AAUD,QAAM,mBAAmB,CAAC,OAAO,QAAQ;AACxC,QAAI,QAAQ,eAAe;AAC1B,aAAO,MAAM,QAAQ;AAAA,IACrB;AACD,WAAO,MAAM,IAAI,YAAW,MAAO,IAAI,YAAa;AAAA,EACpD;AASD,QAAM,YAAY,CAAC,UAAU;AAC5B,QAAI,OAAO,iBAAiB,YAAY;AACvC,aAAO,aAAa,KAAK;AAAA,IAC5B,WAAa,OAAO,iBAAiB,UAAU;AAC5C,aAAO,iBAAiB,OAAO,YAAY;AAAA,IAC3C,WAAU,MAAM,QAAQ,YAAY,GAAG;AACvC,aAAO,aAAa,KAAK,SAAO,iBAAiB,OAAO,GAAG,CAAC;AAAA,IAC/D,OAAS;AACN,aAAO;AAAA,IACP;AAAA,EACD;AAED,QAAM,cAAcA,KAAAA,YAAY,WAAW,aAAa,UAAU,OAAO,GAAG;AAAA,IAC3E,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,SAAS,CAAC,QAAQ;AAAA,EACpB,CAAE;AAED,QAAM,YAAY,QAAQ,OACvBA,KAAAA,YAAY,WAAW,aAAa,UAAU,OAAO,GAAG;AAAA,IACzD,WAAW;AAAA,IACX,SAAS,CAAC,QAAQ;AAAA,EACrB,CAAG,IACC,MAAM;AAAA,EAAE;AAEX,SAAO,MAAM;AACZ,gBAAa;AACb,cAAW;AAAA,EACX;AACF;;"}