-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
94 lines (82 loc) · 2.53 KB
/
index.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
var document = require('global/document')
var morph = require('nanomorph')
module.exports = CacheComponent
function makeId () {
return 'cc-' + Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1)
}
function CacheComponent () {
this._hasWindow = typeof window !== 'undefined'
this._proxy = null
this._args = null
this._ccId = null
this._id = null
var self = this
Object.defineProperty(this, '_element', {
get: function () {
var el = document.getElementById(self._id)
if (el) return el.dataset.cacheComponent === self._ccId ? el : undefined
}
})
}
CacheComponent.prototype.render = function () {
var args = new Array(arguments.length)
var self = this
var el
for (var i = 0; i < arguments.length; i++) args[i] = arguments[i]
if (!this._hasWindow) {
return this._render.apply(this, args)
} else if (this._element) {
var shouldUpdate = this._update.apply(this, args)
if (shouldUpdate) {
this._args = args
this._proxy = null
el = this._brandNode(this._handleId(this._render.apply(this, args)))
if (this._willUpdate) this._willUpdate()
morph(this._element, el)
if (this._didUpdate) window.requestAnimationFrame(function () { self._didUpdate() })
}
if (!this._proxy) { this._proxy = this._createProxy() }
return this._proxy
} else {
this._ccId = makeId()
this._args = args
this._proxy = null
el = this._brandNode(this._handleId(this._render.apply(this, args)))
if (this._willMount) this._willMount(el)
if (this._didMount) window.requestAnimationFrame(function () { self._didMount(el) })
return el
}
}
CacheComponent.prototype._createProxy = function () {
var proxy = document.createElement('div')
var self = this
this._brandNode(proxy)
proxy.id = this._id
proxy.isSameNode = function (el) {
return (el && el.dataset.cacheComponent === self._ccId)
}
return proxy
}
CacheComponent.prototype._brandNode = function (node) {
node.setAttribute('data-cache-component', this._ccId)
return node
}
CacheComponent.prototype._handleId = function (node) {
if (node.id) {
this._id = node.id
} else {
node.id = this._id = this._ccId
}
return node
}
CacheComponent.prototype._render = function () {
throw new Error('cache-component: _render should be implemented!')
}
CacheComponent.prototype._update = function () {
var length = arguments.length
if (length !== this._args.length) return true
for (var i = 0; i < length; i++) {
if (arguments[i] !== this._args[i]) return true
}
return false
}