js_stack 0.5.7 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +7 -7
- data/lib/js_stack/version.rb +1 -1
- data/vendor/assets/javascripts/js_stack/base/marionette/{1.8.0.js → 1.8.3.js} +173 -8
- data/vendor/assets/javascripts/js_stack/base/marionette.js +1 -1
- data/vendor/assets/javascripts/js_stack/plugins/backbone/stickit/0.8.0.js +595 -0
- data/vendor/assets/javascripts/js_stack/plugins/backbone.stickit.js +1 -1
- metadata +4 -17
- data/vendor/assets/javascripts/js_stack/base/backbone/1.1.0.js +0 -1581
- data/vendor/assets/javascripts/js_stack/base/backbone/1.1.1.js +0 -1609
- data/vendor/assets/javascripts/js_stack/base/marionette/1.6.2.js +0 -2555
- data/vendor/assets/javascripts/js_stack/base/marionette/1.7.0.js +0 -2746
- data/vendor/assets/javascripts/js_stack/base/marionette/1.7.3.js +0 -2765
- data/vendor/assets/javascripts/js_stack/plugins/backbone/associations/0.5.1.js +0 -533
- data/vendor/assets/javascripts/js_stack/plugins/backbone/associations/0.5.4.js +0 -574
- data/vendor/assets/javascripts/js_stack/plugins/backbone/mutators/0.4.1.js +0 -207
- data/vendor/assets/javascripts/js_stack/plugins/backbone/pageable/1.4.5.js +0 -1318
- data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.11.js +0 -345
- data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.12.js +0 -351
- data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.14.js +0 -398
- data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.5.js +0 -293
- data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.8.js +0 -340
@@ -1,345 +0,0 @@
|
|
1
|
-
(function(global, factory) {
|
2
|
-
|
3
|
-
// Set up lib appropriately for the environment. Start with AMD.
|
4
|
-
if (typeof define === 'function' && define.amd) {
|
5
|
-
define(['underscore', 'backbone'], factory);
|
6
|
-
|
7
|
-
// Next for Node.js or CommonJS.
|
8
|
-
} else if (typeof module !== 'undefined' && module.exports) {
|
9
|
-
module.exports = factory(require('underscore'), require('backbone'));
|
10
|
-
|
11
|
-
// Finally, use browser globals.
|
12
|
-
} else {
|
13
|
-
factory(global._, global.Backbone);
|
14
|
-
}
|
15
|
-
|
16
|
-
}(this, function(_, Backbone) {
|
17
|
-
'use strict';
|
18
|
-
|
19
|
-
var vc, iterators, proxy;
|
20
|
-
|
21
|
-
iterators = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
|
22
|
-
'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
|
23
|
-
'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
|
24
|
-
'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
|
25
|
-
'tail', 'drop', 'last', 'without', 'indexOf', 'shuffle', 'lastIndexOf',
|
26
|
-
'isEmpty', 'chain'];
|
27
|
-
|
28
|
-
proxy = ['add', 'remove'];
|
29
|
-
|
30
|
-
/**
|
31
|
-
* Constructor for the virtual collection
|
32
|
-
* @param {Collection} collection
|
33
|
-
* @param {Function|Object} filter function, or hash of properties to match
|
34
|
-
* @param {Object} options
|
35
|
-
* @param {[Function|Object]} filter function, or hash of properties to match
|
36
|
-
* @param {[Function|String]} comparator
|
37
|
-
*/
|
38
|
-
function VirtualCollection(collection, options) {
|
39
|
-
this.collection = collection;
|
40
|
-
options = options || {};
|
41
|
-
this.comparator = options.comparator;
|
42
|
-
|
43
|
-
_.bindAll(this, 'each', 'map', 'get', 'at', 'indexOf', 'sort', 'closeWith',
|
44
|
-
'_rebuildIndex', '_models', '_onAdd', '_onRemove', '_onChange', '_onReset',
|
45
|
-
'_indexAdd', '_indexRemove');
|
46
|
-
|
47
|
-
// set filter
|
48
|
-
this.filterFunction = VirtualCollection.buildFilter(options.filter);
|
49
|
-
|
50
|
-
// build index
|
51
|
-
this._rebuildIndex();
|
52
|
-
|
53
|
-
this.listenTo(this.collection, 'add', this._onAdd, this);
|
54
|
-
this.listenTo(this.collection, 'remove', this._onRemove, this);
|
55
|
-
this.listenTo(this.collection, 'change', this._onChange, this);
|
56
|
-
this.listenTo(this.collection, 'reset', this._onReset, this);
|
57
|
-
|
58
|
-
if (options.close_with) {
|
59
|
-
this.closeWith(options.close_with);
|
60
|
-
}
|
61
|
-
}
|
62
|
-
|
63
|
-
/**
|
64
|
-
* [static] Returns a function that returns true for models that meet the specified conditions
|
65
|
-
* @param {Object} hash of model attributes or {Function} filter
|
66
|
-
* @return {Function} filtering function
|
67
|
-
*/
|
68
|
-
VirtualCollection.buildFilter = function (filter) {
|
69
|
-
if (!filter) {
|
70
|
-
// If no filter is passed, all models should be added
|
71
|
-
return function () { return true; };
|
72
|
-
} else if (_.isFunction(filter)) {
|
73
|
-
// If filter is passed a function, just return it
|
74
|
-
return filter;
|
75
|
-
} else if (filter.constructor === Object) {
|
76
|
-
// If filter is a hash of attributes, return a function that checks each of them
|
77
|
-
return function (model) {
|
78
|
-
return !Boolean(_(Object.keys(filter)).detect(function (key) {
|
79
|
-
return model.get(key) !== filter[key];
|
80
|
-
}));
|
81
|
-
};
|
82
|
-
}
|
83
|
-
};
|
84
|
-
|
85
|
-
vc = VirtualCollection.prototype;
|
86
|
-
|
87
|
-
|
88
|
-
// mix in Underscore method as proxies
|
89
|
-
_.each(iterators, function (method) {
|
90
|
-
vc[method] = function () {
|
91
|
-
var args = Array.prototype.slice.call(arguments);
|
92
|
-
args.unshift(this._models());
|
93
|
-
return _[method].apply(_, args);
|
94
|
-
};
|
95
|
-
});
|
96
|
-
|
97
|
-
// proxy functions to parent
|
98
|
-
_.each(proxy, function (method) {
|
99
|
-
vc[method] = function () {
|
100
|
-
var args = Array.prototype.slice.call(arguments);
|
101
|
-
return this.collection[method].apply(this.collection, args);
|
102
|
-
};
|
103
|
-
});
|
104
|
-
|
105
|
-
/**
|
106
|
-
* Returns a model if it belongs to the virtual collection
|
107
|
-
* @param {String} id
|
108
|
-
* @return {Model}
|
109
|
-
*/
|
110
|
-
vc.get = function (id) {
|
111
|
-
var model = this.collection.get(id);
|
112
|
-
if (model && this.filterFunction(model)) {
|
113
|
-
return model;
|
114
|
-
}
|
115
|
-
};
|
116
|
-
|
117
|
-
/**
|
118
|
-
* Returns the model at the position in the index
|
119
|
-
* @param {Number} index
|
120
|
-
* @return {Model}
|
121
|
-
*/
|
122
|
-
vc.at = function (index) {
|
123
|
-
return this.collection.get(this.index[index]);
|
124
|
-
};
|
125
|
-
|
126
|
-
vc.where = Backbone.Collection.prototype.where;
|
127
|
-
vc.findWhere = Backbone.Collection.prototype.findWhere;
|
128
|
-
|
129
|
-
/**
|
130
|
-
* Returns the index of the model in the virtual collection
|
131
|
-
* @param {Model} model
|
132
|
-
* @return {Number} index
|
133
|
-
*/
|
134
|
-
vc.indexOf = function (model) {
|
135
|
-
return this.index.indexOf(model.cid);
|
136
|
-
};
|
137
|
-
|
138
|
-
/**
|
139
|
-
* Returns a JSON representation of all the models in the index
|
140
|
-
* @return {Array} JSON models
|
141
|
-
*/
|
142
|
-
vc.toJSON = function() {
|
143
|
-
return _.map(this._models(), function(model) {
|
144
|
-
return model.toJSON();
|
145
|
-
});
|
146
|
-
};
|
147
|
-
|
148
|
-
/**
|
149
|
-
* Sorts the models in the virtual collection
|
150
|
-
*
|
151
|
-
* You only need to trigger this manually if you change the comparator
|
152
|
-
* @param {Object} options
|
153
|
-
* @return {VirtualCollection}
|
154
|
-
*/
|
155
|
-
vc.sort = function (options) {
|
156
|
-
var self = this;
|
157
|
-
if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
|
158
|
-
options = options || {};
|
159
|
-
|
160
|
-
// Run sort based on type of `comparator`.
|
161
|
-
if (_.isString(this.comparator)) {
|
162
|
-
this.index = _.sortBy(this.index, function (cid) {
|
163
|
-
var model = this.collection.get(cid);
|
164
|
-
return model.get(this.comparator);
|
165
|
-
}, this);
|
166
|
-
} else if (this.comparator.length === 1) {
|
167
|
-
this.index = _.sortBy(this.index, function (cid) {
|
168
|
-
var model = this.collection.get(cid);
|
169
|
-
return this.comparator.call(self, model);
|
170
|
-
}, this);
|
171
|
-
} else {
|
172
|
-
this.index.sort(function (cid1, cid2) {
|
173
|
-
var model1 = self.collection.get(cid1),
|
174
|
-
model2 = self.collection.get(cid2);
|
175
|
-
|
176
|
-
return self.comparator.call(self, model1, model2);
|
177
|
-
});
|
178
|
-
}
|
179
|
-
|
180
|
-
if (!options.silent) this.trigger('sort', this, options);
|
181
|
-
return this;
|
182
|
-
};
|
183
|
-
|
184
|
-
/**
|
185
|
-
* Change the filter and update collection
|
186
|
-
*
|
187
|
-
* @param {Object} hash of model attributes or {Function} filter
|
188
|
-
* @return {VirtualCollection}
|
189
|
-
*/
|
190
|
-
|
191
|
-
vc.updateFilter = function(filter){
|
192
|
-
// Reset the filter
|
193
|
-
this.filterFunction = VirtualCollection.buildFilter(filter);
|
194
|
-
|
195
|
-
// Update the models
|
196
|
-
this._rebuildIndex();
|
197
|
-
|
198
|
-
// Trigger filter event
|
199
|
-
this.trigger('filter', this, filter);
|
200
|
-
|
201
|
-
// Trigger reset event
|
202
|
-
this.trigger('reset', this, filter);
|
203
|
-
|
204
|
-
return this;
|
205
|
-
};
|
206
|
-
|
207
|
-
/**
|
208
|
-
* A utility function for unbiding listeners
|
209
|
-
* @param {View} view (marionette view)
|
210
|
-
*/
|
211
|
-
vc.closeWith = function (view) {
|
212
|
-
view.on('close', function () {
|
213
|
-
this.stopListening();
|
214
|
-
}, this);
|
215
|
-
};
|
216
|
-
|
217
|
-
// private
|
218
|
-
|
219
|
-
vc._rebuildIndex = function () {
|
220
|
-
this.index = [];
|
221
|
-
this.collection.each(function (model, index) {
|
222
|
-
if (this.filterFunction(model, index)) {
|
223
|
-
this.index.push(model.cid);
|
224
|
-
}
|
225
|
-
}, this);
|
226
|
-
if (this.comparator) {
|
227
|
-
this.sort({silent: true});
|
228
|
-
}
|
229
|
-
this.length = this.index.length;
|
230
|
-
};
|
231
|
-
|
232
|
-
/**
|
233
|
-
* Returns an array of models in the virtual collection
|
234
|
-
* @return {Array}
|
235
|
-
*/
|
236
|
-
vc._models = function () {
|
237
|
-
return _.map(this.index, function (cid) {
|
238
|
-
return this.collection.get(cid);
|
239
|
-
}, this);
|
240
|
-
};
|
241
|
-
|
242
|
-
/**
|
243
|
-
* Handles the collection:add event
|
244
|
-
* May update the virtual collection's index
|
245
|
-
* @param {Model} model
|
246
|
-
* @return {undefined}
|
247
|
-
*/
|
248
|
-
vc._onAdd = function (model, collection, options) {
|
249
|
-
if (this.filterFunction(model)) {
|
250
|
-
this._indexAdd(model);
|
251
|
-
this.trigger('add', model, this, options);
|
252
|
-
}
|
253
|
-
};
|
254
|
-
|
255
|
-
/**
|
256
|
-
* Handles the collection:remove event
|
257
|
-
* May update the virtual collection's index
|
258
|
-
* @param {Model} model
|
259
|
-
* @return {undefined}
|
260
|
-
*/
|
261
|
-
vc._onRemove = function (model, collection, options) {
|
262
|
-
if (_(this.index).contains(model.cid)) {
|
263
|
-
this._indexRemove(model);
|
264
|
-
this.trigger('remove', model, this, options);
|
265
|
-
}
|
266
|
-
};
|
267
|
-
|
268
|
-
/**
|
269
|
-
* Handles the collection:change event
|
270
|
-
* May update the virtual collection's index
|
271
|
-
* @param {Model} model
|
272
|
-
* @param {Object} object
|
273
|
-
*/
|
274
|
-
vc._onChange = function (model, options) {
|
275
|
-
var already_here = _.contains(this.index, model.cid);
|
276
|
-
if (this.filterFunction(model)) {
|
277
|
-
if (already_here) {
|
278
|
-
this.trigger('change', model, this, options);
|
279
|
-
} else {
|
280
|
-
this._indexAdd(model);
|
281
|
-
this.trigger('add', model, this, options);
|
282
|
-
}
|
283
|
-
} else {
|
284
|
-
if (already_here) {
|
285
|
-
this._indexRemove(model);
|
286
|
-
this.trigger('remove', model, this, options);
|
287
|
-
}
|
288
|
-
}
|
289
|
-
};
|
290
|
-
|
291
|
-
/**
|
292
|
-
* Handles the collection:reset event
|
293
|
-
* @param {Collection} collection
|
294
|
-
* @param {Object} object
|
295
|
-
*/
|
296
|
-
vc._onReset = function (collection, options) {
|
297
|
-
this._rebuildIndex();
|
298
|
-
this.trigger('reset', this, options);
|
299
|
-
};
|
300
|
-
|
301
|
-
/**
|
302
|
-
* Adds a model to the virtual collection index
|
303
|
-
* Inserting it in the correct order
|
304
|
-
* @param {Model} model
|
305
|
-
* @return {undefined}
|
306
|
-
*/
|
307
|
-
vc._indexAdd = function (model) {
|
308
|
-
if (this.index.indexOf(model.cid) === -1) {
|
309
|
-
|
310
|
-
if (!this.comparator) { // order inherit's from parent collection
|
311
|
-
var i, orig_index = this.collection.indexOf(model);
|
312
|
-
for (i = 0; i < this.length; i++) {
|
313
|
-
if (this.collection.indexOf(this.collection.get(this.index[i])) > orig_index) {
|
314
|
-
break;
|
315
|
-
}
|
316
|
-
}
|
317
|
-
this.index.splice(i, 0, model.cid);
|
318
|
-
|
319
|
-
} else { // the virtual collection has a custom order
|
320
|
-
this.index.push(model.cid);
|
321
|
-
this.sort({silent: true});
|
322
|
-
}
|
323
|
-
this.length = this.index.length;
|
324
|
-
}
|
325
|
-
};
|
326
|
-
|
327
|
-
/**
|
328
|
-
* Removes a model from the virtual collection index
|
329
|
-
* @param {Model} model
|
330
|
-
* @return {undefined}
|
331
|
-
*/
|
332
|
-
vc._indexRemove = function (model) {
|
333
|
-
var i = this.index.indexOf(model.cid);
|
334
|
-
if (i !== -1) {
|
335
|
-
this.index.splice(i, 1);
|
336
|
-
this.length = this.index.length;
|
337
|
-
}
|
338
|
-
};
|
339
|
-
|
340
|
-
_.extend(vc, Backbone.Events);
|
341
|
-
|
342
|
-
Backbone.VirtualCollection = VirtualCollection;
|
343
|
-
|
344
|
-
return VirtualCollection;
|
345
|
-
}));
|
@@ -1,351 +0,0 @@
|
|
1
|
-
(function(global, factory) {
|
2
|
-
|
3
|
-
// Set up lib appropriately for the environment. Start with AMD.
|
4
|
-
if (typeof define === 'function' && define.amd) {
|
5
|
-
define(['underscore', 'backbone'], factory);
|
6
|
-
|
7
|
-
// Next for Node.js or CommonJS.
|
8
|
-
} else if (typeof module !== 'undefined' && module.exports) {
|
9
|
-
module.exports = factory(require('underscore'), require('backbone'));
|
10
|
-
|
11
|
-
// Finally, use browser globals.
|
12
|
-
} else {
|
13
|
-
factory(global._, global.Backbone);
|
14
|
-
}
|
15
|
-
|
16
|
-
}(this, function(_, Backbone) {
|
17
|
-
'use strict';
|
18
|
-
|
19
|
-
var vc, iterators, proxy;
|
20
|
-
|
21
|
-
iterators = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
|
22
|
-
'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
|
23
|
-
'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
|
24
|
-
'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
|
25
|
-
'tail', 'drop', 'last', 'without', 'indexOf', 'shuffle', 'lastIndexOf',
|
26
|
-
'isEmpty', 'chain'];
|
27
|
-
|
28
|
-
proxy = ['add', 'remove'];
|
29
|
-
|
30
|
-
/**
|
31
|
-
* Constructor for the virtual collection
|
32
|
-
* @param {Collection} collection
|
33
|
-
* @param {Function|Object} filter function, or hash of properties to match
|
34
|
-
* @param {Object} options
|
35
|
-
* @param {[Function|Object]} filter function, or hash of properties to match
|
36
|
-
* @param {[Function|String]} comparator
|
37
|
-
*/
|
38
|
-
function VirtualCollection(collection, options) {
|
39
|
-
this.collection = collection;
|
40
|
-
options = options || {};
|
41
|
-
this.comparator = options.comparator;
|
42
|
-
|
43
|
-
_.bindAll(this, 'each', 'map', 'get', 'at', 'indexOf', 'sort', 'closeWith',
|
44
|
-
'_rebuildIndex', '_models', '_onAdd', '_onRemove', '_onChange', '_onReset',
|
45
|
-
'_indexAdd', '_indexRemove');
|
46
|
-
|
47
|
-
// set filter
|
48
|
-
this.filterFunction = VirtualCollection.buildFilter(options.filter);
|
49
|
-
|
50
|
-
// build index
|
51
|
-
this._rebuildIndex();
|
52
|
-
|
53
|
-
this.listenTo(this.collection, 'add', this._onAdd, this);
|
54
|
-
this.listenTo(this.collection, 'remove', this._onRemove, this);
|
55
|
-
this.listenTo(this.collection, 'change', this._onChange, this);
|
56
|
-
this.listenTo(this.collection, 'reset', this._onReset, this);
|
57
|
-
|
58
|
-
if (options.close_with) {
|
59
|
-
this.closeWith(options.close_with);
|
60
|
-
}
|
61
|
-
}
|
62
|
-
|
63
|
-
/**
|
64
|
-
* [static] Returns a function that returns true for models that meet the specified conditions
|
65
|
-
* @param {Object} hash of model attributes or {Function} filter
|
66
|
-
* @return {Function} filtering function
|
67
|
-
*/
|
68
|
-
VirtualCollection.buildFilter = function (filter) {
|
69
|
-
if (!filter) {
|
70
|
-
// If no filter is passed, all models should be added
|
71
|
-
return function () { return true; };
|
72
|
-
} else if (_.isFunction(filter)) {
|
73
|
-
// If filter is passed a function, just return it
|
74
|
-
return filter;
|
75
|
-
} else if (filter.constructor === Object) {
|
76
|
-
// If filter is a hash of attributes, return a function that checks each of them
|
77
|
-
return function (model) {
|
78
|
-
return !Boolean(_(Object.keys(filter)).detect(function (key) {
|
79
|
-
return model.get(key) !== filter[key];
|
80
|
-
}));
|
81
|
-
};
|
82
|
-
}
|
83
|
-
};
|
84
|
-
|
85
|
-
vc = VirtualCollection.prototype;
|
86
|
-
|
87
|
-
|
88
|
-
// mix in Underscore method as proxies
|
89
|
-
_.each(iterators, function (method) {
|
90
|
-
vc[method] = function () {
|
91
|
-
var args = Array.prototype.slice.call(arguments);
|
92
|
-
args.unshift(this._models());
|
93
|
-
return _[method].apply(_, args);
|
94
|
-
};
|
95
|
-
});
|
96
|
-
|
97
|
-
// proxy functions to parent
|
98
|
-
_.each(proxy, function (method) {
|
99
|
-
vc[method] = function () {
|
100
|
-
var args = Array.prototype.slice.call(arguments);
|
101
|
-
return this.collection[method].apply(this.collection, args);
|
102
|
-
};
|
103
|
-
});
|
104
|
-
|
105
|
-
/**
|
106
|
-
* Returns a model if it belongs to the virtual collection
|
107
|
-
* @param {String} id
|
108
|
-
* @return {Model}
|
109
|
-
*/
|
110
|
-
vc.get = function (id) {
|
111
|
-
var model = this.collection.get(id);
|
112
|
-
if (model && this.filterFunction(model)) {
|
113
|
-
return model;
|
114
|
-
}
|
115
|
-
};
|
116
|
-
|
117
|
-
/**
|
118
|
-
* Returns the model at the position in the index
|
119
|
-
* @param {Number} index
|
120
|
-
* @return {Model}
|
121
|
-
*/
|
122
|
-
vc.at = function (index) {
|
123
|
-
return this.collection.get(this.index[index]);
|
124
|
-
};
|
125
|
-
|
126
|
-
vc.where = Backbone.Collection.prototype.where;
|
127
|
-
vc.findWhere = Backbone.Collection.prototype.findWhere;
|
128
|
-
|
129
|
-
/**
|
130
|
-
* Returns the index of the model in the virtual collection
|
131
|
-
* @param {Model} model
|
132
|
-
* @return {Number} index
|
133
|
-
*/
|
134
|
-
vc.indexOf = function (model) {
|
135
|
-
return this.index.indexOf(model.cid);
|
136
|
-
};
|
137
|
-
|
138
|
-
/**
|
139
|
-
* Returns a JSON representation of all the models in the index
|
140
|
-
* @return {Array} JSON models
|
141
|
-
*/
|
142
|
-
vc.toJSON = function() {
|
143
|
-
return _.map(this._models(), function(model) {
|
144
|
-
return model.toJSON();
|
145
|
-
});
|
146
|
-
};
|
147
|
-
|
148
|
-
/**
|
149
|
-
* Sorts the models in the virtual collection
|
150
|
-
*
|
151
|
-
* You only need to trigger this manually if you change the comparator
|
152
|
-
* @param {Object} options
|
153
|
-
* @return {VirtualCollection}
|
154
|
-
*/
|
155
|
-
vc.sort = function (options) {
|
156
|
-
var self = this;
|
157
|
-
if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
|
158
|
-
options = options || {};
|
159
|
-
|
160
|
-
// Run sort based on type of `comparator`.
|
161
|
-
if (_.isString(this.comparator)) {
|
162
|
-
this.index = _.sortBy(this.index, function (cid) {
|
163
|
-
var model = this.collection.get(cid);
|
164
|
-
return model.get(this.comparator);
|
165
|
-
}, this);
|
166
|
-
} else if (this.comparator.length === 1) {
|
167
|
-
this.index = _.sortBy(this.index, function (cid) {
|
168
|
-
var model = this.collection.get(cid);
|
169
|
-
return this.comparator.call(self, model);
|
170
|
-
}, this);
|
171
|
-
} else {
|
172
|
-
this.index.sort(function (cid1, cid2) {
|
173
|
-
var model1 = self.collection.get(cid1),
|
174
|
-
model2 = self.collection.get(cid2);
|
175
|
-
|
176
|
-
return self.comparator.call(self, model1, model2);
|
177
|
-
});
|
178
|
-
}
|
179
|
-
|
180
|
-
if (!options.silent) this.trigger('sort', this, options);
|
181
|
-
return this;
|
182
|
-
};
|
183
|
-
|
184
|
-
/**
|
185
|
-
* Change the filter and update collection
|
186
|
-
*
|
187
|
-
* @param {Object} hash of model attributes or {Function} filter
|
188
|
-
* @return {VirtualCollection}
|
189
|
-
*/
|
190
|
-
|
191
|
-
vc.updateFilter = function(filter){
|
192
|
-
// Reset the filter
|
193
|
-
this.filterFunction = VirtualCollection.buildFilter(filter);
|
194
|
-
|
195
|
-
// Update the models
|
196
|
-
this._rebuildIndex();
|
197
|
-
|
198
|
-
// Trigger filter event
|
199
|
-
this.trigger('filter', this, filter);
|
200
|
-
|
201
|
-
// Trigger reset event
|
202
|
-
this.trigger('reset', this, filter);
|
203
|
-
|
204
|
-
return this;
|
205
|
-
};
|
206
|
-
|
207
|
-
/**
|
208
|
-
* A utility function for unbiding listeners
|
209
|
-
* @param {View} view (marionette view)
|
210
|
-
*/
|
211
|
-
vc.closeWith = function (view) {
|
212
|
-
view.on('close', function () {
|
213
|
-
this.stopListening();
|
214
|
-
}, this);
|
215
|
-
};
|
216
|
-
|
217
|
-
// private
|
218
|
-
|
219
|
-
vc._rebuildIndex = function () {
|
220
|
-
this.index = [];
|
221
|
-
this.collection.each(function (model, index) {
|
222
|
-
if (this.filterFunction(model, index)) {
|
223
|
-
this.index.push(model.cid);
|
224
|
-
}
|
225
|
-
}, this);
|
226
|
-
if (this.comparator) {
|
227
|
-
this.sort({silent: true});
|
228
|
-
}
|
229
|
-
this.length = this.index.length;
|
230
|
-
};
|
231
|
-
|
232
|
-
/**
|
233
|
-
* Returns an array of models in the virtual collection
|
234
|
-
* @return {Array}
|
235
|
-
*/
|
236
|
-
vc._models = function () {
|
237
|
-
return _.map(this.index, function (cid) {
|
238
|
-
return this.collection.get(cid);
|
239
|
-
}, this);
|
240
|
-
};
|
241
|
-
|
242
|
-
/**
|
243
|
-
* Handles the collection:add event
|
244
|
-
* May update the virtual collection's index
|
245
|
-
* @param {Model} model
|
246
|
-
* @return {undefined}
|
247
|
-
*/
|
248
|
-
vc._onAdd = function (model, collection, options) {
|
249
|
-
if (this.filterFunction(model)) {
|
250
|
-
this._indexAdd(model);
|
251
|
-
this.trigger('add', model, this, options);
|
252
|
-
}
|
253
|
-
};
|
254
|
-
|
255
|
-
/**
|
256
|
-
* Handles the collection:remove event
|
257
|
-
* May update the virtual collection's index
|
258
|
-
* @param {Model} model
|
259
|
-
* @return {undefined}
|
260
|
-
*/
|
261
|
-
vc._onRemove = function (model, collection, options) {
|
262
|
-
if (_(this.index).contains(model.cid)) {
|
263
|
-
var i = this._indexRemove(model);
|
264
|
-
if (options) {
|
265
|
-
var options_clone = _.clone(options);
|
266
|
-
options_clone.index = i;
|
267
|
-
}
|
268
|
-
|
269
|
-
this.trigger('remove', model, this, options_clone);
|
270
|
-
}
|
271
|
-
};
|
272
|
-
|
273
|
-
/**
|
274
|
-
* Handles the collection:change event
|
275
|
-
* May update the virtual collection's index
|
276
|
-
* @param {Model} model
|
277
|
-
* @param {Object} object
|
278
|
-
*/
|
279
|
-
vc._onChange = function (model, options) {
|
280
|
-
var already_here = _.contains(this.index, model.cid);
|
281
|
-
if (this.filterFunction(model)) {
|
282
|
-
if (already_here) {
|
283
|
-
this.trigger('change', model, this, options);
|
284
|
-
} else {
|
285
|
-
this._indexAdd(model);
|
286
|
-
this.trigger('add', model, this, options);
|
287
|
-
}
|
288
|
-
} else {
|
289
|
-
if (already_here) {
|
290
|
-
this._indexRemove(model);
|
291
|
-
this.trigger('remove', model, this, options);
|
292
|
-
}
|
293
|
-
}
|
294
|
-
};
|
295
|
-
|
296
|
-
/**
|
297
|
-
* Handles the collection:reset event
|
298
|
-
* @param {Collection} collection
|
299
|
-
* @param {Object} object
|
300
|
-
*/
|
301
|
-
vc._onReset = function (collection, options) {
|
302
|
-
this._rebuildIndex();
|
303
|
-
this.trigger('reset', this, options);
|
304
|
-
};
|
305
|
-
|
306
|
-
/**
|
307
|
-
* Adds a model to the virtual collection index
|
308
|
-
* Inserting it in the correct order
|
309
|
-
* @param {Model} model
|
310
|
-
* @return {undefined}
|
311
|
-
*/
|
312
|
-
vc._indexAdd = function (model) {
|
313
|
-
if (this.index.indexOf(model.cid) === -1) {
|
314
|
-
|
315
|
-
if (!this.comparator) { // order inherit's from parent collection
|
316
|
-
var i, orig_index = this.collection.indexOf(model);
|
317
|
-
for (i = 0; i < this.length; i++) {
|
318
|
-
if (this.collection.indexOf(this.collection.get(this.index[i])) > orig_index) {
|
319
|
-
break;
|
320
|
-
}
|
321
|
-
}
|
322
|
-
this.index.splice(i, 0, model.cid);
|
323
|
-
|
324
|
-
} else { // the virtual collection has a custom order
|
325
|
-
this.index.push(model.cid);
|
326
|
-
this.sort({silent: true});
|
327
|
-
}
|
328
|
-
this.length = this.index.length;
|
329
|
-
}
|
330
|
-
};
|
331
|
-
|
332
|
-
/**
|
333
|
-
* Removes a model from the virtual collection index
|
334
|
-
* @param {Model} model
|
335
|
-
* @return {int} the index for the removed model or -1 if not found
|
336
|
-
*/
|
337
|
-
vc._indexRemove = function (model) {
|
338
|
-
var i = this.index.indexOf(model.cid);
|
339
|
-
if (i !== -1) {
|
340
|
-
this.index.splice(i, 1);
|
341
|
-
this.length = this.index.length;
|
342
|
-
}
|
343
|
-
return i;
|
344
|
-
};
|
345
|
-
|
346
|
-
_.extend(vc, Backbone.Events);
|
347
|
-
|
348
|
-
Backbone.VirtualCollection = VirtualCollection;
|
349
|
-
|
350
|
-
return VirtualCollection;
|
351
|
-
}));
|