-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathcomponentWidget.js
138 lines (114 loc) · 3.22 KB
/
componentWidget.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
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
var VText = require('virtual-dom/vnode/vtext.js')
var domComponent = require('./domComponent')
var render = require('./render')
var deprecations = require('./deprecations')
function ComponentWidget (state, vdom) {
if (!vdom) {
throw new Error('hyperdom.html.component([options], vdom) expects a vdom argument')
}
this.state = state
this.key = state.key
var currentRender = render.currentRender()
if (typeof vdom === 'function') {
this.render = function () {
if (currentRender && state.on) {
currentRender.transformFunctionAttribute = function (key, value) {
return state.on(key.replace(/^on/, ''), value)
}
}
return vdom.apply(this.state, arguments)
}
this.canRefresh = true
} else {
vdom = vdom || new VText('')
this.render = function () {
return vdom
}
}
this.cacheKey = state.cacheKey
this.component = domComponent.create()
var renderFinished = currentRender && currentRender.finished
if (renderFinished) {
this.afterRender = function (fn) {
renderFinished.then(fn)
}
} else {
this.afterRender = function () {}
}
}
ComponentWidget.prototype.type = 'Widget'
ComponentWidget.prototype.init = function () {
var self = this
if (self.state.onbeforeadd) {
self.state.onbeforeadd()
}
var vdom = this.render(this)
if (vdom instanceof Array) {
throw new Error('vdom returned from component cannot be an array')
}
var element = this.component.create(vdom)
if (self.state.onadd) {
this.afterRender(function () {
self.state.onadd(element)
})
}
if (self.state.detached) {
return document.createTextNode('')
} else {
return element
}
}
ComponentWidget.prototype.update = function (previous) {
var self = this
var refresh = !this.cacheKey || this.cacheKey !== previous.cacheKey
if (refresh) {
if (self.state.onupdate) {
this.afterRender(function () {
self.state.onupdate(self.component.element)
})
}
}
this.component = previous.component
if (previous.state && this.state) {
var keys = Object.keys(this.state)
for (var n = 0; n < keys.length; n++) {
var key = keys[n]
previous.state[key] = self.state[key]
}
this.state = previous.state
}
if (refresh) {
var element = this.component.update(this.render(this))
if (self.state.detached) {
return document.createTextNode('')
} else {
return element
}
}
}
ComponentWidget.prototype.refresh = function () {
this.component.update(this.render(this))
if (this.state.onupdate) {
this.state.onupdate(this.component.element)
}
}
ComponentWidget.prototype.destroy = function (element) {
var self = this
if (self.state.onremove) {
this.afterRender(function () {
self.state.onremove(element)
})
}
this.component.destroy()
}
module.exports = function (state, vdom) {
deprecations.component('hyperdom.html.component is deprecated, please use hyperdom.viewComponent')
if (typeof state === 'function') {
return new ComponentWidget({}, state)
} else if (state.constructor === Object) {
return new ComponentWidget(state, vdom)
} else {
return new ComponentWidget({}, state)
}
}
module.exports.ComponentWidget = ComponentWidget