@@ -0,0 +1,68 @@
1+import { writable, get } from 'svelte/store';
2+
3+const docs = {};
4+
5+class MapWithDefault<K, V> extends Map<K, V> {
6+ default: Function;
7+
8+ get(key: K) {
9+ if (!this.has(key)) {
10+ this.set(key, this.default());
11+ }
12+ return super.get(key);
13+ }
14+
15+ constructor(defaultFunction: () => V) {
16+ super();
17+ this.default = defaultFunction;
18+ }
19+}
20+
21+type Bindings = MapWithDefault<string, MapWithDefault<string, Function>>;
22+interface KeysStore {
23+ keydown: Bindings;
24+ keyup: Bindings;
25+ globalkeydown: Bindings;
26+ globalkeyup: Bindings;
27+};
28+function newEmptyBindings(): Bindings {
29+ return new MapWithDefault(() => new MapWithDefault(() => Function));
30+}
31+const initStore: KeysStore = {
32+ keydown: newEmptyBindings(),
33+ keyup: newEmptyBindings(),
34+ globalkeydown: newEmptyBindings(),
35+ globalkeyup: newEmptyBindings(),
36+};
37+
38+const store = writable(initStore);
39+const { subscribe, update, set } = store;
40+
41+function runCallbacks(bindings: Bindings, event: KeyboardEvent) {
42+ let els = [];
43+ if (event.ctrlKey) els.push('ctrl');
44+ if (event.metaKey) els.push('cmd');
45+ if (event.altKey) els.push('alt');
46+ if (event.shiftKey) els.push('shift');
47+ els.push(event.key == ' ' ? 'Space' : event.key.toLowerCase());
48+ let combo = els.join('+');
49+ // console.log(event);
50+ let callbacks = bindings.get(combo);
51+ if (callbacks) {
52+ callbacks.forEach((callback) => {
53+ try {
54+ if (callback)
55+ callback(event);
56+ } catch (e) {
57+ console.error(e);
58+ }
59+ });
60+ }
61+}
62+
63+export default {
64+ subscribe,
65+ update,
66+ set,
67+ runCallbacks,
68+};