backbone_extensions 0.0.25 → 0.0.26
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/lib/assets/javascripts/backbone.js +95 -68
- data/lib/backbone_extensions/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41065848bcb6d0904170efdcf9d0ab594e139a5b
|
4
|
+
data.tar.gz: c57e5fbe5d6dd6483fe8e9505058f0cf9359dd0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b58476dad803260f8f93c4cd335d07f4ba61057a02fb61dfab32981e97569ed55bf49b861acfe28b101edbc8df461867594762a1a463a2839be9a8057b748865
|
7
|
+
data.tar.gz: fce7ee30b61fbb97601ff7b6e30f2f2479c8da2bd08a7334ee09be1bb811f0dea105969049b6bdb56f7f8a20ca228b52b702885c05eddcebbd7d8988780181fd
|
@@ -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.
|
@@ -745,7 +750,7 @@
|
|
745
750
|
}
|
746
751
|
if (sort || (order && order.length)) this.trigger('sort', this, options);
|
747
752
|
}
|
748
|
-
|
753
|
+
|
749
754
|
// Return the added (or merged) model (or models).
|
750
755
|
return singular ? models[0] : models;
|
751
756
|
},
|
@@ -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
|
+
}));
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backbone_extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.26
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Dy
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-02-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fuubar
|