yano-backbone-rails 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/yano/backbone/rails/version.rb +2 -2
- data/vendor/assets/javascripts/marionette/backbone.marionette.js +419 -329
- data/vendor/assets/javascripts/marionette/backbone.marionette.min.js.erb +3 -3
- data/vendor/assets/source_maps/backbone.marionette.min.js.map +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21b6e33f2a3faa15fb31fd4854e4310eee9572ee
|
4
|
+
data.tar.gz: 78c2afe4e9a9ed45d268de71979b347239dcc44e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3884b74a2f08993340de28d252d7e7f1a1aa5ccdfeb0f7a3ef3c68910b8196df472befd6eaf166327877af07c09045b06c78efd6457292dd788e752492b0a80
|
7
|
+
data.tar.gz: 1a4e8868c4e53aebef3be87f5ed1fa85d99d2c113355c066dad52518b7015d2b83c9834e3a2ab21b6795568fbebf6ccca459d8a760e849bd8585cdd326140939
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// MarionetteJS (Backbone.Marionette)
|
2
2
|
// ----------------------------------
|
3
|
-
// v3.
|
3
|
+
// v3.1.0
|
4
4
|
//
|
5
5
|
// Copyright (c)2016 Derick Bailey, Muted Solutions, LLC.
|
6
6
|
// Distributed under MIT license
|
@@ -18,7 +18,7 @@
|
|
18
18
|
_ = 'default' in _ ? _['default'] : _;
|
19
19
|
Radio = 'default' in Radio ? Radio['default'] : Radio;
|
20
20
|
|
21
|
-
var version = "3.
|
21
|
+
var version = "3.1.0";
|
22
22
|
|
23
23
|
//Internal utility for creating context style global utils
|
24
24
|
var proxy = function proxy(method) {
|
@@ -63,10 +63,18 @@
|
|
63
63
|
|
64
64
|
// Merge `keys` from `options` onto `this`
|
65
65
|
var mergeOptions = function mergeOptions(options, keys) {
|
66
|
+
var _this = this;
|
67
|
+
|
66
68
|
if (!options) {
|
67
69
|
return;
|
68
70
|
}
|
69
|
-
|
71
|
+
|
72
|
+
_.each(keys, function (key) {
|
73
|
+
var option = options[key];
|
74
|
+
if (option !== undefined) {
|
75
|
+
_this[key] = option;
|
76
|
+
}
|
77
|
+
});
|
70
78
|
};
|
71
79
|
|
72
80
|
// Marionette.getOption
|
@@ -113,6 +121,10 @@
|
|
113
121
|
return eventName.toUpperCase();
|
114
122
|
}
|
115
123
|
|
124
|
+
var getOnMethodName = _.memoize(function (event) {
|
125
|
+
return 'on' + event.replace(splitter, getEventName);
|
126
|
+
});
|
127
|
+
|
116
128
|
// Trigger an event and/or a corresponding method name. Examples:
|
117
129
|
//
|
118
130
|
// `this.triggerMethod("foo")` will trigger the "foo" event and
|
@@ -121,24 +133,23 @@
|
|
121
133
|
// `this.triggerMethod("foo:bar")` will trigger the "foo:bar" event and
|
122
134
|
// call the "onFooBar" method.
|
123
135
|
function triggerMethod(event) {
|
136
|
+
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
137
|
+
args[_key - 1] = arguments[_key];
|
138
|
+
}
|
139
|
+
|
124
140
|
// get the method name from the event name
|
125
|
-
var methodName =
|
141
|
+
var methodName = getOnMethodName(event);
|
126
142
|
var method = getOption.call(this, methodName);
|
127
143
|
var result = void 0;
|
128
144
|
|
129
145
|
// call the onMethodName if it exists
|
130
|
-
|
131
|
-
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
132
|
-
args[_key - 1] = arguments[_key];
|
133
|
-
}
|
134
|
-
|
135
146
|
if (_.isFunction(method)) {
|
136
147
|
// pass all args, except the event name
|
137
148
|
result = method.apply(this, args);
|
138
149
|
}
|
139
150
|
|
140
151
|
// trigger the event
|
141
|
-
this.trigger.apply(this,
|
152
|
+
this.trigger.apply(this, arguments);
|
142
153
|
|
143
154
|
return result;
|
144
155
|
}
|
@@ -148,13 +159,15 @@
|
|
148
159
|
// e.g. `Marionette.triggerMethodOn(view, 'show')`
|
149
160
|
// will trigger a "show" event or invoke onShow the view.
|
150
161
|
function triggerMethodOn(context) {
|
151
|
-
var fnc = _.isFunction(context.triggerMethod) ? context.triggerMethod : triggerMethod;
|
152
|
-
|
153
162
|
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
154
163
|
args[_key2 - 1] = arguments[_key2];
|
155
164
|
}
|
156
165
|
|
157
|
-
|
166
|
+
if (_.isFunction(context.triggerMethod)) {
|
167
|
+
return context.triggerMethod.apply(context, args);
|
168
|
+
}
|
169
|
+
|
170
|
+
return triggerMethod.apply(context, args);
|
158
171
|
}
|
159
172
|
|
160
173
|
// Trigger method on children unless a pure Backbone.View
|
@@ -194,41 +207,41 @@
|
|
194
207
|
return true;
|
195
208
|
}
|
196
209
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
if (view._areViewEventsMonitored) {
|
201
|
-
return;
|
210
|
+
function triggerDOMRefresh(view) {
|
211
|
+
if (view._isAttached && view._isRendered) {
|
212
|
+
triggerMethodOn(view, 'dom:refresh', view);
|
202
213
|
}
|
214
|
+
}
|
203
215
|
|
204
|
-
|
216
|
+
function handleBeforeAttach() {
|
217
|
+
triggerMethodChildren(this, 'before:attach', shouldTriggerAttach);
|
218
|
+
}
|
205
219
|
|
206
|
-
|
207
|
-
|
208
|
-
|
220
|
+
function handleAttach() {
|
221
|
+
triggerMethodChildren(this, 'attach', shouldAttach);
|
222
|
+
triggerDOMRefresh(this);
|
223
|
+
}
|
209
224
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
}
|
225
|
+
function handleBeforeDetach() {
|
226
|
+
triggerMethodChildren(this, 'before:detach', shouldTriggerDetach);
|
227
|
+
}
|
214
228
|
|
215
|
-
|
216
|
-
|
217
|
-
|
229
|
+
function handleDetach() {
|
230
|
+
triggerMethodChildren(this, 'detach', shouldDetach);
|
231
|
+
}
|
218
232
|
|
219
|
-
|
220
|
-
|
221
|
-
|
233
|
+
function handleRender() {
|
234
|
+
triggerDOMRefresh(this);
|
235
|
+
}
|
222
236
|
|
223
|
-
|
224
|
-
|
237
|
+
// Monitor a view's state, propagating attach/detach events to children and firing dom:refresh
|
238
|
+
// whenever a rendered view is attached or an attached view is rendered.
|
239
|
+
function monitorViewEvents(view) {
|
240
|
+
if (view._areViewEventsMonitored) {
|
241
|
+
return;
|
225
242
|
}
|
226
243
|
|
227
|
-
|
228
|
-
if (view._isAttached && view._isRendered) {
|
229
|
-
triggerMethodOn(view, 'dom:refresh', view);
|
230
|
-
}
|
231
|
-
}
|
244
|
+
view._areViewEventsMonitored = true;
|
232
245
|
|
233
246
|
view.on({
|
234
247
|
'before:attach': handleBeforeAttach,
|
@@ -591,15 +604,7 @@
|
|
591
604
|
|
592
605
|
var _invoke = _.invokeMap || _.invoke;
|
593
606
|
|
594
|
-
var
|
595
|
-
if (Array.isArray(arr)) {
|
596
|
-
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
|
597
|
-
|
598
|
-
return arr2;
|
599
|
-
} else {
|
600
|
-
return Array.from(arr);
|
601
|
-
}
|
602
|
-
};
|
607
|
+
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
603
608
|
|
604
609
|
// MixinOptions
|
605
610
|
// - behaviors
|
@@ -651,11 +656,11 @@
|
|
651
656
|
},
|
652
657
|
_getBehaviorTriggers: function _getBehaviorTriggers() {
|
653
658
|
var triggers = _invoke(this._behaviors, 'getTriggers');
|
654
|
-
return _.extend.apply(_, [{}].concat(
|
659
|
+
return _.extend.apply(_, [{}].concat(_toConsumableArray(triggers)));
|
655
660
|
},
|
656
661
|
_getBehaviorEvents: function _getBehaviorEvents() {
|
657
662
|
var events = _invoke(this._behaviors, 'getEvents');
|
658
|
-
return _.extend.apply(_, [{}].concat(
|
663
|
+
return _.extend.apply(_, [{}].concat(_toConsumableArray(events)));
|
659
664
|
},
|
660
665
|
|
661
666
|
|
@@ -680,7 +685,7 @@
|
|
680
685
|
// destroying the view.
|
681
686
|
// This unbinds event listeners
|
682
687
|
// that behaviors have registered for.
|
683
|
-
_invoke.apply(undefined, [this._behaviors, 'destroy'].concat(
|
688
|
+
_invoke.apply(undefined, [this._behaviors, 'destroy'].concat(_toConsumableArray(args)));
|
684
689
|
},
|
685
690
|
_bindBehaviorUIElements: function _bindBehaviorUIElements() {
|
686
691
|
_invoke(this._behaviors, 'bindUIElements');
|
@@ -691,13 +696,8 @@
|
|
691
696
|
_triggerEventOnBehaviors: function _triggerEventOnBehaviors() {
|
692
697
|
var behaviors = this._behaviors;
|
693
698
|
// Use good ol' for as this is a very hot function
|
694
|
-
|
695
|
-
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
696
|
-
args[_key] = arguments[_key];
|
697
|
-
}
|
698
|
-
|
699
699
|
for (var i = 0, length = behaviors && behaviors.length; i < length; i++) {
|
700
|
-
triggerMethod.apply(behaviors[i],
|
700
|
+
triggerMethod.apply(behaviors[i], arguments);
|
701
701
|
}
|
702
702
|
}
|
703
703
|
};
|
@@ -786,7 +786,7 @@
|
|
786
786
|
// Returns a new, non-mutated, parsed events hash.
|
787
787
|
var _normalizeUIKeys = function _normalizeUIKeys(hash, ui) {
|
788
788
|
return _.reduce(hash, function (memo, val, key) {
|
789
|
-
var normalizedKey =
|
789
|
+
var normalizedKey = _normalizeUIString(key, ui);
|
790
790
|
memo[normalizedKey] = val;
|
791
791
|
return memo;
|
792
792
|
}, {});
|
@@ -794,7 +794,7 @@
|
|
794
794
|
|
795
795
|
// utility method for parsing @ui. syntax strings
|
796
796
|
// into associated selector
|
797
|
-
var
|
797
|
+
var _normalizeUIString = function _normalizeUIString(uiString, ui) {
|
798
798
|
return uiString.replace(/@ui\.[a-zA-Z-_$0-9]*/g, function (r) {
|
799
799
|
return ui[r.slice(4)];
|
800
800
|
});
|
@@ -806,14 +806,14 @@
|
|
806
806
|
var _normalizeUIValues = function _normalizeUIValues(hash, ui, properties) {
|
807
807
|
_.each(hash, function (val, key) {
|
808
808
|
if (_.isString(val)) {
|
809
|
-
hash[key] =
|
809
|
+
hash[key] = _normalizeUIString(val, ui);
|
810
810
|
} else if (_.isObject(val) && _.isArray(properties)) {
|
811
811
|
_.extend(val, _normalizeUIValues(_.pick(val, properties), ui));
|
812
812
|
/* Value is an object, and we got an array of embedded property names to normalize. */
|
813
813
|
_.each(properties, function (property) {
|
814
814
|
var propertyVal = val[property];
|
815
815
|
if (_.isString(propertyVal)) {
|
816
|
-
val[property] =
|
816
|
+
val[property] = _normalizeUIString(propertyVal, ui);
|
817
817
|
}
|
818
818
|
});
|
819
819
|
}
|
@@ -831,6 +831,14 @@
|
|
831
831
|
},
|
832
832
|
|
833
833
|
|
834
|
+
// normalize the passed string with the views `ui` selectors.
|
835
|
+
// `"@ui.bar"`
|
836
|
+
normalizeUIString: function normalizeUIString(uiString) {
|
837
|
+
var uiBindings = this._getUIBindings();
|
838
|
+
return _normalizeUIString(uiString, uiBindings);
|
839
|
+
},
|
840
|
+
|
841
|
+
|
834
842
|
// normalize the values of passed hash with the views `ui` selectors.
|
835
843
|
// `{foo: "@ui.bar"}`
|
836
844
|
normalizeUIValues: function normalizeUIValues(hash, properties) {
|
@@ -930,23 +938,6 @@
|
|
930
938
|
},
|
931
939
|
|
932
940
|
|
933
|
-
// Overriding Backbone.View's `setElement` to handle
|
934
|
-
// if an el was previously defined. If so, the view might be
|
935
|
-
// rendered or attached on setElement.
|
936
|
-
setElement: function setElement() {
|
937
|
-
var hasEl = !!this.el;
|
938
|
-
|
939
|
-
Backbone.View.prototype.setElement.apply(this, arguments);
|
940
|
-
|
941
|
-
if (hasEl) {
|
942
|
-
this._isRendered = !!this.$el.length;
|
943
|
-
this._isAttached = isNodeAttached(this.el);
|
944
|
-
}
|
945
|
-
|
946
|
-
return this;
|
947
|
-
},
|
948
|
-
|
949
|
-
|
950
941
|
// Overriding Backbone.View's `delegateEvents` to handle
|
951
942
|
// `events` and `triggers`
|
952
943
|
delegateEvents: function delegateEvents(eventsArg) {
|
@@ -1095,14 +1086,10 @@
|
|
1095
1086
|
// import the `triggerMethod` to trigger events with corresponding
|
1096
1087
|
// methods if the method exists
|
1097
1088
|
triggerMethod: function triggerMethod$$() {
|
1098
|
-
|
1099
|
-
args[_key2] = arguments[_key2];
|
1100
|
-
}
|
1089
|
+
var ret = triggerMethod.apply(this, arguments);
|
1101
1090
|
|
1102
|
-
|
1103
|
-
|
1104
|
-
this._triggerEventOnBehaviors.apply(this, args);
|
1105
|
-
this._triggerEventOnParentLayout.apply(this, args);
|
1091
|
+
this._triggerEventOnBehaviors.apply(this, arguments);
|
1092
|
+
this._triggerEventOnParentLayout.apply(this, arguments);
|
1106
1093
|
|
1107
1094
|
return ret;
|
1108
1095
|
},
|
@@ -1113,49 +1100,55 @@
|
|
1113
1100
|
this._childViewEvents = _.result(this, 'childViewEvents');
|
1114
1101
|
this._childViewTriggers = _.result(this, 'childViewTriggers');
|
1115
1102
|
},
|
1116
|
-
_triggerEventOnParentLayout: function _triggerEventOnParentLayout(
|
1103
|
+
_triggerEventOnParentLayout: function _triggerEventOnParentLayout() {
|
1117
1104
|
var layoutView = this._parentView();
|
1118
1105
|
if (!layoutView) {
|
1119
1106
|
return;
|
1120
1107
|
}
|
1121
1108
|
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1109
|
+
layoutView._childViewEventHandler.apply(layoutView, arguments);
|
1110
|
+
},
|
1111
|
+
|
1112
|
+
|
1113
|
+
// Walk the _parent tree until we find a view (if one exists).
|
1114
|
+
// Returns the parent view hierarchically closest to this view.
|
1115
|
+
_parentView: function _parentView() {
|
1116
|
+
var parent = this._parent;
|
1125
1117
|
|
1126
|
-
|
1127
|
-
|
1118
|
+
while (parent) {
|
1119
|
+
if (parent instanceof View) {
|
1120
|
+
return parent;
|
1121
|
+
}
|
1122
|
+
parent = parent._parent;
|
1128
1123
|
}
|
1124
|
+
},
|
1125
|
+
_childViewEventHandler: function _childViewEventHandler(eventName) {
|
1126
|
+
var childViewEvents = this.normalizeMethods(this._childViewEvents);
|
1129
1127
|
|
1130
|
-
|
1128
|
+
// call collectionView childViewEvent if defined
|
1131
1129
|
|
1132
|
-
|
1133
|
-
|
1130
|
+
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
1131
|
+
args[_key2 - 1] = arguments[_key2];
|
1132
|
+
}
|
1134
1133
|
|
1135
|
-
if (
|
1136
|
-
childViewEvents[eventName].apply(
|
1134
|
+
if (typeof childViewEvents !== 'undefined' && _.isFunction(childViewEvents[eventName])) {
|
1135
|
+
childViewEvents[eventName].apply(this, args);
|
1137
1136
|
}
|
1138
1137
|
|
1139
1138
|
// use the parent view's proxyEvent handlers
|
1140
|
-
var childViewTriggers =
|
1139
|
+
var childViewTriggers = this._childViewTriggers;
|
1141
1140
|
|
1142
1141
|
// Call the event with the proxy name on the parent layout
|
1143
1142
|
if (childViewTriggers && _.isString(childViewTriggers[eventName])) {
|
1144
|
-
|
1143
|
+
this.triggerMethod.apply(this, [childViewTriggers[eventName]].concat(args));
|
1145
1144
|
}
|
1146
|
-
},
|
1147
1145
|
|
1146
|
+
var prefix = _.result(this, 'childViewEventPrefix');
|
1148
1147
|
|
1149
|
-
|
1150
|
-
|
1151
|
-
_parentView: function _parentView() {
|
1152
|
-
var parent = this._parent;
|
1148
|
+
if (prefix !== false) {
|
1149
|
+
var childEventName = prefix + ':' + eventName;
|
1153
1150
|
|
1154
|
-
|
1155
|
-
if (parent instanceof View) {
|
1156
|
-
return parent;
|
1157
|
-
}
|
1158
|
-
parent = parent._parent;
|
1151
|
+
this.triggerMethod.apply(this, [childEventName].concat(args));
|
1159
1152
|
}
|
1160
1153
|
}
|
1161
1154
|
};
|
@@ -1238,7 +1231,7 @@
|
|
1238
1231
|
// We need to listen for if a view is destroyed in a way other than through the region.
|
1239
1232
|
// If this happens we need to remove the reference to the currentView since once a view
|
1240
1233
|
// has been destroyed we can not reuse it.
|
1241
|
-
view.on('destroy', this.
|
1234
|
+
view.on('destroy', this._empty, this);
|
1242
1235
|
|
1243
1236
|
// Make this region the view's parent.
|
1244
1237
|
// It's important that this parent binding happens before rendering so that any events
|
@@ -1269,7 +1262,7 @@
|
|
1269
1262
|
}
|
1270
1263
|
},
|
1271
1264
|
_attachView: function _attachView(view) {
|
1272
|
-
var options = arguments.length
|
1265
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
1273
1266
|
|
1274
1267
|
var shouldTriggerAttach = !view._isAttached && isNodeAttached(this.el);
|
1275
1268
|
var shouldReplaceEl = typeof options.replaceElement === 'undefined' ? !!_.result(this, 'replaceElement') : !!options.replaceElement;
|
@@ -1278,7 +1271,11 @@
|
|
1278
1271
|
triggerMethodOn(view, 'before:attach', view);
|
1279
1272
|
}
|
1280
1273
|
|
1281
|
-
|
1274
|
+
if (shouldReplaceEl) {
|
1275
|
+
this._replaceEl(view);
|
1276
|
+
} else {
|
1277
|
+
this.attachHtml(view);
|
1278
|
+
}
|
1282
1279
|
|
1283
1280
|
if (shouldTriggerAttach) {
|
1284
1281
|
view._isAttached = true;
|
@@ -1288,7 +1285,7 @@
|
|
1288
1285
|
this.currentView = view;
|
1289
1286
|
},
|
1290
1287
|
_ensureElement: function _ensureElement() {
|
1291
|
-
var options = arguments.length
|
1288
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
1292
1289
|
|
1293
1290
|
if (!_.isObject(this.el)) {
|
1294
1291
|
this.$el = this.getEl(this.el);
|
@@ -1371,20 +1368,15 @@
|
|
1371
1368
|
|
1372
1369
|
// Override this method to change how the new view is appended to the `$el` that the
|
1373
1370
|
// region is managing
|
1374
|
-
attachHtml: function attachHtml(view
|
1375
|
-
|
1376
|
-
// replace the region's node with the view's node
|
1377
|
-
this._replaceEl(view);
|
1378
|
-
} else {
|
1379
|
-
this.el.appendChild(view.el);
|
1380
|
-
}
|
1371
|
+
attachHtml: function attachHtml(view) {
|
1372
|
+
this.el.appendChild(view.el);
|
1381
1373
|
},
|
1382
1374
|
|
1383
1375
|
|
1384
1376
|
// Destroy the current view, if there is one. If there is no current view, it does
|
1385
1377
|
// nothing and returns immediately.
|
1386
1378
|
empty: function empty() {
|
1387
|
-
var options = arguments.length
|
1379
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { allowMissingEl: true };
|
1388
1380
|
|
1389
1381
|
var view = this.currentView;
|
1390
1382
|
|
@@ -1396,7 +1388,17 @@
|
|
1396
1388
|
return this;
|
1397
1389
|
}
|
1398
1390
|
|
1399
|
-
|
1391
|
+
var shouldDestroy = !options.preventDestroy;
|
1392
|
+
|
1393
|
+
if (!shouldDestroy) {
|
1394
|
+
deprecate('The preventDestroy option is deprecated. Use Region#detachView');
|
1395
|
+
}
|
1396
|
+
|
1397
|
+
this._empty(view, shouldDestroy);
|
1398
|
+
return this;
|
1399
|
+
},
|
1400
|
+
_empty: function _empty(view, shouldDestroy) {
|
1401
|
+
view.off('destroy', this._empty, this);
|
1400
1402
|
this.triggerMethod('before:empty', this, view);
|
1401
1403
|
|
1402
1404
|
this._restoreEl();
|
@@ -1404,21 +1406,14 @@
|
|
1404
1406
|
delete this.currentView;
|
1405
1407
|
|
1406
1408
|
if (!view._isDestroyed) {
|
1407
|
-
this._removeView(view,
|
1409
|
+
this._removeView(view, shouldDestroy);
|
1408
1410
|
delete view._parent;
|
1409
1411
|
}
|
1410
1412
|
|
1411
1413
|
this.triggerMethod('empty', this, view);
|
1412
|
-
return this;
|
1413
1414
|
},
|
1414
|
-
_removeView: function _removeView(view) {
|
1415
|
-
|
1416
|
-
|
1417
|
-
var preventDestroy = _ref.preventDestroy;
|
1418
|
-
|
1419
|
-
var shouldPreventDestroy = !!preventDestroy;
|
1420
|
-
|
1421
|
-
if (shouldPreventDestroy) {
|
1415
|
+
_removeView: function _removeView(view, shouldDestroy) {
|
1416
|
+
if (!shouldDestroy) {
|
1422
1417
|
this._detachView(view);
|
1423
1418
|
return;
|
1424
1419
|
}
|
@@ -1429,6 +1424,17 @@
|
|
1429
1424
|
destroyBackboneView(view);
|
1430
1425
|
}
|
1431
1426
|
},
|
1427
|
+
detachView: function detachView() {
|
1428
|
+
var view = this.currentView;
|
1429
|
+
|
1430
|
+
if (!view) {
|
1431
|
+
return;
|
1432
|
+
}
|
1433
|
+
|
1434
|
+
this._empty(view);
|
1435
|
+
|
1436
|
+
return view;
|
1437
|
+
},
|
1432
1438
|
_detachView: function _detachView(view) {
|
1433
1439
|
var shouldTriggerDetach = !!view._isAttached;
|
1434
1440
|
if (shouldTriggerDetach) {
|
@@ -1476,6 +1482,54 @@
|
|
1476
1482
|
}
|
1477
1483
|
});
|
1478
1484
|
|
1485
|
+
// return the region instance from the definition
|
1486
|
+
function buildRegion (definition, defaults) {
|
1487
|
+
if (definition instanceof Region) {
|
1488
|
+
return definition;
|
1489
|
+
}
|
1490
|
+
|
1491
|
+
return buildRegionFromDefinition(definition, defaults);
|
1492
|
+
}
|
1493
|
+
|
1494
|
+
function buildRegionFromDefinition(definition, defaults) {
|
1495
|
+
var opts = _.extend({}, defaults);
|
1496
|
+
|
1497
|
+
if (_.isString(definition)) {
|
1498
|
+
_.extend(opts, { el: definition });
|
1499
|
+
|
1500
|
+
return buildRegionFromObject(opts);
|
1501
|
+
}
|
1502
|
+
|
1503
|
+
if (_.isFunction(definition)) {
|
1504
|
+
_.extend(opts, { regionClass: definition });
|
1505
|
+
|
1506
|
+
return buildRegionFromObject(opts);
|
1507
|
+
}
|
1508
|
+
|
1509
|
+
if (_.isObject(definition)) {
|
1510
|
+
if (definition.selector) {
|
1511
|
+
deprecate('The selector option on a Region definition object is deprecated. Use el to pass a selector string');
|
1512
|
+
}
|
1513
|
+
|
1514
|
+
_.extend(opts, { el: definition.selector }, definition);
|
1515
|
+
|
1516
|
+
return buildRegionFromObject(opts);
|
1517
|
+
}
|
1518
|
+
|
1519
|
+
throw new MarionetteError({
|
1520
|
+
message: 'Improper region configuration type.',
|
1521
|
+
url: 'marionette.region.html#region-configuration-types'
|
1522
|
+
});
|
1523
|
+
}
|
1524
|
+
|
1525
|
+
function buildRegionFromObject(definition) {
|
1526
|
+
var RegionClass = definition.regionClass;
|
1527
|
+
|
1528
|
+
var options = _.omit(definition, 'regionClass');
|
1529
|
+
|
1530
|
+
return new RegionClass(options);
|
1531
|
+
}
|
1532
|
+
|
1479
1533
|
// MixinOptions
|
1480
1534
|
// - regions
|
1481
1535
|
// - regionClass
|
@@ -1532,60 +1586,17 @@
|
|
1532
1586
|
_addRegions: function _addRegions(regionDefinitions) {
|
1533
1587
|
var _this = this;
|
1534
1588
|
|
1589
|
+
var defaults = {
|
1590
|
+
regionClass: this.regionClass,
|
1591
|
+
parentEl: _.partial(_.result, this, 'el')
|
1592
|
+
};
|
1593
|
+
|
1535
1594
|
return _.reduce(regionDefinitions, function (regions, definition, name) {
|
1536
|
-
regions[name] =
|
1595
|
+
regions[name] = buildRegion(definition, defaults);
|
1537
1596
|
_this._addRegion(regions[name], name);
|
1538
1597
|
return regions;
|
1539
1598
|
}, {});
|
1540
1599
|
},
|
1541
|
-
|
1542
|
-
|
1543
|
-
// return the region instance from the definition
|
1544
|
-
_buildRegion: function _buildRegion(definition) {
|
1545
|
-
if (definition instanceof Region) {
|
1546
|
-
return definition;
|
1547
|
-
}
|
1548
|
-
|
1549
|
-
return this._buildRegionFromDefinition(definition);
|
1550
|
-
},
|
1551
|
-
_buildRegionFromDefinition: function _buildRegionFromDefinition(definition) {
|
1552
|
-
if (_.isString(definition)) {
|
1553
|
-
return this._buildRegionFromObject({ el: definition });
|
1554
|
-
}
|
1555
|
-
|
1556
|
-
if (_.isFunction(definition)) {
|
1557
|
-
return this._buildRegionFromRegionClass(definition);
|
1558
|
-
}
|
1559
|
-
|
1560
|
-
if (_.isObject(definition)) {
|
1561
|
-
return this._buildRegionFromObject(definition);
|
1562
|
-
}
|
1563
|
-
|
1564
|
-
throw new MarionetteError({
|
1565
|
-
message: 'Improper region configuration type.',
|
1566
|
-
url: 'marionette.region.html#region-configuration-types'
|
1567
|
-
});
|
1568
|
-
},
|
1569
|
-
_buildRegionFromObject: function _buildRegionFromObject(definition) {
|
1570
|
-
var RegionClass = definition.regionClass || this.regionClass;
|
1571
|
-
|
1572
|
-
var options = _.omit(definition, 'regionClass');
|
1573
|
-
|
1574
|
-
_.defaults(options, {
|
1575
|
-
el: definition.selector,
|
1576
|
-
parentEl: _.partial(_.result, this, 'el')
|
1577
|
-
});
|
1578
|
-
|
1579
|
-
return new RegionClass(options);
|
1580
|
-
},
|
1581
|
-
|
1582
|
-
|
1583
|
-
// Build the region directly from a given `RegionClass`
|
1584
|
-
_buildRegionFromRegionClass: function _buildRegionFromRegionClass(RegionClass) {
|
1585
|
-
return new RegionClass({
|
1586
|
-
parentEl: _.partial(_.result, this, 'el')
|
1587
|
-
});
|
1588
|
-
},
|
1589
1600
|
_addRegion: function _addRegion(region, name) {
|
1590
1601
|
this.triggerMethod('before:add:region', this, name, region);
|
1591
1602
|
|
@@ -1618,8 +1629,7 @@
|
|
1618
1629
|
_removeRegion: function _removeRegion(region, name) {
|
1619
1630
|
this.triggerMethod('before:remove:region', this, name, region);
|
1620
1631
|
|
1621
|
-
region.
|
1622
|
-
region.stopListening();
|
1632
|
+
region.destroy();
|
1623
1633
|
|
1624
1634
|
delete this.regions[name];
|
1625
1635
|
delete this._regions[name];
|
@@ -1666,6 +1676,9 @@
|
|
1666
1676
|
|
1667
1677
|
return region.show.apply(region, [view].concat(args));
|
1668
1678
|
},
|
1679
|
+
detachChildView: function detachChildView(name) {
|
1680
|
+
return this.getRegion(name).detachView();
|
1681
|
+
},
|
1669
1682
|
getChildView: function getChildView(name) {
|
1670
1683
|
return this.getRegion(name).currentView;
|
1671
1684
|
}
|
@@ -1762,6 +1775,27 @@
|
|
1762
1775
|
},
|
1763
1776
|
|
1764
1777
|
|
1778
|
+
// Overriding Backbone.View's `setElement` to handle
|
1779
|
+
// if an el was previously defined. If so, the view might be
|
1780
|
+
// rendered or attached on setElement.
|
1781
|
+
setElement: function setElement() {
|
1782
|
+
var hasEl = !!this.el;
|
1783
|
+
|
1784
|
+
Backbone.View.prototype.setElement.apply(this, arguments);
|
1785
|
+
|
1786
|
+
if (hasEl) {
|
1787
|
+
this._isRendered = !!this.$el.length;
|
1788
|
+
this._isAttached = isNodeAttached(this.el);
|
1789
|
+
}
|
1790
|
+
|
1791
|
+
if (this._isRendered) {
|
1792
|
+
this.bindUIElements();
|
1793
|
+
}
|
1794
|
+
|
1795
|
+
return this;
|
1796
|
+
},
|
1797
|
+
|
1798
|
+
|
1765
1799
|
// Render the view, defaulting to underscore.js templates.
|
1766
1800
|
// You can override this in your view definition to provide
|
1767
1801
|
// a very specific rendering for your view. In general, though,
|
@@ -1824,7 +1858,7 @@
|
|
1824
1858
|
// literal. All methods and attributes from this object
|
1825
1859
|
// are copies to the object passed in.
|
1826
1860
|
mixinTemplateContext: function mixinTemplateContext() {
|
1827
|
-
var target = arguments.length
|
1861
|
+
var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
1828
1862
|
|
1829
1863
|
var templateContext = _.result(this, 'templateContext');
|
1830
1864
|
return _.extend(target, templateContext);
|
@@ -2070,7 +2104,7 @@
|
|
2070
2104
|
_initialEvents: function _initialEvents() {
|
2071
2105
|
if (this.collection) {
|
2072
2106
|
this.listenTo(this.collection, 'add', this._onCollectionAdd);
|
2073
|
-
this.listenTo(this.collection, '
|
2107
|
+
this.listenTo(this.collection, 'update', this._onCollectionUpdate);
|
2074
2108
|
this.listenTo(this.collection, 'reset', this.render);
|
2075
2109
|
|
2076
2110
|
if (this.sort) {
|
@@ -2092,17 +2126,109 @@
|
|
2092
2126
|
|
2093
2127
|
if (this._shouldAddChild(child, index)) {
|
2094
2128
|
this._destroyEmptyView();
|
2095
|
-
|
2096
|
-
|
2129
|
+
this._addChild(child, index);
|
2130
|
+
}
|
2131
|
+
},
|
2132
|
+
|
2133
|
+
|
2134
|
+
// Handle collection update model removals
|
2135
|
+
_onCollectionUpdate: function _onCollectionUpdate(collection, options) {
|
2136
|
+
var changes = options.changes;
|
2137
|
+
this._removeChildModels(changes.removed);
|
2138
|
+
},
|
2139
|
+
|
2140
|
+
|
2141
|
+
// Remove the child views and destroy them.
|
2142
|
+
// This function also updates the indices of later views
|
2143
|
+
// in the collection in order to keep the children in sync with the collection.
|
2144
|
+
// "models" is an array of models and the corresponding views
|
2145
|
+
// will be removed and destroyed from the CollectionView
|
2146
|
+
_removeChildModels: function _removeChildModels(models) {
|
2147
|
+
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
2148
|
+
|
2149
|
+
var checkEmpty = _ref.checkEmpty;
|
2150
|
+
|
2151
|
+
var shouldCheckEmpty = checkEmpty !== false;
|
2152
|
+
|
2153
|
+
// Used to determine where to update the remaining
|
2154
|
+
// sibling view indices after these views are removed.
|
2155
|
+
var removedViews = this._getRemovedViews(models);
|
2156
|
+
|
2157
|
+
if (!removedViews.length) {
|
2158
|
+
return;
|
2159
|
+
}
|
2160
|
+
|
2161
|
+
this.children._updateLength();
|
2162
|
+
|
2163
|
+
// decrement the index of views after this one
|
2164
|
+
this._updateIndices(removedViews, false);
|
2165
|
+
|
2166
|
+
if (shouldCheckEmpty) {
|
2167
|
+
this._checkEmpty();
|
2168
|
+
}
|
2169
|
+
},
|
2170
|
+
|
2171
|
+
|
2172
|
+
// Returns the views that will be used for re-indexing
|
2173
|
+
// through CollectionView#_updateIndices.
|
2174
|
+
_getRemovedViews: function _getRemovedViews(models) {
|
2175
|
+
var _this = this;
|
2176
|
+
|
2177
|
+
// Returning a view means something was removed.
|
2178
|
+
return _.reduce(models, function (removingViews, model) {
|
2179
|
+
var view = _this.children.findByModel(model);
|
2180
|
+
|
2181
|
+
if (!view || view._isDestroyed) {
|
2182
|
+
return removingViews;
|
2183
|
+
}
|
2184
|
+
|
2185
|
+
_this._removeChildView(view);
|
2186
|
+
|
2187
|
+
removingViews.push(view);
|
2188
|
+
|
2189
|
+
return removingViews;
|
2190
|
+
}, []);
|
2191
|
+
},
|
2192
|
+
_findGreatestIndexedView: function _findGreatestIndexedView(views) {
|
2193
|
+
|
2194
|
+
return _.reduce(views, function (greatestIndexedView, view) {
|
2195
|
+
// Even if the index is `undefined`, a view will get returned.
|
2196
|
+
if (!greatestIndexedView || greatestIndexedView._index < view._index) {
|
2197
|
+
return view;
|
2198
|
+
}
|
2199
|
+
|
2200
|
+
return greatestIndexedView;
|
2201
|
+
}, undefined);
|
2202
|
+
},
|
2203
|
+
_removeChildView: function _removeChildView(view) {
|
2204
|
+
this.triggerMethod('before:remove:child', this, view);
|
2205
|
+
|
2206
|
+
this.children._remove(view);
|
2207
|
+
if (view.destroy) {
|
2208
|
+
view.destroy();
|
2209
|
+
} else {
|
2210
|
+
destroyBackboneView(view);
|
2097
2211
|
}
|
2212
|
+
|
2213
|
+
delete view._parent;
|
2214
|
+
this.stopListening(view);
|
2215
|
+
this.triggerMethod('remove:child', this, view);
|
2098
2216
|
},
|
2099
2217
|
|
2100
2218
|
|
2101
|
-
//
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
this.
|
2219
|
+
// Overriding Backbone.View's `setElement` to handle
|
2220
|
+
// if an el was previously defined. If so, the view might be
|
2221
|
+
// attached on setElement.
|
2222
|
+
setElement: function setElement() {
|
2223
|
+
var hasEl = !!this.el;
|
2224
|
+
|
2225
|
+
Backbone.View.prototype.setElement.apply(this, arguments);
|
2226
|
+
|
2227
|
+
if (hasEl) {
|
2228
|
+
this._isAttached = isNodeAttached(this.el);
|
2229
|
+
}
|
2230
|
+
|
2231
|
+
return this;
|
2106
2232
|
},
|
2107
2233
|
|
2108
2234
|
|
@@ -2121,9 +2247,9 @@
|
|
2121
2247
|
// An efficient rendering used for filtering. Instead of modifying the whole DOM for the
|
2122
2248
|
// collection view, we are only adding or removing the related childrenViews.
|
2123
2249
|
setFilter: function setFilter(filter) {
|
2124
|
-
var
|
2250
|
+
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
2125
2251
|
|
2126
|
-
var preventRender =
|
2252
|
+
var preventRender = _ref2.preventRender;
|
2127
2253
|
|
2128
2254
|
var canBeRendered = this._isRendered && !this._isDestroyed;
|
2129
2255
|
var filterChanged = this.filter !== filter;
|
@@ -2150,22 +2276,22 @@
|
|
2150
2276
|
|
2151
2277
|
// Calculate and apply difference by cid between `models` and `previousModels`.
|
2152
2278
|
_applyModelDeltas: function _applyModelDeltas(models, previousModels) {
|
2153
|
-
var
|
2279
|
+
var _this2 = this;
|
2154
2280
|
|
2155
2281
|
var currentIds = {};
|
2156
2282
|
_.each(models, function (model, index) {
|
2157
|
-
var addedChildNotExists = !
|
2283
|
+
var addedChildNotExists = !_this2.children.findByModel(model);
|
2158
2284
|
if (addedChildNotExists) {
|
2159
|
-
|
2285
|
+
_this2._onCollectionAdd(model, _this2.collection, { at: index });
|
2160
2286
|
}
|
2161
2287
|
currentIds[model.cid] = true;
|
2162
2288
|
});
|
2163
|
-
|
2164
|
-
|
2165
|
-
|
2166
|
-
_this._onCollectionRemove(prevModel);
|
2167
|
-
}
|
2289
|
+
|
2290
|
+
var removeModels = _.filter(previousModels, function (prevModel) {
|
2291
|
+
return !currentIds[prevModel.cid] && _this2.children.findByModel(prevModel);
|
2168
2292
|
});
|
2293
|
+
|
2294
|
+
this._removeChildModels(removeModels);
|
2169
2295
|
},
|
2170
2296
|
|
2171
2297
|
|
@@ -2173,7 +2299,7 @@
|
|
2173
2299
|
// you can pass reorderOnSort: true to only reorder the DOM after a sort instead of
|
2174
2300
|
// rendering all the collectionView.
|
2175
2301
|
reorder: function reorder() {
|
2176
|
-
var
|
2302
|
+
var _this3 = this;
|
2177
2303
|
|
2178
2304
|
var children = this.children;
|
2179
2305
|
var models = this._filteredSortedModels();
|
@@ -2192,29 +2318,36 @@
|
|
2192
2318
|
this.render();
|
2193
2319
|
} else {
|
2194
2320
|
(function () {
|
2195
|
-
|
2196
|
-
var
|
2197
|
-
|
2321
|
+
|
2322
|
+
var filteredOutModels = [];
|
2323
|
+
|
2324
|
+
// Get the DOM nodes in the same order as the models and
|
2325
|
+
// find the model that were children before but aren't in this new order.
|
2326
|
+
var elsToReorder = children.reduce(function (viewEls, view) {
|
2327
|
+
var index = _.indexOf(models, view.model);
|
2328
|
+
|
2329
|
+
if (index === -1) {
|
2330
|
+
filteredOutModels.push(view.model);
|
2331
|
+
return viewEls;
|
2332
|
+
}
|
2333
|
+
|
2198
2334
|
view._index = index;
|
2199
|
-
return view.el;
|
2200
|
-
});
|
2201
2335
|
|
2202
|
-
|
2203
|
-
var filteredOutViews = children.filter(function (view) {
|
2204
|
-
return !_.contains(elsToReorder, view.el);
|
2205
|
-
});
|
2336
|
+
viewEls[index] = view.el;
|
2206
2337
|
|
2207
|
-
|
2338
|
+
return viewEls;
|
2339
|
+
}, new Array(models.length));
|
2340
|
+
|
2341
|
+
_this3.triggerMethod('before:reorder', _this3);
|
2208
2342
|
|
2209
2343
|
// Since append moves elements that are already in the DOM, appending the elements
|
2210
2344
|
// will effectively reorder them.
|
2211
|
-
|
2345
|
+
_this3._appendReorderedChildren(elsToReorder);
|
2212
2346
|
|
2213
2347
|
// remove any views that have been filtered out
|
2214
|
-
|
2215
|
-
_this2._checkEmpty();
|
2348
|
+
_this3._removeChildModels(filteredOutModels);
|
2216
2349
|
|
2217
|
-
|
2350
|
+
_this3.triggerMethod('reorder', _this3);
|
2218
2351
|
})();
|
2219
2352
|
}
|
2220
2353
|
return this;
|
@@ -2236,13 +2369,13 @@
|
|
2236
2369
|
// Internal method. This checks for any changes in the order of the collection.
|
2237
2370
|
// If the index of any view doesn't match, it will render.
|
2238
2371
|
_sortViews: function _sortViews() {
|
2239
|
-
var
|
2372
|
+
var _this4 = this;
|
2240
2373
|
|
2241
2374
|
var models = this._filteredSortedModels();
|
2242
2375
|
|
2243
2376
|
// check for any changes in sort order of views
|
2244
2377
|
var orderChanged = _.find(models, function (item, index) {
|
2245
|
-
var view =
|
2378
|
+
var view = _this4.children.findByModel(item);
|
2246
2379
|
return !view || view._index !== index;
|
2247
2380
|
});
|
2248
2381
|
|
@@ -2281,16 +2414,30 @@
|
|
2281
2414
|
this.triggerMethod('render:children', this);
|
2282
2415
|
}
|
2283
2416
|
},
|
2417
|
+
_createView: function _createView(model, index) {
|
2418
|
+
var ChildView = this._getChildView(model);
|
2419
|
+
var childViewOptions = this._getChildViewOptions(model, index);
|
2420
|
+
var view = this.buildChildView(model, ChildView, childViewOptions);
|
2421
|
+
return view;
|
2422
|
+
},
|
2423
|
+
_setupChildView: function _setupChildView(view, index) {
|
2424
|
+
view._parent = this;
|
2425
|
+
|
2426
|
+
monitorViewEvents(view);
|
2427
|
+
|
2428
|
+
// set up the child view event forwarding
|
2429
|
+
this._proxyChildEvents(view);
|
2430
|
+
|
2431
|
+
if (this.sort) {
|
2432
|
+
view._index = index;
|
2433
|
+
}
|
2434
|
+
},
|
2284
2435
|
|
2285
2436
|
|
2286
2437
|
// Internal method to loop through collection and show each child view.
|
2287
2438
|
_showCollection: function _showCollection(models) {
|
2288
|
-
|
2289
|
-
|
2290
|
-
_.each(models, function (child, index) {
|
2291
|
-
var ChildView = _this4._getChildView(child);
|
2292
|
-
_this4._addChild(child, ChildView, index);
|
2293
|
-
});
|
2439
|
+
_.each(models, _.bind(this._addChild, this));
|
2440
|
+
this.children._updateLength();
|
2294
2441
|
},
|
2295
2442
|
|
2296
2443
|
|
@@ -2368,10 +2515,8 @@
|
|
2368
2515
|
var view = this.buildChildView(model, EmptyView, emptyViewOptions);
|
2369
2516
|
|
2370
2517
|
this.triggerMethod('before:render:empty', this, view);
|
2371
|
-
this.
|
2518
|
+
this.addChildView(view, 0);
|
2372
2519
|
this.triggerMethod('render:empty', this, view);
|
2373
|
-
|
2374
|
-
view._parent = this;
|
2375
2520
|
}
|
2376
2521
|
},
|
2377
2522
|
|
@@ -2441,11 +2586,8 @@
|
|
2441
2586
|
|
2442
2587
|
|
2443
2588
|
// Internal method for building and adding a child view
|
2444
|
-
_addChild: function _addChild(child,
|
2445
|
-
var
|
2446
|
-
|
2447
|
-
var view = this.buildChildView(child, ChildView, childViewOptions);
|
2448
|
-
|
2589
|
+
_addChild: function _addChild(child, index) {
|
2590
|
+
var view = this._createView(child, index);
|
2449
2591
|
this.addChildView(view, index);
|
2450
2592
|
|
2451
2593
|
return view;
|
@@ -2464,13 +2606,21 @@
|
|
2464
2606
|
// children in sync with the collection.
|
2465
2607
|
addChildView: function addChildView(view, index) {
|
2466
2608
|
this.triggerMethod('before:add:child', this, view);
|
2609
|
+
this._setupChildView(view, index);
|
2467
2610
|
|
2468
|
-
//
|
2469
|
-
this.
|
2611
|
+
// Store the child view itself so we can properly remove and/or destroy it later
|
2612
|
+
if (this._isBuffering) {
|
2613
|
+
// Add to children, but don't update children's length.
|
2614
|
+
this.children._add(view);
|
2615
|
+
} else {
|
2616
|
+
// increment indices of views after this one
|
2617
|
+
this._updateIndices(view, true);
|
2618
|
+
this.children.add(view);
|
2619
|
+
}
|
2470
2620
|
|
2471
|
-
view
|
2621
|
+
this._renderView(view);
|
2472
2622
|
|
2473
|
-
this.
|
2623
|
+
this._attachView(view, index);
|
2474
2624
|
|
2475
2625
|
this.triggerMethod('add:child', this, view);
|
2476
2626
|
|
@@ -2480,15 +2630,12 @@
|
|
2480
2630
|
|
2481
2631
|
// Internal method. This decrements or increments the indices of views after the added/removed
|
2482
2632
|
// view to keep in sync with the collection.
|
2483
|
-
_updateIndices: function _updateIndices(
|
2633
|
+
_updateIndices: function _updateIndices(views, increment) {
|
2484
2634
|
if (!this.sort) {
|
2485
2635
|
return;
|
2486
2636
|
}
|
2487
2637
|
|
2488
|
-
|
2489
|
-
// assign the index to the view
|
2490
|
-
view._index = index;
|
2491
|
-
}
|
2638
|
+
var view = _.isArray(views) ? this._findGreatestIndexedView(views) : views;
|
2492
2639
|
|
2493
2640
|
// update the indexes of views after this one
|
2494
2641
|
this.children.each(function (laterView) {
|
@@ -2497,39 +2644,31 @@
|
|
2497
2644
|
}
|
2498
2645
|
});
|
2499
2646
|
},
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
// Only trigger attach if already attached and not buffering,
|
2505
|
-
// otherwise _endBuffering() or Region#show() handles this.
|
2506
|
-
var shouldTriggerAttach = !this._isBuffering && this._isAttached;
|
2507
|
-
|
2508
|
-
monitorViewEvents(view);
|
2509
|
-
|
2510
|
-
// set up the child view event forwarding
|
2511
|
-
this._proxyChildEvents(view);
|
2512
|
-
|
2513
|
-
// Store the child view itself so we can properly remove and/or destroy it later
|
2514
|
-
this.children.add(view);
|
2647
|
+
_renderView: function _renderView(view) {
|
2648
|
+
if (view._isRendered) {
|
2649
|
+
return;
|
2650
|
+
}
|
2515
2651
|
|
2516
2652
|
if (!view.supportsRenderLifecycle) {
|
2517
2653
|
triggerMethodOn(view, 'before:render', view);
|
2518
2654
|
}
|
2519
2655
|
|
2520
|
-
// Render view
|
2521
2656
|
view.render();
|
2522
2657
|
|
2523
2658
|
if (!view.supportsRenderLifecycle) {
|
2524
2659
|
view._isRendered = true;
|
2525
2660
|
triggerMethodOn(view, 'render', view);
|
2526
2661
|
}
|
2662
|
+
},
|
2663
|
+
_attachView: function _attachView(view, index) {
|
2664
|
+
// Only trigger attach if already attached and not buffering,
|
2665
|
+
// otherwise _endBuffering() or Region#show() handles this.
|
2666
|
+
var shouldTriggerAttach = !view._isAttached && !this._isBuffering && this._isAttached;
|
2527
2667
|
|
2528
2668
|
if (shouldTriggerAttach) {
|
2529
2669
|
triggerMethodOn(view, 'before:attach', view);
|
2530
2670
|
}
|
2531
2671
|
|
2532
|
-
// Attach view
|
2533
2672
|
this.attachHtml(this, view, index);
|
2534
2673
|
|
2535
2674
|
if (shouldTriggerAttach) {
|
@@ -2553,22 +2692,10 @@
|
|
2553
2692
|
return view;
|
2554
2693
|
}
|
2555
2694
|
|
2556
|
-
this.
|
2557
|
-
|
2558
|
-
if (view.destroy) {
|
2559
|
-
view.destroy();
|
2560
|
-
} else {
|
2561
|
-
destroyBackboneView(view);
|
2562
|
-
}
|
2563
|
-
|
2564
|
-
delete view._parent;
|
2565
|
-
this.stopListening(view);
|
2566
|
-
this.children.remove(view);
|
2567
|
-
this.triggerMethod('remove:child', this, view);
|
2568
|
-
|
2695
|
+
this._removeChildView(view);
|
2696
|
+
this.children._updateLength();
|
2569
2697
|
// decrement the index of views after this one
|
2570
2698
|
this._updateIndices(view, false);
|
2571
|
-
|
2572
2699
|
return view;
|
2573
2700
|
},
|
2574
2701
|
|
@@ -2668,23 +2795,15 @@
|
|
2668
2795
|
|
2669
2796
|
|
2670
2797
|
// Destroy the child views that this collection view is holding on to, if any
|
2671
|
-
_destroyChildren: function _destroyChildren() {
|
2672
|
-
|
2673
|
-
|
2674
|
-
var checkEmpty = _ref2.checkEmpty;
|
2675
|
-
|
2676
|
-
this.triggerMethod('before:destroy:children', this);
|
2677
|
-
var shouldCheckEmpty = checkEmpty !== false;
|
2678
|
-
var childViews = this.children.map(_.identity);
|
2679
|
-
|
2680
|
-
this.children.each(_.bind(this.removeChildView, this));
|
2681
|
-
|
2682
|
-
if (shouldCheckEmpty) {
|
2683
|
-
this._checkEmpty();
|
2798
|
+
_destroyChildren: function _destroyChildren(options) {
|
2799
|
+
if (!this.children.length) {
|
2800
|
+
return;
|
2684
2801
|
}
|
2685
2802
|
|
2803
|
+
this.triggerMethod('before:destroy:children', this);
|
2804
|
+
var childModels = this.children.map('model');
|
2805
|
+
this._removeChildModels(childModels, options);
|
2686
2806
|
this.triggerMethod('destroy:children', this);
|
2687
|
-
return childViews;
|
2688
2807
|
},
|
2689
2808
|
|
2690
2809
|
|
@@ -2701,36 +2820,7 @@
|
|
2701
2820
|
|
2702
2821
|
// Set up the child view event forwarding. Uses a "childview:" prefix in front of all forwarded events.
|
2703
2822
|
_proxyChildEvents: function _proxyChildEvents(view) {
|
2704
|
-
|
2705
|
-
|
2706
|
-
var prefix = _.result(this, 'childViewEventPrefix');
|
2707
|
-
|
2708
|
-
// Forward all child view events through the parent,
|
2709
|
-
// prepending "childview:" to the event name
|
2710
|
-
this.listenTo(view, 'all', function (eventName) {
|
2711
|
-
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
2712
|
-
args[_key - 1] = arguments[_key];
|
2713
|
-
}
|
2714
|
-
|
2715
|
-
var childEventName = prefix + ':' + eventName;
|
2716
|
-
|
2717
|
-
var childViewEvents = _this6.normalizeMethods(_this6._childViewEvents);
|
2718
|
-
|
2719
|
-
// call collectionView childViewEvent if defined
|
2720
|
-
if (typeof childViewEvents !== 'undefined' && _.isFunction(childViewEvents[eventName])) {
|
2721
|
-
childViewEvents[eventName].apply(_this6, args);
|
2722
|
-
}
|
2723
|
-
|
2724
|
-
// use the parent view's proxyEvent handlers
|
2725
|
-
var childViewTriggers = _this6._childViewTriggers;
|
2726
|
-
|
2727
|
-
// Call the event with the proxy name on the parent layout
|
2728
|
-
if (childViewTriggers && _.isString(childViewTriggers[eventName])) {
|
2729
|
-
_this6.triggerMethod.apply(_this6, [childViewTriggers[eventName]].concat(args));
|
2730
|
-
}
|
2731
|
-
|
2732
|
-
_this6.triggerMethod.apply(_this6, [childEventName].concat(args));
|
2733
|
-
});
|
2823
|
+
this.listenTo(view, 'all', this._childViewEventHandler);
|
2734
2824
|
}
|
2735
2825
|
});
|
2736
2826
|
|
@@ -2767,7 +2857,7 @@
|
|
2767
2857
|
|
2768
2858
|
if (this.collection) {
|
2769
2859
|
this.listenTo(this.collection, 'add', this._onCollectionAdd);
|
2770
|
-
this.listenTo(this.collection, '
|
2860
|
+
this.listenTo(this.collection, 'update', this._onCollectionUpdate);
|
2771
2861
|
this.listenTo(this.collection, 'reset', this.renderChildren);
|
2772
2862
|
|
2773
2863
|
if (this.sort) {
|
@@ -2986,6 +3076,8 @@
|
|
2986
3076
|
return this;
|
2987
3077
|
},
|
2988
3078
|
getEvents: function getEvents() {
|
3079
|
+
var _this = this;
|
3080
|
+
|
2989
3081
|
// Normalize behavior events hash to allow
|
2990
3082
|
// a user to use the @ui. syntax.
|
2991
3083
|
var behaviorEvents = this.normalizeUIKeys(_.result(this, 'events'));
|
@@ -2993,15 +3085,15 @@
|
|
2993
3085
|
// binds the handler to the behavior and builds a unique eventName
|
2994
3086
|
return _.reduce(behaviorEvents, function (events, behaviorHandler, key) {
|
2995
3087
|
if (!_.isFunction(behaviorHandler)) {
|
2996
|
-
behaviorHandler =
|
3088
|
+
behaviorHandler = _this[behaviorHandler];
|
2997
3089
|
}
|
2998
3090
|
if (!behaviorHandler) {
|
2999
3091
|
return;
|
3000
3092
|
}
|
3001
3093
|
key = getUniqueEventName(key);
|
3002
|
-
events[key] = _.bind(behaviorHandler,
|
3094
|
+
events[key] = _.bind(behaviorHandler, _this);
|
3003
3095
|
return events;
|
3004
|
-
}, {}
|
3096
|
+
}, {});
|
3005
3097
|
},
|
3006
3098
|
|
3007
3099
|
|
@@ -3040,20 +3132,18 @@
|
|
3040
3132
|
|
3041
3133
|
regionClass: Region,
|
3042
3134
|
|
3043
|
-
_initRegion: function _initRegion(
|
3135
|
+
_initRegion: function _initRegion() {
|
3044
3136
|
var region = this.region;
|
3045
|
-
var RegionClass = this.regionClass;
|
3046
3137
|
|
3047
|
-
|
3048
|
-
// and instantiate a region
|
3049
|
-
if (_.isString(region)) {
|
3050
|
-
this._region = new RegionClass({
|
3051
|
-
el: region
|
3052
|
-
});
|
3138
|
+
if (!region) {
|
3053
3139
|
return;
|
3054
3140
|
}
|
3055
3141
|
|
3056
|
-
|
3142
|
+
var defaults = {
|
3143
|
+
regionClass: this.regionClass
|
3144
|
+
};
|
3145
|
+
|
3146
|
+
this._region = buildRegion(region, defaults);
|
3057
3147
|
},
|
3058
3148
|
getRegion: function getRegion() {
|
3059
3149
|
return this._region;
|