tolaria 2.0.1 → 2.0.2
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/app/assets/javascripts/admin/lib/backbone.js +125 -102
- data/app/assets/javascripts/admin/lib/jquery.chosen.js +31 -20
- data/app/assets/javascripts/admin/lib/jquery.js +4225 -4502
- data/app/assets/javascripts/admin/lib/moment.js +10748 -1989
- data/app/assets/javascripts/admin/lib/underscore.js +14 -17
- data/lib/generators/tolaria/install/templates/administrators_migration.rb +1 -5
- data/lib/tolaria.rb +0 -1
- data/lib/tolaria/version.rb +1 -1
- data/test/demo/db/migrate/20150601202901_create_administrators.rb +2 -6
- data/test/demo/db/migrate/20150603204006_add_testing_models.rb +1 -1
- data/test/demo/db/migrate/20150609232013_create_footnotes.rb +1 -1
- data/test/demo/db/migrate/20150610135235_create_additional_demo_objects.rb +1 -1
- data/tolaria.gemspec +1 -1
- metadata +4 -5
- data/lib/tolaria/ransack.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f72ecaf99c8d0f57914a8fcd621ca087c14406f0
|
4
|
+
data.tar.gz: 681f402268c1440a79b1d8bb19a4c6c28c597194
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cc57c634c9d114fe3d8fcc12a1c9740051248a51e09efd41b09d628f2cb903da3d7ca40a54d96cc759eae16deb19b84d3aa0c10ce76eec906742904f515136b
|
7
|
+
data.tar.gz: 88de63e2ed3b799fdbf9dca3b415a0b812c98ac33eda8d3c895169b05bd05d7f7e107ffbb9840beafb409a2c937024c7cd7035683dd02ad6ae932ed9cc869e95
|
@@ -1,36 +1,33 @@
|
|
1
|
-
// Backbone 1.
|
1
|
+
// Backbone 1.3.3
|
2
2
|
// https://github.com/jashkenas/backbone
|
3
3
|
//
|
4
|
-
// Copyright
|
5
|
-
// Investigative Reporters & Editors
|
4
|
+
// Copyright © Jeremy Ashkenas, DocumentCloud, and Investigative Reporters & Editors
|
6
5
|
//
|
7
|
-
// Permission is hereby granted, free of charge, to any person
|
8
|
-
//
|
9
|
-
//
|
10
|
-
//
|
11
|
-
//
|
12
|
-
//
|
13
|
-
//
|
14
|
-
// conditions:
|
6
|
+
// Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
// a copy of this software and associated documentation files
|
8
|
+
// (the "Software"), to deal in the Software without restriction,
|
9
|
+
// including without limitation the rights to use, copy, modify, merge,
|
10
|
+
// publish, distribute, sublicense, and/or sell copies of the Software,
|
11
|
+
// and to permit persons to whom the Software is furnished to do so,
|
12
|
+
// subject to the following conditions:
|
15
13
|
//
|
16
14
|
// The above copyright notice and this permission notice shall be
|
17
15
|
// included in all copies or substantial portions of the Software.
|
18
16
|
//
|
19
17
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
20
|
-
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
21
|
-
//
|
22
|
-
//
|
23
|
-
//
|
24
|
-
//
|
25
|
-
//
|
26
|
-
// OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
21
|
+
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
23
|
+
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
24
|
|
28
25
|
(function(factory) {
|
29
26
|
|
30
27
|
// Establish the root object, `window` (`self`) in the browser, or `global` on the server.
|
31
28
|
// We use `self` instead of `window` for `WebWorker` support.
|
32
|
-
var root = (typeof self == 'object' && self.self
|
33
|
-
(typeof global == 'object' && global.global
|
29
|
+
var root = (typeof self == 'object' && self.self === self && self) ||
|
30
|
+
(typeof global == 'object' && global.global === global && global);
|
34
31
|
|
35
32
|
// Set up Backbone appropriately for the environment. Start with AMD.
|
36
33
|
if (typeof define === 'function' && define.amd) {
|
@@ -43,7 +40,7 @@
|
|
43
40
|
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
|
44
41
|
} else if (typeof exports !== 'undefined') {
|
45
42
|
var _ = require('underscore'), $;
|
46
|
-
try { $ = require('jquery'); } catch(e) {}
|
43
|
+
try { $ = require('jquery'); } catch (e) {}
|
47
44
|
factory(root, exports, _, $);
|
48
45
|
|
49
46
|
// Finally, as a browser global.
|
@@ -51,7 +48,7 @@
|
|
51
48
|
root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
|
52
49
|
}
|
53
50
|
|
54
|
-
}(function(root, Backbone, _, $) {
|
51
|
+
})(function(root, Backbone, _, $) {
|
55
52
|
|
56
53
|
// Initial Setup
|
57
54
|
// -------------
|
@@ -64,7 +61,7 @@
|
|
64
61
|
var slice = Array.prototype.slice;
|
65
62
|
|
66
63
|
// Current version of the library. Keep in sync with `package.json`.
|
67
|
-
Backbone.VERSION = '1.
|
64
|
+
Backbone.VERSION = '1.3.3';
|
68
65
|
|
69
66
|
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
|
70
67
|
// the `$` variable.
|
@@ -166,7 +163,7 @@
|
|
166
163
|
events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
|
167
164
|
}
|
168
165
|
} else if (name && eventSplitter.test(name)) {
|
169
|
-
// Handle space
|
166
|
+
// Handle space-separated event names by delegating them individually.
|
170
167
|
for (names = name.split(eventSplitter); i < names.length; i++) {
|
171
168
|
events = iteratee(events, names[i], callback, opts);
|
172
169
|
}
|
@@ -186,9 +183,9 @@
|
|
186
183
|
// Guard the `listening` argument from the public API.
|
187
184
|
var internalOn = function(obj, name, callback, context, listening) {
|
188
185
|
obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
|
189
|
-
|
190
|
-
|
191
|
-
|
186
|
+
context: context,
|
187
|
+
ctx: obj,
|
188
|
+
listening: listening
|
192
189
|
});
|
193
190
|
|
194
191
|
if (listening) {
|
@@ -202,7 +199,7 @@
|
|
202
199
|
// Inversion-of-control versions of `on`. Tell *this* object to listen to
|
203
200
|
// an event in another object... keeping track of what it's listening to
|
204
201
|
// for easier unbinding later.
|
205
|
-
Events.listenTo =
|
202
|
+
Events.listenTo = function(obj, name, callback) {
|
206
203
|
if (!obj) return this;
|
207
204
|
var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
|
208
205
|
var listeningTo = this._listeningTo || (this._listeningTo = {});
|
@@ -227,7 +224,7 @@
|
|
227
224
|
var context = options.context, ctx = options.ctx, listening = options.listening;
|
228
225
|
if (listening) listening.count++;
|
229
226
|
|
230
|
-
handlers.push({
|
227
|
+
handlers.push({callback: callback, context: context, ctx: context || ctx, listening: listening});
|
231
228
|
}
|
232
229
|
return events;
|
233
230
|
};
|
@@ -236,18 +233,18 @@
|
|
236
233
|
// callbacks with that function. If `callback` is null, removes all
|
237
234
|
// callbacks for the event. If `name` is null, removes all bound
|
238
235
|
// callbacks for all events.
|
239
|
-
Events.off =
|
236
|
+
Events.off = function(name, callback, context) {
|
240
237
|
if (!this._events) return this;
|
241
238
|
this._events = eventsApi(offApi, this._events, name, callback, {
|
242
|
-
|
243
|
-
|
239
|
+
context: context,
|
240
|
+
listeners: this._listeners
|
244
241
|
});
|
245
242
|
return this;
|
246
243
|
};
|
247
244
|
|
248
245
|
// Tell this object to stop listening to either specific events ... or
|
249
246
|
// to every object it's currently listening to.
|
250
|
-
Events.stopListening =
|
247
|
+
Events.stopListening = function(obj, name, callback) {
|
251
248
|
var listeningTo = this._listeningTo;
|
252
249
|
if (!listeningTo) return this;
|
253
250
|
|
@@ -262,7 +259,6 @@
|
|
262
259
|
|
263
260
|
listening.obj.off(name, callback, this);
|
264
261
|
}
|
265
|
-
if (_.isEmpty(listeningTo)) this._listeningTo = void 0;
|
266
262
|
|
267
263
|
return this;
|
268
264
|
};
|
@@ -319,21 +315,22 @@
|
|
319
315
|
delete events[name];
|
320
316
|
}
|
321
317
|
}
|
322
|
-
|
318
|
+
return events;
|
323
319
|
};
|
324
320
|
|
325
321
|
// Bind an event to only be triggered a single time. After the first time
|
326
322
|
// the callback is invoked, its listener will be removed. If multiple events
|
327
323
|
// are passed in using the space-separated syntax, the handler will fire
|
328
324
|
// once for each event, not once for a combination of all events.
|
329
|
-
Events.once =
|
325
|
+
Events.once = function(name, callback, context) {
|
330
326
|
// Map the event into a `{event: once}` object.
|
331
327
|
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
|
332
|
-
|
328
|
+
if (typeof name === 'string' && context == null) callback = void 0;
|
329
|
+
return this.on(events, callback, context);
|
333
330
|
};
|
334
331
|
|
335
332
|
// Inversion-of-control versions of `once`.
|
336
|
-
Events.listenToOnce =
|
333
|
+
Events.listenToOnce = function(obj, name, callback) {
|
337
334
|
// Map the event into a `{event: once}` object.
|
338
335
|
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
|
339
336
|
return this.listenTo(obj, events);
|
@@ -356,7 +353,7 @@
|
|
356
353
|
// passed the same arguments as `trigger` is, apart from the event name
|
357
354
|
// (unless you're listening on `"all"`, which will cause your callback to
|
358
355
|
// receive the true name of the event as the first argument).
|
359
|
-
Events.trigger =
|
356
|
+
Events.trigger = function(name) {
|
360
357
|
if (!this._events) return this;
|
361
358
|
|
362
359
|
var length = Math.max(0, arguments.length - 1);
|
@@ -368,7 +365,7 @@
|
|
368
365
|
};
|
369
366
|
|
370
367
|
// Handles triggering the appropriate event callbacks.
|
371
|
-
var triggerApi = function(objEvents, name,
|
368
|
+
var triggerApi = function(objEvents, name, callback, args) {
|
372
369
|
if (objEvents) {
|
373
370
|
var events = objEvents[name];
|
374
371
|
var allEvents = objEvents.all;
|
@@ -418,7 +415,8 @@
|
|
418
415
|
this.attributes = {};
|
419
416
|
if (options.collection) this.collection = options.collection;
|
420
417
|
if (options.parse) attrs = this.parse(attrs, options) || {};
|
421
|
-
|
418
|
+
var defaults = _.result(this, 'defaults');
|
419
|
+
attrs = _.defaults(_.extend({}, defaults, attrs), defaults);
|
422
420
|
this.set(attrs, options);
|
423
421
|
this.changed = {};
|
424
422
|
this.initialize.apply(this, arguments);
|
@@ -526,7 +524,7 @@
|
|
526
524
|
}
|
527
525
|
|
528
526
|
// Update the `id`.
|
529
|
-
this.id = this.get(this.idAttribute);
|
527
|
+
if (this.idAttribute in attrs) this.id = this.get(this.idAttribute);
|
530
528
|
|
531
529
|
// Trigger all relevant attribute changes.
|
532
530
|
if (!silent) {
|
@@ -639,8 +637,8 @@
|
|
639
637
|
// the model will be valid when the attributes, if any, are set.
|
640
638
|
if (attrs && !wait) {
|
641
639
|
if (!this.set(attrs, options)) return false;
|
642
|
-
} else {
|
643
|
-
|
640
|
+
} else if (!this._validate(attrs, options)) {
|
641
|
+
return false;
|
644
642
|
}
|
645
643
|
|
646
644
|
// After a successful server-side save, the client is (optionally)
|
@@ -734,7 +732,7 @@
|
|
734
732
|
|
735
733
|
// Check if the model is currently in a valid state.
|
736
734
|
isValid: function(options) {
|
737
|
-
return this._validate({}, _.
|
735
|
+
return this._validate({}, _.extend({}, options, {validate: true}));
|
738
736
|
},
|
739
737
|
|
740
738
|
// Run validation against the next complete set of model attributes,
|
@@ -752,8 +750,8 @@
|
|
752
750
|
|
753
751
|
// Underscore methods that we want to implement on the Model, mapped to the
|
754
752
|
// number of arguments they take.
|
755
|
-
var modelMethods = {
|
756
|
-
omit: 0, chain: 1, isEmpty: 1
|
753
|
+
var modelMethods = {keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
|
754
|
+
omit: 0, chain: 1, isEmpty: 1};
|
757
755
|
|
758
756
|
// Mix in each Underscore method as a proxy to `Model#attributes`.
|
759
757
|
addUnderscoreMethods(Model, modelMethods, 'attributes');
|
@@ -789,7 +787,8 @@
|
|
789
787
|
at = Math.min(Math.max(at, 0), array.length);
|
790
788
|
var tail = Array(array.length - at);
|
791
789
|
var length = insert.length;
|
792
|
-
|
790
|
+
var i;
|
791
|
+
for (i = 0; i < tail.length; i++) tail[i] = array[i + at];
|
793
792
|
for (i = 0; i < length; i++) array[i + at] = insert[i];
|
794
793
|
for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
|
795
794
|
};
|
@@ -827,9 +826,12 @@
|
|
827
826
|
remove: function(models, options) {
|
828
827
|
options = _.extend({}, options);
|
829
828
|
var singular = !_.isArray(models);
|
830
|
-
models = singular ? [models] :
|
829
|
+
models = singular ? [models] : models.slice();
|
831
830
|
var removed = this._removeModels(models, options);
|
832
|
-
if (!options.silent && removed)
|
831
|
+
if (!options.silent && removed.length) {
|
832
|
+
options.changes = {added: [], merged: [], removed: removed};
|
833
|
+
this.trigger('update', this, options);
|
834
|
+
}
|
833
835
|
return singular ? removed[0] : removed;
|
834
836
|
},
|
835
837
|
|
@@ -840,18 +842,22 @@
|
|
840
842
|
set: function(models, options) {
|
841
843
|
if (models == null) return;
|
842
844
|
|
843
|
-
options = _.
|
844
|
-
if (options.parse && !this._isModel(models))
|
845
|
+
options = _.extend({}, setOptions, options);
|
846
|
+
if (options.parse && !this._isModel(models)) {
|
847
|
+
models = this.parse(models, options) || [];
|
848
|
+
}
|
845
849
|
|
846
850
|
var singular = !_.isArray(models);
|
847
851
|
models = singular ? [models] : models.slice();
|
848
852
|
|
849
853
|
var at = options.at;
|
850
854
|
if (at != null) at = +at;
|
855
|
+
if (at > this.length) at = this.length;
|
851
856
|
if (at < 0) at += this.length + 1;
|
852
857
|
|
853
858
|
var set = [];
|
854
859
|
var toAdd = [];
|
860
|
+
var toMerge = [];
|
855
861
|
var toRemove = [];
|
856
862
|
var modelMap = {};
|
857
863
|
|
@@ -860,13 +866,13 @@
|
|
860
866
|
var remove = options.remove;
|
861
867
|
|
862
868
|
var sort = false;
|
863
|
-
var sortable = this.comparator &&
|
869
|
+
var sortable = this.comparator && at == null && options.sort !== false;
|
864
870
|
var sortAttr = _.isString(this.comparator) ? this.comparator : null;
|
865
871
|
|
866
872
|
// Turn bare objects into model references, and prevent invalid models
|
867
873
|
// from being added.
|
868
|
-
var model;
|
869
|
-
for (
|
874
|
+
var model, i;
|
875
|
+
for (i = 0; i < models.length; i++) {
|
870
876
|
model = models[i];
|
871
877
|
|
872
878
|
// If a duplicate is found, prevent it from being added and
|
@@ -877,6 +883,7 @@
|
|
877
883
|
var attrs = this._isModel(model) ? model.attributes : model;
|
878
884
|
if (options.parse) attrs = existing.parse(attrs, options);
|
879
885
|
existing.set(attrs, options);
|
886
|
+
toMerge.push(existing);
|
880
887
|
if (sortable && !sort) sort = existing.hasChanged(sortAttr);
|
881
888
|
}
|
882
889
|
if (!modelMap[existing.cid]) {
|
@@ -910,8 +917,8 @@
|
|
910
917
|
var orderChanged = false;
|
911
918
|
var replace = !sortable && add && remove;
|
912
919
|
if (set.length && replace) {
|
913
|
-
orderChanged = this.length
|
914
|
-
return
|
920
|
+
orderChanged = this.length !== set.length || _.some(this.models, function(m, index) {
|
921
|
+
return m !== set[index];
|
915
922
|
});
|
916
923
|
this.models.length = 0;
|
917
924
|
splice(this.models, set, 0);
|
@@ -925,7 +932,7 @@
|
|
925
932
|
// Silently sort the collection if appropriate.
|
926
933
|
if (sort) this.sort({silent: true});
|
927
934
|
|
928
|
-
// Unless silenced, it's time to fire all appropriate add/sort events.
|
935
|
+
// Unless silenced, it's time to fire all appropriate add/sort/update events.
|
929
936
|
if (!options.silent) {
|
930
937
|
for (i = 0; i < toAdd.length; i++) {
|
931
938
|
if (at != null) options.index = at + i;
|
@@ -933,7 +940,14 @@
|
|
933
940
|
model.trigger('add', model, this, options);
|
934
941
|
}
|
935
942
|
if (sort || orderChanged) this.trigger('sort', this, options);
|
936
|
-
if (toAdd.length || toRemove.length
|
943
|
+
if (toAdd.length || toRemove.length || toMerge.length) {
|
944
|
+
options.changes = {
|
945
|
+
added: toAdd,
|
946
|
+
removed: toRemove,
|
947
|
+
merged: toMerge
|
948
|
+
};
|
949
|
+
this.trigger('update', this, options);
|
950
|
+
}
|
937
951
|
}
|
938
952
|
|
939
953
|
// Return the added (or merged) model (or models).
|
@@ -983,11 +997,18 @@
|
|
983
997
|
return slice.apply(this.models, arguments);
|
984
998
|
},
|
985
999
|
|
986
|
-
// Get a model from the set by id
|
1000
|
+
// Get a model from the set by id, cid, model object with id or cid
|
1001
|
+
// properties, or an attributes object that is transformed through modelId.
|
987
1002
|
get: function(obj) {
|
988
1003
|
if (obj == null) return void 0;
|
989
|
-
|
990
|
-
|
1004
|
+
return this._byId[obj] ||
|
1005
|
+
this._byId[this.modelId(obj.attributes || obj)] ||
|
1006
|
+
obj.cid && this._byId[obj.cid];
|
1007
|
+
},
|
1008
|
+
|
1009
|
+
// Returns `true` if the model is in the collection.
|
1010
|
+
has: function(obj) {
|
1011
|
+
return this.get(obj) != null;
|
991
1012
|
},
|
992
1013
|
|
993
1014
|
// Get the model at the given index.
|
@@ -1031,7 +1052,7 @@
|
|
1031
1052
|
|
1032
1053
|
// Pluck an attribute from each model in the collection.
|
1033
1054
|
pluck: function(attr) {
|
1034
|
-
return
|
1055
|
+
return this.map(attr + '');
|
1035
1056
|
},
|
1036
1057
|
|
1037
1058
|
// Fetch the default set of models for this collection, resetting the
|
@@ -1062,9 +1083,9 @@
|
|
1062
1083
|
if (!wait) this.add(model, options);
|
1063
1084
|
var collection = this;
|
1064
1085
|
var success = options.success;
|
1065
|
-
options.success = function(
|
1066
|
-
if (wait) collection.add(
|
1067
|
-
if (success) success.call(callbackOpts.context,
|
1086
|
+
options.success = function(m, resp, callbackOpts) {
|
1087
|
+
if (wait) collection.add(m, callbackOpts);
|
1088
|
+
if (success) success.call(callbackOpts.context, m, resp, callbackOpts);
|
1068
1089
|
};
|
1069
1090
|
model.save(null, options);
|
1070
1091
|
return model;
|
@@ -1085,7 +1106,7 @@
|
|
1085
1106
|
},
|
1086
1107
|
|
1087
1108
|
// Define how to uniquely identify models in the collection.
|
1088
|
-
modelId: function
|
1109
|
+
modelId: function(attrs) {
|
1089
1110
|
return attrs[this.model.prototype.idAttribute || 'id'];
|
1090
1111
|
},
|
1091
1112
|
|
@@ -1123,6 +1144,12 @@
|
|
1123
1144
|
this.models.splice(index, 1);
|
1124
1145
|
this.length--;
|
1125
1146
|
|
1147
|
+
// Remove references before triggering 'remove' event to prevent an
|
1148
|
+
// infinite loop. #3693
|
1149
|
+
delete this._byId[model.cid];
|
1150
|
+
var id = this.modelId(model.attributes);
|
1151
|
+
if (id != null) delete this._byId[id];
|
1152
|
+
|
1126
1153
|
if (!options.silent) {
|
1127
1154
|
options.index = index;
|
1128
1155
|
model.trigger('remove', model, this, options);
|
@@ -1131,12 +1158,12 @@
|
|
1131
1158
|
removed.push(model);
|
1132
1159
|
this._removeReference(model, options);
|
1133
1160
|
}
|
1134
|
-
return removed
|
1161
|
+
return removed;
|
1135
1162
|
},
|
1136
1163
|
|
1137
1164
|
// Method for checking whether an object should be considered a model for
|
1138
1165
|
// the purposes of adding to the collection.
|
1139
|
-
_isModel: function
|
1166
|
+
_isModel: function(model) {
|
1140
1167
|
return model instanceof Model;
|
1141
1168
|
},
|
1142
1169
|
|
@@ -1162,14 +1189,16 @@
|
|
1162
1189
|
// events simply proxy through. "add" and "remove" events that originate
|
1163
1190
|
// in other collections are ignored.
|
1164
1191
|
_onModelEvent: function(event, model, collection, options) {
|
1165
|
-
if (
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
if (prevId
|
1172
|
-
|
1192
|
+
if (model) {
|
1193
|
+
if ((event === 'add' || event === 'remove') && collection !== this) return;
|
1194
|
+
if (event === 'destroy') this.remove(model, options);
|
1195
|
+
if (event === 'change') {
|
1196
|
+
var prevId = this.modelId(model.previousAttributes());
|
1197
|
+
var id = this.modelId(model.attributes);
|
1198
|
+
if (prevId !== id) {
|
1199
|
+
if (prevId != null) delete this._byId[prevId];
|
1200
|
+
if (id != null) this._byId[id] = model;
|
1201
|
+
}
|
1173
1202
|
}
|
1174
1203
|
}
|
1175
1204
|
this.trigger.apply(this, arguments);
|
@@ -1180,14 +1209,14 @@
|
|
1180
1209
|
// Underscore methods that we want to implement on the Collection.
|
1181
1210
|
// 90% of the core usefulness of Backbone Collections is actually implemented
|
1182
1211
|
// right here:
|
1183
|
-
var collectionMethods = {
|
1184
|
-
foldl:
|
1212
|
+
var collectionMethods = {forEach: 3, each: 3, map: 3, collect: 3, reduce: 0,
|
1213
|
+
foldl: 0, inject: 0, reduceRight: 0, foldr: 0, find: 3, detect: 3, filter: 3,
|
1185
1214
|
select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
|
1186
1215
|
contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
|
1187
1216
|
head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
|
1188
1217
|
without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
|
1189
1218
|
isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
|
1190
|
-
sortBy: 3, indexBy: 3};
|
1219
|
+
sortBy: 3, indexBy: 3, findIndex: 3, findLastIndex: 3};
|
1191
1220
|
|
1192
1221
|
// Mix in each Underscore method as a proxy to `Collection#models`.
|
1193
1222
|
addUnderscoreMethods(Collection, collectionMethods, 'models');
|
@@ -1437,9 +1466,9 @@
|
|
1437
1466
|
var methodMap = {
|
1438
1467
|
'create': 'POST',
|
1439
1468
|
'update': 'PUT',
|
1440
|
-
'patch':
|
1469
|
+
'patch': 'PATCH',
|
1441
1470
|
'delete': 'DELETE',
|
1442
|
-
'read':
|
1471
|
+
'read': 'GET'
|
1443
1472
|
};
|
1444
1473
|
|
1445
1474
|
// Set the default implementation of `Backbone.ajax` to proxy through to `$`.
|
@@ -1596,8 +1625,8 @@
|
|
1596
1625
|
// Does the pathname match the root?
|
1597
1626
|
matchRoot: function() {
|
1598
1627
|
var path = this.decodeFragment(this.location.pathname);
|
1599
|
-
var
|
1600
|
-
return
|
1628
|
+
var rootPath = path.slice(0, this.root.length - 1) + '/';
|
1629
|
+
return rootPath === this.root;
|
1601
1630
|
},
|
1602
1631
|
|
1603
1632
|
// Unicode characters in `location.pathname` are percent encoded so they're
|
@@ -1669,8 +1698,8 @@
|
|
1669
1698
|
// If we've started off with a route from a `pushState`-enabled
|
1670
1699
|
// browser, but we're currently in a browser that doesn't support it...
|
1671
1700
|
if (!this._hasPushState && !this.atRoot()) {
|
1672
|
-
var
|
1673
|
-
this.location.replace(
|
1701
|
+
var rootPath = this.root.slice(0, -1) || '/';
|
1702
|
+
this.location.replace(rootPath + '#' + this.getPath());
|
1674
1703
|
// Return immediately as browser will do redirect to new url
|
1675
1704
|
return true;
|
1676
1705
|
|
@@ -1699,7 +1728,7 @@
|
|
1699
1728
|
}
|
1700
1729
|
|
1701
1730
|
// Add a cross-platform `addEventListener` shim for older browsers.
|
1702
|
-
var addEventListener = window.addEventListener || function
|
1731
|
+
var addEventListener = window.addEventListener || function(eventName, listener) {
|
1703
1732
|
return attachEvent('on' + eventName, listener);
|
1704
1733
|
};
|
1705
1734
|
|
@@ -1720,7 +1749,7 @@
|
|
1720
1749
|
// but possibly useful for unit testing Routers.
|
1721
1750
|
stop: function() {
|
1722
1751
|
// Add a cross-platform `removeEventListener` shim for older browsers.
|
1723
|
-
var removeEventListener = window.removeEventListener || function
|
1752
|
+
var removeEventListener = window.removeEventListener || function(eventName, listener) {
|
1724
1753
|
return detachEvent('on' + eventName, listener);
|
1725
1754
|
};
|
1726
1755
|
|
@@ -1794,11 +1823,11 @@
|
|
1794
1823
|
fragment = this.getFragment(fragment || '');
|
1795
1824
|
|
1796
1825
|
// Don't include a trailing slash on the root.
|
1797
|
-
var
|
1826
|
+
var rootPath = this.root;
|
1798
1827
|
if (fragment === '' || fragment.charAt(0) === '?') {
|
1799
|
-
|
1828
|
+
rootPath = rootPath.slice(0, -1) || '/';
|
1800
1829
|
}
|
1801
|
-
var url =
|
1830
|
+
var url = rootPath + fragment;
|
1802
1831
|
|
1803
1832
|
// Strip the hash and decode for matching.
|
1804
1833
|
fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
|
@@ -1814,7 +1843,7 @@
|
|
1814
1843
|
// fragment to store history.
|
1815
1844
|
} else if (this._wantsHashChange) {
|
1816
1845
|
this._updateHash(this.location, fragment, options.replace);
|
1817
|
-
if (this.iframe &&
|
1846
|
+
if (this.iframe && fragment !== this.getHash(this.iframe.contentWindow)) {
|
1818
1847
|
var iWindow = this.iframe.contentWindow;
|
1819
1848
|
|
1820
1849
|
// Opening and closing the iframe tricks IE7 and earlier to push a
|
@@ -1876,14 +1905,9 @@
|
|
1876
1905
|
_.extend(child, parent, staticProps);
|
1877
1906
|
|
1878
1907
|
// Set the prototype chain to inherit from `parent`, without calling
|
1879
|
-
// `parent` constructor function.
|
1880
|
-
|
1881
|
-
|
1882
|
-
child.prototype = new Surrogate;
|
1883
|
-
|
1884
|
-
// Add prototype properties (instance properties) to the subclass,
|
1885
|
-
// if supplied.
|
1886
|
-
if (protoProps) _.extend(child.prototype, protoProps);
|
1908
|
+
// `parent`'s constructor function and add the prototype properties.
|
1909
|
+
child.prototype = _.create(parent.prototype, protoProps);
|
1910
|
+
child.prototype.constructor = child;
|
1887
1911
|
|
1888
1912
|
// Set a convenience property in case the parent's prototype is needed
|
1889
1913
|
// later.
|
@@ -1910,5 +1934,4 @@
|
|
1910
1934
|
};
|
1911
1935
|
|
1912
1936
|
return Backbone;
|
1913
|
-
|
1914
|
-
}));
|
1937
|
+
});
|