git ssb

1+

Matt McKegg / mutant



Commit 880a92caf2ae2e1a7551e7a500794c09adf5880b

html-element: don't double bind nodes unless nextTick

Matt McKegg committed on 7/27/2016, 6:27:22 AM
Parent: b588b1cbc0c0e85d0288a7fa484660bf8225a915

Files changed

html-element.jschanged
lib/invalidate-next-tick.jsadded
html-element.jsView
@@ -4,8 +4,9 @@
44 var walk = require('./lib/walk')
55 var watch = require('./watch')
66 var caches = new global.WeakMap()
77 var watcher = null
8 +var invalidateNextTick = require('./lib/invalidate-next-tick')
89
910 module.exports = function (tag, attributes, children) {
1011 return Element(global.document, null, tag, attributes, children)
1112 }
@@ -58,9 +59,9 @@
5859 } else if (isObservable(node)) {
5960 var nodes = getNodes(document, resolve(node))
6061 nodes.forEach(append, target)
6162 data.targets.set(node, nodes)
62- data.bindings.push(new Binding(bind, document, node, data))
63 + data.bindings.push(new Binding(document, node, data))
6364 } else {
6465 node = getNode(document, node)
6566 target.appendChild(node)
6667 walk(node, rebind)
@@ -100,19 +101,8 @@
100101 }
101102 }
102103 }
103104
104-function bind (document, obs, data) {
105- return watch(obs, function (value) {
106- var oldNodes = data.targets.get(obs)
107- var newNodes = getNodes(document, value)
108- if (oldNodes) {
109- replace(oldNodes, newNodes)
110- data.targets.set(obs, newNodes)
111- }
112- })
113-}
114-
115105 function indexOf (target, item) {
116106 return Array.prototype.indexOf.call(target, item)
117107 }
118108
@@ -216,27 +206,40 @@
216206 function resolve (source) {
217207 return typeof source === 'function' ? source() : source
218208 }
219209
220-function Binding (fn, document, obs, data) {
210 +function Binding (document, obs, data) {
221211 this.document = document
222212 this.obs = obs
223213 this.data = data
224- this.fn = fn
225214 this.bound = false
215 + this.invalid = false
216 + this.update = function (value) {
217 + var oldNodes = data.targets.get(obs)
218 + var newNodes = getNodes(document, value)
219 + if (oldNodes) {
220 + replace(oldNodes, newNodes)
221 + data.targets.set(obs, newNodes)
222 + }
223 + }
224 + invalidateNextTick(this)
226225 }
227226
228227 Binding.prototype = {
229228 bind: function () {
230229 if (!this.bound) {
231- this._release = this.fn(this.document, this.obs, this.data)
230 + this._release = this.invalid
231 + ? watch(this.obs, this.update)
232 + : this.obs(this.update)
233 + this.invalid = false
232234 this.bound = true
233235 }
234236 },
235237 unbind: function () {
236238 if (this.bound && typeof this._release === 'function') {
237239 this._release()
238240 this._release = null
239241 this.bound = false
242 + invalidateNextTick(this)
240243 }
241244 }
242245 }
lib/invalidate-next-tick.jsView
@@ -1,0 +1,17 @@
1 +var queue = []
2 +
3 +module.exports = function (item) {
4 + if (queue.length === 0) {
5 + setImmediate(flush)
6 + }
7 + queue.push(item)
8 +}
9 +
10 +function flush () {
11 + while (queue.length) {
12 + var item = queue.pop()
13 + if (!item.bound) {
14 + item.invalidated = true
15 + }
16 + }
17 +}

Built with git-ssb-web