js_stack 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- //= require js_stack/base/marionette/1.7.3
1
+ //= require js_stack/base/marionette/1.7.4
@@ -0,0 +1,398 @@
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', 'pluck'];
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
+ *
66
+ * @param {Object} hash of model attributes or {Function} filter
67
+ * @return {Function} filtering function
68
+ */
69
+ VirtualCollection.buildFilter = function (filter) {
70
+ if (!filter) {
71
+ // If no filter is passed, all models should be added
72
+ return function () {
73
+ return true;
74
+ };
75
+ } else if (_.isFunction(filter)) {
76
+ // If filter is passed a function, just return it
77
+ return filter;
78
+ } else if (filter.constructor === Object) {
79
+ // If filter is a hash of attributes, return a function that checks each of them
80
+ return function (model) {
81
+ return !Boolean(_(Object.keys(filter)).detect(function (key) {
82
+ return model.get(key) !== filter[key];
83
+ }));
84
+ };
85
+ }
86
+ };
87
+
88
+ vc = VirtualCollection.prototype;
89
+
90
+ // mix in Underscore method as proxies
91
+ _.each(iterators, function (method) {
92
+ vc[method] = function () {
93
+ var args = Array.prototype.slice.call(arguments)
94
+ , proxyCollection = { models: this._models() };
95
+ return Backbone.Collection.prototype[method].apply(proxyCollection, args);
96
+ };
97
+ });
98
+
99
+ // proxy functions to parent
100
+ _.each(proxy, function (method) {
101
+ vc[method] = function () {
102
+ var args = Array.prototype.slice.call(arguments);
103
+ return this.collection[method].apply(this.collection, args);
104
+ };
105
+ });
106
+
107
+ /**
108
+ * Returns a model if it belongs to the virtual collection
109
+ *
110
+ * @param {String} id or cid
111
+ * @return {Model}
112
+ */
113
+ vc.get = function (id) {
114
+ var model = this._getParentCollection().get(id);
115
+ if (model && _.contains(this.index, model.cid)) {
116
+ return model;
117
+ }
118
+ };
119
+
120
+ /**
121
+ * Returns the parent non-virtual collection.
122
+ *
123
+ * @return {Collection}
124
+ */
125
+ vc._getParentCollection = function () {
126
+ if (this.collection instanceof VirtualCollection) {
127
+ return this.collection._getParentCollection();
128
+ } else {
129
+ return this.collection;
130
+ }
131
+ };
132
+
133
+ /**
134
+ * Returns the model at the position in the index
135
+ *
136
+ * @param {Number} index
137
+ * @return {Model}
138
+ */
139
+ vc.at = function (index) {
140
+ return this.collection.get(this.index[index]);
141
+ };
142
+
143
+ vc.where = Backbone.Collection.prototype.where;
144
+ vc.findWhere = Backbone.Collection.prototype.findWhere;
145
+
146
+ /**
147
+ * Returns the index of the model in the virtual collection
148
+ *
149
+ * @param {Model} model
150
+ * @return {Number} index
151
+ */
152
+ vc.indexOf = function (model) {
153
+ return this.index.indexOf(model.cid);
154
+ };
155
+
156
+ /**
157
+ * Returns a JSON representation of all the models in the index
158
+ *
159
+ * @return {Array} JSON models
160
+ */
161
+ vc.toJSON = function () {
162
+ return _.map(this._models(), function (model) {
163
+ return model.toJSON();
164
+ });
165
+ };
166
+
167
+ /**
168
+ * Sorts the models in the virtual collection
169
+ *
170
+ * You only need to trigger this manually if you change the comparator
171
+ *
172
+ * @param {Object} options
173
+ * @return {VirtualCollection}
174
+ */
175
+ vc.sort = function (options) {
176
+ var self = this;
177
+
178
+ if (!this.comparator) {
179
+ throw new Error('Cannot sort a set without a comparator');
180
+ }
181
+
182
+ options = options || {};
183
+
184
+ // Run sort based on type of `comparator`.
185
+ if (_.isString(this.comparator)) {
186
+ this.index = _.sortBy(this.index, function (cid) {
187
+ var model = this.collection.get(cid);
188
+ return model.get(this.comparator);
189
+ }, this);
190
+ } else if (this.comparator.length === 1) {
191
+ this.index = _.sortBy(this.index, function (cid) {
192
+ var model = this.collection.get(cid);
193
+ return this.comparator.call(self, model);
194
+ }, this);
195
+ } else {
196
+ this.index.sort(function (cid1, cid2) {
197
+ var model1 = self.collection.get(cid1),
198
+ model2 = self.collection.get(cid2);
199
+
200
+ return self.comparator.call(self, model1, model2);
201
+ });
202
+ }
203
+
204
+ if (!options.silent) {
205
+ this.trigger('sort', this, options);
206
+ }
207
+
208
+ return this;
209
+ };
210
+
211
+ /**
212
+ * Change the filter and update collection
213
+ *
214
+ * @param {Object} hash of model attributes or {Function} filter
215
+ * @return {VirtualCollection}
216
+ */
217
+
218
+ vc.updateFilter = function (filter) {
219
+ // Reset the filter
220
+ this.filterFunction = VirtualCollection.buildFilter(filter);
221
+
222
+ // Update the models
223
+ this._rebuildIndex();
224
+
225
+ // Trigger filter event
226
+ this.trigger('filter', this, filter);
227
+
228
+ // Trigger reset event
229
+ this.trigger('reset', this, filter);
230
+
231
+ return this;
232
+ };
233
+
234
+ /**
235
+ * A utility function for unbiding listeners
236
+ *
237
+ * @param {View} view (marionette view)
238
+ */
239
+ vc.closeWith = function (view) {
240
+ view.on('close', function () {
241
+ this.stopListening();
242
+ }, this);
243
+ };
244
+
245
+ // private
246
+
247
+ vc._rebuildIndex = function () {
248
+ this.index = [];
249
+
250
+ this.collection.each(function (model, index) {
251
+ if (this.filterFunction(model, index)) {
252
+ this.index.push(model.cid);
253
+ }
254
+ }, this);
255
+
256
+ if (this.comparator) {
257
+ this.sort({silent: true});
258
+ }
259
+
260
+ this.length = this.index.length;
261
+ };
262
+
263
+ /**
264
+ * Returns an array of models in the virtual collection
265
+ *
266
+ * @return {Array}
267
+ */
268
+ vc._models = function () {
269
+ var parentCollection = this._getParentCollection();
270
+
271
+ return _.map(this.index, function (cid) {
272
+ return parentCollection.get(cid);
273
+ }, this);
274
+ };
275
+
276
+ /**
277
+ * Handles the collection:add event
278
+ * May update the virtual collection's index
279
+ *
280
+ * @param {Model} model
281
+ * @return {undefined}
282
+ */
283
+ vc._onAdd = function (model, collection, options) {
284
+ if (this.filterFunction(model)) {
285
+ this._indexAdd(model);
286
+ this.trigger('add', model, this, options);
287
+ }
288
+ };
289
+
290
+ /**
291
+ * Handles the collection:remove event
292
+ * May update the virtual collection's index
293
+ *
294
+ * @param {Model} model
295
+ * @return {undefined}
296
+ */
297
+ vc._onRemove = function (model, collection, options) {
298
+ if (_(this.index).contains(model.cid)) {
299
+ var i = this._indexRemove(model)
300
+ , options_clone;
301
+
302
+ if (options) {
303
+ options_clone = _.clone(options);
304
+ options_clone.index = i;
305
+ }
306
+
307
+ this.trigger('remove', model, this, options_clone);
308
+ }
309
+ };
310
+
311
+ /**
312
+ * Handles the collection:change event
313
+ * May update the virtual collection's index
314
+ *
315
+ * @param {Model} model
316
+ * @param {Object} object
317
+ */
318
+ vc._onChange = function (model, options) {
319
+ var already_here = _.contains(this.index, model.cid);
320
+
321
+ if (this.filterFunction(model)) {
322
+ if (already_here) {
323
+ this.trigger('change', model, this, options);
324
+ } else {
325
+ this._indexAdd(model);
326
+ this.trigger('add', model, this, options);
327
+ }
328
+ } else {
329
+ if (already_here) {
330
+ this._indexRemove(model);
331
+ this.trigger('remove', model, this, options);
332
+ }
333
+ }
334
+ };
335
+
336
+ /**
337
+ * Handles the collection:reset event
338
+ *
339
+ * @param {Collection} collection
340
+ * @param {Object} object
341
+ */
342
+ vc._onReset = function (collection, options) {
343
+ this._rebuildIndex();
344
+ this.trigger('reset', this, options);
345
+ };
346
+
347
+ /**
348
+ * Adds a model to the virtual collection index
349
+ * Inserting it in the correct order
350
+ *
351
+ * @param {Model} model
352
+ * @return {undefined}
353
+ */
354
+ vc._indexAdd = function (model) {
355
+ if (this.index.indexOf(model.cid) === -1) {
356
+
357
+ if (!this.comparator) { // order inherit's from parent collection
358
+ var i, orig_index = this.collection.indexOf(model);
359
+ for (i = 0; i < this.length; i++) {
360
+ if (this.collection.indexOf(this.collection.get(this.index[i])) > orig_index) {
361
+ break;
362
+ }
363
+ }
364
+ this.index.splice(i, 0, model.cid);
365
+
366
+ } else { // the virtual collection has a custom order
367
+ this.index.push(model.cid);
368
+ this.sort({silent: true});
369
+ }
370
+ this.length = this.index.length;
371
+ }
372
+ };
373
+
374
+ /**
375
+ * Removes a model from the virtual collection index
376
+ *
377
+ * @param {Model} model
378
+ * @return {int} the index for the removed model or -1 if not found
379
+ */
380
+ vc._indexRemove = function (model) {
381
+ var i = this.index.indexOf(model.cid);
382
+
383
+ if (i !== -1) {
384
+ this.index.splice(i, 1);
385
+ this.length = this.index.length;
386
+ }
387
+
388
+ return i;
389
+ };
390
+
391
+ _.extend(vc, Backbone.Events);
392
+
393
+ VirtualCollection.extend = Backbone.Collection.extend;
394
+
395
+ Backbone.VirtualCollection = VirtualCollection;
396
+
397
+ return VirtualCollection;
398
+ }));
@@ -1 +1 @@
1
- //= require js_stack/plugins/backbone/virtualcollection/0.4.12
1
+ //= require js_stack/plugins/backbone/virtualcollection/0.4.14
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: js_stack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Pewiński
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-28 00:00:00.000000000 Z
12
+ date: 2014-04-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: haml_coffee_assets
@@ -116,6 +116,7 @@ files:
116
116
  - vendor/assets/javascripts/js_stack/base/marionette/1.6.4.js
117
117
  - vendor/assets/javascripts/js_stack/base/marionette/1.7.0.js
118
118
  - vendor/assets/javascripts/js_stack/base/marionette/1.7.3.js
119
+ - vendor/assets/javascripts/js_stack/base/marionette/1.7.4.js
119
120
  - vendor/assets/javascripts/js_stack/base/underscore.js
120
121
  - vendor/assets/javascripts/js_stack/base/underscore/1.5.2.js
121
122
  - vendor/assets/javascripts/js_stack/base/underscore/1.6.0.js
@@ -144,6 +145,7 @@ files:
144
145
  - vendor/assets/javascripts/js_stack/plugins/backbone/validation/0.9.1.js
145
146
  - vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.11.js
146
147
  - vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.12.js
148
+ - vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.14.js
147
149
  - vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.5.js
148
150
  - vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.8.js
149
151
  - vendor/assets/javascripts/js_stack/plugins/cocktail.js