Repository navigation
Expand file tree
/
Copy pathindex.js
More file actions
73 lines (68 loc) · 1.95 KB
/
Copy pathindex.js
File metadata and controls
73 lines (68 loc) · 1.95 KB
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
module.exports = function Obz (filter) {
let value = null
const listeners = []
let oncers = []
function trigger (nextValue) {
value = nextValue
let length = listeners.length
for (let i = 0; i < length && value === nextValue; i++) { // eslint-disable-line
const listener = listeners[i]
if (listener(value) === false) {
listeners.splice(i, 1)
i--
length--
}
if (listeners.length !== length) {
// something was removed
length = listeners.length
if (listener !== listeners[i]) {
// we removed an earlier listener, must decrement i also
i -= 1
}
}
}
// decrement from length, in case an immediately
// listener is added during a trigger
let oncersLen = oncers.length
const oldOncers = oncers
oncers = []
while (oncersLen-- && nextValue === value) { // eslint-disable-line
oldOncers.shift()(value)
}
}
function obz (listener, immediately) {
let i = listeners.push(listener) - 1
if (value !== null && immediately !== false) {
if (listener(value) === false) {
remove()
return function noop () {}
}
}
function remove () {
// manually remove...
// fast path, will happen if an earlier listener has not been removed.
if (listeners[i] !== listener) i = listeners.indexOf(listener)
if (i >= 0) listeners.splice(i, 1)
}
return remove
}
obz.set = function set (nextValue) {
if (filter ? filter(value, nextValue) : true) {
trigger((obz.value = nextValue))
}
return obz
}
obz.once = function once (oncer, immediately) {
if (value !== null && immediately !== false) {
oncer(value)
return function noop () {}
} else {
let i = oncers.push(oncer) - 1
return function remove () {
if (oncers[i] !== oncer) i = oncers.indexOf(oncer)
if (i >= 0) oncers.splice(i, 1)
}
}
}
return obz
}