marionette-rails 1.0.0.rc1 → 1.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/vendor/assets/javascripts/backbone.marionette.js +185 -154
- metadata +1 -1
@@ -1,17 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
// Backbone.Marionette, v1.0.0-rc2
|
2
|
+
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
3
|
+
// Distributed under MIT license
|
4
|
+
// http://github.com/marionettejs/backbone.marionette
|
5
|
+
|
6
|
+
|
7
7
|
/*!
|
8
8
|
* Includes BabySitter
|
9
9
|
* https://github.com/marionettejs/backbone.babysitter/
|
10
|
+
*
|
10
11
|
* Includes Wreqr
|
11
12
|
* https://github.com/marionettejs/backbone.wreqr/
|
13
|
+
*
|
12
14
|
* Includes EventBinder
|
13
15
|
* https://github.com/marionettejs/backbone.eventbinder/
|
14
16
|
*/
|
17
|
+
|
18
|
+
|
15
19
|
// Backbone.BabySitter, v0.0.4
|
16
20
|
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
17
21
|
// Distributed under MIT license
|
@@ -572,6 +576,48 @@ Marionette.triggerMethod = function(){
|
|
572
576
|
}
|
573
577
|
};
|
574
578
|
|
579
|
+
// DOMRefresh
|
580
|
+
// ----------
|
581
|
+
//
|
582
|
+
// Monitor a view's state, and after it has been rendered and shown
|
583
|
+
// in the DOM, trigger a "dom:refresh" event every time it is
|
584
|
+
// re-rendered.
|
585
|
+
|
586
|
+
Marionette.MonitorDOMRefresh = (function(){
|
587
|
+
// track when the view has been rendered
|
588
|
+
function handleShow(view){
|
589
|
+
view._isShown = true;
|
590
|
+
triggerDOMRefresh(view);
|
591
|
+
}
|
592
|
+
|
593
|
+
// track when the view has been shown in the DOM,
|
594
|
+
// using a Marionette.Region (or by other means of triggering "show")
|
595
|
+
function handleRender(view){
|
596
|
+
view._isRendered = true;
|
597
|
+
triggerDOMRefresh(view);
|
598
|
+
}
|
599
|
+
|
600
|
+
// Trigger the "dom:refresh" event and corresponding "onDomRefresh" method
|
601
|
+
function triggerDOMRefresh(view){
|
602
|
+
if (view._isShown && view._isRendered){
|
603
|
+
if (_.isFunction(view.triggerMethod)){
|
604
|
+
view.triggerMethod("dom:refresh");
|
605
|
+
}
|
606
|
+
}
|
607
|
+
}
|
608
|
+
|
609
|
+
// Export public API
|
610
|
+
return function(view){
|
611
|
+
view.bindTo(view, "show", function(){
|
612
|
+
handleShow(view);
|
613
|
+
});
|
614
|
+
|
615
|
+
view.bindTo(view, "render", function(){
|
616
|
+
handleRender(view);
|
617
|
+
});
|
618
|
+
};
|
619
|
+
})();
|
620
|
+
|
575
621
|
|
576
622
|
// EventBinder
|
577
623
|
// -----------
|
@@ -722,125 +768,6 @@ _.extend(Marionette.Callbacks.prototype, {
|
|
722
768
|
});
|
723
769
|
|
724
770
|
|
725
|
-
// Template Cache
|
726
|
-
// --------------
|
727
|
-
|
728
|
-
// Manage templates stored in `<script>` blocks,
|
729
|
-
// caching them for faster access.
|
730
|
-
Marionette.TemplateCache = function(templateId){
|
731
|
-
this.templateId = templateId;
|
732
|
-
};
|
733
|
-
|
734
|
-
// TemplateCache object-level methods. Manage the template
|
735
|
-
// caches from these method calls instead of creating
|
736
|
-
// your own TemplateCache instances
|
737
|
-
_.extend(Marionette.TemplateCache, {
|
738
|
-
templateCaches: {},
|
739
|
-
|
740
|
-
// Get the specified template by id. Either
|
741
|
-
// retrieves the cached version, or loads it
|
742
|
-
// from the DOM.
|
743
|
-
get: function(templateId){
|
744
|
-
var that = this;
|
745
|
-
var cachedTemplate = this.templateCaches[templateId];
|
746
|
-
|
747
|
-
if (!cachedTemplate){
|
748
|
-
cachedTemplate = new Marionette.TemplateCache(templateId);
|
749
|
-
this.templateCaches[templateId] = cachedTemplate;
|
750
|
-
}
|
751
|
-
|
752
|
-
return cachedTemplate.load();
|
753
|
-
},
|
754
|
-
|
755
|
-
// Clear templates from the cache. If no arguments
|
756
|
-
// are specified, clears all templates:
|
757
|
-
// `clear()`
|
758
|
-
//
|
759
|
-
// If arguments are specified, clears each of the
|
760
|
-
// specified templates from the cache:
|
761
|
-
// `clear("#t1", "#t2", "...")`
|
762
|
-
clear: function(){
|
763
|
-
var i;
|
764
|
-
var args = Array.prototype.slice.apply(arguments);
|
765
|
-
var length = args.length;
|
766
|
-
|
767
|
-
if (length > 0){
|
768
|
-
for(i=0; i<length; i++){
|
769
|
-
delete this.templateCaches[args[i]];
|
770
|
-
}
|
771
|
-
} else {
|
772
|
-
this.templateCaches = {};
|
773
|
-
}
|
774
|
-
}
|
775
|
-
});
|
776
|
-
|
777
|
-
// TemplateCache instance methods, allowing each
|
778
|
-
// template cache object to manage it's own state
|
779
|
-
// and know whether or not it has been loaded
|
780
|
-
_.extend(Marionette.TemplateCache.prototype, {
|
781
|
-
|
782
|
-
// Internal method to load the template asynchronously.
|
783
|
-
load: function(){
|
784
|
-
var that = this;
|
785
|
-
|
786
|
-
// Guard clause to prevent loading this template more than once
|
787
|
-
if (this.compiledTemplate){
|
788
|
-
return this.compiledTemplate;
|
789
|
-
}
|
790
|
-
|
791
|
-
// Load the template and compile it
|
792
|
-
var template = this.loadTemplate(this.templateId);
|
793
|
-
this.compiledTemplate = this.compileTemplate(template);
|
794
|
-
|
795
|
-
return this.compiledTemplate;
|
796
|
-
},
|
797
|
-
|
798
|
-
// Load a template from the DOM, by default. Override
|
799
|
-
// this method to provide your own template retrieval,
|
800
|
-
// such as asynchronous loading from a server.
|
801
|
-
loadTemplate: function(templateId){
|
802
|
-
var template = $(templateId).html();
|
803
|
-
|
804
|
-
if (!template || template.length === 0){
|
805
|
-
var msg = "Could not find template: '" + templateId + "'";
|
806
|
-
var err = new Error(msg);
|
807
|
-
err.name = "NoTemplateError";
|
808
|
-
throw err;
|
809
|
-
}
|
810
|
-
|
811
|
-
return template;
|
812
|
-
},
|
813
|
-
|
814
|
-
// Pre-compile the template before caching it. Override
|
815
|
-
// this method if you do not need to pre-compile a template
|
816
|
-
// (JST / RequireJS for example) or if you want to change
|
817
|
-
// the template engine used (Handebars, etc).
|
818
|
-
compileTemplate: function(rawTemplate){
|
819
|
-
return _.template(rawTemplate);
|
820
|
-
}
|
821
|
-
});
|
822
|
-
|
823
|
-
|
824
|
-
// Renderer
|
825
|
-
// --------
|
826
|
-
|
827
|
-
// Render a template with data by passing in the template
|
828
|
-
// selector and the data to render.
|
829
|
-
Marionette.Renderer = {
|
830
|
-
|
831
|
-
// Render a template with data. The `template` parameter is
|
832
|
-
// passed to the `TemplateCache` object to retrieve the
|
833
|
-
// template function. Override this method to provide your own
|
834
|
-
// custom rendering and template handling for all of Marionette.
|
835
|
-
render: function(template, data){
|
836
|
-
var templateFunc = typeof template === 'function' ? template : Marionette.TemplateCache.get(template);
|
837
|
-
var html = templateFunc(data);
|
838
|
-
return html;
|
839
|
-
}
|
840
|
-
};
|
841
|
-
|
842
|
-
|
843
|
-
|
844
771
|
// Marionette Controller
|
845
772
|
// ---------------------
|
846
773
|
//
|
@@ -1040,6 +967,125 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
|
|
1040
967
|
Marionette.Region.extend = Marionette.extend;
|
1041
968
|
|
1042
969
|
|
970
|
+
// Template Cache
|
971
|
+
// --------------
|
972
|
+
|
973
|
+
// Manage templates stored in `<script>` blocks,
|
974
|
+
// caching them for faster access.
|
975
|
+
Marionette.TemplateCache = function(templateId){
|
976
|
+
this.templateId = templateId;
|
977
|
+
};
|
978
|
+
|
979
|
+
// TemplateCache object-level methods. Manage the template
|
980
|
+
// caches from these method calls instead of creating
|
981
|
+
// your own TemplateCache instances
|
982
|
+
_.extend(Marionette.TemplateCache, {
|
983
|
+
templateCaches: {},
|
984
|
+
|
985
|
+
// Get the specified template by id. Either
|
986
|
+
// retrieves the cached version, or loads it
|
987
|
+
// from the DOM.
|
988
|
+
get: function(templateId){
|
989
|
+
var that = this;
|
990
|
+
var cachedTemplate = this.templateCaches[templateId];
|
991
|
+
|
992
|
+
if (!cachedTemplate){
|
993
|
+
cachedTemplate = new Marionette.TemplateCache(templateId);
|
994
|
+
this.templateCaches[templateId] = cachedTemplate;
|
995
|
+
}
|
996
|
+
|
997
|
+
return cachedTemplate.load();
|
998
|
+
},
|
999
|
+
|
1000
|
+
// Clear templates from the cache. If no arguments
|
1001
|
+
// are specified, clears all templates:
|
1002
|
+
// `clear()`
|
1003
|
+
//
|
1004
|
+
// If arguments are specified, clears each of the
|
1005
|
+
// specified templates from the cache:
|
1006
|
+
// `clear("#t1", "#t2", "...")`
|
1007
|
+
clear: function(){
|
1008
|
+
var i;
|
1009
|
+
var args = Array.prototype.slice.apply(arguments);
|
1010
|
+
var length = args.length;
|
1011
|
+
|
1012
|
+
if (length > 0){
|
1013
|
+
for(i=0; i<length; i++){
|
1014
|
+
delete this.templateCaches[args[i]];
|
1015
|
+
}
|
1016
|
+
} else {
|
1017
|
+
this.templateCaches = {};
|
1018
|
+
}
|
1019
|
+
}
|
1020
|
+
});
|
1021
|
+
|
1022
|
+
// TemplateCache instance methods, allowing each
|
1023
|
+
// template cache object to manage it's own state
|
1024
|
+
// and know whether or not it has been loaded
|
1025
|
+
_.extend(Marionette.TemplateCache.prototype, {
|
1026
|
+
|
1027
|
+
// Internal method to load the template asynchronously.
|
1028
|
+
load: function(){
|
1029
|
+
var that = this;
|
1030
|
+
|
1031
|
+
// Guard clause to prevent loading this template more than once
|
1032
|
+
if (this.compiledTemplate){
|
1033
|
+
return this.compiledTemplate;
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
// Load the template and compile it
|
1037
|
+
var template = this.loadTemplate(this.templateId);
|
1038
|
+
this.compiledTemplate = this.compileTemplate(template);
|
1039
|
+
|
1040
|
+
return this.compiledTemplate;
|
1041
|
+
},
|
1042
|
+
|
1043
|
+
// Load a template from the DOM, by default. Override
|
1044
|
+
// this method to provide your own template retrieval,
|
1045
|
+
// such as asynchronous loading from a server.
|
1046
|
+
loadTemplate: function(templateId){
|
1047
|
+
var template = $(templateId).html();
|
1048
|
+
|
1049
|
+
if (!template || template.length === 0){
|
1050
|
+
var msg = "Could not find template: '" + templateId + "'";
|
1051
|
+
var err = new Error(msg);
|
1052
|
+
err.name = "NoTemplateError";
|
1053
|
+
throw err;
|
1054
|
+
}
|
1055
|
+
|
1056
|
+
return template;
|
1057
|
+
},
|
1058
|
+
|
1059
|
+
// Pre-compile the template before caching it. Override
|
1060
|
+
// this method if you do not need to pre-compile a template
|
1061
|
+
// (JST / RequireJS for example) or if you want to change
|
1062
|
+
// the template engine used (Handebars, etc).
|
1063
|
+
compileTemplate: function(rawTemplate){
|
1064
|
+
return _.template(rawTemplate);
|
1065
|
+
}
|
1066
|
+
});
|
1067
|
+
|
1068
|
+
|
1069
|
+
// Renderer
|
1070
|
+
// --------
|
1071
|
+
|
1072
|
+
// Render a template with data by passing in the template
|
1073
|
+
// selector and the data to render.
|
1074
|
+
Marionette.Renderer = {
|
1075
|
+
|
1076
|
+
// Render a template with data. The `template` parameter is
|
1077
|
+
// passed to the `TemplateCache` object to retrieve the
|
1078
|
+
// template function. Override this method to provide your own
|
1079
|
+
// custom rendering and template handling for all of Marionette.
|
1080
|
+
render: function(template, data){
|
1081
|
+
var templateFunc = typeof template === 'function' ? template : Marionette.TemplateCache.get(template);
|
1082
|
+
var html = templateFunc(data);
|
1083
|
+
return html;
|
1084
|
+
}
|
1085
|
+
};
|
1086
|
+
|
1087
|
+
|
1088
|
+
|
1043
1089
|
// Marionette.View
|
1044
1090
|
// ---------------
|
1045
1091
|
|
@@ -1056,6 +1102,7 @@ Marionette.View = Backbone.View.extend({
|
|
1056
1102
|
Marionette.bindEntityEvents(this, this.model, Marionette.getOption(this, "modelEvents"));
|
1057
1103
|
Marionette.bindEntityEvents(this, this.collection, Marionette.getOption(this, "collectionEvents"));
|
1058
1104
|
|
1105
|
+
Marionette.MonitorDOMRefresh(this);
|
1059
1106
|
this.bindTo(this, "show", this.onShowCalled, this);
|
1060
1107
|
},
|
1061
1108
|
|
@@ -1134,16 +1181,20 @@ Marionette.View = Backbone.View.extend({
|
|
1134
1181
|
close: function(){
|
1135
1182
|
if (this.isClosed) { return; }
|
1136
1183
|
|
1184
|
+
// allow the close to be stopped by returning `false`
|
1185
|
+
// from the `onBeforeClose` method
|
1137
1186
|
var shouldClose = this.triggerMethod("before:close");
|
1138
1187
|
if (shouldClose === false){
|
1139
1188
|
return;
|
1140
1189
|
}
|
1141
1190
|
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1191
|
+
// mark as closed before doing the actual close, to
|
1192
|
+
// prevent infinite loops within "close" event handlers
|
1193
|
+
// that are trying to close other views
|
1145
1194
|
this.isClosed = true;
|
1146
1195
|
|
1196
|
+
this.remove();
|
1197
|
+
this.triggerMethod("close");
|
1147
1198
|
this.unbindAll();
|
1148
1199
|
},
|
1149
1200
|
|
@@ -1183,29 +1234,6 @@ Marionette.ItemView = Marionette.View.extend({
|
|
1183
1234
|
if (this.initialEvents){
|
1184
1235
|
this.initialEvents();
|
1185
1236
|
}
|
1186
|
-
|
1187
|
-
this.bindTo(this, "show", this._handleShow, this);
|
1188
|
-
this.bindTo(this, "render", this._handleRender, this);
|
1189
|
-
},
|
1190
|
-
|
1191
|
-
// internal event handler to track when the view has been rendered
|
1192
|
-
_handleShow: function(){
|
1193
|
-
this._isShown = true;
|
1194
|
-
this.triggerDOMRefresh();
|
1195
|
-
},
|
1196
|
-
|
1197
|
-
// internal event handler to track when the view has been shown in the DOM,
|
1198
|
-
// using a Marionette.Region (or by other means of triggering "show")
|
1199
|
-
_handleRender: function(){
|
1200
|
-
this._isRendered = true;
|
1201
|
-
this.triggerDOMRefresh();
|
1202
|
-
},
|
1203
|
-
|
1204
|
-
// Trigger the "dom:refresh" event and corresponding "onDomRefresh" method
|
1205
|
-
triggerDOMRefresh: function(){
|
1206
|
-
if (this._isShown && this._isRendered){
|
1207
|
-
this.triggerMethod("dom:refresh");
|
1208
|
-
}
|
1209
1237
|
},
|
1210
1238
|
|
1211
1239
|
// Serialize the model or collection for the view. If a model is
|
@@ -1279,12 +1307,12 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1279
1307
|
// constructor
|
1280
1308
|
constructor: function(options){
|
1281
1309
|
this.initChildViewStorage();
|
1310
|
+
this.onShowCallbacks = new Marionette.Callbacks();
|
1282
1311
|
|
1283
1312
|
var args = Array.prototype.slice.apply(arguments);
|
1284
1313
|
Marionette.View.prototype.constructor.apply(this, args);
|
1285
1314
|
|
1286
1315
|
this.initialEvents();
|
1287
|
-
this.onShowCallbacks = new Marionette.Callbacks();
|
1288
1316
|
},
|
1289
1317
|
|
1290
1318
|
// Configured the initial events that the collection view
|
@@ -1419,6 +1447,9 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1419
1447
|
// set up the child view event forwarding
|
1420
1448
|
this.addChildViewEventForwarding(view);
|
1421
1449
|
|
1450
|
+
// this view is about to be added
|
1451
|
+
this.triggerMethod("before:item:added", view);
|
1452
|
+
|
1422
1453
|
// Store the child view itself so we can properly
|
1423
1454
|
// remove and/or close it later
|
1424
1455
|
this.children.add(view);
|
@@ -1426,8 +1457,8 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1426
1457
|
// Render it and show it
|
1427
1458
|
var renderResult = this.renderItemView(view, index);
|
1428
1459
|
|
1429
|
-
//
|
1430
|
-
this.triggerMethod("item:added", view);
|
1460
|
+
// this view was added
|
1461
|
+
this.triggerMethod("after:item:added", view);
|
1431
1462
|
|
1432
1463
|
// call onShow for child item views
|
1433
1464
|
if (view.onShow){
|