backbone-rails 1.1.0 → 1.1.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.
- data/vendor/assets/javascripts/backbone.js +94 -67
- data/vendor/assets/javascripts/underscore.js +150 -83
- metadata +13 -9
- checksums.yaml +0 -7
@@ -1,20 +1,35 @@
|
|
1
|
-
// Backbone.js 1.1.
|
1
|
+
// Backbone.js 1.1.2
|
2
2
|
|
3
|
-
// (c) 2010-
|
4
|
-
// (c) 2011-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
3
|
+
// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
5
4
|
// Backbone may be freely distributed under the MIT license.
|
6
5
|
// For all details and documentation:
|
7
6
|
// http://backbonejs.org
|
8
7
|
|
9
|
-
(function(){
|
8
|
+
(function(root, factory) {
|
9
|
+
|
10
|
+
// Set up Backbone appropriately for the environment. Start with AMD.
|
11
|
+
if (typeof define === 'function' && define.amd) {
|
12
|
+
define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
|
13
|
+
// Export global even in AMD case in case this script is loaded with
|
14
|
+
// others that may still expect a global Backbone.
|
15
|
+
root.Backbone = factory(root, exports, _, $);
|
16
|
+
});
|
17
|
+
|
18
|
+
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
|
19
|
+
} else if (typeof exports !== 'undefined') {
|
20
|
+
var _ = require('underscore');
|
21
|
+
factory(root, exports, _);
|
22
|
+
|
23
|
+
// Finally, as a browser global.
|
24
|
+
} else {
|
25
|
+
root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
|
26
|
+
}
|
27
|
+
|
28
|
+
}(this, function(root, Backbone, _, $) {
|
10
29
|
|
11
30
|
// Initial Setup
|
12
31
|
// -------------
|
13
32
|
|
14
|
-
// Save a reference to the global object (`window` in the browser, `exports`
|
15
|
-
// on the server).
|
16
|
-
var root = this;
|
17
|
-
|
18
33
|
// Save the previous value of the `Backbone` variable, so that it can be
|
19
34
|
// restored later on, if `noConflict` is used.
|
20
35
|
var previousBackbone = root.Backbone;
|
@@ -25,25 +40,12 @@
|
|
25
40
|
var slice = array.slice;
|
26
41
|
var splice = array.splice;
|
27
42
|
|
28
|
-
// The top-level namespace. All public Backbone classes and modules will
|
29
|
-
// be attached to this. Exported for both the browser and the server.
|
30
|
-
var Backbone;
|
31
|
-
if (typeof exports !== 'undefined') {
|
32
|
-
Backbone = exports;
|
33
|
-
} else {
|
34
|
-
Backbone = root.Backbone = {};
|
35
|
-
}
|
36
|
-
|
37
43
|
// Current version of the library. Keep in sync with `package.json`.
|
38
|
-
Backbone.VERSION = '1.1.
|
39
|
-
|
40
|
-
// Require Underscore, if we're on the server, and it's not already present.
|
41
|
-
var _ = root._;
|
42
|
-
if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
|
44
|
+
Backbone.VERSION = '1.1.2';
|
43
45
|
|
44
46
|
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
|
45
47
|
// the `$` variable.
|
46
|
-
Backbone.$ =
|
48
|
+
Backbone.$ = $;
|
47
49
|
|
48
50
|
// Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
|
49
51
|
// to its previous owner. Returns a reference to this Backbone object.
|
@@ -109,7 +111,7 @@
|
|
109
111
|
var retain, ev, events, names, i, l, j, k;
|
110
112
|
if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
|
111
113
|
if (!name && !callback && !context) {
|
112
|
-
this._events =
|
114
|
+
this._events = void 0;
|
113
115
|
return this;
|
114
116
|
}
|
115
117
|
names = name ? [name] : _.keys(this._events);
|
@@ -205,7 +207,7 @@
|
|
205
207
|
case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
|
206
208
|
case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
|
207
209
|
case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
|
208
|
-
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
|
210
|
+
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
|
209
211
|
}
|
210
212
|
};
|
211
213
|
|
@@ -350,7 +352,7 @@
|
|
350
352
|
|
351
353
|
// Trigger all relevant attribute changes.
|
352
354
|
if (!silent) {
|
353
|
-
if (changes.length) this._pending =
|
355
|
+
if (changes.length) this._pending = options;
|
354
356
|
for (var i = 0, l = changes.length; i < l; i++) {
|
355
357
|
this.trigger('change:' + changes[i], this, current[changes[i]], options);
|
356
358
|
}
|
@@ -361,6 +363,7 @@
|
|
361
363
|
if (changing) return this;
|
362
364
|
if (!silent) {
|
363
365
|
while (this._pending) {
|
366
|
+
options = this._pending;
|
364
367
|
this._pending = false;
|
365
368
|
this.trigger('change', this, options);
|
366
369
|
}
|
@@ -528,9 +531,12 @@
|
|
528
531
|
// using Backbone's restful methods, override this to change the endpoint
|
529
532
|
// that will be called.
|
530
533
|
url: function() {
|
531
|
-
var base =
|
534
|
+
var base =
|
535
|
+
_.result(this, 'urlRoot') ||
|
536
|
+
_.result(this.collection, 'url') ||
|
537
|
+
urlError();
|
532
538
|
if (this.isNew()) return base;
|
533
|
-
return base
|
539
|
+
return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id);
|
534
540
|
},
|
535
541
|
|
536
542
|
// **parse** converts a response into the hash of attributes to be `set` on
|
@@ -546,7 +552,7 @@
|
|
546
552
|
|
547
553
|
// A model is new if it has never been saved to the server, and lacks an id.
|
548
554
|
isNew: function() {
|
549
|
-
return this.
|
555
|
+
return !this.has(this.idAttribute);
|
550
556
|
},
|
551
557
|
|
552
558
|
// Check if the model is currently in a valid state.
|
@@ -650,7 +656,7 @@
|
|
650
656
|
options.index = index;
|
651
657
|
model.trigger('remove', model, this, options);
|
652
658
|
}
|
653
|
-
this._removeReference(model);
|
659
|
+
this._removeReference(model, options);
|
654
660
|
}
|
655
661
|
return singular ? models[0] : models;
|
656
662
|
},
|
@@ -676,11 +682,11 @@
|
|
676
682
|
// Turn bare objects into model references, and prevent invalid models
|
677
683
|
// from being added.
|
678
684
|
for (i = 0, l = models.length; i < l; i++) {
|
679
|
-
attrs = models[i];
|
685
|
+
attrs = models[i] || {};
|
680
686
|
if (attrs instanceof Model) {
|
681
687
|
id = model = attrs;
|
682
688
|
} else {
|
683
|
-
id = attrs[targetModel.prototype.idAttribute];
|
689
|
+
id = attrs[targetModel.prototype.idAttribute || 'id'];
|
684
690
|
}
|
685
691
|
|
686
692
|
// If a duplicate is found, prevent it from being added and
|
@@ -700,14 +706,13 @@
|
|
700
706
|
model = models[i] = this._prepareModel(attrs, options);
|
701
707
|
if (!model) continue;
|
702
708
|
toAdd.push(model);
|
703
|
-
|
704
|
-
// Listen to added models' events, and index models for lookup by
|
705
|
-
// `id` and by `cid`.
|
706
|
-
model.on('all', this._onModelEvent, this);
|
707
|
-
this._byId[model.cid] = model;
|
708
|
-
if (model.id != null) this._byId[model.id] = model;
|
709
|
+
this._addReference(model, options);
|
709
710
|
}
|
710
|
-
|
711
|
+
|
712
|
+
// Do not add multiple models with the same `id`.
|
713
|
+
model = existing || model;
|
714
|
+
if (order && (model.isNew() || !modelMap[model.id])) order.push(model);
|
715
|
+
modelMap[model.id] = true;
|
711
716
|
}
|
712
717
|
|
713
718
|
// Remove nonexistent models if appropriate.
|
@@ -757,7 +762,7 @@
|
|
757
762
|
reset: function(models, options) {
|
758
763
|
options || (options = {});
|
759
764
|
for (var i = 0, l = this.models.length; i < l; i++) {
|
760
|
-
this._removeReference(this.models[i]);
|
765
|
+
this._removeReference(this.models[i], options);
|
761
766
|
}
|
762
767
|
options.previousModels = this.models;
|
763
768
|
this._reset();
|
@@ -798,7 +803,7 @@
|
|
798
803
|
// Get a model from the set by id.
|
799
804
|
get: function(obj) {
|
800
805
|
if (obj == null) return void 0;
|
801
|
-
return this._byId[obj
|
806
|
+
return this._byId[obj] || this._byId[obj.id] || this._byId[obj.cid];
|
802
807
|
},
|
803
808
|
|
804
809
|
// Get the model at the given index.
|
@@ -874,7 +879,7 @@
|
|
874
879
|
if (!options.wait) this.add(model, options);
|
875
880
|
var collection = this;
|
876
881
|
var success = options.success;
|
877
|
-
options.success = function(model, resp
|
882
|
+
options.success = function(model, resp) {
|
878
883
|
if (options.wait) collection.add(model, options);
|
879
884
|
if (success) success(model, resp, options);
|
880
885
|
};
|
@@ -904,10 +909,7 @@
|
|
904
909
|
// Prepare a hash of attributes (or other model) to be added to this
|
905
910
|
// collection.
|
906
911
|
_prepareModel: function(attrs, options) {
|
907
|
-
if (attrs instanceof Model)
|
908
|
-
if (!attrs.collection) attrs.collection = this;
|
909
|
-
return attrs;
|
910
|
-
}
|
912
|
+
if (attrs instanceof Model) return attrs;
|
911
913
|
options = options ? _.clone(options) : {};
|
912
914
|
options.collection = this;
|
913
915
|
var model = new this.model(attrs, options);
|
@@ -916,8 +918,16 @@
|
|
916
918
|
return false;
|
917
919
|
},
|
918
920
|
|
921
|
+
// Internal method to create a model's ties to a collection.
|
922
|
+
_addReference: function(model, options) {
|
923
|
+
this._byId[model.cid] = model;
|
924
|
+
if (model.id != null) this._byId[model.id] = model;
|
925
|
+
if (!model.collection) model.collection = this;
|
926
|
+
model.on('all', this._onModelEvent, this);
|
927
|
+
},
|
928
|
+
|
919
929
|
// Internal method to sever a model's ties to a collection.
|
920
|
-
_removeReference: function(model) {
|
930
|
+
_removeReference: function(model, options) {
|
921
931
|
if (this === model.collection) delete model.collection;
|
922
932
|
model.off('all', this._onModelEvent, this);
|
923
933
|
},
|
@@ -946,7 +956,7 @@
|
|
946
956
|
'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
|
947
957
|
'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
|
948
958
|
'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
|
949
|
-
'lastIndexOf', 'isEmpty', 'chain'];
|
959
|
+
'lastIndexOf', 'isEmpty', 'chain', 'sample'];
|
950
960
|
|
951
961
|
// Mix in each Underscore method as a proxy to `Collection#models`.
|
952
962
|
_.each(methods, function(method) {
|
@@ -958,7 +968,7 @@
|
|
958
968
|
});
|
959
969
|
|
960
970
|
// Underscore methods that take a property name as an argument.
|
961
|
-
var attributeMethods = ['groupBy', 'countBy', 'sortBy'];
|
971
|
+
var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy'];
|
962
972
|
|
963
973
|
// Use attributes instead of properties.
|
964
974
|
_.each(attributeMethods, function(method) {
|
@@ -1180,7 +1190,9 @@
|
|
1180
1190
|
return xhr;
|
1181
1191
|
};
|
1182
1192
|
|
1183
|
-
var noXhrPatch =
|
1193
|
+
var noXhrPatch =
|
1194
|
+
typeof window !== 'undefined' && !!window.ActiveXObject &&
|
1195
|
+
!(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
|
1184
1196
|
|
1185
1197
|
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
|
1186
1198
|
var methodMap = {
|
@@ -1239,7 +1251,7 @@
|
|
1239
1251
|
var router = this;
|
1240
1252
|
Backbone.history.route(route, function(fragment) {
|
1241
1253
|
var args = router._extractParameters(route, fragment);
|
1242
|
-
|
1254
|
+
router.execute(callback, args);
|
1243
1255
|
router.trigger.apply(router, ['route:' + name].concat(args));
|
1244
1256
|
router.trigger('route', name, args);
|
1245
1257
|
Backbone.history.trigger('route', router, name, args);
|
@@ -1247,6 +1259,12 @@
|
|
1247
1259
|
return this;
|
1248
1260
|
},
|
1249
1261
|
|
1262
|
+
// Execute a route handler with the provided parameters. This is an
|
1263
|
+
// excellent place to do pre-route setup or post-route cleanup.
|
1264
|
+
execute: function(callback, args) {
|
1265
|
+
if (callback) callback.apply(this, args);
|
1266
|
+
},
|
1267
|
+
|
1250
1268
|
// Simple proxy to `Backbone.history` to save a fragment into the history.
|
1251
1269
|
navigate: function(fragment, options) {
|
1252
1270
|
Backbone.history.navigate(fragment, options);
|
@@ -1271,10 +1289,10 @@
|
|
1271
1289
|
route = route.replace(escapeRegExp, '\\$&')
|
1272
1290
|
.replace(optionalParam, '(?:$1)?')
|
1273
1291
|
.replace(namedParam, function(match, optional) {
|
1274
|
-
return optional ? match : '([
|
1292
|
+
return optional ? match : '([^/?]+)';
|
1275
1293
|
})
|
1276
|
-
.replace(splatParam, '(
|
1277
|
-
return new RegExp('^' + route + '
|
1294
|
+
.replace(splatParam, '([^?]*?)');
|
1295
|
+
return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
|
1278
1296
|
},
|
1279
1297
|
|
1280
1298
|
// Given a route, and a URL fragment that it matches, return the array of
|
@@ -1282,7 +1300,9 @@
|
|
1282
1300
|
// treated as `null` to normalize cross-browser behavior.
|
1283
1301
|
_extractParameters: function(route, fragment) {
|
1284
1302
|
var params = route.exec(fragment).slice(1);
|
1285
|
-
return _.map(params, function(param) {
|
1303
|
+
return _.map(params, function(param, i) {
|
1304
|
+
// Don't decode the search params.
|
1305
|
+
if (i === params.length - 1) return param || null;
|
1286
1306
|
return param ? decodeURIComponent(param) : null;
|
1287
1307
|
});
|
1288
1308
|
}
|
@@ -1320,8 +1340,8 @@
|
|
1320
1340
|
// Cached regex for removing a trailing slash.
|
1321
1341
|
var trailingSlash = /\/$/;
|
1322
1342
|
|
1323
|
-
// Cached regex for stripping urls of hash
|
1324
|
-
var pathStripper =
|
1343
|
+
// Cached regex for stripping urls of hash.
|
1344
|
+
var pathStripper = /#.*$/;
|
1325
1345
|
|
1326
1346
|
// Has the history handling already been started?
|
1327
1347
|
History.started = false;
|
@@ -1333,6 +1353,11 @@
|
|
1333
1353
|
// twenty times a second.
|
1334
1354
|
interval: 50,
|
1335
1355
|
|
1356
|
+
// Are we at the app root?
|
1357
|
+
atRoot: function() {
|
1358
|
+
return this.location.pathname.replace(/[^\/]$/, '$&/') === this.root;
|
1359
|
+
},
|
1360
|
+
|
1336
1361
|
// Gets the true hash value. Cannot use location.hash directly due to bug
|
1337
1362
|
// in Firefox where location.hash will always be decoded.
|
1338
1363
|
getHash: function(window) {
|
@@ -1345,7 +1370,7 @@
|
|
1345
1370
|
getFragment: function(fragment, forcePushState) {
|
1346
1371
|
if (fragment == null) {
|
1347
1372
|
if (this._hasPushState || !this._wantsHashChange || forcePushState) {
|
1348
|
-
fragment = this.location.pathname;
|
1373
|
+
fragment = decodeURI(this.location.pathname + this.location.search);
|
1349
1374
|
var root = this.root.replace(trailingSlash, '');
|
1350
1375
|
if (!fragment.indexOf(root)) fragment = fragment.slice(root.length);
|
1351
1376
|
} else {
|
@@ -1376,7 +1401,8 @@
|
|
1376
1401
|
this.root = ('/' + this.root + '/').replace(rootStripper, '/');
|
1377
1402
|
|
1378
1403
|
if (oldIE && this._wantsHashChange) {
|
1379
|
-
|
1404
|
+
var frame = Backbone.$('<iframe src="javascript:0" tabindex="-1">');
|
1405
|
+
this.iframe = frame.hide().appendTo('body')[0].contentWindow;
|
1380
1406
|
this.navigate(fragment);
|
1381
1407
|
}
|
1382
1408
|
|
@@ -1394,7 +1420,6 @@
|
|
1394
1420
|
// opened by a non-pushState browser.
|
1395
1421
|
this.fragment = fragment;
|
1396
1422
|
var loc = this.location;
|
1397
|
-
var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
|
1398
1423
|
|
1399
1424
|
// Transition from hashChange to pushState or vice versa if both are
|
1400
1425
|
// requested.
|
@@ -1402,17 +1427,17 @@
|
|
1402
1427
|
|
1403
1428
|
// If we've started off with a route from a `pushState`-enabled
|
1404
1429
|
// browser, but we're currently in a browser that doesn't support it...
|
1405
|
-
if (!this._hasPushState && !atRoot) {
|
1430
|
+
if (!this._hasPushState && !this.atRoot()) {
|
1406
1431
|
this.fragment = this.getFragment(null, true);
|
1407
|
-
this.location.replace(this.root +
|
1432
|
+
this.location.replace(this.root + '#' + this.fragment);
|
1408
1433
|
// Return immediately as browser will do redirect to new url
|
1409
1434
|
return true;
|
1410
1435
|
|
1411
1436
|
// Or if we've started out with a hash-based route, but we're currently
|
1412
1437
|
// in a browser where it could be `pushState`-based instead...
|
1413
|
-
} else if (this._hasPushState && atRoot && loc.hash) {
|
1438
|
+
} else if (this._hasPushState && this.atRoot() && loc.hash) {
|
1414
1439
|
this.fragment = this.getHash().replace(routeStripper, '');
|
1415
|
-
this.history.replaceState({}, document.title, this.root + this.fragment
|
1440
|
+
this.history.replaceState({}, document.title, this.root + this.fragment);
|
1416
1441
|
}
|
1417
1442
|
|
1418
1443
|
}
|
@@ -1424,7 +1449,7 @@
|
|
1424
1449
|
// but possibly useful for unit testing Routers.
|
1425
1450
|
stop: function() {
|
1426
1451
|
Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
|
1427
|
-
clearInterval(this._checkUrlInterval);
|
1452
|
+
if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
|
1428
1453
|
History.started = false;
|
1429
1454
|
},
|
1430
1455
|
|
@@ -1472,7 +1497,7 @@
|
|
1472
1497
|
|
1473
1498
|
var url = this.root + (fragment = this.getFragment(fragment || ''));
|
1474
1499
|
|
1475
|
-
// Strip the
|
1500
|
+
// Strip the hash for matching.
|
1476
1501
|
fragment = fragment.replace(pathStripper, '');
|
1477
1502
|
|
1478
1503
|
if (this.fragment === fragment) return;
|
@@ -1578,4 +1603,6 @@
|
|
1578
1603
|
};
|
1579
1604
|
};
|
1580
1605
|
|
1581
|
-
|
1606
|
+
return Backbone;
|
1607
|
+
|
1608
|
+
}));
|
@@ -1,6 +1,6 @@
|
|
1
|
-
// Underscore.js 1.
|
1
|
+
// Underscore.js 1.6.0
|
2
2
|
// http://underscorejs.org
|
3
|
-
// (c) 2009-
|
3
|
+
// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
4
4
|
// Underscore may be freely distributed under the MIT license.
|
5
5
|
|
6
6
|
(function() {
|
@@ -65,7 +65,7 @@
|
|
65
65
|
}
|
66
66
|
|
67
67
|
// Current version.
|
68
|
-
_.VERSION = '1.
|
68
|
+
_.VERSION = '1.6.0';
|
69
69
|
|
70
70
|
// Collection Functions
|
71
71
|
// --------------------
|
@@ -74,7 +74,7 @@
|
|
74
74
|
// Handles objects with the built-in `forEach`, arrays, and raw objects.
|
75
75
|
// Delegates to **ECMAScript 5**'s native `forEach` if available.
|
76
76
|
var each = _.each = _.forEach = function(obj, iterator, context) {
|
77
|
-
if (obj == null) return;
|
77
|
+
if (obj == null) return obj;
|
78
78
|
if (nativeForEach && obj.forEach === nativeForEach) {
|
79
79
|
obj.forEach(iterator, context);
|
80
80
|
} else if (obj.length === +obj.length) {
|
@@ -87,6 +87,7 @@
|
|
87
87
|
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
|
88
88
|
}
|
89
89
|
}
|
90
|
+
return obj;
|
90
91
|
};
|
91
92
|
|
92
93
|
// Return the results of applying the iterator to each element.
|
@@ -152,10 +153,10 @@
|
|
152
153
|
};
|
153
154
|
|
154
155
|
// Return the first value which passes a truth test. Aliased as `detect`.
|
155
|
-
_.find = _.detect = function(obj,
|
156
|
+
_.find = _.detect = function(obj, predicate, context) {
|
156
157
|
var result;
|
157
158
|
any(obj, function(value, index, list) {
|
158
|
-
if (
|
159
|
+
if (predicate.call(context, value, index, list)) {
|
159
160
|
result = value;
|
160
161
|
return true;
|
161
162
|
}
|
@@ -166,33 +167,33 @@
|
|
166
167
|
// Return all the elements that pass a truth test.
|
167
168
|
// Delegates to **ECMAScript 5**'s native `filter` if available.
|
168
169
|
// Aliased as `select`.
|
169
|
-
_.filter = _.select = function(obj,
|
170
|
+
_.filter = _.select = function(obj, predicate, context) {
|
170
171
|
var results = [];
|
171
172
|
if (obj == null) return results;
|
172
|
-
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(
|
173
|
+
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
|
173
174
|
each(obj, function(value, index, list) {
|
174
|
-
if (
|
175
|
+
if (predicate.call(context, value, index, list)) results.push(value);
|
175
176
|
});
|
176
177
|
return results;
|
177
178
|
};
|
178
179
|
|
179
180
|
// Return all the elements for which a truth test fails.
|
180
|
-
_.reject = function(obj,
|
181
|
+
_.reject = function(obj, predicate, context) {
|
181
182
|
return _.filter(obj, function(value, index, list) {
|
182
|
-
return !
|
183
|
+
return !predicate.call(context, value, index, list);
|
183
184
|
}, context);
|
184
185
|
};
|
185
186
|
|
186
187
|
// Determine whether all of the elements match a truth test.
|
187
188
|
// Delegates to **ECMAScript 5**'s native `every` if available.
|
188
189
|
// Aliased as `all`.
|
189
|
-
_.every = _.all = function(obj,
|
190
|
-
|
190
|
+
_.every = _.all = function(obj, predicate, context) {
|
191
|
+
predicate || (predicate = _.identity);
|
191
192
|
var result = true;
|
192
193
|
if (obj == null) return result;
|
193
|
-
if (nativeEvery && obj.every === nativeEvery) return obj.every(
|
194
|
+
if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
|
194
195
|
each(obj, function(value, index, list) {
|
195
|
-
if (!(result = result &&
|
196
|
+
if (!(result = result && predicate.call(context, value, index, list))) return breaker;
|
196
197
|
});
|
197
198
|
return !!result;
|
198
199
|
};
|
@@ -200,13 +201,13 @@
|
|
200
201
|
// Determine if at least one element in the object matches a truth test.
|
201
202
|
// Delegates to **ECMAScript 5**'s native `some` if available.
|
202
203
|
// Aliased as `any`.
|
203
|
-
var any = _.some = _.any = function(obj,
|
204
|
-
|
204
|
+
var any = _.some = _.any = function(obj, predicate, context) {
|
205
|
+
predicate || (predicate = _.identity);
|
205
206
|
var result = false;
|
206
207
|
if (obj == null) return result;
|
207
|
-
if (nativeSome && obj.some === nativeSome) return obj.some(
|
208
|
+
if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
|
208
209
|
each(obj, function(value, index, list) {
|
209
|
-
if (result || (result =
|
210
|
+
if (result || (result = predicate.call(context, value, index, list))) return breaker;
|
210
211
|
});
|
211
212
|
return !!result;
|
212
213
|
};
|
@@ -232,25 +233,19 @@
|
|
232
233
|
|
233
234
|
// Convenience version of a common use case of `map`: fetching a property.
|
234
235
|
_.pluck = function(obj, key) {
|
235
|
-
return _.map(obj,
|
236
|
+
return _.map(obj, _.property(key));
|
236
237
|
};
|
237
238
|
|
238
239
|
// Convenience version of a common use case of `filter`: selecting only objects
|
239
240
|
// containing specific `key:value` pairs.
|
240
|
-
_.where = function(obj, attrs
|
241
|
-
|
242
|
-
return _[first ? 'find' : 'filter'](obj, function(value) {
|
243
|
-
for (var key in attrs) {
|
244
|
-
if (attrs[key] !== value[key]) return false;
|
245
|
-
}
|
246
|
-
return true;
|
247
|
-
});
|
241
|
+
_.where = function(obj, attrs) {
|
242
|
+
return _.filter(obj, _.matches(attrs));
|
248
243
|
};
|
249
244
|
|
250
245
|
// Convenience version of a common use case of `find`: getting the first object
|
251
246
|
// containing specific `key:value` pairs.
|
252
247
|
_.findWhere = function(obj, attrs) {
|
253
|
-
return _.
|
248
|
+
return _.find(obj, _.matches(attrs));
|
254
249
|
};
|
255
250
|
|
256
251
|
// Return the maximum element or (element-based computation).
|
@@ -260,13 +255,15 @@
|
|
260
255
|
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
|
261
256
|
return Math.max.apply(Math, obj);
|
262
257
|
}
|
263
|
-
|
264
|
-
var result = {computed : -Infinity, value: -Infinity};
|
258
|
+
var result = -Infinity, lastComputed = -Infinity;
|
265
259
|
each(obj, function(value, index, list) {
|
266
260
|
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
267
|
-
computed >
|
261
|
+
if (computed > lastComputed) {
|
262
|
+
result = value;
|
263
|
+
lastComputed = computed;
|
264
|
+
}
|
268
265
|
});
|
269
|
-
return result
|
266
|
+
return result;
|
270
267
|
};
|
271
268
|
|
272
269
|
// Return the minimum element (or element-based computation).
|
@@ -274,17 +271,19 @@
|
|
274
271
|
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
|
275
272
|
return Math.min.apply(Math, obj);
|
276
273
|
}
|
277
|
-
|
278
|
-
var result = {computed : Infinity, value: Infinity};
|
274
|
+
var result = Infinity, lastComputed = Infinity;
|
279
275
|
each(obj, function(value, index, list) {
|
280
276
|
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
281
|
-
computed <
|
277
|
+
if (computed < lastComputed) {
|
278
|
+
result = value;
|
279
|
+
lastComputed = computed;
|
280
|
+
}
|
282
281
|
});
|
283
|
-
return result
|
282
|
+
return result;
|
284
283
|
};
|
285
284
|
|
286
285
|
// Shuffle an array, using the modern version of the
|
287
|
-
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher
|
286
|
+
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
288
287
|
_.shuffle = function(obj) {
|
289
288
|
var rand;
|
290
289
|
var index = 0;
|
@@ -297,11 +296,12 @@
|
|
297
296
|
return shuffled;
|
298
297
|
};
|
299
298
|
|
300
|
-
// Sample **n** random values from
|
301
|
-
// If **n** is not specified, returns a single random element
|
299
|
+
// Sample **n** random values from a collection.
|
300
|
+
// If **n** is not specified, returns a single random element.
|
302
301
|
// The internal `guard` argument allows it to work with `map`.
|
303
302
|
_.sample = function(obj, n, guard) {
|
304
|
-
if (
|
303
|
+
if (n == null || guard) {
|
304
|
+
if (obj.length !== +obj.length) obj = _.values(obj);
|
305
305
|
return obj[_.random(obj.length - 1)];
|
306
306
|
}
|
307
307
|
return _.shuffle(obj).slice(0, Math.max(0, n));
|
@@ -309,12 +309,14 @@
|
|
309
309
|
|
310
310
|
// An internal function to generate lookup iterators.
|
311
311
|
var lookupIterator = function(value) {
|
312
|
-
|
312
|
+
if (value == null) return _.identity;
|
313
|
+
if (_.isFunction(value)) return value;
|
314
|
+
return _.property(value);
|
313
315
|
};
|
314
316
|
|
315
317
|
// Sort the object's values by a criterion produced by an iterator.
|
316
|
-
_.sortBy = function(obj,
|
317
|
-
|
318
|
+
_.sortBy = function(obj, iterator, context) {
|
319
|
+
iterator = lookupIterator(iterator);
|
318
320
|
return _.pluck(_.map(obj, function(value, index, list) {
|
319
321
|
return {
|
320
322
|
value: value,
|
@@ -334,9 +336,9 @@
|
|
334
336
|
|
335
337
|
// An internal function used for aggregate "group by" operations.
|
336
338
|
var group = function(behavior) {
|
337
|
-
return function(obj,
|
339
|
+
return function(obj, iterator, context) {
|
338
340
|
var result = {};
|
339
|
-
|
341
|
+
iterator = lookupIterator(iterator);
|
340
342
|
each(obj, function(value, index) {
|
341
343
|
var key = iterator.call(context, value, index, obj);
|
342
344
|
behavior(result, key, value);
|
@@ -348,7 +350,7 @@
|
|
348
350
|
// Groups the object's values by a criterion. Pass either a string attribute
|
349
351
|
// to group by, or a function that returns the criterion.
|
350
352
|
_.groupBy = group(function(result, key, value) {
|
351
|
-
|
353
|
+
_.has(result, key) ? result[key].push(value) : result[key] = [value];
|
352
354
|
});
|
353
355
|
|
354
356
|
// Indexes the object's values by a criterion, similar to `groupBy`, but for
|
@@ -367,7 +369,7 @@
|
|
367
369
|
// Use a comparator function to figure out the smallest index at which
|
368
370
|
// an object should be inserted so as to maintain order. Uses binary search.
|
369
371
|
_.sortedIndex = function(array, obj, iterator, context) {
|
370
|
-
iterator =
|
372
|
+
iterator = lookupIterator(iterator);
|
371
373
|
var value = iterator.call(context, obj);
|
372
374
|
var low = 0, high = array.length;
|
373
375
|
while (low < high) {
|
@@ -399,7 +401,9 @@
|
|
399
401
|
// allows it to work with `_.map`.
|
400
402
|
_.first = _.head = _.take = function(array, n, guard) {
|
401
403
|
if (array == null) return void 0;
|
402
|
-
|
404
|
+
if ((n == null) || guard) return array[0];
|
405
|
+
if (n < 0) return [];
|
406
|
+
return slice.call(array, 0, n);
|
403
407
|
};
|
404
408
|
|
405
409
|
// Returns everything but the last entry of the array. Especially useful on
|
@@ -414,11 +418,8 @@
|
|
414
418
|
// values in the array. The **guard** check allows it to work with `_.map`.
|
415
419
|
_.last = function(array, n, guard) {
|
416
420
|
if (array == null) return void 0;
|
417
|
-
if ((n == null) || guard)
|
418
|
-
|
419
|
-
} else {
|
420
|
-
return slice.call(array, Math.max(array.length - n, 0));
|
421
|
-
}
|
421
|
+
if ((n == null) || guard) return array[array.length - 1];
|
422
|
+
return slice.call(array, Math.max(array.length - n, 0));
|
422
423
|
};
|
423
424
|
|
424
425
|
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
|
@@ -459,6 +460,16 @@
|
|
459
460
|
return _.difference(array, slice.call(arguments, 1));
|
460
461
|
};
|
461
462
|
|
463
|
+
// Split an array into two arrays: one whose elements all satisfy the given
|
464
|
+
// predicate, and one whose elements all do not satisfy the predicate.
|
465
|
+
_.partition = function(array, predicate) {
|
466
|
+
var pass = [], fail = [];
|
467
|
+
each(array, function(elem) {
|
468
|
+
(predicate(elem) ? pass : fail).push(elem);
|
469
|
+
});
|
470
|
+
return [pass, fail];
|
471
|
+
};
|
472
|
+
|
462
473
|
// Produce a duplicate-free version of the array. If the array has already
|
463
474
|
// been sorted, you have the option of using a faster algorithm.
|
464
475
|
// Aliased as `unique`.
|
@@ -492,7 +503,7 @@
|
|
492
503
|
var rest = slice.call(arguments, 1);
|
493
504
|
return _.filter(_.uniq(array), function(item) {
|
494
505
|
return _.every(rest, function(other) {
|
495
|
-
return _.
|
506
|
+
return _.contains(other, item);
|
496
507
|
});
|
497
508
|
});
|
498
509
|
};
|
@@ -507,7 +518,7 @@
|
|
507
518
|
// Zip together multiple lists into a single array -- elements that share
|
508
519
|
// an index go together.
|
509
520
|
_.zip = function() {
|
510
|
-
var length = _.max(_.pluck(arguments,
|
521
|
+
var length = _.max(_.pluck(arguments, 'length').concat(0));
|
511
522
|
var results = new Array(length);
|
512
523
|
for (var i = 0; i < length; i++) {
|
513
524
|
results[i] = _.pluck(arguments, '' + i);
|
@@ -613,19 +624,27 @@
|
|
613
624
|
};
|
614
625
|
|
615
626
|
// Partially apply a function by creating a version that has had some of its
|
616
|
-
// arguments pre-filled, without changing its dynamic `this` context.
|
627
|
+
// arguments pre-filled, without changing its dynamic `this` context. _ acts
|
628
|
+
// as a placeholder, allowing any combination of arguments to be pre-filled.
|
617
629
|
_.partial = function(func) {
|
618
|
-
var
|
630
|
+
var boundArgs = slice.call(arguments, 1);
|
619
631
|
return function() {
|
620
|
-
|
632
|
+
var position = 0;
|
633
|
+
var args = boundArgs.slice();
|
634
|
+
for (var i = 0, length = args.length; i < length; i++) {
|
635
|
+
if (args[i] === _) args[i] = arguments[position++];
|
636
|
+
}
|
637
|
+
while (position < arguments.length) args.push(arguments[position++]);
|
638
|
+
return func.apply(this, args);
|
621
639
|
};
|
622
640
|
};
|
623
641
|
|
624
|
-
// Bind
|
625
|
-
//
|
642
|
+
// Bind a number of an object's methods to that object. Remaining arguments
|
643
|
+
// are the method names to be bound. Useful for ensuring that all callbacks
|
644
|
+
// defined on an object belong to it.
|
626
645
|
_.bindAll = function(obj) {
|
627
646
|
var funcs = slice.call(arguments, 1);
|
628
|
-
if (funcs.length === 0) throw new Error(
|
647
|
+
if (funcs.length === 0) throw new Error('bindAll must be passed function names');
|
629
648
|
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
|
630
649
|
return obj;
|
631
650
|
};
|
@@ -664,12 +683,13 @@
|
|
664
683
|
var previous = 0;
|
665
684
|
options || (options = {});
|
666
685
|
var later = function() {
|
667
|
-
previous = options.leading === false ? 0 :
|
686
|
+
previous = options.leading === false ? 0 : _.now();
|
668
687
|
timeout = null;
|
669
688
|
result = func.apply(context, args);
|
689
|
+
context = args = null;
|
670
690
|
};
|
671
691
|
return function() {
|
672
|
-
var now =
|
692
|
+
var now = _.now();
|
673
693
|
if (!previous && options.leading === false) previous = now;
|
674
694
|
var remaining = wait - (now - previous);
|
675
695
|
context = this;
|
@@ -679,6 +699,7 @@
|
|
679
699
|
timeout = null;
|
680
700
|
previous = now;
|
681
701
|
result = func.apply(context, args);
|
702
|
+
context = args = null;
|
682
703
|
} else if (!timeout && options.trailing !== false) {
|
683
704
|
timeout = setTimeout(later, remaining);
|
684
705
|
}
|
@@ -692,24 +713,33 @@
|
|
692
713
|
// leading edge, instead of the trailing.
|
693
714
|
_.debounce = function(func, wait, immediate) {
|
694
715
|
var timeout, args, context, timestamp, result;
|
716
|
+
|
717
|
+
var later = function() {
|
718
|
+
var last = _.now() - timestamp;
|
719
|
+
if (last < wait) {
|
720
|
+
timeout = setTimeout(later, wait - last);
|
721
|
+
} else {
|
722
|
+
timeout = null;
|
723
|
+
if (!immediate) {
|
724
|
+
result = func.apply(context, args);
|
725
|
+
context = args = null;
|
726
|
+
}
|
727
|
+
}
|
728
|
+
};
|
729
|
+
|
695
730
|
return function() {
|
696
731
|
context = this;
|
697
732
|
args = arguments;
|
698
|
-
timestamp =
|
699
|
-
var later = function() {
|
700
|
-
var last = (new Date()) - timestamp;
|
701
|
-
if (last < wait) {
|
702
|
-
timeout = setTimeout(later, wait - last);
|
703
|
-
} else {
|
704
|
-
timeout = null;
|
705
|
-
if (!immediate) result = func.apply(context, args);
|
706
|
-
}
|
707
|
-
};
|
733
|
+
timestamp = _.now();
|
708
734
|
var callNow = immediate && !timeout;
|
709
735
|
if (!timeout) {
|
710
736
|
timeout = setTimeout(later, wait);
|
711
737
|
}
|
712
|
-
if (callNow)
|
738
|
+
if (callNow) {
|
739
|
+
result = func.apply(context, args);
|
740
|
+
context = args = null;
|
741
|
+
}
|
742
|
+
|
713
743
|
return result;
|
714
744
|
};
|
715
745
|
};
|
@@ -731,11 +761,7 @@
|
|
731
761
|
// allowing you to adjust arguments, run code before and after, and
|
732
762
|
// conditionally execute the original function.
|
733
763
|
_.wrap = function(func, wrapper) {
|
734
|
-
return
|
735
|
-
var args = [func];
|
736
|
-
push.apply(args, arguments);
|
737
|
-
return wrapper.apply(this, args);
|
738
|
-
};
|
764
|
+
return _.partial(wrapper, func);
|
739
765
|
};
|
740
766
|
|
741
767
|
// Returns a function that is the composition of a list of functions, each
|
@@ -765,8 +791,9 @@
|
|
765
791
|
|
766
792
|
// Retrieve the names of an object's properties.
|
767
793
|
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
768
|
-
_.keys =
|
769
|
-
if (
|
794
|
+
_.keys = function(obj) {
|
795
|
+
if (!_.isObject(obj)) return [];
|
796
|
+
if (nativeKeys) return nativeKeys(obj);
|
770
797
|
var keys = [];
|
771
798
|
for (var key in obj) if (_.has(obj, key)) keys.push(key);
|
772
799
|
return keys;
|
@@ -921,7 +948,8 @@
|
|
921
948
|
// from different frames are.
|
922
949
|
var aCtor = a.constructor, bCtor = b.constructor;
|
923
950
|
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
|
924
|
-
_.isFunction(bCtor) && (bCtor instanceof bCtor))
|
951
|
+
_.isFunction(bCtor) && (bCtor instanceof bCtor))
|
952
|
+
&& ('constructor' in a && 'constructor' in b)) {
|
925
953
|
return false;
|
926
954
|
}
|
927
955
|
// Add the first object to the stack of traversed objects.
|
@@ -1061,6 +1089,30 @@
|
|
1061
1089
|
return value;
|
1062
1090
|
};
|
1063
1091
|
|
1092
|
+
_.constant = function(value) {
|
1093
|
+
return function () {
|
1094
|
+
return value;
|
1095
|
+
};
|
1096
|
+
};
|
1097
|
+
|
1098
|
+
_.property = function(key) {
|
1099
|
+
return function(obj) {
|
1100
|
+
return obj[key];
|
1101
|
+
};
|
1102
|
+
};
|
1103
|
+
|
1104
|
+
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
|
1105
|
+
_.matches = function(attrs) {
|
1106
|
+
return function(obj) {
|
1107
|
+
if (obj === attrs) return true; //avoid comparing an object to itself.
|
1108
|
+
for (var key in attrs) {
|
1109
|
+
if (attrs[key] !== obj[key])
|
1110
|
+
return false;
|
1111
|
+
}
|
1112
|
+
return true;
|
1113
|
+
}
|
1114
|
+
};
|
1115
|
+
|
1064
1116
|
// Run a function **n** times.
|
1065
1117
|
_.times = function(n, iterator, context) {
|
1066
1118
|
var accum = Array(Math.max(0, n));
|
@@ -1077,6 +1129,9 @@
|
|
1077
1129
|
return min + Math.floor(Math.random() * (max - min + 1));
|
1078
1130
|
};
|
1079
1131
|
|
1132
|
+
// A (possibly faster) way to get the current timestamp as an integer.
|
1133
|
+
_.now = Date.now || function() { return new Date().getTime(); };
|
1134
|
+
|
1080
1135
|
// List of HTML entities for escaping.
|
1081
1136
|
var entityMap = {
|
1082
1137
|
escape: {
|
@@ -1273,4 +1328,16 @@
|
|
1273
1328
|
|
1274
1329
|
});
|
1275
1330
|
|
1331
|
+
// AMD registration happens at the end for compatibility with AMD loaders
|
1332
|
+
// that may not enforce next-turn semantics on modules. Even though general
|
1333
|
+
// practice for AMD registration is to be anonymous, underscore registers
|
1334
|
+
// as a named module because, like jQuery, it is a base library that is
|
1335
|
+
// popular enough to be bundled in a third party lib, but not be part of
|
1336
|
+
// an AMD load request. Those cases could generate an error when an
|
1337
|
+
// anonymous define() is called outside of a loader request.
|
1338
|
+
if (typeof define === 'function' && define.amd) {
|
1339
|
+
define('underscore', [], function() {
|
1340
|
+
return _;
|
1341
|
+
});
|
1342
|
+
}
|
1276
1343
|
}).call(this);
|
metadata
CHANGED
@@ -1,27 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backbone-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Alexander Flatter
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2014-
|
12
|
+
date: 2014-06-11 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rails
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- - '>='
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: 3.0.0
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- - '>='
|
27
|
+
- - ! '>='
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: 3.0.0
|
27
30
|
description: Ships backbone and underscore to your Rails 3.1 application through the
|
@@ -44,25 +47,26 @@ files:
|
|
44
47
|
- README.md
|
45
48
|
homepage: https://github.com/aflatter/backbone-rails
|
46
49
|
licenses: []
|
47
|
-
metadata: {}
|
48
50
|
post_install_message:
|
49
51
|
rdoc_options: []
|
50
52
|
require_paths:
|
51
53
|
- lib
|
52
54
|
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
53
56
|
requirements:
|
54
|
-
- - '>='
|
57
|
+
- - ! '>='
|
55
58
|
- !ruby/object:Gem::Version
|
56
59
|
version: '0'
|
57
60
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
58
62
|
requirements:
|
59
|
-
- - '>='
|
63
|
+
- - ! '>='
|
60
64
|
- !ruby/object:Gem::Version
|
61
65
|
version: 1.3.6
|
62
66
|
requirements: []
|
63
67
|
rubyforge_project:
|
64
|
-
rubygems_version:
|
68
|
+
rubygems_version: 1.8.23
|
65
69
|
signing_key:
|
66
|
-
specification_version:
|
70
|
+
specification_version: 3
|
67
71
|
summary: backbone and underscore for Rails
|
68
72
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 1915d7968e842a3fb966a315c8746acdc28d5478
|
4
|
-
data.tar.gz: 29859b0847514c85434204e33060bf08c8c6b3c6
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 7f81db49eb8c5c109d1ae6b4d75efe120f1d5447a66dbb8a18cf028c0d2d618a2a0629e7a9b219ca694d6d9dd0ae650f805c089385432b259cee2cbaba033385
|
7
|
-
data.tar.gz: 731a21c6332295da0dc143a3c5454bc3dd117d9dad3879640290620465f5e57c6e8edd1dbba8809f8b7ad5f436a3036cb3b7998ccc004372ae6a0b72b9c23ecc
|