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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4450bf6abdde6f868ccb6b701f304cf9aceaf682
4
- data.tar.gz: bc67b331bb75c30b437cfc5af44fc0e3bc976174
3
+ metadata.gz: f72ecaf99c8d0f57914a8fcd621ca087c14406f0
4
+ data.tar.gz: 681f402268c1440a79b1d8bb19a4c6c28c597194
5
5
  SHA512:
6
- metadata.gz: 91095ce63931a301e5cd84e230414bc497d762d049efe3f13907f17f59f6a39cfa87d9c6af762ff6c8150c32360a64bb4dd6551e7686f375d77ea1caa91a12a4
7
- data.tar.gz: 83bbbd13e2765cbfadf037114f5b09aaf2364ded8ebcdda56be987effb1eceffe02b9ae3649e7edbeb402f03357834270e7cf21128655d346f6b22f286d334e1
6
+ metadata.gz: 7cc57c634c9d114fe3d8fcc12a1c9740051248a51e09efd41b09d628f2cb903da3d7ca40a54d96cc759eae16deb19b84d3aa0c10ce76eec906742904f515136b
7
+ data.tar.gz: 88de63e2ed3b799fdbf9dca3b415a0b812c98ac33eda8d3c895169b05bd05d7f7e107ffbb9840beafb409a2c937024c7cd7035683dd02ad6ae932ed9cc869e95
@@ -1,36 +1,33 @@
1
- // Backbone 1.2.3
1
+ // Backbone 1.3.3
2
2
  // https://github.com/jashkenas/backbone
3
3
  //
4
- // Copyright (c) Jeremy Ashkenas, DocumentCloud, and
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
- // obtaining a copy of this software and associated documentation
9
- // files (the "Software"), to deal in the Software without
10
- // restriction, including without limitation the rights to use,
11
- // copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- // copies of the Software, and to permit persons to whom the
13
- // Software is furnished to do so, subject to the following
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
- // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
- // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
- // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
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 == self && self) ||
33
- (typeof global == 'object' && global.global == 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.2.3';
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 separated event names by delegating them individually.
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
- context: context,
190
- ctx: obj,
191
- listening: listening
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 = function(obj, name, callback) {
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({ callback: callback, context: context, ctx: context || ctx, listening: listening });
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 = function(name, callback, context) {
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
- context: context,
243
- listeners: this._listeners
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 = function(obj, name, callback) {
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
- if (_.size(events)) return events;
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 = function(name, callback, context) {
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
- return this.on(events, void 0, context);
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 = function(obj, name, callback) {
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 = function(name) {
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, cb, args) {
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
- attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
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
- if (!this._validate(attrs, options)) return false;
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({}, _.defaults({validate: true}, options));
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 = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
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
- for (var i = 0; i < tail.length; i++) tail[i] = array[i + at];
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] : _.clone(models);
829
+ models = singular ? [models] : models.slice();
831
830
  var removed = this._removeModels(models, options);
832
- if (!options.silent && removed) this.trigger('update', this, options);
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 = _.defaults({}, options, setOptions);
844
- if (options.parse && !this._isModel(models)) models = this.parse(models, options);
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 && (at == null) && options.sort !== false;
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 (var i = 0; i < models.length; i++) {
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 != set.length || _.some(this.models, function(model, index) {
914
- return model !== set[index];
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) this.trigger('update', this, options);
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
- var id = this.modelId(this._isModel(obj) ? obj.attributes : obj);
990
- return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
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 _.invoke(this.models, 'get', attr);
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(model, resp, callbackOpts) {
1066
- if (wait) collection.add(model, callbackOpts);
1067
- if (success) success.call(callbackOpts.context, model, resp, callbackOpts);
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 (attrs) {
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.length ? removed : false;
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 (model) {
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 ((event === 'add' || event === 'remove') && collection !== this) return;
1166
- if (event === 'destroy') this.remove(model, options);
1167
- if (event === 'change') {
1168
- var prevId = this.modelId(model.previousAttributes());
1169
- var id = this.modelId(model.attributes);
1170
- if (prevId !== id) {
1171
- if (prevId != null) delete this._byId[prevId];
1172
- if (id != null) this._byId[id] = model;
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 = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 4,
1184
- foldl: 4, inject: 4, reduceRight: 4, foldr: 4, find: 3, detect: 3, filter: 3,
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': 'PATCH',
1469
+ 'patch': 'PATCH',
1441
1470
  'delete': 'DELETE',
1442
- 'read': 'GET'
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 root = path.slice(0, this.root.length - 1) + '/';
1600
- return root === this.root;
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 root = this.root.slice(0, -1) || '/';
1673
- this.location.replace(root + '#' + this.getPath());
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 (eventName, listener) {
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 (eventName, listener) {
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 root = this.root;
1826
+ var rootPath = this.root;
1798
1827
  if (fragment === '' || fragment.charAt(0) === '?') {
1799
- root = root.slice(0, -1) || '/';
1828
+ rootPath = rootPath.slice(0, -1) || '/';
1800
1829
  }
1801
- var url = root + fragment;
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 && (fragment !== this.getHash(this.iframe.contentWindow))) {
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
- var Surrogate = function(){ this.constructor = child; };
1881
- Surrogate.prototype = parent.prototype;
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
+ });