-
Notifications
You must be signed in to change notification settings - Fork 239
/
fastdom-sandbox.js
147 lines (130 loc) · 2.76 KB
/
fastdom-sandbox.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
(function(exports) {
/**
* Mini logger
*
* @return {Function}
*/
var debug = 0 ? console.log.bind(console, '[fastdom-sandbox]') : function() {};
/**
* Exports
*/
/**
* Create a new `Sandbox`.
*
* Scheduling tasks via a sandbox is
* useful because you can clear all
* sandboxed tasks in one go.
*
* This is handy when working with view
* components. You can create one sandbox
* per component and call `.clear()` when
* tearing down.
*
* @example
*
* var sandbox = fastdom.sandbox();
*
* sandbox.measure(function() { console.log(1); });
* sandbox.measure(function() { console.log(2); });
*
* fastdom.measure(function() { console.log(3); });
* fastdom.measure(function() { console.log(4); });
*
* sandbox.clear();
*
* // => 3
* // => 4
*
* @return {Sandbox}
* @public
*/
exports.sandbox = function() {
return new Sandbox(this.fastdom);
};
/**
* Initialize a new `Sandbox`
*
* @param {FastDom} fastdom
*/
function Sandbox(fastdom) {
this.fastdom = fastdom;
this.tasks = [];
debug('initialized');
}
/**
* Schedule a 'measure' task.
*
* @param {Function} fn
* @param {Object} ctx
* @return {Object} can be passed to .clear()
*/
Sandbox.prototype.measure = function(fn, ctx) {
var tasks = this.tasks;
var task = this.fastdom.measure(function() {
tasks.splice(tasks.indexOf(task));
return fn.call(ctx);
});
tasks.push(task);
return task;
};
/**
* Schedule a 'mutate' task.
*
* @param {Function} fn
* @param {Object} ctx
* @return {Object} can be passed to .clear()
*/
Sandbox.prototype.mutate = function(fn, ctx) {
var tasks = this.tasks;
var task = this.fastdom.mutate(function() {
tasks.splice(tasks.indexOf(task));
return fn.call(ctx);
});
this.tasks.push(task);
return task;
};
/**
* Clear a single task or is no task is
* passsed, all tasks in the `Sandbox`.
*
* @param {Object} task (optional)
*/
Sandbox.prototype.clear = function(task) {
if (!arguments.length) clearAll(this.fastdom, this.tasks);
remove(this.tasks, task);
return this.fastdom.clear(task);
};
/**
* Clears all the given tasks from
* the given `FastDom`.
*
* @param {FastDom} fastdom
* @param {Array} tasks
* @private
*/
function clearAll(fastdom, tasks) {
debug('clear all', fastdom, tasks);
var i = tasks.length;
while (i--) {
fastdom.clear(tasks[i]);
tasks.splice(i, 1);
}
}
/**
* Remove an item from an Array.
*
* @param {Array} array
* @param {*} item
* @return {Boolean}
*/
function remove(array, item) {
var index = array.indexOf(item);
return !!~index && !!array.splice(index, 1);
}
/**
* Expose
*/
if ((typeof define)[0] == 'f') define(function() { return exports; });
else if ((typeof module)[0] == 'o') module.exports = exports;
else window.fastdomSandbox = exports;
})({});