UNPKG

@dotglitch/ngx-common

Version:

Angular components and utilities that are commonly used.

128 lines 15.4 kB
import { Injectable, HostListener } from '@angular/core'; import { Subject } from 'rxjs'; import * as i0 from "@angular/core"; /** * Service that listens for global keyboard events */ export class KeyboardService { constructor() { this.heldKeys = {}; this.keyCommands = []; window.addEventListener("keydown", (evt) => this.onKeyDown(evt)); window.addEventListener("keyup", (evt) => this.onKeyUp(evt)); } onKeyDown(evt) { // console.log("keydown", evt.key) this.heldKeys[evt.key.toLowerCase()] = true; // Do a general filter where all of the modifiers must be matched if specified // Then check that the actual keys match what was specified let commands = this.keyCommands .filter(kc => (kc.ctrl == undefined || kc.ctrl === evt.ctrlKey) && (kc.alt == undefined || kc.alt === evt.altKey) && (kc.shift == undefined || kc.shift === evt.shiftKey) && (kc.super == undefined || kc.super === evt.metaKey) && kc.keys.length == kc.keys.filter(k => this.heldKeys[k])?.length); if (evt.ctrlKey && commands.length > 0 || commands.find(c => c.interrupt)) { evt.stopPropagation(); evt.preventDefault(); } if (evt.key == "Pause") debugger; commands.forEach(kc => kc.sub.next(evt)); /** * Prevent CTRL+P and other standard key events from being handled by the browser. * Allow specific combonations: * CTRL+W * CTRL+T * CTRL+F5 */ // if (evt.ctrlKey && !['w', 't', 'F5'].includes(evt.key)) { // evt.preventDefault(); // } } onKeyUp(evt) { this.heldKeys[evt.key.toLowerCase()] = false; } onKeyPress(evt) { // this.heldKeys[evt.key] = false; } /** * Use this to subscribe to keyboard events throughout * the application. This is a passive listener and will * **NOT** interrupt the event chain. */ onKeyCommand(key) { const sub = new Subject(); let item = { ...key, keys: (Array.isArray(key.key) ? key.key : [key.key]), sub: sub }; this.keyCommands.push(item); return { ...sub, subscribe: ((...args) => { const s = sub.subscribe(...args); return { ...s, unsubscribe: () => { s.unsubscribe(); // Remove the keycommand from the list of listeners. const i = this.keyCommands.findIndex(c => c == item); this.keyCommands.splice(i, 1); } }; }) }; } /** * Return `true` if shift is currently pressed. */ get isShiftPressed() { return !!this.heldKeys["shift"]; } /** * Return `true` if ctrl is currently pressed. */ get isCtrlPressed() { return !!this.heldKeys["control"]; } /** * Return `true` if alt is currently pressed. */ get isAltPressed() { return !!this.heldKeys["alt"]; } /** * Return `true` if super (mac/linux) or the windows key is currently pressed. */ get isSuperPressed() { return !!this.heldKeys["super"]; } /** * Return `true` if tab is currently pressed. */ get isTabPressed() { return !!this.heldKeys["tab"]; } clearKeys() { Object.keys(this.heldKeys).forEach(k => { this.heldKeys[k] = false; }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: KeyboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: KeyboardService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: KeyboardService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [], propDecorators: { clearKeys: [{ type: HostListener, args: ["window:blur"] }, { type: HostListener, args: ["window:resize"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Ym9hcmQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi9zcmMvc2VydmljZXMva2V5Ym9hcmQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQXFCL0I7O0dBRUc7QUFJSCxNQUFNLE9BQU8sZUFBZTtJQWN4QjtRQVpRLGFBQVEsR0FBK0IsRUFBRSxDQUFDO1FBQzNDLGdCQUFXLEdBU1osRUFBRSxDQUFDO1FBR0wsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRU8sU0FBUyxDQUFDLEdBQWtCO1FBQ2hDLGtDQUFrQztRQUNsQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7UUFFNUMsOEVBQThFO1FBQzlFLDJEQUEyRDtRQUMzRCxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVzthQUMxQixNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FDVCxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksU0FBUyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLE9BQU8sQ0FBQztZQUNqRCxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksU0FBUyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEtBQUss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QUFDLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUNEOztPQUVHO0lBQ0gsSUFBSSxZQUFZO1FBQ1osT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBQ0Q7O09BRUc7SUFDSCxJQUFJLGNBQWM7UUFDZCxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRDs7T0FFRztJQUNILElBQUksWUFBWTtRQUNaLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUlELFNBQVM7UUFDTCxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDbkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDOzhHQXRJUSxlQUFlO2tIQUFmLGVBQWUsY0FGWixNQUFNOzsyRkFFVCxlQUFlO2tCQUgzQixVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQjt3REFtSUcsU0FBUztzQkFGUixZQUFZO3VCQUFDLGFBQWE7O3NCQUMxQixZQUFZO3VCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBIb3N0TGlzdGVuZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuZXhwb3J0IHR5cGUgS2V5Q29tbWFuZCA9IHtcbiAgICAvKipcbiAgICAgKiBUaGUgbm9uLW1vZGlmaWVyIGtleShzKSB0aGF0IG11c3QgYmUgcHJlc3NlZCBmb3IgdGhlIGV2ZW50IHRvIGZpcmUuXG4gICAgICovXG4gICAga2V5OiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgICBsYWJlbD86IHN0cmluZyxcblxuICAgIGN0cmw/OiBib29sZWFuLFxuICAgIGFsdD86IGJvb2xlYW4sXG4gICAgc2hpZnQ/OiBib29sZWFuLFxuICAgIHN1cGVyPzogYm9vbGVhbixcbiAgICB0YWI/OiBib29sZWFuLFxuXG4gICAgLyoqXG4gICAgICogU2hvdWxkIHRoZSBoYW5kbGVyIGludGVycnVwdCBkZWZhdWx0IGV2ZW50IGhhbmRsaW5nXG4gICAgICovXG4gICAgaW50ZXJydXB0PzogYm9vbGVhbixcbn1cblxuLyoqXG4gKiBTZXJ2aWNlIHRoYXQgbGlzdGVucyBmb3IgZ2xvYmFsIGtleWJvYXJkIGV2ZW50c1xuICovXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEtleWJvYXJkU2VydmljZSB7XG5cbiAgICBwcml2YXRlIGhlbGRLZXlzOiB7IFtrZXk6IHN0cmluZ106IGJvb2xlYW4gfSA9IHt9O1xuICAgIHB1YmxpYyBrZXlDb21tYW5kczoge1xuICAgICAgICBjdHJsPzogYm9vbGVhbixcbiAgICAgICAgYWx0PzogYm9vbGVhbixcbiAgICAgICAgc2hpZnQ/OiBib29sZWFuLFxuICAgICAgICBzdXBlcj86IGJvb2xlYW4sXG4gICAgICAgIGludGVycnVwdD86IGJvb2xlYW4sXG4gICAgICAgIGxhYmVsPzogc3RyaW5nLFxuICAgICAgICBrZXlzOiBzdHJpbmdbXSxcbiAgICAgICAgc3ViOiBTdWJqZWN0PEtleWJvYXJkRXZlbnQ+XG4gICAgfVtdID0gW107XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIChldnQpID0+IHRoaXMub25LZXlEb3duKGV2dCkpO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImtleXVwXCIsIChldnQpID0+IHRoaXMub25LZXlVcChldnQpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uS2V5RG93bihldnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJrZXlkb3duXCIsIGV2dC5rZXkpXG4gICAgICAgIHRoaXMuaGVsZEtleXNbZXZ0LmtleS50b0xvd2VyQ2FzZSgpXSA9IHRydWU7XG5cbiAgICAgICAgLy8gRG8gYSBnZW5lcmFsIGZpbHRlciB3aGVyZSBhbGwgb2YgdGhlIG1vZGlmaWVycyBtdXN0IGJlIG1hdGNoZWQgaWYgc3BlY2lmaWVkXG4gICAgICAgIC8vIFRoZW4gY2hlY2sgdGhhdCB0aGUgYWN0dWFsIGtleXMgbWF0Y2ggd2hhdCB3YXMgc3BlY2lmaWVkXG4gICAgICAgIGxldCBjb21tYW5kcyA9IHRoaXMua2V5Q29tbWFuZHNcbiAgICAgICAgICAgIC5maWx0ZXIoa2MgPT5cbiAgICAgICAgICAgICAgICAoa2MuY3RybCA9PSB1bmRlZmluZWQgfHwga2MuY3RybCA9PT0gZXZ0LmN0cmxLZXkpICYmXG4gICAgICAgICAgICAgICAgKGtjLmFsdCA9PSB1bmRlZmluZWQgfHwga2MuYWx0ID09PSBldnQuYWx0S2V5KSAmJlxuICAgICAgICAgICAgICAgIChrYy5zaGlmdCA9PSB1bmRlZmluZWQgfHwga2Muc2hpZnQgPT09IGV2dC5zaGlmdEtleSkgJiZcbiAgICAgICAgICAgICAgICAoa2Muc3VwZXIgPT0gdW5kZWZpbmVkIHx8IGtjLnN1cGVyID09PSBldnQubWV0YUtleSkgJiZcbiAgICAgICAgICAgICAgICBrYy5rZXlzLmxlbmd0aCA9PSBrYy5rZXlzLmZpbHRlcihrID0+IHRoaXMuaGVsZEtleXNba10pPy5sZW5ndGhcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgaWYgKGV2dC5jdHJsS2V5ICYmIGNvbW1hbmRzLmxlbmd0aCA+IDAgfHwgY29tbWFuZHMuZmluZChjID0+IGMuaW50ZXJydXB0KSkge1xuICAgICAgICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZ0LmtleSA9PSBcIlBhdXNlXCIpXG4gICAgICAgICAgICBkZWJ1Z2dlcjtcblxuICAgICAgICBjb21tYW5kcy5mb3JFYWNoKGtjID0+IGtjLnN1Yi5uZXh0KGV2dCkpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcmV2ZW50IENUUkwrUCBhbmQgb3RoZXIgc3RhbmRhcmQga2V5IGV2ZW50cyBmcm9tIGJlaW5nIGhhbmRsZWQgYnkgdGhlIGJyb3dzZXIuXG4gICAgICAgICAqIEFsbG93IHNwZWNpZmljIGNvbWJvbmF0aW9uczpcbiAgICAgICAgICogQ1RSTCtXXG4gICAgICAgICAqIENUUkwrVFxuICAgICAgICAgKiBDVFJMK0Y1XG4gICAgICAgICAqL1xuICAgICAgICAvLyBpZiAoZXZ0LmN0cmxLZXkgJiYgIVsndycsICd0JywgJ0Y1J10uaW5jbHVkZXMoZXZ0LmtleSkpIHtcbiAgICAgICAgLy8gICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAvLyB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbktleVVwKGV2dDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICB0aGlzLmhlbGRLZXlzW2V2dC5rZXkudG9Mb3dlckNhc2UoKV0gPSBmYWxzZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uS2V5UHJlc3MoZXZ0OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgICAgIC8vIHRoaXMuaGVsZEtleXNbZXZ0LmtleV0gPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2UgdGhpcyB0byBzdWJzY3JpYmUgdG8ga2V5Ym9hcmQgZXZlbnRzIHRocm91Z2hvdXRcbiAgICAgKiB0aGUgYXBwbGljYXRpb24uIFRoaXMgaXMgYSBwYXNzaXZlIGxpc3RlbmVyIGFuZCB3aWxsXG4gICAgICogKipOT1QqKiBpbnRlcnJ1cHQgdGhlIGV2ZW50IGNoYWluLlxuICAgICAqL1xuICAgIHB1YmxpYyBvbktleUNvbW1hbmQoa2V5OiBLZXlDb21tYW5kKSB7XG4gICAgICAgIGNvbnN0IHN1YiA9IG5ldyBTdWJqZWN0PEtleWJvYXJkRXZlbnQ+KCk7XG4gICAgICAgIGxldCBpdGVtID0ge1xuICAgICAgICAgICAgLi4ua2V5LFxuICAgICAgICAgICAga2V5czogKEFycmF5LmlzQXJyYXkoa2V5LmtleSkgPyBrZXkua2V5IDogW2tleS5rZXldKSxcbiAgICAgICAgICAgIHN1Yjogc3ViXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmtleUNvbW1hbmRzLnB1c2goaXRlbSk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLnN1YixcbiAgICAgICAgICAgIHN1YnNjcmliZTogKCguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcyA9IHN1Yi5zdWJzY3JpYmUoLi4uYXJncyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucyxcbiAgICAgICAgICAgICAgICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHMudW5zdWJzY3JpYmUoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBrZXljb21tYW5kIGZyb20gdGhlIGxpc3Qgb2YgbGlzdGVuZXJzLlxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaSA9IHRoaXMua2V5Q29tbWFuZHMuZmluZEluZGV4KGMgPT4gYyA9PSBpdGVtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMua2V5Q29tbWFuZHMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pIGFzIFN1YmplY3Q8S2V5Ym9hcmRFdmVudD5bJ3N1YnNjcmliZSddXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIGB0cnVlYCBpZiBzaGlmdCBpcyBjdXJyZW50bHkgcHJlc3NlZC5cbiAgICAgKi9cbiAgICBnZXQgaXNTaGlmdFByZXNzZWQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuaGVsZEtleXNbXCJzaGlmdFwiXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIGB0cnVlYCBpZiBjdHJsIGlzIGN1cnJlbnRseSBwcmVzc2VkLlxuICAgICAqL1xuICAgIGdldCBpc0N0cmxQcmVzc2VkKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLmhlbGRLZXlzW1wiY29udHJvbFwiXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIGB0cnVlYCBpZiBhbHQgaXMgY3VycmVudGx5IHByZXNzZWQuXG4gICAgICovXG4gICAgZ2V0IGlzQWx0UHJlc3NlZCgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5oZWxkS2V5c1tcImFsdFwiXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIGB0cnVlYCBpZiBzdXBlciAobWFjL2xpbnV4KSBvciB0aGUgd2luZG93cyBrZXkgaXMgY3VycmVudGx5IHByZXNzZWQuXG4gICAgICovXG4gICAgZ2V0IGlzU3VwZXJQcmVzc2VkKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLmhlbGRLZXlzW1wic3VwZXJcIl07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiBgdHJ1ZWAgaWYgdGFiIGlzIGN1cnJlbnRseSBwcmVzc2VkLlxuICAgICAqL1xuICAgIGdldCBpc1RhYlByZXNzZWQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuaGVsZEtleXNbXCJ0YWJcIl07XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcihcIndpbmRvdzpibHVyXCIpXG4gICAgQEhvc3RMaXN0ZW5lcihcIndpbmRvdzpyZXNpemVcIilcbiAgICBjbGVhcktleXMoKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuaGVsZEtleXMpLmZvckVhY2goayA9PiB7XG4gICAgICAgICAgICB0aGlzLmhlbGRLZXlzW2tdID0gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiJdfQ==