keyboard_handler.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. class KeyboardHandler {
  2. constructor() {
  3. this.queue = [];
  4. this.shortcuts = new Map();
  5. this.triggers = new Set();
  6. }
  7. on(combination, callback) {
  8. const keys = combination.split(" ");
  9. this.shortcuts.set(combination, { keys, callback });
  10. this.triggers.add(keys[0]);
  11. }
  12. listen() {
  13. document.onkeydown = (event) => {
  14. const key = KeyboardHandler.getKey(event);
  15. if (this.isEventIgnored(event, key) || KeyboardHandler.isModifierKeyDown(event)) {
  16. return;
  17. }
  18. if (key !== "Enter") {
  19. event.preventDefault();
  20. }
  21. this.queue.push(key);
  22. for (const [combination, { keys, callback }] of this.shortcuts.entries()) {
  23. if (keys.every((value, index) => value === this.queue[index])) {
  24. this.queue = [];
  25. callback(event);
  26. return;
  27. }
  28. if (keys.length === 1 && key === keys[0]) {
  29. this.queue = [];
  30. callback(event);
  31. return;
  32. }
  33. }
  34. if (this.queue.length >= 2) {
  35. this.queue = [];
  36. }
  37. };
  38. }
  39. isEventIgnored(event, key) {
  40. return event.target.tagName === "INPUT" ||
  41. event.target.tagName === "TEXTAREA" ||
  42. (this.queue.length < 1 && !this.triggers.has(key));
  43. }
  44. static isModifierKeyDown(event) {
  45. return event.getModifierState("Control") || event.getModifierState("Alt") || event.getModifierState("Meta");
  46. }
  47. static getKey(event) {
  48. switch (event.key) {
  49. case 'Esc': return 'Escape';
  50. case 'Up': return 'ArrowUp';
  51. case 'Down': return 'ArrowDown';
  52. case 'Left': return 'ArrowLeft';
  53. case 'Right': return 'ArrowRight';
  54. default: return event.key;
  55. }
  56. }
  57. }