git ssb

1+

Matt McKegg / mutant



Tree: 1b3ee2905a0cb00a98265dfd85dc66f2e87d675b

Files: 1b3ee2905a0cb00a98265dfd85dc66f2e87d675b / lib / apply-properties.js

3133 bytesRaw
1var isObservable = require('../is-observable')
2var Set = require('../set')
3var watch = require('../watch')
4var caches = new global.WeakMap()
5
6module.exports = applyProperties
7
8function applyProperties (target, properties) {
9 var data = caches.get(target)
10 if (!data) {
11 data = { releases: [] }
12 caches.set(target, data)
13 }
14
15 var classList = Set()
16 if (target.className) {
17 classList.add(target.className)
18 }
19
20 for (var key in properties) {
21 var valueOrObs = properties[key]
22 var value = resolve(valueOrObs)
23
24 if (key === 'style') {
25 // TODO: handle observable at root for style objects
26 for (var k in value) {
27 var styleValue = resolve(value[k])
28 var styleObs = isObservable(value[k]) ? value[k] : null
29 target.style.setProperty(k, styleValue)
30
31 if (styleObs) {
32 data.releases.push(bindStyle(target, styleObs, k))
33 }
34 }
35 } else if (key === 'hooks') {
36 value.forEach(function (v) {
37 var release = v(target)
38 if (typeof release === 'function') {
39 data.releases.push(release)
40 }
41 })
42 } else if (key === 'attributes') {
43 for (var k in value) {
44 var attrValue = resolve(value[k])
45 var attrObs = isObservable(value[k]) ? value[k] : null
46 target.setAttribute(k, attrValue)
47
48 if (attrObs) {
49 data.releases.push(bindAttr(target, attrObs, k))
50 }
51 }
52 } else if (key === 'events') {
53 for (var name in value) {
54 target.addEventListener(name, value[name], false)
55 }
56 } else if (key.slice(0, 3) === 'ev-') {
57 target.addEventListener(key.slice(3), value, false)
58 } else if (key === 'className' || key === 'classList') {
59 if (Array.isArray(valueOrObs)) {
60 valueOrObs.forEach(function (v) {
61 classList.add(v)
62 })
63 } else {
64 classList.add(valueOrObs)
65 }
66 } else {
67 target[key] = value
68 var obs = isObservable(valueOrObs) ? valueOrObs : null
69 if (obs) {
70 data.releases.push(bind(target, obs, key))
71 }
72 }
73 }
74
75 watch(classList, function (value) {
76 value = [].concat.apply([], value).filter(present).join(' ')
77 if (value || target.className) {
78 target.className = value
79 }
80 })
81}
82
83applyProperties.destroy = function (target) {
84 var data = caches.get(target)
85 if (data) {
86 while (data.releases.length) {
87 data.releases.pop()()
88 }
89 caches.delete(target)
90 }
91}
92
93function bindStyle (target, styleObs, key) {
94 return styleObs(function (value) {
95 target.style.setProperty(key, value)
96 })
97}
98
99function bindAttr (target, attrObs, key) {
100 return attrObs(function (value) {
101 if (value == null) {
102 target.removeAttribute(key)
103 } else {
104 target.setAttribute(key, value)
105 }
106 })
107}
108
109function bind (target, obs, key) {
110 return obs(function (toValue) {
111 var fromValue = target.getAttribute(key)
112 if (fromValue !== toValue) {
113 target.setAttribute(key, toValue)
114 }
115 })
116}
117
118function present (val) {
119 return val != null
120}
121
122function resolve (source) {
123 return typeof source === 'function' ? source() : source
124}
125

Built with git-ssb-web