-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmulti-state.js
43 lines (42 loc) · 1.84 KB
/
multi-state.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
export {MultiState};
import {BaseElement} from "./base-element.js";
const KEY_CODES = "key-codes";
// =============================================================================
// The multi-state base class, emulates change (not input) event, this.change
// declared in sub-classes, all of them dispatch a change event to the client.
// It has no references to the shadow DOM (this._dom).
class MultiState extends BaseElement {
static observedAttributes = [KEY_CODES, ...BaseElement.observedAttributes];
constructor(meta, template, noAwait) {
super(meta, template, noAwait);
this._keyCodes = new Set;
this.addEventListener("keyup", this._change, false);
this.addEventListener("click", this._change, false);
this.addEventListener("mousedown", this.#kludge, false); // Chrome issue
}
// attributeChangedCallback() handles changes to the observed attributes
attributeChangedCallback(name, _, val) {
if (name == KEY_CODES) {
if (!val) // null or ""
this._keyCodes.clear();
else
this._keyCodes = new Set(JSON.parse(val)) //!!validation??
}
else
super.attributeChangedCallback(name, _, val);
}
// this.keyCodes is the Set of keycodes that act like mouseclick
get keyCodes() { return Array.from(this._keyCodes); }
set keyCodes(val) {
this.setAttribute(KEY_CODES, JSON.stringify(Array.from(val))); //!!validation??
}
// _handleEvent() determines whether or not to handle an event
_handleEvent(evt) {
return evt.type == "click" || this._keyCodes.has(evt.code);
}
// #kludge() prevents Chrome from selecting the text in the next element
#kludge(evt) {
if (document.activeElement === this) // don't prevent setting of focus
evt.preventDefault();
}
}