git ssb

1+

Matt McKegg / mutant



Tree: 955ee4ba0914a6c2c9a1158bdfa7ea7a186ca900

Files: 955ee4ba0914a6c2c9a1158bdfa7ea7a186ca900 / lib / apply-properties.js

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

Built with git-ssb-web