hotkey-router 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
- // hotkey-router v0.2.2 | SEE LICENSE IN LICENSE
1
+ // hotkey-router v0.2.3 | SEE LICENSE IN LICENSE
2
2
 
3
- function P(e,t,n,s){return e.addEventListener(t,n,s),()=>e.removeEventListener(t,n,s)}var D=typeof navigator<"u"&&/Mac|iPhone|iPad|iPod/.test(navigator.platform),F=new Set(["ctrl","shift","alt","meta"]),L=Object.freeze({Alt:"alt",AltGraph:"alt",Control:"ctrl",Shift:"shift",Meta:"meta",OS:"meta"}),R=new Map([["^","ctrl"],["!","alt"],["+","shift"],["#","meta"]]),T=Object.freeze({esc:"escape",escape:"escape",space:" ",spacebar:" ",enter:"enter",return:"enter",del:"delete",delete:"delete",backspace:"backspace",tab:"tab",up:"arrowup",down:"arrowdown",left:"arrowleft",right:"arrowright",home:"home",end:"end",pageup:"pageup",pagedown:"pagedown",pgup:"pageup",pgdn:"pagedown",cmd:"meta",command:"meta",win:"meta",meta:"meta",control:"ctrl",ctrl:"ctrl",option:"alt",alt:"alt",shift:"shift","\u2318":"meta","\u2303":"ctrl","\u2325":"alt","\u21E7":"shift",mod:D?"meta":"ctrl",plus:"+"}),S=!0,_=typeof window<"u"?window:null,y=[],g=new Map,w=new Map,m=new Map,K=!1,N=1;function v(e){let t=String(e??"").trim(),n=t.toLowerCase();return T[n]??(t===" "?" ":n)}function E({ctrl:e,shift:t,alt:n,meta:s,key:o,code:r,bareModifier:l}){if(l)return`__bare__:${l}`;let i="";return e&&(i+="ctrl+"),t&&(i+="shift+"),n&&(i+="alt+"),s&&(i+="meta+"),r?i+"code:"+r:i?i+o:o}function U(e){let t=L[e.key];return t?`__bare__:${t}`:E({ctrl:e.ctrlKey,shift:e.shiftKey,alt:e.altKey,meta:e.metaKey,key:v(e.key)})}function Z(e){if(!e.code)return null;let t="";return e.ctrlKey&&(t+="ctrl+"),e.shiftKey&&(t+="shift+"),e.altKey&&(t+="alt+"),e.metaKey&&(t+="meta+"),t+"code:"+e.code}function j(e){let t=v(e);return F.has(t)}var H=/(^|\+)code:([A-Za-z][A-Za-z0-9_]*)/;function I(e){let t=String(e||"").trim(),n=/\s+up$/i.test(t),s=n?t.replace(/\s+up$/i,"").trim():t,o={ctrl:!1,shift:!1,alt:!1,meta:!1,key:null,code:null,bareModifier:null},r=s;for(;r.length;){let a=R.get(r[0])??null;if(!a)break;o[a]=!0,r=r.slice(1).trimStart()}let l=r.match(/code:[A-Za-z][A-Za-z0-9_]*/g);if(l&&l.length>1)throw new Error(`Invalid hotkey "${e}": multiple code: tokens not supported (got ${l.length}).`);let i=null,f=r.replace(H,(a,p,B)=>(i=B,p+"__code__")).toLowerCase(),u=f.split("+").map(a=>a.trim()),h=u.filter(Boolean),d=u.some(a=>a==="")&&f.includes("++");if(!d){let a=!1;for(let p of h)if(j(p)){if(a)throw new Error(`Invalid hotkey "${e}": modifiers must come before the base key (e.g. "ctrl+k", not "k+ctrl")`)}else a||(a=!0)}for(let a of h){if(a==="__code__"){o.code=i;continue}let p=T[a]??a;p==="ctrl"?o.ctrl=!0:p==="shift"?o.shift=!0:p==="alt"?o.alt=!0:p==="meta"?o.meta=!0:o.key=v(p)}if(!o.key&&!o.code&&d&&(o.key="+"),!o.key&&!o.code){let a=(o.ctrl?1:0)+(o.shift?1:0)+(o.alt?1:0)+(o.meta?1:0);if(a===1)o.bareModifier=o.ctrl?"ctrl":o.shift?"shift":o.alt?"alt":"meta";else throw a>1?new Error(`Invalid hotkey "${e}": multi-modifier bare bindings not supported. Add a base key (e.g. "ctrl+alt+x").`):new Error(`Invalid hotkey "${e}" (missing base key)`)}return{combo:o,type:n?"keyup":"keydown",raw:e}}function Y(e){let t=e?.target;if(!t)return!1;let n=String(t.tagName||"").toUpperCase();return t.isContentEditable||n==="INPUT"||n==="TEXTAREA"||n==="SELECT"||t.getAttribute?.("role")==="textbox"}function q(e,t){let n=t?{...t}:{};return e==="keydown"&&n.repeat==null&&(n.repeat=!1),n.priority==null&&(n.priority=0),n}function G(e,t){let n=g.get(e);n||(n=new Map,g.set(e,n));let s=n.get(t);return s||(s=[],n.set(t,s)),s}function M(e){let t=m.get(e);if(!t)return!1;let{comboStr:n,type:s}=t,o=g.get(n),r=o?.get(s);if(!r?.length)return m.delete(e),!1;let l=r.filter(i=>i.id!==e);return l.length?o.set(s,l):o.delete(s),o.size||g.delete(n),m.delete(e),!0}function O(e,t,n=null,s={}){let{combo:o,type:r,raw:l}=I(e),i=E(o),c=q(r,s),f={id:N++,comboStr:i,type:r,combo:o,handler:t,plugin:n,raw:l,options:c};if(G(i,r).push(f),m.set(f.id,{comboStr:i,type:r}),y.length)for(let h of y)try{h({combo:o,raw:l,options:c,plugin:n,id:f.id})}catch(d){console.error("[hotkey-router] onBind hook threw:",d)}let u=()=>M(f.id);return u.id=f.id,u.hotkey=l,u}function V(e){if(typeof e!="function")throw new TypeError("hotkeys.onBind(hook) expects a function");return y.push(e),()=>{y=y.filter(t=>t!==e)}}function W(e,t){let{combo:n,type:s}=I(e),o=E(n),r=g.get(o);if(!r)return;let l=r.get(s);if(l?.length){if(t){let i=[];for(let c of l)c.handler===t?m.delete(c.id):i.push(c);i.length?r.set(s,i):r.delete(s)}else{for(let i of l)m.delete(i.id);r.delete(s)}r.size||g.delete(o)}}function X(e,t){if(w.has(e))throw new Error(`Plugin "${e}" already registered`);let n=[];for(let[s,o]of Object.entries(t)){let[r,l]=Array.isArray(o)?o:[o,{}],i=O(s,r,e,l);n.push(i.id)}return w.set(e,n),()=>x(e)}function x(e){let t=w.get(e);if(t){for(let n of t)M(n);w.delete(e)}}function J(){K=!0}function Q(){K=!1}function ee(e=!0){S=!!e}function te(e){_=e}function z(e){let t=null;for(let n of e)t?(n.options.priority>t.options.priority||n.options.priority===t.options.priority&&n.id>t.id)&&(t=n):t=n;return t}function A(e){return t=>{if(K)return;let n=S&&Y(t),s=U(t),o=Z(t),r=new Set,l=[];for(let f of[s,o]){if(!f||r.has(f))continue;r.add(f);let u=g.get(f)?.get(e);if(u?.length)for(let h of u){let d=h.options;n&&!d.allowIn?.(t)||e==="keydown"&&d.repeat===!1&&t.repeat||d.when&&d.when(t)===!1||l.push(h)}}if(!l.length)return;let i=z(l),c=i.options;c.preventDefault&&t.preventDefault(),c.stopImmediatePropagation?t.stopImmediatePropagation():c.stopPropagation&&t.stopPropagation(),i.handler(t),c.once&&M(i.id)}}var b=null,k=null;function $({target:e=_,capture:t=!1}={}){if(!e)throw new Error("hotkeys.init() requires a target (e.g. window)");(b||k)&&C(),b=P(e,"keydown",A("keydown"),{capture:t}),k=P(e,"keyup",A("keyup"),{capture:t})}function C(){b?.(),k?.(),b=null,k=null,g.clear(),w.clear(),m.clear()}var ne={ctrl:"Control",shift:"Shift",alt:"Alt",meta:"Meta"};function oe(e,{type:t}={}){let{combo:n,type:s}=I(e),o=E(n),r=t||s,l=g.get(o)?.get(r);if(!l?.length)return!1;let i=n.bareModifier?ne[n.bareModifier]:n.key,c=!!n.alt,f=!!n.ctrl,u=!!n.shift,h=!!n.meta;n.bareModifier&&r==="keyup"&&(n.bareModifier==="alt"?c=!1:n.bareModifier==="ctrl"?f=!1:n.bareModifier==="shift"?u=!1:n.bareModifier==="meta"&&(h=!1));let d={type:r,key:i,code:n.code||null,ctrlKey:f,shiftKey:u,altKey:c,metaKey:h,repeat:!1,preventDefault(){},stopPropagation(){},stopImmediatePropagation(){},target:null},a=z(l.filter(p=>p.options.when?p.options.when(d)!==!1:!0));return a?(a.handler(d),a.options.once&&M(a.id),!0):!1}_&&$();var re={init:$,destroy:C,setTarget:te,bind:O,unbind:W,registerPlugin:X,unregisterPlugin:x,onBind:V,pause:J,resume:Q,ignoreInput:ee,trigger:oe};export{re as default};
3
+ function P(e,t,n,i){return e.addEventListener(t,n,i),()=>e.removeEventListener(t,n,i)}var D=typeof navigator<"u"&&/Mac|iPhone|iPad|iPod/.test(navigator.platform),F=new Set(["ctrl","shift","alt","meta"]),L=Object.freeze({Alt:"alt",AltGraph:"alt",Control:"ctrl",Shift:"shift",Meta:"meta",OS:"meta"}),R=new Map([["^","ctrl"],["!","alt"],["+","shift"],["#","meta"]]),T=Object.freeze({esc:"escape",escape:"escape",space:" ",spacebar:" ",enter:"enter",return:"enter",del:"delete",delete:"delete",backspace:"backspace",tab:"tab",up:"arrowup",down:"arrowdown",left:"arrowleft",right:"arrowright",home:"home",end:"end",pageup:"pageup",pagedown:"pagedown",pgup:"pageup",pgdn:"pagedown",cmd:"meta",command:"meta",win:"meta",meta:"meta",control:"ctrl",ctrl:"ctrl",option:"alt",alt:"alt",shift:"shift","\u2318":"meta","\u2303":"ctrl","\u2325":"alt","\u21E7":"shift",mod:D?"meta":"ctrl",plus:"+"}),S=!0,_=typeof window<"u"?window:null,y=[],g=new Map,w=new Map,h=new Map,K=!1,N=1;function v(e){let t=String(e??"");if(t===" ")return" ";let i=t.trim().toLowerCase();return T[i]??i}function E({ctrl:e,shift:t,alt:n,meta:i,key:o,code:r,bareModifier:l}){if(l)return`__bare__:${l}`;let s="";return e&&(s+="ctrl+"),t&&(s+="shift+"),n&&(s+="alt+"),i&&(s+="meta+"),r?s+"code:"+r:s?s+o:o}function U(e){let t=L[e.key];return t?`__bare__:${t}`:E({ctrl:e.ctrlKey,shift:e.shiftKey,alt:e.altKey,meta:e.metaKey,key:v(e.key)})}function Z(e){if(!e.code)return null;let t="";return e.ctrlKey&&(t+="ctrl+"),e.shiftKey&&(t+="shift+"),e.altKey&&(t+="alt+"),e.metaKey&&(t+="meta+"),t+"code:"+e.code}function j(e){let t=v(e);return F.has(t)}var H=/(^|\+)code:([A-Za-z][A-Za-z0-9_]*)/;function I(e){let t=String(e||"").trim(),n=/\s+up$/i.test(t),i=n?t.replace(/\s+up$/i,"").trim():t,o={ctrl:!1,shift:!1,alt:!1,meta:!1,key:null,code:null,bareModifier:null},r=i;for(;r.length;){let a=R.get(r[0])??null;if(!a)break;o[a]=!0,r=r.slice(1).trimStart()}let l=r.match(/code:[A-Za-z][A-Za-z0-9_]*/g);if(l&&l.length>1)throw new Error(`Invalid hotkey "${e}": multiple code: tokens not supported (got ${l.length}).`);let s=null,f=r.replace(H,(a,p,B)=>(s=B,p+"__code__")).toLowerCase(),u=f.split("+").map(a=>a.trim()),m=u.filter(Boolean),d=u.some(a=>a==="")&&f.includes("++");if(!d){let a=!1;for(let p of m)if(j(p)){if(a)throw new Error(`Invalid hotkey "${e}": modifiers must come before the base key (e.g. "ctrl+k", not "k+ctrl")`)}else a||(a=!0)}for(let a of m){if(a==="__code__"){o.code=s;continue}let p=T[a]??a;p==="ctrl"?o.ctrl=!0:p==="shift"?o.shift=!0:p==="alt"?o.alt=!0:p==="meta"?o.meta=!0:o.key=v(p)}if(!o.key&&!o.code&&d&&(o.key="+"),!o.key&&!o.code){let a=(o.ctrl?1:0)+(o.shift?1:0)+(o.alt?1:0)+(o.meta?1:0);if(a===1)o.bareModifier=o.ctrl?"ctrl":o.shift?"shift":o.alt?"alt":"meta";else throw a>1?new Error(`Invalid hotkey "${e}": multi-modifier bare bindings not supported. Add a base key (e.g. "ctrl+alt+x").`):new Error(`Invalid hotkey "${e}" (missing base key)`)}return{combo:o,type:n?"keyup":"keydown",raw:e}}function Y(e){let t=e?.target;if(!t)return!1;let n=String(t.tagName||"").toUpperCase();return t.isContentEditable||n==="INPUT"||n==="TEXTAREA"||n==="SELECT"||t.getAttribute?.("role")==="textbox"}function q(e,t){let n=t?{...t}:{};return e==="keydown"&&n.repeat==null&&(n.repeat=!1),n.priority==null&&(n.priority=0),n}function G(e,t){let n=g.get(e);n||(n=new Map,g.set(e,n));let i=n.get(t);return i||(i=[],n.set(t,i)),i}function M(e){let t=h.get(e);if(!t)return!1;let{comboStr:n,type:i}=t,o=g.get(n),r=o?.get(i);if(!r?.length)return h.delete(e),!1;let l=r.filter(s=>s.id!==e);return l.length?o.set(i,l):o.delete(i),o.size||g.delete(n),h.delete(e),!0}function O(e,t,n=null,i={}){let{combo:o,type:r,raw:l}=I(e),s=E(o),c=q(r,i),f={id:N++,comboStr:s,type:r,combo:o,handler:t,plugin:n,raw:l,options:c};if(G(s,r).push(f),h.set(f.id,{comboStr:s,type:r}),y.length)for(let m of y)try{m({combo:o,raw:l,options:c,plugin:n,id:f.id})}catch(d){console.error("[hotkey-router] onBind hook threw:",d)}let u=()=>M(f.id);return u.id=f.id,u.hotkey=l,u}function V(e){if(typeof e!="function")throw new TypeError("hotkeys.onBind(hook) expects a function");return y.push(e),()=>{y=y.filter(t=>t!==e)}}function W(e,t){let{combo:n,type:i}=I(e),o=E(n),r=g.get(o);if(!r)return;let l=r.get(i);if(l?.length){if(t){let s=[];for(let c of l)c.handler===t?h.delete(c.id):s.push(c);s.length?r.set(i,s):r.delete(i)}else{for(let s of l)h.delete(s.id);r.delete(i)}r.size||g.delete(o)}}function X(e,t){if(w.has(e))throw new Error(`Plugin "${e}" already registered`);let n=[];for(let[i,o]of Object.entries(t)){let[r,l]=Array.isArray(o)?o:[o,{}],s=O(i,r,e,l);n.push(s.id)}return w.set(e,n),()=>x(e)}function x(e){let t=w.get(e);if(t){for(let n of t)M(n);w.delete(e)}}function J(){K=!0}function Q(){K=!1}function ee(e=!0){S=!!e}function te(e){_=e}function z(e){let t=null;for(let n of e)t?(n.options.priority>t.options.priority||n.options.priority===t.options.priority&&n.id>t.id)&&(t=n):t=n;return t}function A(e){return t=>{if(K)return;let n=S&&Y(t),i=U(t),o=Z(t),r=new Set,l=[];for(let f of[i,o]){if(!f||r.has(f))continue;r.add(f);let u=g.get(f)?.get(e);if(u?.length)for(let m of u){let d=m.options;n&&!d.allowIn?.(t)||e==="keydown"&&d.repeat===!1&&t.repeat||d.when&&d.when(t)===!1||l.push(m)}}if(!l.length)return;let s=z(l),c=s.options;c.preventDefault&&t.preventDefault(),c.stopImmediatePropagation?t.stopImmediatePropagation():c.stopPropagation&&t.stopPropagation(),s.handler(t),c.once&&M(s.id)}}var b=null,k=null;function $({target:e=_,capture:t=!1}={}){if(!e)throw new Error("hotkeys.init() requires a target (e.g. window)");(b||k)&&C(),b=P(e,"keydown",A("keydown"),{capture:t}),k=P(e,"keyup",A("keyup"),{capture:t})}function C(){b?.(),k?.(),b=null,k=null,g.clear(),w.clear(),h.clear()}var ne={ctrl:"Control",shift:"Shift",alt:"Alt",meta:"Meta"};function oe(e,{type:t}={}){let{combo:n,type:i}=I(e),o=E(n),r=t||i,l=g.get(o)?.get(r);if(!l?.length)return!1;let s=n.bareModifier?ne[n.bareModifier]:n.key,c=!!n.alt,f=!!n.ctrl,u=!!n.shift,m=!!n.meta;n.bareModifier&&r==="keyup"&&(n.bareModifier==="alt"?c=!1:n.bareModifier==="ctrl"?f=!1:n.bareModifier==="shift"?u=!1:n.bareModifier==="meta"&&(m=!1));let d={type:r,key:s,code:n.code||null,ctrlKey:f,shiftKey:u,altKey:c,metaKey:m,repeat:!1,preventDefault(){},stopPropagation(){},stopImmediatePropagation(){},target:null},a=z(l.filter(p=>p.options.when?p.options.when(d)!==!1:!0));return a?(a.handler(d),a.options.once&&M(a.id),!0):!1}_&&$();var re={init:$,destroy:C,setTarget:te,bind:O,unbind:W,registerPlugin:X,unregisterPlugin:x,onBind:V,pause:J,resume:Q,ignoreInput:ee,trigger:oe};export{re as default};
@@ -1,4 +1,4 @@
1
- // hotkey-router v0.2.2 | SEE LICENSE IN LICENSE
1
+ // hotkey-router v0.2.3 | SEE LICENSE IN LICENSE
2
2
 
3
3
 
4
4
  // data/browser-hotkeys.json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hotkey-router",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "A tiny, deterministic keyboard routing engine for modern web apps.",
5
5
  "type": "module",
6
6
  "author": "WATT3D <WATT3D@protonmail.com>",