yano-backbone-rails 2.2.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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;
|