-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathBindingSourceList.js
110 lines (100 loc) · 3.27 KB
/
BindingSourceList.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/** @module liaison/BindingSourceList */
define(["./BindingSource"], function (BindingSource) {
"use strict";
/**
* A list of {@link module:liaison/BindingSource BindingSource}.
* @class module:liaison/BindingSourceList
* @augments module:liaison/BindingSource
* @param {Array.<BindingSource>} sources The list of {@link module:liaison/BindingSource BindingSource}.
* @param {Function} [formatter]
* A function that converts the value from source
* before being sent to {@link BindingSource#observe observe()} callback
* or {@link BindingSource#getFrom getFrom()}’s return value.
* @param {Function} [parser]
* A function that converts the value in {@link BindingSource#setTo setTo()}
* before being sent to source.
*/
function BindingSourceList(sources, formatter, parser) {
this.sources = sources;
this.formatter = formatter;
this.parser = parser;
}
BindingSourceList.prototype = Object.create(BindingSource);
BindingSourceList.Observer = function (sources) {
this.sources = sources;
this.remove = this.close;
};
BindingSourceList.Observer.prototype = {
open: (function () {
function miniBindingSourceListCallback(changeIndex, newValue, oldValue) {
if (!this.deliveringRest) {
this.oldValues = this.values.slice();
}
this.values[changeIndex] = newValue;
this.oldValues[changeIndex] = oldValue;
if (!this.deliveringRest) {
this.deliveringRest = true;
this.sources.forEach(function (source, i) {
if (i !== changeIndex) {
source.deliver();
}
});
this.callback(this.values, this.oldValues);
this.deliveringRest = false;
}
}
return function (callback, thisObject) {
this.callback = callback.bind(thisObject);
this.values = [];
this.handles = [];
for (var i = 0, l = this.sources.length; i < l; ++i) {
if (typeof this.sources[i].observe === "function") {
this.values[i] = this.sources[i].getFrom();
this.handles[i] = this.sources[i].observe(miniBindingSourceListCallback.bind(this, i));
} else if (typeof this.sources[i].open === "function") {
this.handles[i] = this.sources[i];
this.values[i] = this.sources[i].open(miniBindingSourceListCallback.bind(this, i));
} else {
throw new Error("Cannot observe source: " + this.sources[i] + " at index: " + i);
}
}
this.opened = true;
return this.values;
};
})(),
deliver: function () {
this.beingDelivered = true;
this.sources.forEach(function (source) {
source.deliver();
});
this.beingDelivered = false;
},
discardChanges: function () {
var values = [];
for (var i = 0, l = this.sources.length; i < l; ++i) {
values[i] = this.sources[i].discardChanges();
}
return values;
},
setValue: function (value) {
for (var i = 0, l = this.sources.length; i < l; ++i) {
this.sources[i].setValue(value[i]);
}
},
close: function () {
if (this.handles) {
for (var h; (h = this.handles.shift());) {
typeof h.remove === "function" ? h.remove() : h.close();
}
}
this.closed = true;
}
};
BindingSourceList.prototype._ensureObserver = function () {
if (!this.observer) {
this.observer = new BindingSourceList.Observer(this.sources);
}
return this.observer;
};
return BindingSourceList;
});