js_stack 1.5.0 → 1.6.0
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/CHANGELOG.md +6 -0
- data/README.md +4 -4
- data/lib/js_stack/version.rb +1 -1
- data/vendor/assets/javascripts/js_stack/base/marionette/{2.3.0.js → 2.3.1.js} +68 -111
- data/vendor/assets/javascripts/js_stack/base/marionette.js +1 -1
- data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.6.0.js +202 -0
- data/vendor/assets/javascripts/js_stack/plugins/backbone.virtualcollection.js +1 -1
- data/vendor/assets/javascripts/js_stack/plugins/underscore/string/3.0.1.js +1013 -0
- data/vendor/assets/javascripts/js_stack/plugins/underscore.string.js +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 109a21b1d4dbcac6bc91e568c3bce32477405e38
|
|
4
|
+
data.tar.gz: 064f5b1736ef2ac8c4f6a0ae072f211bdeb93749
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d60ef1d9ff3db827d27b746d19f4dcb0e63f20fb0eeeb2cd24338ae519d7e0193e31dfd7059535243aba873ee7d569d458c9004a9846b7dfc700b18d7b345d0f
|
|
7
|
+
data.tar.gz: faf2447bcb752361755b4ddcc7aeba9bcba99ae776f8ab1dbff1c7b6769f602aef4a19c97a720c54d085f6557cce35a0e82064a3f7f6abc971c367b0c959e547
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -48,7 +48,7 @@ Examples:
|
|
|
48
48
|
| Library | Versions | Changelog | Homepage |
|
|
49
49
|
| :-----: | :------: | :-------: | :------: |
|
|
50
50
|
| backbone | **1.1.2**, 1.0.0 | [changelog](http://backbonejs.org/#changelog) | [homepage](http://backbonejs.org/) |
|
|
51
|
-
| marionette | **2.3.
|
|
51
|
+
| marionette | **2.3.1**, 2.2.2, 2.1.0, 2.0.3, 1.8.8, 1.7.4, 1.6.4, 1.5.1, 1.4.1, 1.1.0 | [changelog](https://github.com/marionettejs/backbone.marionette/blob/master/changelog.md) | [homepage](http://marionettejs.com/) |
|
|
52
52
|
| underscore | **1.7.0**, 1.6.0, 1.5.2 | [changelog](http://underscorejs.org/#changelog) | [homepage](http://underscorejs.org/) |
|
|
53
53
|
| hamlcoffee | **1.16** | [changelog](https://github.com/netzpirat/haml_coffee_assets/blob/master/CHANGELOG.md) | [homepage](https://github.com/netzpirat/haml_coffee_assets) |
|
|
54
54
|
| js-routes | **1.0.0** | [changelog](https://github.com/railsware/js-routes/blob/master/CHANGELOG.md) | [homepage](https://github.com/railsware/js-routes) |
|
|
@@ -65,11 +65,11 @@ Examples:
|
|
|
65
65
|
| backbone routefilter | **0.2.1** | [changelog](https://github.com/boazsender/backbone.routefilter#release-history) | [homepage](https://github.com/boazsender/backbone.routefilter) |
|
|
66
66
|
| backbone stickit | **0.8.0**, 0.7.0, 0.6.3 | [changelog](http://nytimes.github.io/backbone.stickit/#change-log) | [homepage](http://nytimes.github.io/backbone.stickit/) |
|
|
67
67
|
| backbone validation | **0.9.1**, 0.8.1 | [changelog](https://github.com/thedersen/backbone.validation#release-notes) | [homepage](https://github.com/thedersen/backbone.validation) |
|
|
68
|
-
| backbone virtualcollection | **0.5.3
|
|
68
|
+
| backbone virtualcollection | **0.6.0**, 0.5.3, 0.4.15 | [changelog](https://github.com/p3drosola/Backbone.VirtualCollection/wiki/Changelog) | [homepage](https://github.com/p3drosola/Backbone.VirtualCollection) |
|
|
69
69
|
| cocktail | **0.5.8** | None | [homepage](https://github.com/onsi/cocktail) |
|
|
70
|
-
| momentjs | **2.
|
|
70
|
+
| momentjs | **2.9.0** | [changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md) | [homepage](https://github.com/derekprior/momentjs-rails) |
|
|
71
71
|
| underscore inflections | **0.2.1** | None | [homepage](https://github.com/geetarista/underscore.inflections) |
|
|
72
|
-
| underscore string | **2.4.0
|
|
72
|
+
| underscore string | **3.0.1**, 2.4.0, 2.3.2 | [changelog](https://github.com/epeli/underscore.string/blob/master/CHANGELOG.markdown) | [homepage](http://epeli.github.io/underscore.string/) |
|
|
73
73
|
|
|
74
74
|
## Contributing
|
|
75
75
|
|
data/lib/js_stack/version.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// MarionetteJS (Backbone.Marionette)
|
|
2
2
|
// ----------------------------------
|
|
3
|
-
// v2.3.
|
|
3
|
+
// v2.3.1
|
|
4
4
|
//
|
|
5
|
-
// Copyright (c)
|
|
5
|
+
// Copyright (c)2015 Derick Bailey, Muted Solutions, LLC.
|
|
6
6
|
// Distributed under MIT license
|
|
7
7
|
//
|
|
8
8
|
// http://marionettejs.com
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
/* istanbul ignore next */
|
|
39
39
|
// Backbone.BabySitter
|
|
40
40
|
// -------------------
|
|
41
|
-
// v0.1.
|
|
41
|
+
// v0.1.5
|
|
42
42
|
//
|
|
43
43
|
// Copyright (c)2014 Derick Bailey, Muted Solutions, LLC.
|
|
44
44
|
// Distributed under MIT license
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
// return the public API
|
|
168
168
|
return Container;
|
|
169
169
|
}(Backbone, _);
|
|
170
|
-
Backbone.ChildViewContainer.VERSION = "0.1.
|
|
170
|
+
Backbone.ChildViewContainer.VERSION = "0.1.5";
|
|
171
171
|
Backbone.ChildViewContainer.noConflict = function() {
|
|
172
172
|
Backbone.ChildViewContainer = previousChildViewContainer;
|
|
173
173
|
return this;
|
|
@@ -493,7 +493,7 @@
|
|
|
493
493
|
|
|
494
494
|
var Marionette = Backbone.Marionette = {};
|
|
495
495
|
|
|
496
|
-
Marionette.VERSION = '2.3.
|
|
496
|
+
Marionette.VERSION = '2.3.1';
|
|
497
497
|
|
|
498
498
|
Marionette.noConflict = function() {
|
|
499
499
|
root.Marionette = previousMarionette;
|
|
@@ -544,6 +544,17 @@
|
|
|
544
544
|
return Marionette.getOption(this, optionName);
|
|
545
545
|
};
|
|
546
546
|
|
|
547
|
+
// Similar to `_.result`, this is a simple helper
|
|
548
|
+
// If a function is provided we call it with context
|
|
549
|
+
// otherwise just return the value. If the value is
|
|
550
|
+
// undefined return a default value
|
|
551
|
+
Marionette._getValue = function(value, context, params) {
|
|
552
|
+
if (_.isFunction(value)) {
|
|
553
|
+
value = value.apply(context, params);
|
|
554
|
+
}
|
|
555
|
+
return value;
|
|
556
|
+
};
|
|
557
|
+
|
|
547
558
|
// Marionette.normalizeMethods
|
|
548
559
|
// ----------------------
|
|
549
560
|
|
|
@@ -802,7 +813,7 @@
|
|
|
802
813
|
if (!entity || !bindings) { return; }
|
|
803
814
|
|
|
804
815
|
// type-check bindings
|
|
805
|
-
if (!_.
|
|
816
|
+
if (!_.isObject(bindings)) {
|
|
806
817
|
throw new Marionette.Error({
|
|
807
818
|
message: 'Bindings must be an object or function.',
|
|
808
819
|
url: 'marionette.functions.html#marionettebindentityevents'
|
|
@@ -810,9 +821,7 @@
|
|
|
810
821
|
}
|
|
811
822
|
|
|
812
823
|
// allow the bindings to be a function
|
|
813
|
-
|
|
814
|
-
bindings = bindings.call(target);
|
|
815
|
-
}
|
|
824
|
+
bindings = Marionette._getValue(bindings, target);
|
|
816
825
|
|
|
817
826
|
// iterate the bindings and bind them
|
|
818
827
|
_.each(bindings, function(methods, evt) {
|
|
@@ -1206,24 +1215,18 @@
|
|
|
1206
1215
|
}
|
|
1207
1216
|
},
|
|
1208
1217
|
|
|
1209
|
-
// Override this method to change how the region finds the
|
|
1210
|
-
//
|
|
1218
|
+
// Override this method to change how the region finds the DOM
|
|
1219
|
+
// element that it manages. Return a jQuery selector object scoped
|
|
1220
|
+
// to a provided parent el or the document if none exists.
|
|
1211
1221
|
getEl: function(el) {
|
|
1212
|
-
return Backbone.$(el);
|
|
1222
|
+
return Backbone.$(el, Marionette._getValue(this.options.parentEl, this));
|
|
1213
1223
|
},
|
|
1214
1224
|
|
|
1215
1225
|
// Override this method to change how the new view is
|
|
1216
1226
|
// appended to the `$el` that the region is managing
|
|
1217
1227
|
attachHtml: function(view) {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
// will not let us clear the html of tables and selects.
|
|
1221
|
-
// We also do not want to use the more declarative `empty` method
|
|
1222
|
-
// that jquery exposes since `.empty` loops over all of the children DOM
|
|
1223
|
-
// nodes and unsets the listeners on each node. While this seems like
|
|
1224
|
-
// a desirable thing, it comes at quite a high perf cost. For that reason
|
|
1225
|
-
// we are simply clearing the html contents of the node.
|
|
1226
|
-
this.$el.html('');
|
|
1228
|
+
this.$el.contents().detach();
|
|
1229
|
+
|
|
1227
1230
|
this.el.appendChild(view.el);
|
|
1228
1231
|
},
|
|
1229
1232
|
|
|
@@ -1349,28 +1352,7 @@
|
|
|
1349
1352
|
options.el = regionConfig.selector;
|
|
1350
1353
|
}
|
|
1351
1354
|
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
// override the `getEl` function if we have a parentEl
|
|
1355
|
-
// this must be overridden to ensure the selector is found
|
|
1356
|
-
// on the first use of the region. if we try to assign the
|
|
1357
|
-
// region's `el` to `parentEl.find(selector)` in the object
|
|
1358
|
-
// literal to build the region, the element will not be
|
|
1359
|
-
// guaranteed to be in the DOM already, and will cause problems
|
|
1360
|
-
if (regionConfig.parentEl) {
|
|
1361
|
-
region.getEl = function(el) {
|
|
1362
|
-
if (_.isObject(el)) {
|
|
1363
|
-
return Backbone.$(el);
|
|
1364
|
-
}
|
|
1365
|
-
var parentEl = regionConfig.parentEl;
|
|
1366
|
-
if (_.isFunction(parentEl)) {
|
|
1367
|
-
parentEl = parentEl();
|
|
1368
|
-
}
|
|
1369
|
-
return parentEl.find(el);
|
|
1370
|
-
};
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
|
-
return region;
|
|
1355
|
+
return new RegionClass(options);
|
|
1374
1356
|
},
|
|
1375
1357
|
|
|
1376
1358
|
// Build the region directly from a given `RegionClass`
|
|
@@ -1397,26 +1379,19 @@
|
|
|
1397
1379
|
// each key becomes the region name, and each value is
|
|
1398
1380
|
// the region definition.
|
|
1399
1381
|
addRegions: function(regionDefinitions, defaults) {
|
|
1400
|
-
|
|
1401
|
-
regionDefinitions = regionDefinitions.apply(this, arguments);
|
|
1402
|
-
}
|
|
1382
|
+
regionDefinitions = Marionette._getValue(regionDefinitions, this, arguments);
|
|
1403
1383
|
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
_.each(regionDefinitions, function(definition, name) {
|
|
1384
|
+
return _.reduce(regionDefinitions, function(regions, definition, name) {
|
|
1407
1385
|
if (_.isString(definition)) {
|
|
1408
1386
|
definition = {selector: definition};
|
|
1409
1387
|
}
|
|
1410
|
-
|
|
1411
1388
|
if (definition.selector) {
|
|
1412
1389
|
definition = _.defaults({}, definition, defaults);
|
|
1413
1390
|
}
|
|
1414
1391
|
|
|
1415
|
-
|
|
1416
|
-
regions
|
|
1417
|
-
}, this);
|
|
1418
|
-
|
|
1419
|
-
return regions;
|
|
1392
|
+
regions[name] = this.addRegion(name, definition);
|
|
1393
|
+
return regions;
|
|
1394
|
+
}, {}, this);
|
|
1420
1395
|
},
|
|
1421
1396
|
|
|
1422
1397
|
// Add an individual region to the region manager,
|
|
@@ -1627,12 +1602,7 @@
|
|
|
1627
1602
|
});
|
|
1628
1603
|
}
|
|
1629
1604
|
|
|
1630
|
-
var templateFunc;
|
|
1631
|
-
if (typeof template === 'function') {
|
|
1632
|
-
templateFunc = template;
|
|
1633
|
-
} else {
|
|
1634
|
-
templateFunc = Marionette.TemplateCache.get(template);
|
|
1635
|
-
}
|
|
1605
|
+
var templateFunc = _.isFunction(template) ? template : Marionette.TemplateCache.get(template);
|
|
1636
1606
|
|
|
1637
1607
|
return templateFunc(data);
|
|
1638
1608
|
}
|
|
@@ -1645,11 +1615,12 @@
|
|
|
1645
1615
|
|
|
1646
1616
|
// The core view class that other Marionette views extend from.
|
|
1647
1617
|
Marionette.View = Backbone.View.extend({
|
|
1618
|
+
isDestroyed: false,
|
|
1648
1619
|
|
|
1649
1620
|
constructor: function(options) {
|
|
1650
1621
|
_.bindAll(this, 'render');
|
|
1651
1622
|
|
|
1652
|
-
options =
|
|
1623
|
+
options = Marionette._getValue(options, this);
|
|
1653
1624
|
|
|
1654
1625
|
// this exposes view options to the view initializer
|
|
1655
1626
|
// this is a backfill since backbone removed the assignment
|
|
@@ -1687,9 +1658,7 @@
|
|
|
1687
1658
|
mixinTemplateHelpers: function(target) {
|
|
1688
1659
|
target = target || {};
|
|
1689
1660
|
var templateHelpers = this.getOption('templateHelpers');
|
|
1690
|
-
|
|
1691
|
-
templateHelpers = templateHelpers.call(this);
|
|
1692
|
-
}
|
|
1661
|
+
templateHelpers = Marionette._getValue(templateHelpers, this);
|
|
1693
1662
|
return _.extend(target, templateHelpers);
|
|
1694
1663
|
},
|
|
1695
1664
|
|
|
@@ -1741,8 +1710,7 @@
|
|
|
1741
1710
|
|
|
1742
1711
|
// internal method to delegate DOM events and triggers
|
|
1743
1712
|
_delegateDOMEvents: function(eventsArg) {
|
|
1744
|
-
var events = eventsArg || this.events;
|
|
1745
|
-
if (_.isFunction(events)) { events = events.call(this); }
|
|
1713
|
+
var events = Marionette._getValue(eventsArg || this.events, this);
|
|
1746
1714
|
|
|
1747
1715
|
// normalize ui keys
|
|
1748
1716
|
events = this.normalizeUIKeys(events);
|
|
@@ -1845,8 +1813,7 @@
|
|
|
1845
1813
|
this.ui = {};
|
|
1846
1814
|
|
|
1847
1815
|
// bind each of the selectors
|
|
1848
|
-
_.each(
|
|
1849
|
-
var selector = bindings[key];
|
|
1816
|
+
_.each(bindings, function(selector, key) {
|
|
1850
1817
|
this.ui[key] = this.$(selector);
|
|
1851
1818
|
}, this);
|
|
1852
1819
|
},
|
|
@@ -2342,9 +2309,7 @@
|
|
|
2342
2309
|
// in order to keep the children in sync with the collection.
|
|
2343
2310
|
addChild: function(child, ChildView, index) {
|
|
2344
2311
|
var childViewOptions = this.getOption('childViewOptions');
|
|
2345
|
-
|
|
2346
|
-
childViewOptions = childViewOptions.call(this, child, index);
|
|
2347
|
-
}
|
|
2312
|
+
childViewOptions = Marionette._getValue(childViewOptions, this, [child, index]);
|
|
2348
2313
|
|
|
2349
2314
|
var view = this.buildChildView(child, ChildView, childViewOptions);
|
|
2350
2315
|
|
|
@@ -2368,22 +2333,14 @@
|
|
|
2368
2333
|
if (increment) {
|
|
2369
2334
|
// assign the index to the view
|
|
2370
2335
|
view._index = index;
|
|
2371
|
-
|
|
2372
|
-
// increment the index of views after this one
|
|
2373
|
-
this.children.each(function (laterView) {
|
|
2374
|
-
if (laterView._index >= view._index) {
|
|
2375
|
-
laterView._index++;
|
|
2376
|
-
}
|
|
2377
|
-
});
|
|
2378
|
-
}
|
|
2379
|
-
else {
|
|
2380
|
-
// decrement the index of views after this one
|
|
2381
|
-
this.children.each(function (laterView) {
|
|
2382
|
-
if (laterView._index >= view._index) {
|
|
2383
|
-
laterView._index--;
|
|
2384
|
-
}
|
|
2385
|
-
});
|
|
2386
2336
|
}
|
|
2337
|
+
|
|
2338
|
+
// update the indexes of views after this one
|
|
2339
|
+
this.children.each(function (laterView) {
|
|
2340
|
+
if (laterView._index >= view._index) {
|
|
2341
|
+
laterView._index += increment ? 1 : -1;
|
|
2342
|
+
}
|
|
2343
|
+
});
|
|
2387
2344
|
},
|
|
2388
2345
|
|
|
2389
2346
|
|
|
@@ -2707,7 +2664,7 @@
|
|
|
2707
2664
|
var childViewContainer = Marionette.getOption(containerView, 'childViewContainer');
|
|
2708
2665
|
if (childViewContainer) {
|
|
2709
2666
|
|
|
2710
|
-
var selector =
|
|
2667
|
+
var selector = Marionette._getValue(childViewContainer, containerView);
|
|
2711
2668
|
|
|
2712
2669
|
if (selector.charAt(0) === '@' && containerView.ui) {
|
|
2713
2670
|
container = containerView.ui[selector.substr(4)];
|
|
@@ -2824,7 +2781,7 @@
|
|
|
2824
2781
|
_buildRegions: function(regions) {
|
|
2825
2782
|
var defaults = {
|
|
2826
2783
|
regionClass: this.getOption('regionClass'),
|
|
2827
|
-
parentEl: _.partial(_.result, this, '
|
|
2784
|
+
parentEl: _.partial(_.result, this, 'el')
|
|
2828
2785
|
};
|
|
2829
2786
|
|
|
2830
2787
|
return this.regionManager.addRegions(regions, defaults);
|
|
@@ -2836,19 +2793,13 @@
|
|
|
2836
2793
|
var regions;
|
|
2837
2794
|
this._initRegionManager();
|
|
2838
2795
|
|
|
2839
|
-
|
|
2840
|
-
regions = this.regions(options);
|
|
2841
|
-
} else {
|
|
2842
|
-
regions = this.regions || {};
|
|
2843
|
-
}
|
|
2796
|
+
regions = Marionette._getValue(this.regions, this, [options]) || {};
|
|
2844
2797
|
|
|
2845
2798
|
// Enable users to define `regions` as instance options.
|
|
2846
2799
|
var regionOptions = this.getOption.call(options, 'regions');
|
|
2847
2800
|
|
|
2848
2801
|
// enable region options to be a function
|
|
2849
|
-
|
|
2850
|
-
regionOptions = regionOptions.call(this, options);
|
|
2851
|
-
}
|
|
2802
|
+
regionOptions = Marionette._getValue(regionOptions, this, [options]);
|
|
2852
2803
|
|
|
2853
2804
|
_.extend(regions, regionOptions);
|
|
2854
2805
|
|
|
@@ -2957,6 +2908,8 @@
|
|
|
2957
2908
|
// method for things to work properly.
|
|
2958
2909
|
|
|
2959
2910
|
Marionette.Behaviors = (function(Marionette, _) {
|
|
2911
|
+
// Borrow event splitter from Backbone
|
|
2912
|
+
var delegateEventSplitter = /^(\S+)\s*(.*)$/;
|
|
2960
2913
|
|
|
2961
2914
|
function Behaviors(view, behaviors) {
|
|
2962
2915
|
|
|
@@ -2983,12 +2936,12 @@
|
|
|
2983
2936
|
|
|
2984
2937
|
behaviorEvents: function(behaviorEvents, behaviors) {
|
|
2985
2938
|
var _behaviorsEvents = {};
|
|
2986
|
-
var viewUI = _.result(this, 'ui');
|
|
2939
|
+
var viewUI = this._uiBindings || _.result(this, 'ui');
|
|
2987
2940
|
|
|
2988
2941
|
_.each(behaviors, function(b, i) {
|
|
2989
2942
|
var _events = {};
|
|
2990
2943
|
var behaviorEvents = _.clone(_.result(b, 'events')) || {};
|
|
2991
|
-
var behaviorUI = _.result(b, 'ui');
|
|
2944
|
+
var behaviorUI = b._uiBindings || _.result(b, 'ui');
|
|
2992
2945
|
|
|
2993
2946
|
// Construct an internal UI hash first using
|
|
2994
2947
|
// the views UI hash and then the behaviors UI hash.
|
|
@@ -3001,21 +2954,25 @@
|
|
|
3001
2954
|
// a user to use the @ui. syntax.
|
|
3002
2955
|
behaviorEvents = Marionette.normalizeUIKeys(behaviorEvents, ui);
|
|
3003
2956
|
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
2957
|
+
var j = 0;
|
|
2958
|
+
_.each(behaviorEvents, function(behaviour, key) {
|
|
2959
|
+
var match = key.match(delegateEventSplitter);
|
|
2960
|
+
|
|
2961
|
+
// Set event name to be namespaced using the view cid,
|
|
2962
|
+
// the behavior index, and the behavior event index
|
|
2963
|
+
// to generate a non colliding event namespace
|
|
2964
|
+
// http://api.jquery.com/event.namespace/
|
|
2965
|
+
var eventName = match[1] + '.' + [this.cid, i, j++, ' '].join(''),
|
|
2966
|
+
selector = match[2];
|
|
3008
2967
|
|
|
3009
|
-
|
|
3010
|
-
var
|
|
3011
|
-
var eventKey = key + whitespace;
|
|
3012
|
-
var handler = _.isFunction(behaviorEvents[key]) ? behaviorEvents[key] : b[behaviorEvents[key]];
|
|
2968
|
+
var eventKey = eventName + selector;
|
|
2969
|
+
var handler = _.isFunction(behaviour) ? behaviour : b[behaviour];
|
|
3013
2970
|
|
|
3014
2971
|
_events[eventKey] = _.bind(handler, b);
|
|
3015
|
-
});
|
|
2972
|
+
}, this);
|
|
3016
2973
|
|
|
3017
2974
|
_behaviorsEvents = _.extend(_behaviorsEvents, _events);
|
|
3018
|
-
});
|
|
2975
|
+
}, this);
|
|
3019
2976
|
|
|
3020
2977
|
return _behaviorsEvents;
|
|
3021
2978
|
}
|
|
@@ -3050,7 +3007,7 @@
|
|
|
3050
3007
|
}
|
|
3051
3008
|
|
|
3052
3009
|
// Get behavior class can be either a flat object or a method
|
|
3053
|
-
return
|
|
3010
|
+
return Marionette._getValue(Behaviors.behaviorsLookup, this, [options, key])[key];
|
|
3054
3011
|
},
|
|
3055
3012
|
|
|
3056
3013
|
// Iterate over the behaviors object, for each behavior
|
|
@@ -3101,7 +3058,7 @@
|
|
|
3101
3058
|
|
|
3102
3059
|
triggersHash = Marionette.normalizeUIKeys(triggersHash, ui);
|
|
3103
3060
|
|
|
3104
|
-
_.each(triggersHash, _.
|
|
3061
|
+
_.each(triggersHash, _.bind(this._setHandlerForBehavior, this, behavior, i));
|
|
3105
3062
|
},
|
|
3106
3063
|
|
|
3107
3064
|
// Internal method to create and assign the trigger handler for a given
|
|
@@ -1 +1 @@
|
|
|
1
|
-
//= require js_stack/base/marionette/2.3.
|
|
1
|
+
//= require js_stack/base/marionette/2.3.1
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// Available under the MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
var VirtualCollection,
|
|
4
|
+
Backbone = require('backbone'),
|
|
5
|
+
_ = require('underscore');
|
|
6
|
+
|
|
7
|
+
VirtualCollection = Backbone.Collection.extend({
|
|
8
|
+
|
|
9
|
+
constructor: function (collection, options) {
|
|
10
|
+
options = options || {};
|
|
11
|
+
this.collection = collection;
|
|
12
|
+
|
|
13
|
+
if (options.comparator !== undefined) this.comparator = options.comparator;
|
|
14
|
+
if (options.close_with) this.bindLifecycle(options.close_with, 'close'); // Marionette 1.*
|
|
15
|
+
if (options.destroy_with) this.bindLifecycle(options.destroy_with, 'destroy'); // Marionette 2.*
|
|
16
|
+
if (!this.model) this.model = collection.model;
|
|
17
|
+
|
|
18
|
+
this.accepts = VirtualCollection.buildFilter(options.filter);
|
|
19
|
+
this._rebuildIndex();
|
|
20
|
+
this.listenTo(this.collection, 'add', this._onAdd);
|
|
21
|
+
this.listenTo(this.collection, 'remove', this._onRemove);
|
|
22
|
+
this.listenTo(this.collection, 'change', this._onChange);
|
|
23
|
+
this.listenTo(this.collection, 'reset', this._onReset);
|
|
24
|
+
this.listenTo(this.collection, 'sort', this._onSort);
|
|
25
|
+
|
|
26
|
+
this.initialize.apply(this, arguments);
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
// Marionette 1.*
|
|
30
|
+
bindLifecycle: function (view, method_name) {
|
|
31
|
+
view.on(method_name, _.bind(this.stopListening, this));
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
updateFilter: function (filter) {
|
|
35
|
+
this.accepts = VirtualCollection.buildFilter(filter);
|
|
36
|
+
this._rebuildIndex();
|
|
37
|
+
this.trigger('filter', this, filter);
|
|
38
|
+
this.trigger('reset', this, filter);
|
|
39
|
+
return this;
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
_rebuildIndex: function () {
|
|
43
|
+
for(idx in this.models) {
|
|
44
|
+
this.models[idx].off('all', this._onModelEvent, this);
|
|
45
|
+
}
|
|
46
|
+
this._reset();
|
|
47
|
+
this.collection.each(function (model, i) {
|
|
48
|
+
if (this.accepts(model, i)) {
|
|
49
|
+
model.on('all', this._onModelEvent, this);
|
|
50
|
+
this.models.push(model);
|
|
51
|
+
this._byId[model.cid] = model;
|
|
52
|
+
if (model.id) this._byId[model.id] = model;
|
|
53
|
+
}
|
|
54
|
+
}, this);
|
|
55
|
+
this.length = this.models.length;
|
|
56
|
+
|
|
57
|
+
if (this.comparator) this.sort({silent: true});
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
orderViaParent: function (options) {
|
|
61
|
+
this.models = this.collection.filter(function (model) {
|
|
62
|
+
return (this._byId[model.cid] !== undefined);
|
|
63
|
+
}, this);
|
|
64
|
+
if (!options.silent) this.trigger('sort', this, options);
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
_onSort: function (collection, options) {
|
|
68
|
+
if (this.comparator !== undefined) return;
|
|
69
|
+
this.orderViaParent(options);
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
_onAdd: function (model, collection, options) {
|
|
73
|
+
var already_here = this.get(model);
|
|
74
|
+
if (!already_here && this.accepts(model, options.index)) {
|
|
75
|
+
this._indexAdd(model);
|
|
76
|
+
model.on('all', this._onModelEvent, this);
|
|
77
|
+
this.trigger('add', model, this, options);
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
_onRemove: function (model, collection, options) {
|
|
82
|
+
if (!this.get(model)) return;
|
|
83
|
+
|
|
84
|
+
var i = this._indexRemove(model)
|
|
85
|
+
, options_clone = _.clone(options);
|
|
86
|
+
options_clone.index = i;
|
|
87
|
+
model.off('all', this._onModelEvent, this);
|
|
88
|
+
this.trigger('remove', model, this, options_clone);
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
_onChange: function (model, options) {
|
|
92
|
+
if (!model || !options) return; // ignore malformed arguments coming from custom events
|
|
93
|
+
var already_here = this.get(model);
|
|
94
|
+
|
|
95
|
+
if (this.accepts(model, options.index)) {
|
|
96
|
+
if (already_here) {
|
|
97
|
+
this.trigger('change', model, this, options);
|
|
98
|
+
} else {
|
|
99
|
+
this._indexAdd(model);
|
|
100
|
+
this.trigger('add', model, this, options);
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
if (already_here) {
|
|
104
|
+
var i = this._indexRemove(model)
|
|
105
|
+
, options_clone = _.clone(options);
|
|
106
|
+
options_clone.index = i;
|
|
107
|
+
this.trigger('remove', model, this, options_clone);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
_onReset: function (collection, options) {
|
|
113
|
+
this._rebuildIndex();
|
|
114
|
+
this.trigger('reset', this, options);
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
sortedIndex: function (model, value, context) {
|
|
118
|
+
var iterator = _.isFunction(value) ? value : function(target) {
|
|
119
|
+
return target.get(value);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
if (iterator.length == 1) {
|
|
123
|
+
return _.sortedIndex(this.models, model, iterator, context);
|
|
124
|
+
} else {
|
|
125
|
+
return sortedIndexTwo(this.models, model, iterator, context);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
_indexAdd: function (model) {
|
|
130
|
+
if (this.get(model)) return;
|
|
131
|
+
var i;
|
|
132
|
+
// uses a binsearch to find the right index
|
|
133
|
+
if (this.comparator) {
|
|
134
|
+
i = this.sortedIndex(model, this.comparator, this);
|
|
135
|
+
} else if (this.comparator === undefined) {
|
|
136
|
+
i = this.sortedIndex(model, function (target) {
|
|
137
|
+
//TODO: indexOf traverses the array every time the iterator is called
|
|
138
|
+
return this.collection.indexOf(target);
|
|
139
|
+
}, this);
|
|
140
|
+
} else {
|
|
141
|
+
i = this.length;
|
|
142
|
+
}
|
|
143
|
+
this.models.splice(i, 0, model);
|
|
144
|
+
this._byId[model.cid] = model;
|
|
145
|
+
if (model.id) this._byId[model.id] = model;
|
|
146
|
+
this.length += 1;
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
_indexRemove: function (model) {
|
|
150
|
+
model.off('all', this._onModelEvent, this);
|
|
151
|
+
var i = this.indexOf(model);
|
|
152
|
+
if (i === -1) return i;
|
|
153
|
+
this.models.splice(i, 1);
|
|
154
|
+
delete this._byId[model.cid];
|
|
155
|
+
if (model.id) delete this._byId[model.id];
|
|
156
|
+
this.length -= 1;
|
|
157
|
+
return i;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
}, { // static props
|
|
161
|
+
|
|
162
|
+
buildFilter: function (options) {
|
|
163
|
+
if (!options) {
|
|
164
|
+
return function () {
|
|
165
|
+
return true;
|
|
166
|
+
};
|
|
167
|
+
} else if (_.isFunction(options)) {
|
|
168
|
+
return options;
|
|
169
|
+
} else if (options.constructor === Object) {
|
|
170
|
+
return function (model) {
|
|
171
|
+
return !Boolean(_(Object.keys(options)).detect(function (key) {
|
|
172
|
+
return model.get(key) !== options[key];
|
|
173
|
+
}));
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// methods that alter data should proxy to the parent collection
|
|
180
|
+
_.each(['add', 'remove', 'set', 'reset', 'push', 'pop', 'unshift', 'shift', 'slice', 'sync', 'fetch'], function (method_name) {
|
|
181
|
+
VirtualCollection.prototype[method_name] = function () {
|
|
182
|
+
return this.collection[method_name].apply(this.collection, _.toArray(arguments));
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
|
|
188
|
+
Equivalent to _.sortedIndex, but for comparators with two arguments
|
|
189
|
+
|
|
190
|
+
**/
|
|
191
|
+
function sortedIndexTwo (array, obj, iterator, context) {
|
|
192
|
+
var low = 0, high = array.length;
|
|
193
|
+
while (low < high) {
|
|
194
|
+
var mid = (low + high) >>> 1;
|
|
195
|
+
iterator.call(context, obj, array[mid]) > 0 ? low = mid + 1 : high = mid;
|
|
196
|
+
}
|
|
197
|
+
return low;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
_.extend(VirtualCollection.prototype, Backbone.Events);
|
|
201
|
+
|
|
202
|
+
module.exports = VirtualCollection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
//= require js_stack/plugins/backbone/virtualcollection/0.
|
|
1
|
+
//= require js_stack/plugins/backbone/virtualcollection/0.6.0
|