Skip to content

Commit 06b515b

Browse files
committed
Use browserify
1 parent b5b673a commit 06b515b

8 files changed

+416
-258
lines changed

backbone.virtual-collection.js

+178-190
Original file line numberDiff line numberDiff line change
@@ -1,215 +1,203 @@
11

22
// Available under the MIT License (MIT)
33

4-
(function (root, factory) {
5-
if (typeof define === 'function' && define.amd) {
6-
define(['backbone', 'underscore'], function (Backbone, _) {
7-
Backbone.VirtualCollection = factory(root, Backbone, _);
8-
root.VirtualCollection = Backbone.VirtualCollection;
9-
});
10-
} else if (typeof exports !== 'undefined') {
11-
var Backbone = require('backbone');
12-
var _ = require('underscore');
13-
module.exports = factory(root, Backbone, _);
14-
} else {
15-
root.Backbone.VirtualCollection = factory(root, root.Backbone, root._);
16-
root.VirtualCollection = root.Backbone.VirtualCollection;
17-
}
18-
}(this, function (root, Backbone, _) {
19-
var VirtualCollection = Backbone.Collection.extend({
20-
21-
constructor: function (collection, options) {
22-
options = options || {};
23-
this.collection = collection;
24-
25-
if (options.comparator !== undefined) this.comparator = options.comparator;
26-
if (options.close_with) this.bindLifecycle(options.close_with, 'close'); // Marionette 1.*
27-
if (options.destroy_with) this.bindLifecycle(options.destroy_with, 'destroy'); // Marionette 2.*
28-
if (!this.model) this.model = collection.model;
29-
30-
this.accepts = VirtualCollection.buildFilter(options.filter);
31-
this._rebuildIndex();
32-
this.listenTo(this.collection, 'add', this._onAdd);
33-
this.listenTo(this.collection, 'remove', this._onRemove);
34-
this.listenTo(this.collection, 'change', this._onChange);
35-
this.listenTo(this.collection, 'reset', this._onReset);
36-
this.listenTo(this.collection, 'sort', this._onSort);
37-
38-
this.initialize.apply(this, arguments);
39-
},
40-
41-
// Marionette 1.*
42-
bindLifecycle: function (view, method_name) {
43-
view.on(method_name, _.bind(this.stopListening, this));
44-
},
45-
46-
updateFilter: function (filter) {
47-
this.accepts = VirtualCollection.buildFilter(filter);
48-
this._rebuildIndex();
49-
this.trigger('filter', this, filter);
50-
this.trigger('reset', this, filter);
51-
return this;
52-
},
53-
54-
_rebuildIndex: function () {
55-
for(idx in this.models) {
56-
this.models[idx].off('all', this._onModelEvent, this);
4+
var VirtualCollection,
5+
Backbone = require('backbone'),
6+
_ = require('underscore');
7+
8+
VirtualCollection = Backbone.Collection.extend({
9+
10+
constructor: function (collection, options) {
11+
options = options || {};
12+
this.collection = collection;
13+
14+
if (options.comparator !== undefined) this.comparator = options.comparator;
15+
if (options.close_with) this.bindLifecycle(options.close_with, 'close'); // Marionette 1.*
16+
if (options.destroy_with) this.bindLifecycle(options.destroy_with, 'destroy'); // Marionette 2.*
17+
if (!this.model) this.model = collection.model;
18+
19+
this.accepts = VirtualCollection.buildFilter(options.filter);
20+
this._rebuildIndex();
21+
this.listenTo(this.collection, 'add', this._onAdd);
22+
this.listenTo(this.collection, 'remove', this._onRemove);
23+
this.listenTo(this.collection, 'change', this._onChange);
24+
this.listenTo(this.collection, 'reset', this._onReset);
25+
this.listenTo(this.collection, 'sort', this._onSort);
26+
27+
this.initialize.apply(this, arguments);
28+
},
29+
30+
// Marionette 1.*
31+
bindLifecycle: function (view, method_name) {
32+
view.on(method_name, _.bind(this.stopListening, this));
33+
},
34+
35+
updateFilter: function (filter) {
36+
this.accepts = VirtualCollection.buildFilter(filter);
37+
this._rebuildIndex();
38+
this.trigger('filter', this, filter);
39+
this.trigger('reset', this, filter);
40+
return this;
41+
},
42+
43+
_rebuildIndex: function () {
44+
for(idx in this.models) {
45+
this.models[idx].off('all', this._onModelEvent, this);
46+
}
47+
this._reset();
48+
this.collection.each(function (model, i) {
49+
if (this.accepts(model, i)) {
50+
model.on('all', this._onModelEvent, this);
51+
this.models.push(model);
52+
this._byId[model.cid] = model;
53+
if (model.id) this._byId[model.id] = model;
5754
}
58-
this._reset();
59-
this.collection.each(function (model, i) {
60-
if (this.accepts(model, i)) {
61-
model.on('all', this._onModelEvent, this);
62-
this.models.push(model);
63-
this._byId[model.cid] = model;
64-
if (model.id) this._byId[model.id] = model;
65-
}
66-
}, this);
67-
this.length = this.models.length;
55+
}, this);
56+
this.length = this.models.length;
57+
58+
if (this.comparator) this.sort({silent: true});
59+
},
60+
61+
orderViaParent: function (options) {
62+
this.models = this.collection.filter(function (model) {
63+
return (this._byId[model.cid] !== undefined);
64+
}, this);
65+
if (!options.silent) this.trigger('sort', this, options);
66+
},
67+
68+
_onSort: function (collection, options) {
69+
if (this.comparator !== undefined) return;
70+
this.orderViaParent(options);
71+
},
72+
73+
_onAdd: function (model, collection, options) {
74+
var already_here = this.get(model);
75+
if (!already_here && this.accepts(model, options.index)) {
76+
this._indexAdd(model);
77+
model.on('all', this._onModelEvent, this);
78+
this.trigger('add', model, this, options);
79+
}
80+
},
6881

69-
if (this.comparator) this.sort({silent: true});
70-
},
82+
_onRemove: function (model, collection, options) {
83+
if (!this.get(model)) return;
7184

72-
orderViaParent: function (options) {
73-
this.models = this.collection.filter(function (model) {
74-
return (this._byId[model.cid] !== undefined);
75-
}, this);
76-
if (!options.silent) this.trigger('sort', this, options);
77-
},
85+
var i = this._indexRemove(model)
86+
, options_clone = _.clone(options);
87+
options_clone.index = i;
88+
model.off('all', this._onModelEvent, this);
89+
this.trigger('remove', model, this, options_clone);
90+
},
7891

79-
_onSort: function (collection, options) {
80-
if (this.comparator !== undefined) return;
81-
this.orderViaParent(options);
82-
},
92+
_onChange: function (model, options) {
93+
if (!model || !options) return; // ignore malformed arguments coming from custom events
94+
var already_here = this.get(model);
8395

84-
_onAdd: function (model, collection, options) {
85-
var already_here = this.get(model);
86-
if (!already_here && this.accepts(model, options.index)) {
96+
if (this.accepts(model, options.index)) {
97+
if (already_here) {
98+
this.trigger('change', model, this, options);
99+
} else {
87100
this._indexAdd(model);
88-
model.on('all', this._onModelEvent, this);
89101
this.trigger('add', model, this, options);
90102
}
91-
},
92-
93-
_onRemove: function (model, collection, options) {
94-
if (!this.get(model)) return;
95-
96-
var i = this._indexRemove(model)
97-
, options_clone = _.clone(options);
98-
options_clone.index = i;
99-
model.off('all', this._onModelEvent, this);
100-
this.trigger('remove', model, this, options_clone);
101-
},
102-
103-
_onChange: function (model, options) {
104-
if (!model || !options) return; // ignore malformed arguments coming from custom events
105-
var already_here = this.get(model);
106-
107-
if (this.accepts(model, options.index)) {
108-
if (already_here) {
109-
this.trigger('change', model, this, options);
110-
} else {
111-
this._indexAdd(model);
112-
this.trigger('add', model, this, options);
113-
}
114-
} else {
115-
if (already_here) {
116-
var i = this._indexRemove(model)
117-
, options_clone = _.clone(options);
118-
options_clone.index = i;
119-
this.trigger('remove', model, this, options_clone);
120-
}
103+
} else {
104+
if (already_here) {
105+
var i = this._indexRemove(model)
106+
, options_clone = _.clone(options);
107+
options_clone.index = i;
108+
this.trigger('remove', model, this, options_clone);
121109
}
122-
},
110+
}
111+
},
123112

124-
_onReset: function (collection, options) {
125-
this._rebuildIndex();
126-
this.trigger('reset', this, options);
127-
},
113+
_onReset: function (collection, options) {
114+
this._rebuildIndex();
115+
this.trigger('reset', this, options);
116+
},
128117

129-
sortedIndex: function (model, value, context) {
130-
var iterator = _.isFunction(value) ? value : function(target) {
131-
return target.get(value);
132-
};
118+
sortedIndex: function (model, value, context) {
119+
var iterator = _.isFunction(value) ? value : function(target) {
120+
return target.get(value);
121+
};
133122

134-
if (iterator.length == 1) {
135-
return _.sortedIndex(this.models, model, iterator, context);
136-
} else {
137-
return sortedIndexTwo(this.models, model, iterator, context);
138-
}
139-
},
140-
141-
_indexAdd: function (model) {
142-
if (this.get(model)) return;
143-
var i;
144-
// uses a binsearch to find the right index
145-
if (this.comparator) {
146-
i = this.sortedIndex(model, this.comparator, this);
147-
} else if (this.comparator === undefined) {
148-
i = this.sortedIndex(model, function (target) {
149-
//TODO: indexOf traverses the array every time the iterator is called
150-
return this.collection.indexOf(target);
151-
}, this);
152-
} else {
153-
i = this.length;
154-
}
155-
this.models.splice(i, 0, model);
156-
this._byId[model.cid] = model;
157-
if (model.id) this._byId[model.id] = model;
158-
this.length += 1;
159-
},
160-
161-
_indexRemove: function (model) {
162-
model.off('all', this._onModelEvent, this);
163-
var i = this.indexOf(model);
164-
if (i === -1) return i;
165-
this.models.splice(i, 1);
166-
delete this._byId[model.cid];
167-
if (model.id) delete this._byId[model.id];
168-
this.length -= 1;
169-
return i;
123+
if (iterator.length == 1) {
124+
return _.sortedIndex(this.models, model, iterator, context);
125+
} else {
126+
return sortedIndexTwo(this.models, model, iterator, context);
127+
}
128+
},
129+
130+
_indexAdd: function (model) {
131+
if (this.get(model)) return;
132+
var i;
133+
// uses a binsearch to find the right index
134+
if (this.comparator) {
135+
i = this.sortedIndex(model, this.comparator, this);
136+
} else if (this.comparator === undefined) {
137+
i = this.sortedIndex(model, function (target) {
138+
//TODO: indexOf traverses the array every time the iterator is called
139+
return this.collection.indexOf(target);
140+
}, this);
141+
} else {
142+
i = this.length;
170143
}
144+
this.models.splice(i, 0, model);
145+
this._byId[model.cid] = model;
146+
if (model.id) this._byId[model.id] = model;
147+
this.length += 1;
148+
},
149+
150+
_indexRemove: function (model) {
151+
model.off('all', this._onModelEvent, this);
152+
var i = this.indexOf(model);
153+
if (i === -1) return i;
154+
this.models.splice(i, 1);
155+
delete this._byId[model.cid];
156+
if (model.id) delete this._byId[model.id];
157+
this.length -= 1;
158+
return i;
159+
}
171160

172-
}, { // static props
173-
174-
buildFilter: function (options) {
175-
if (!options) {
176-
return function () {
177-
return true;
178-
};
179-
} else if (_.isFunction(options)) {
180-
return options;
181-
} else if (options.constructor === Object) {
182-
return function (model) {
183-
return !Boolean(_(Object.keys(options)).detect(function (key) {
184-
return model.get(key) !== options[key];
185-
}));
186-
};
187-
}
161+
}, { // static props
162+
163+
buildFilter: function (options) {
164+
if (!options) {
165+
return function () {
166+
return true;
167+
};
168+
} else if (_.isFunction(options)) {
169+
return options;
170+
} else if (options.constructor === Object) {
171+
return function (model) {
172+
return !Boolean(_(Object.keys(options)).detect(function (key) {
173+
return model.get(key) !== options[key];
174+
}));
175+
};
188176
}
189-
});
177+
}
178+
});
190179

191-
// methods that alter data should proxy to the parent collection
192-
_.each(['add', 'remove', 'set', 'reset', 'push', 'pop', 'unshift', 'shift', 'slice', 'sync', 'fetch'], function (method_name) {
193-
VirtualCollection.prototype[method_name] = function () {
194-
return this.collection[method_name].apply(this.collection, _.toArray(arguments));
195-
};
196-
});
180+
// methods that alter data should proxy to the parent collection
181+
_.each(['add', 'remove', 'set', 'reset', 'push', 'pop', 'unshift', 'shift', 'slice', 'sync', 'fetch'], function (method_name) {
182+
VirtualCollection.prototype[method_name] = function () {
183+
return this.collection[method_name].apply(this.collection, _.toArray(arguments));
184+
};
185+
});
197186

198-
/**
187+
/**
199188
200-
Equivalent to _.sortedIndex, but for comparators with two arguments
189+
Equivalent to _.sortedIndex, but for comparators with two arguments
201190
202-
**/
203-
function sortedIndexTwo (array, obj, iterator, context) {
204-
var low = 0, high = array.length;
205-
while (low < high) {
206-
var mid = (low + high) >>> 1;
207-
iterator.call(context, obj, array[mid]) > 0 ? low = mid + 1 : high = mid;
208-
}
209-
return low;
191+
**/
192+
function sortedIndexTwo (array, obj, iterator, context) {
193+
var low = 0, high = array.length;
194+
while (low < high) {
195+
var mid = (low + high) >>> 1;
196+
iterator.call(context, obj, array[mid]) > 0 ? low = mid + 1 : high = mid;
210197
}
198+
return low;
199+
}
211200

212-
_.extend(VirtualCollection.prototype, Backbone.Events);
201+
_.extend(VirtualCollection.prototype, Backbone.Events);
213202

214-
return VirtualCollection;
215-
}));
203+
module.exports = VirtualCollection;

0 commit comments

Comments
 (0)