1 import {Injectable, EventEmitter, HostListener} from '@angular/core';
3 export interface AccessKeyAssignment {
4 key: string; // keyboard command
5 desc: string; // human-friendly description
6 ctx: string; // template context
7 action: Function; // handler function
11 export class AccessKeyService {
13 // Assignments stored as an array with most recently assigned
14 // items toward the front. Most recent items have precedence.
15 assignments: AccessKeyAssignment[] = [];
19 assign(assn: AccessKeyAssignment): void {
20 this.assignments.unshift(assn);
24 * Compress a set of single-fire keyboard events into single
25 * string. For example: Control and 't' becomes 'ctrl+t'.
27 compressKeys(evt: KeyboardEvent): string {
30 if (evt.ctrlKey || evt.metaKey) { s += 'ctrl+'; }
31 if (evt.altKey) { s += 'alt+'; }
32 s += evt.key.toLowerCase();
38 * Checks for a key assignment and fires the assigned action.
40 fire(evt: KeyboardEvent): void {
41 const keySpec = this.compressKeys(evt);
42 for (const i in this.assignments) { // for-loop to exit early
43 if (keySpec === this.assignments[i].key) {
44 const assign = this.assignments[i];
45 console.debug(`AccessKey assignment found for ${assign.key}`);
46 // Allow the current digest cycle to complete before
47 // firing the access key action.
48 setTimeout(assign.action, 0);
56 * Returns a simplified key assignment list containing just
57 * the key spec and the description. Useful for inspecting
58 * without exposing the actions.
61 return this.assignments.map(a => {
62 return {key: a.key, desc: a.desc, ctx: a.ctx};