-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdefine.js
More file actions
110 lines (85 loc) · 2.88 KB
/
Copy pathdefine.js
File metadata and controls
110 lines (85 loc) · 2.88 KB
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"use strict"
const define = (tag, params) =>
{
const states = new WeakMap
const proxies = new WeakMap
const dasherize = string => string.replace(/([a-z])(?=[A-Z])/g, "$1-")
const isPrivate = key => typeof key == "string" && key.startsWith("_")
const handler =
{
get(target, key)
{
if (isPrivate(key))
target = states.get(target)
let value = target[key]
return typeof value == "function"
? value.bind(target)
: value
},
set(target, key, value)
{
if (isPrivate(key))
target = states.get(target)
target[key] = value
return true
},
}
// let parent = document.createElement(params.extends).constructor
let parent = HTMLTimeElement
class fn extends parent
{
connectedCallback()
{
states.set(this, Object.create(null))
proxies.set(this, new Proxy(this, handler))
params.connect.call(proxies.get(this))
}
disconnectedCallback()
{
params.disconnect.call(proxies.get(this))
}
attributeChangedCallback()
{
params.attrChange.call(proxies.get(this))
}
}
let attrs = fn.observedAttributes = []
for (let [ key, value ] of Object.entries(params.props))
{
let isData = !(key in fn.prototype)
let desc =
{
enumerable: true,
configurable: true,
}
switch (value)
{
case Boolean:
desc.get = isData
? function() { return key in this.dataset }
: function() { return this.hasAttribute(key) }
desc.set = isData
? function(value) { value ? this.dataset[key] = "" : delete this.dataset[key] }
: function(value) { value ? this.setAttribute(key, "") : this.removeAttribute(key) }
break
case Date:
desc.get = isData
? function() { return new Date(this.dataset[key]) }
: function() { return new Date(this.getAttribute(key)) }
desc.set = isData
? function(value) { this.dataset[key] = value instanceof Date ? value.toISOString() : value }
: function(value) { this.setAttribute(key, value instanceof Date ? value.toISOString() : value) }
break
}
let attr = isData ? "data-" + dasherize(key) : key
attrs.push(attr.toLowerCase())
Object.defineProperty(fn.prototype, key, desc)
}
customElements.define(tag, fn,
{
extends: params.extends,
})
delete fn.prototype.connectedCallback
delete fn.prototype.disconnectedCallback
delete fn.prototype.attributeChangedCallback
}