-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathmarble.js
177 lines (160 loc) · 4.98 KB
/
marble.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// shim object.keys
Object.keys = Object.keys || (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
DontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
DontEnumsLength = DontEnums.length;
return function (o) {
if (typeof o != "object" && typeof o != "function" || o === null)
throw new TypeError("Object.keys called on a non-object");
var result = [];
for (var name in o) {
if (hasOwnProperty.call(o, name))
result.push(name);
}
if (hasDontEnumBug) {
for (var i = 0; i < DontEnumsLength; i++) {
if (hasOwnProperty.call(o, DontEnums[i]))
result.push(DontEnums[i]);
}
}
return result;
};
})();
// Generated by CoffeeScript 1.6.2
(function() {
"use strict";
var _ = Bacon._;
function TickScheduler() {
var add, boot, counter, currentTick, nextId, run, running, schedule, toRemove;
counter = 1;
currentTick = 0;
schedule = {};
toRemove = [];
nextId = function() {
return counter++;
};
running = false;
add = function(delay, entry) {
var tick;
tick = currentTick + delay;
if (!entry.id) {
entry.id = nextId();
}
if (!schedule[tick]) {
schedule[tick] = [];
}
schedule[tick].push(entry);
return entry.id;
};
boot = function(id) {
if (!running) {
running = true;
setTimeout(run, 0);
}
return id;
};
run = function() {
var entry, forNow, _i, _len, _ref;
while (Object.keys(schedule).length) {
while ((_ref = schedule[currentTick]) != null ? _ref.length : void 0) {
forNow = schedule[currentTick].splice(0);
for (_i = 0, _len = forNow.length; _i < _len; _i++) {
entry = forNow[_i];
if (_.contains(toRemove, entry.id)) {
_.remove(entry.id, toRemove);
} else {
entry.fn();
if (entry.recur) {
add(entry.recur, entry);
}
}
}
}
delete schedule[currentTick];
currentTick++;
}
return running = false;
};
return {
setTimeout: function(fn, delay) {
return boot(add(delay, {
fn: fn
}));
},
setInterval: function(fn, recur) {
return boot(add(recur, {
fn: fn,
recur: recur
}));
},
clearTimeout: function(id) {
return toRemove.push(id);
},
clearInterval: function(id) {
return toRemove.push(id);
},
now: function() {
return currentTick;
}
};
}
function logMarble(elem, stream) {
stream.onValue(function(x) {
var time = Bacon.scheduler.now()
var parent = $(elem).parent()
var mn = parent.attr('x-time-min')
var min = Math.min(time, typeof mn === 'undefined' ? 9007199254740992 : parseInt(mn))
var max = Math.max(time, parseInt(parent.attr('x-time-max')) || 0)
parent.attr('x-time-min', min);
parent.attr('x-time-max', max);
var content = typeof x.describe === 'undefined' ? x : x.describe;
$(elem).append(
$('<span style="position: absolute" x-time="'+time+'"/>').html(content))
})
};
$(function () {
// mock scheduler
var originalScheduler = Bacon.scheduler;
Bacon.scheduler = new TickScheduler();
var outputs = $('.bacon-marble').map(function() {
var inputs = $(this).find('.bacon-input').map(function() {
var stream = eval(this.attributes['x-bacon-input'].value)
$(this).append('<div style="display: inline"> </div>')
logMarble(this, stream)
return stream;
}).toArray();
return $(this).find('.bacon-output').map(function() {
var stream = eval('(' + this.attributes['x-bacon-output'].value + ')').apply(null, inputs)
var elem = this;
$(this).append('<div style="display: inline"> </div>')
logMarble(this, stream)
stream.onEnd(function() {
var parent = elem.parentNode;
var elems = $(parent).children('div').children('span').toArray()
var max = parent.attributes['x-time-max'].value
var min = parent.attributes['x-time-min'].value
var delta = max - min
for (var i in elems) {
$(elems[i]).css('left', Math.floor(100 * (elems[i].attributes['x-time'].value - min) / delta / 1.1)*1 + 2 + '%')
}
});
return stream;
}).toArray();
});
// flatten
outputs = [].concat.apply([], outputs);
// unmock scheduler
Bacon.mergeAll(outputs).onEnd(function () {
Bacon.scheduler = originalScheduler;
});
});
}).call(this);