hotkeys-js
Version:
A simple micro-library for defining and dispatching keyboard shortcuts. It has no dependencies.
2 lines • 7.48 kB
JavaScript
/*! hotkeys-js v3.13.10 | MIT © 2025 kenny wong <wowohoo@qq.com> https://jaywcjlove.github.io/hotkeys-js */
((e,t)=>{"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).hotkeys=t()})(this,function(){var e="undefined"!=typeof navigator&&0<navigator.userAgent.toLowerCase().indexOf("firefox");function y(e,t,n,o){e.addEventListener?e.addEventListener(t,n,o):e.attachEvent&&e.attachEvent("on".concat(t),n)}function i(e,t,n,o){e.removeEventListener?e.removeEventListener(t,n,o):e.detachEvent&&e.detachEvent("on".concat(t),n)}function h(t,e){var n=e.slice(0,e.length-1);for(let e=0;e<n.length;e++)n[e]=t[n[e].toLowerCase()];return n}function m(e){var t=(e=(e="string"!=typeof e?"":e).replace(/\s/g,"")).split(",");let n=t.lastIndexOf("");for(;0<=n;)t[n-1]+=",",t.splice(n,1),n=t.lastIndexOf("");return t}let o={backspace:8,"\u232b":8,tab:9,clear:12,enter:13,"\u21a9":13,return:13,esc:27,escape:27,space:32,left:37,up:38,right:39,down:40,del:46,delete:46,ins:45,insert:45,home:36,end:35,pageup:33,pagedown:34,capslock:20,num_0:96,num_1:97,num_2:98,num_3:99,num_4:100,num_5:101,num_6:102,num_7:103,num_8:104,num_9:105,num_multiply:106,num_add:107,num_enter:108,num_subtract:109,num_decimal:110,num_divide:111,"\u21ea":20,",":188,".":190,"/":191,"`":192,"-":e?173:189,"=":e?61:187,";":e?59:186,"'":222,"[":219,"]":221,"\\":220},k={"\u21e7":16,shift:16,"\u2325":18,alt:18,option:18,"\u2303":17,ctrl:17,control:17,"\u2318":91,cmd:91,command:91},g={16:"shiftKey",18:"altKey",17:"ctrlKey",91:"metaKey",shiftKey:16,ctrlKey:17,altKey:18,metaKey:91},v={16:!1,18:!1,17:!1,91:!1},w={};for(let e=1;e<20;e++)o["f".concat(e)]=111+e;let O=[],b=null,t="all",E=new Map,K=e=>o[e.toLowerCase()]||k[e.toLowerCase()]||e.toUpperCase().charCodeAt(0);function l(e){t=e||"all"}function j(){return t||"all"}function x(n){if(void 0===n)Object.keys(w).forEach(e=>{Array.isArray(w[e])&&w[e].forEach(e=>a(e)),delete w[e]}),s(null);else if(Array.isArray(n))n.forEach(e=>{e.key&&a(e)});else if("object"==typeof n)n.key&&a(n);else if("string"==typeof n){for(var o=arguments.length,r=Array(1<o?o-1:0),i=1;i<o;i++)r[i-1]=arguments[i];let[e,t]=r;"function"==typeof e&&(t=e,e=""),a({key:n,scope:e,method:t,splitKey:"+"})}}let a=e=>{let{key:t,scope:i,method:l,splitKey:n="+"}=e;m(t).forEach(e=>{var e=e.split(n),t=e.length,r=e[t-1],r="*"===r?"*":K(r);if(w[r]){i=i||j();let n=1<t?h(k,e):[],o=[];w[r]=w[r].filter(e=>{var t=(!l||e.method===l)&&e.scope===i&&((e,t)=>{var n=e.length<t.length?t:e,o=e.length<t.length?e:t;let r=!0;for(let e=0;e<n.length;e++)~o.indexOf(n[e])||(r=!1);return r})(e.mods,n);return t&&o.push(e.element),!t}),o.forEach(e=>s(e))}})};function C(t,n,o,e){if(n.element===e){let e;if(n.scope===o||"all"===n.scope){for(var r in e=0<n.mods.length,v)Object.prototype.hasOwnProperty.call(v,r)&&(!v[r]&&~n.mods.indexOf(+r)||v[r]&&!~n.mods.indexOf(+r))&&(e=!1);(0!==n.mods.length||v[16]||v[18]||v[17]||v[91])&&!e&&"*"!==n.shortcut||(n.keys=[],n.keys=n.keys.concat(O),!1===n.method(t,n)&&(t.preventDefault?t.preventDefault():t.returnValue=!1,t.stopPropagation&&t.stopPropagation(),t.cancelBubble)&&(t.cancelBubble=!0))}}}function L(n,t){var e,o=w["*"];let r=n.keyCode||n.which||n.charCode;if(_.filter.call(this,n)){if(93!==r&&224!==r||(r=91),~O.indexOf(r)||229===r||O.push(r),["metaKey","ctrlKey","altKey","shiftKey"].forEach(e=>{var t=g[e];n[e]&&!~O.indexOf(t)?O.push(t):!n[e]&&~O.indexOf(t)?O.splice(O.indexOf(t),1):"metaKey"===e&&n[e]&&(O=O.filter(e=>e in g||e===r))}),r in v){for(var i in v[r]=!0,k)Object.prototype.hasOwnProperty.call(k,i)&&(e=g[k[i]],_[i]=n[e]);if(!o)return}for(var l in v)Object.prototype.hasOwnProperty.call(v,l)&&(v[l]=n[g[l]]);n.getModifierState&&(!n.altKey||n.ctrlKey)&&n.getModifierState("AltGraph")&&(~O.indexOf(17)||O.push(17),~O.indexOf(18)||O.push(18),v[17]=!0,v[18]=!0);var a=j();if(o)for(let e=0;e<o.length;e++)o[e].scope===a&&("keydown"===n.type&&o[e].keydown||"keyup"===n.type&&o[e].keyup)&&C(n,o[e],a,t);if(r in w){var s=w[r],c=s.length;for(let e=0;e<c;e++)if(("keydown"===n.type&&s[e].keydown||"keyup"===n.type&&s[e].keyup)&&s[e].key){var f=s[e],p=f.splitKey,d=f.key.split(p),u=[];for(let e=0;e<d.length;e++)u.push(K(d[e]));u.sort().join("")===O.sort().join("")&&C(n,f,a,t)}}}}function _(e,t,n){O=[];var o,r=m(e);let i=[],l="all",a=document,s=0,c=!1,f=!0,p="+",d=!1,u=!1;for(void 0===n&&"function"==typeof t&&(n=t),"[object Object]"===Object.prototype.toString.call(t)&&(t.scope&&(l=t.scope),t.element&&(a=t.element),t.keyup&&(c=t.keyup),void 0!==t.keydown&&(f=t.keydown),void 0!==t.capture&&(d=t.capture),"string"==typeof t.splitKey&&(p=t.splitKey),!0===t.single)&&(u=!0),"string"==typeof t&&(l=t),u&&x(e,l);s<r.length;s++)e=r[s].split(p),i=[],1<e.length&&(i=h(k,e)),(e="*"===(e=e[e.length-1])?"*":K(e))in w||(w[e]=[]),w[e].push({keyup:c,keydown:f,scope:l,mods:i,shortcut:r[s],method:n,key:r[s],splitKey:p,element:a});void 0!==a&&window&&(E.has(a)||(t=function(){return L(0<arguments.length&&void 0!==arguments[0]?arguments[0]:window.event,a)},o=function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:window.event;L(t,a);{let e=t.keyCode||t.which||t.charCode;var n=O.indexOf(e);if(n<0||O.splice(n,1),t.key&&"meta"==t.key.toLowerCase()&&O.splice(0,O.length),(e=93!==e&&224!==e?e:91)in v)for(var o in v[e]=!1,k)k[o]===e&&(_[o]=!1)}},E.set(a,{keydownListener:t,keyupListenr:o,capture:d}),y(a,"keydown",t,d),y(a,"keyup",o,d)),b||(t=()=>{O=[]},b={listener:t,capture:d},y(window,"focus",t,d)))}function s(t){var e,n,o,r=Object.values(w).flat();r.findIndex(e=>{e=e.element;return e===t})<0&&({keydownListener:o,keyupListenr:n,capture:e}=E.get(t)||{},o)&&n&&(i(t,"keyup",n,e),i(t,"keydown",o,e),E.delete(t)),0<r.length&&0<E.size||(Object.keys(E).forEach(e=>{var{keydownListener:t,keyupListenr:n,capture:o}=E.get(e)||{};t&&n&&(i(e,"keyup",n,o),i(e,"keydown",t,o),E.delete(e))}),E.clear(),Object.keys(w).forEach(e=>delete w[e]),b&&({listener:n,capture:o}=b,i(window,"focus",n,o),b=null))}var n,r={getPressedKeyString:function(){return O.map(e=>{return n=e,Object.keys(o).find(e=>o[e]===n)||(t=e,Object.keys(k).find(e=>k[e]===t))||String.fromCharCode(e);var t,n})},setScope:l,getScope:j,deleteScope:function(e,t){var n,o;let r;for(o in e=e||j(),w)if(Object.prototype.hasOwnProperty.call(w,o))for(n=w[o],r=0;r<n.length;)n[r].scope===e?n.splice(r,1).forEach(e=>{e=e.element;return s(e)}):r++;j()===e&&l(t||"all")},getPressedKeyCodes:function(){return O.slice(0)},getAllKeyCodes:function(){let r=[];return Object.keys(w).forEach(e=>{w[e].forEach(e=>{var{key:e,scope:t,mods:n,shortcut:o}=e;r.push({scope:t,shortcut:o,mods:n,keys:e.split("+").map(e=>K(e))})})}),r},isPressed:function(e){return"string"==typeof e&&(e=K(e)),!!~O.indexOf(e)},filter:function(e){var t=(e=e.target||e.srcElement).tagName;let n=!0;var o="INPUT"===t&&!["checkbox","radio","range","button","file","reset","submit","color"].includes(e.type);return n=!e.isContentEditable&&(!o&&"TEXTAREA"!==t&&"SELECT"!==t||e.readOnly)?n:!1},trigger:function(t){let n=1<arguments.length&&void 0!==arguments[1]?arguments[1]:"all";Object.keys(w).forEach(e=>{w[e].filter(e=>e.scope===n&&e.shortcut===t).forEach(e=>{e&&e.method&&e.method()})})},unbind:x,keyMap:o,modifier:k,modifierMap:g};for(n in r)Object.prototype.hasOwnProperty.call(r,n)&&(_[n]=r[n]);if("undefined"!=typeof window){let t=window.hotkeys;_.noConflict=e=>(e&&window.hotkeys===_&&(window.hotkeys=t),_),window.hotkeys=_}return _});