Spaces:
Running
on
Zero
Running
on
Zero
class KeyEventService extends EventTarget { | |
constructor() { | |
var _a, _b, _c; | |
super(); | |
this.downKeys = {}; | |
this.ctrlKey = false; | |
this.altKey = false; | |
this.metaKey = false; | |
this.shiftKey = false; | |
this.isMac = !!(((_a = navigator.platform) === null || _a === void 0 ? void 0 : _a.toLocaleUpperCase().startsWith("MAC")) || | |
((_c = (_b = navigator.userAgentData) === null || _b === void 0 ? void 0 : _b.platform) === null || _c === void 0 ? void 0 : _c.toLocaleUpperCase().startsWith("MAC"))); | |
this.initialize(); | |
} | |
initialize() { | |
const that = this; | |
const processKey = LGraphCanvas.prototype.processKey; | |
LGraphCanvas.prototype.processKey = function (e) { | |
if (e.type === "keydown" || e.type === "keyup") { | |
that.handleKeyDownOrUp(e); | |
} | |
return processKey.apply(this, [...arguments]); | |
}; | |
window.addEventListener("keydown", (e) => { | |
that.handleKeyDownOrUp(e); | |
}); | |
window.addEventListener("keyup", (e) => { | |
that.handleKeyDownOrUp(e); | |
}); | |
document.addEventListener("visibilitychange", (e) => { | |
this.clearKeydowns(); | |
}); | |
window.addEventListener("blur", (e) => { | |
this.clearKeydowns(); | |
}); | |
} | |
handleKeyDownOrUp(e) { | |
const key = e.key.toLocaleUpperCase(); | |
if ((e.type === 'keydown' && this.downKeys[key] === true) | |
|| (e.type === 'keyup' && this.downKeys[key] === undefined)) { | |
return; | |
} | |
this.ctrlKey = !!e.ctrlKey; | |
this.altKey = !!e.altKey; | |
this.metaKey = !!e.metaKey; | |
this.shiftKey = !!e.shiftKey; | |
if (e.type === "keydown") { | |
this.downKeys[key] = true; | |
this.dispatchCustomEvent("keydown", { originalEvent: e }); | |
} | |
else if (e.type === "keyup") { | |
if (key === "META" && this.isMac) { | |
this.clearKeydowns(); | |
} | |
else { | |
delete this.downKeys[key]; | |
} | |
this.dispatchCustomEvent("keyup", { originalEvent: e }); | |
} | |
} | |
clearKeydowns() { | |
this.ctrlKey = false; | |
this.altKey = false; | |
this.metaKey = false; | |
this.shiftKey = false; | |
for (const key in this.downKeys) | |
delete this.downKeys[key]; | |
} | |
dispatchCustomEvent(event, detail) { | |
if (detail != null) { | |
return this.dispatchEvent(new CustomEvent(event, { detail })); | |
} | |
return this.dispatchEvent(new CustomEvent(event)); | |
} | |
getKeysFromShortcut(shortcut) { | |
let keys; | |
if (typeof shortcut === "string") { | |
shortcut = shortcut.replace(/\s/g, ""); | |
shortcut = shortcut.replace(/^\+/, "__PLUS__").replace(/\+\+/, "+__PLUS__"); | |
keys = shortcut.split("+").map((i) => i.replace("__PLUS__", "+")); | |
} | |
else { | |
keys = [...shortcut]; | |
} | |
return keys.map((k) => k.toLocaleUpperCase()); | |
} | |
areAllKeysDown(keys) { | |
keys = this.getKeysFromShortcut(keys); | |
return keys.every((k) => { | |
return this.downKeys[k]; | |
}); | |
} | |
areOnlyKeysDown(keys, alsoAllowShift = false) { | |
keys = this.getKeysFromShortcut(keys); | |
const allKeysDown = this.areAllKeysDown(keys); | |
const downKeysLength = Object.values(this.downKeys).length; | |
if (allKeysDown && keys.length === downKeysLength) { | |
return true; | |
} | |
if (alsoAllowShift && !keys.includes("SHIFT") && keys.length === downKeysLength - 1) { | |
return allKeysDown && this.areAllKeysDown(["SHIFT"]); | |
} | |
return false; | |
} | |
} | |
export const SERVICE = new KeyEventService(); | |