-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdsm.js
58 lines (52 loc) · 1.52 KB
/
dsm.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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// This utility is not secured (yet?)
const toHyphen = name => name.replace(/[A-Z]/g, $ => ('-' + $.toLowerCase()));
const fromHyphen = name => name.replace(/-(.)/g, (_, $) => $.toUpperCase());
const dsmRef = new WeakMap;
class DOMStringMap {
constructor(prefix) {
this.prefix = prefix;
}
deleteProperty(target, key) {
key = this.prefix + toHyphen(key);
target.removeAttribute(key);
return true;
}
get(target, key) {
key = this.prefix + toHyphen(key);
const value = target.getAttribute(key);
return value == null ? void 0 : value;
}
has(target, key) {
key = this.prefix + toHyphen(key);
return target.hasAttribute(key);
}
ownKeys(target) {
const {prefix} = this;
const {length} = prefix;
const keys = [];
for (const {name} of target.attributes) {
if (name.startsWith(this.prefix))
keys.push(fromHyphen(name.slice(length)));
}
return keys;
}
set(target, key, value) {
key = this.prefix + toHyphen(key);
target.setAttribute(key, value);
}
}
const handler = {
get(target, name) {
if (/set$/.test(name)) {
if (!dsmRef.has(target))
dsmRef.set(target, new Map);
const nmsp = dsmRef.get(target);
if (!nmsp.has(name))
nmsp.set(name, new Proxy(target, new DOMStringMap(name.slice(0, -3) + '-')));
return nmsp.get(name);
}
return target[name];
}
};
/** @type {<T>(target:T) => target} A Proxy for an element to handle dataset like attributes. */
export const dsm = target => new Proxy(target, handler);