aboutsummaryrefslogtreecommitdiffhomepage
path: root/ui/static/js/keyboard_handler.js
diff options
context:
space:
mode:
Diffstat (limited to 'ui/static/js/keyboard_handler.js')
-rw-r--r--ui/static/js/keyboard_handler.js63
1 files changed, 63 insertions, 0 deletions
diff --git a/ui/static/js/keyboard_handler.js b/ui/static/js/keyboard_handler.js
new file mode 100644
index 0000000..df6eefc
--- /dev/null
+++ b/ui/static/js/keyboard_handler.js
@@ -0,0 +1,63 @@
+class KeyboardHandler {
+ constructor() {
+ this.queue = [];
+ this.shortcuts = {};
+ }
+
+ on(combination, callback) {
+ this.shortcuts[combination] = callback;
+ }
+
+ listen() {
+ document.onkeydown = (event) => {
+ if (this.isEventIgnored(event)) {
+ return;
+ }
+
+ let key = this.getKey(event);
+ this.queue.push(key);
+
+ for (let combination in this.shortcuts) {
+ let keys = combination.split(" ");
+
+ if (keys.every((value, index) => value === this.queue[index])) {
+ this.queue = [];
+ this.shortcuts[combination](event);
+ return;
+ }
+
+ if (keys.length === 1 && key === keys[0]) {
+ this.queue = [];
+ this.shortcuts[combination](event);
+ return;
+ }
+ }
+
+ if (this.queue.length >= 2) {
+ this.queue = [];
+ }
+ };
+ }
+
+ isEventIgnored(event) {
+ return event.target.tagName === "INPUT" || event.target.tagName === "TEXTAREA";
+ }
+
+ getKey(event) {
+ const mapping = {
+ 'Esc': 'Escape',
+ 'Up': 'ArrowUp',
+ 'Down': 'ArrowDown',
+ 'Left': 'ArrowLeft',
+ 'Right': 'ArrowRight'
+ };
+
+ for (let key in mapping) {
+ if (mapping.hasOwnProperty(key) && key === event.key) {
+ return mapping[key];
+ }
+ }
+
+ return event.key;
+ }
+}