UNPKG

@launchmenu/core

Version:

An environment for visual keyboard controlled applets

158 lines 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KeyHandler = void 0; const KeyEvent_1 = require("./KeyEvent"); const keyIds_1 = require("./keyIdentifiers/keyIds"); const keys_1 = require("./keyIdentifiers/keys"); const isPlatform_1 = require("../utils/platform/isPlatform"); /** * A key handler class */ class KeyHandler { /** * Creates a new key handler for the specified target * @param target The target to add the listeners to */ constructor(target) { this.listeners = []; this.pressedKeys = {}; this.id = Math.random(); // TODO: remove after testing this.target = target; this.setupListeners(); } /** * Sets up the listeners for the target * @param resetOnBlur Whether to reset the pressed keys if the window loses focus */ setupListeners() { this.keyListener = (e) => { const event = KeyHandler.getKeyEvent(e); if (event) this.emit(event); }; this.target.addEventListener("keydown", this.keyListener); this.target.addEventListener("keyup", this.keyListener); } /** * Emits a given keyboard event * @param event */ emit(event, { store = true, insertHeldKeys = true, } = {}) { if (event.type == "up" && store) delete this.pressedKeys[event.key.id]; if (insertHeldKeys) { if (event.held.length > 0) event.setHeldKeys([...event.held, ...Object.values(this.pressedKeys)]); else event.setHeldKeys(Object.values(this.pressedKeys)); } if (event.type != "up" && store) this.pressedKeys[event.key.id] = event.key; this.callListeners(event); this.handleMetaIssues(event); } /** * Fixes some issues with the meta key on windows and mac. * @param event the key event to handle meta issues for if relevant */ handleMetaIssues(event) { /* On Mac: {Meta down}{a down}{a up}{meta up} is not picked up correctly {Meta down}{a down}{meta up}{a up} is, instead {Meta down}{a down}{meta up} is received. I.E. key up events of keys are not sent while meta is down. */ if (isPlatform_1.isPlatform("mac")) { const isKeyDown = event.type == "down"; const metaHeld = this.pressedKeys["metaLeft"] || this.pressedKeys["metaRight"]; const isModifier = ["meta", "shift", "ctrl", "alt"].includes(event.key.name); if (isKeyDown && metaHeld && !isModifier) this.emit(new KeyEvent_1.KeyEvent({ key: event.key, type: "up" })); } /* Force all keys to release when meta is released, since sometimes meta consume release of other key presses */ if (event.key.name == "meta" && event.type == "up") this.resetKeys(); } /** * Removes the handlers from the target */ destroy() { this.target.removeEventListener("keydown", this.keyListener); this.target.removeEventListener("keyup", this.keyListener); } /** * Releases all currently held keys */ resetKeys() { // Release all keys on blur Object.values(this.pressedKeys).forEach(key => { this.emit(new KeyEvent_1.KeyEvent({ key, type: "up" })); }); this.pressedKeys = {}; } isDown(name) { if (typeof name == "number") return !!this.pressedKeys[name]; return !!Object.values(this.pressedKeys).find(key => key.name == name); } // Listener management /** * Calls all the listeners with the loaded data */ callListeners(event) { var _a, _b, _c; this.listeners.forEach(listener => listener(event)); (_a = event.original) === null || _a === void 0 ? void 0 : _a.stopImmediatePropagation(); (_b = event.original) === null || _b === void 0 ? void 0 : _b.stopPropagation(); (_c = event.original) === null || _c === void 0 ? void 0 : _c.preventDefault(); } /** * Adds a listener to the key handler * @param listener The listener to add * @returns This, for method chaining */ listen(listener) { this.listeners.push(listener); return this; } /** * Removes a listener from the key handler * @param listener The listener to remove * @returns Whether the listener was removed */ removeListener(listener) { const index = this.listeners.indexOf(listener); if (index != -1) { this.listeners.splice(index, 1); return true; } return false; } // Static helper methods /** * Retrieves the input data for a 'synthetic' key event * @param event The original event * @returns The input for the event */ static getKeyEvent(event) { const sourceId = event.code || event.key; if (!sourceId) return null; const cc = sourceId[0].toLowerCase() + sourceId.substr(1); const keyId = keyIds_1.keyIds[cc]; const keyName = keys_1.keyIdMapping[keyId]; const char = event.key.length == 1 ? event.key : ""; return new KeyEvent_1.KeyEvent({ key: { id: keyId !== null && keyId !== void 0 ? keyId : "", name: keyName !== null && keyName !== void 0 ? keyName : "", char, }, type: event.type == "keydown" ? "down" : "up", original: event, }); } } exports.KeyHandler = KeyHandler; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiS2V5SGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9rZXlIYW5kbGVyL0tleUhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EseUNBQW9DO0FBQ3BDLG9EQUErQztBQUMvQyxnREFBbUQ7QUFDbkQsNkRBQXdEO0FBRXhEOztHQUVHO0FBQ0gsTUFBYSxVQUFVO0lBU25COzs7T0FHRztJQUNILFlBQW1CLE1BQXlCO1FBWmxDLGNBQVMsR0FBd0IsRUFBRSxDQUFDO1FBRXBDLGdCQUFXLEdBQUcsRUFBMkIsQ0FBQztRQUkxQyxPQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsNkJBQTZCO1FBT3ZELElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQ7OztPQUdHO0lBQ08sY0FBYztRQUNwQixJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBZ0IsRUFBRSxFQUFFO1lBQ3BDLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsSUFBSSxLQUFLO2dCQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksSUFBSSxDQUNQLEtBQWUsRUFDZixFQUNJLEtBQUssR0FBRyxJQUFJLEVBQ1osY0FBYyxHQUFHLElBQUksTUFNckIsRUFBRTtRQUVOLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxJQUFJLElB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