marionette_dust 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/README.md +11 -8
- data/lib/dust_engine/dust.rb +1 -1
- data/lib/generators/md/common/templates/controller.js +1 -1
- data/lib/generators/md/common/templates/controller.js.coffee +1 -1
- data/lib/generators/md/common/templates/view.js +2 -2
- data/lib/generators/md/common/templates/view.js.coffee +1 -1
- data/lib/generators/md/helpers.rb +14 -10
- data/lib/generators/md/install/install_generator.rb +4 -6
- data/lib/generators/md/install/templates/.gitkeep +0 -0
- data/lib/generators/md/scaffold/scaffold_generator.rb +4 -9
- data/lib/generators/md/submodule/submodule_generator.rb +11 -7
- data/lib/marionette_dust/version.rb +1 -1
- data/vendor/assets/javascripts/marionette_dust/backbone.marionette.js +261 -91
- data/vendor/assets/javascripts/marionette_dust/template_loader.js +21 -11
- metadata +20 -19
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTBhMmQyODYzYmM2Njk2MDU5Yjg4M2UyYzQxZDY3NjY3NWY5ZTYxOQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OGUyMDFlM2EwZWE2ZDU4NjJlZmExNGE2OTlmMDIyNTgwMWQyY2UwNA==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MGZiNzVjNWUyOTc5YjNlNDdjZmI1MjM1ZTczM2Y2YTQ4NTFjNmE3ZDI1OTNj
|
10
|
+
OTgzNzM4YzRmZDA0YWI0NWQwYzM0MjFlOTRjNjZhNDE0NDY4ODE5MWFmM2Qw
|
11
|
+
MTFkMTRiOWY0N2NjYmFhYjk1Y2M2YjIzMTk0MTY2ZTUwNmRmNTc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ODE3OGQ2ZjhiZTcwMzgwZDg3MTg2N2QyYTk0ZDRjM2RmZTQ3ZTEzOGVjYjU1
|
14
|
+
ZDMxN2JiMzY0ZjhkNGU2ZTI3ZGNlODg5MmFjZGQ3ZjA4ZDJlYzFjNTZhZjg1
|
15
|
+
N2IzODEyZjA4MWMwNzJmZTY0ZmNhNjQ5ZmMxYWM3NmY5MGE2NjE=
|
data/README.md
CHANGED
@@ -104,7 +104,7 @@ Also this project is inspired by:
|
|
104
104
|
|
105
105
|
[Backbone on rails][7] and [Dust assets][6]
|
106
106
|
|
107
|
-
|
107
|
+
Special thanks to [@sauron][8] for making the test suite possible
|
108
108
|
|
109
109
|
Contributing
|
110
110
|
-------
|
@@ -115,7 +115,7 @@ Contributing
|
|
115
115
|
4. Push to the branch (`git push origin my-new-feature`)
|
116
116
|
5. Create new Pull Request
|
117
117
|
|
118
|
-
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/0fcf36aa176a3fc30ebbec87bf7b28d2 "githalytics.com")](http://githalytics.com/
|
118
|
+
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/0fcf36aa176a3fc30ebbec87bf7b28d2 "githalytics.com")](http://githalytics.com/roperzh/marionette_dust-rails)
|
119
119
|
|
120
120
|
[1]: http://marionettejs.com/
|
121
121
|
[2]: http://linkedin.github.io/dustjs/
|
@@ -124,13 +124,16 @@ Contributing
|
|
124
124
|
[5]: http://www.backbonerails.com/
|
125
125
|
[6]: https://github.com/hasmanydevelopers/dust_assets
|
126
126
|
[7]: https://github.com/meleyal/backbone-on-rails
|
127
|
+
[8]: https://github.com/sauron
|
127
128
|
|
128
|
-
[Build Status]: https://travis-ci.org/
|
129
|
-
[Code Climate]: https://codeclimate.com/github/
|
130
|
-
[Gemnasium]: https://gemnasium.com/
|
129
|
+
[Build Status]: https://travis-ci.org/roperzh/marionette_dust-rails
|
130
|
+
[Code Climate]: https://codeclimate.com/github/roperzh/marionette_dust-rails
|
131
|
+
[Gemnasium]: https://gemnasium.com/roperzh/marionette_dust-rails
|
131
132
|
[Gem Version]: https://rubygems.org/gems/marionette_dust
|
132
133
|
|
133
|
-
[BS img]: https://travis-ci.org/
|
134
|
-
[CC img]: https://codeclimate.com/github/
|
135
|
-
[GM img]: https://gemnasium.com/
|
134
|
+
[BS img]: https://travis-ci.org/roperzh/marionette_dust-rails.png
|
135
|
+
[CC img]: https://codeclimate.com/github/roperzh/marionette_dust-rails.png
|
136
|
+
[GM img]: https://gemnasium.com/roperzh/marionette_dust-rails.png
|
136
137
|
[GV img]: https://badge.fury.io/rb/marionette_dust.png
|
138
|
+
|
139
|
+
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/roperzh/marionette_dust-rails/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
|
data/lib/dust_engine/dust.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= app_name %>.module("<%=
|
1
|
+
<%= app_name %>.module("<%= @parent_name.camelize %>.<%= file_name.camelize %>", function (<%= sub_app_scope %>, <%= app_name %>, Backbone, Marionette, $, _) {
|
2
2
|
<%= sub_app_scope %>.Controller = {};
|
3
3
|
});
|
@@ -1,2 +1,2 @@
|
|
1
|
-
<%= app_name %>.module "<%=
|
1
|
+
<%= app_name %>.module "<%= @parent_name.camelize %>.<%= file_name.camelize %>", (<%= sub_app_scope %>, <%= app_name %>, Backbone, Marionette, $, _) ->
|
2
2
|
<%= sub_app_scope %>.Controller = {}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
<%= app_name %>.module("<%=
|
1
|
+
<%= app_name %>.module("<%= @parent_name.camelize %>.<%= file_name.camelize %>", function (<%= sub_app_scope %>, <%= app_name %>, Backbone, Marionette, $, _) {
|
2
2
|
<%= sub_app_scope %>.View = Marionette.ItemView.extend({
|
3
|
-
template: "
|
3
|
+
template: "<%= @submodule_name %>.jst.dust"
|
4
4
|
});
|
5
5
|
});
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<%= app_name %>.module "<%= file_name.capitalize %>.<%= sub_app_scope %>", (<%= sub_app_scope %>, <%= app_name %>, Backbone, Marionette, $, _) ->
|
2
2
|
|
3
|
-
<%= sub_app_scope %>.View = Marionette.ItemView.extend(template: "
|
3
|
+
<%= sub_app_scope %>.View = Marionette.ItemView.extend(template: "<%= @submodule_name %>.jst.dust")
|
@@ -23,15 +23,15 @@ module MarionetteDust
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def singular_file_name
|
26
|
-
"#{file_name.singularize}#{
|
26
|
+
"#{file_name.singularize}#{extension}"
|
27
27
|
end
|
28
28
|
|
29
29
|
def plural_file_name
|
30
|
-
"#{file_name.pluralize}#{
|
30
|
+
"#{file_name.pluralize}#{extension}"
|
31
31
|
end
|
32
32
|
|
33
33
|
def asset_file_name(type)
|
34
|
-
"#{@submodule_name.downcase.singularize}_#{type}#{
|
34
|
+
"#{@submodule_name.downcase.singularize}_#{type}#{extension}"
|
35
35
|
end
|
36
36
|
|
37
37
|
def singular_entity_name
|
@@ -43,29 +43,33 @@ module MarionetteDust
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def sub_app_name
|
46
|
-
[file_name.
|
46
|
+
[file_name.camelize, "App"].join("")
|
47
47
|
end
|
48
48
|
|
49
49
|
def sub_app_file_name
|
50
|
-
[file_name.singularize.downcase, "_app", "#{
|
50
|
+
[file_name.singularize.downcase, "_app", "#{extension}"].join("")
|
51
51
|
end
|
52
52
|
|
53
53
|
def sub_app_scope
|
54
|
-
@submodule_name.
|
54
|
+
@submodule_name.camelize
|
55
55
|
end
|
56
56
|
|
57
|
-
def
|
58
|
-
|
57
|
+
def extension
|
58
|
+
@ext ||= options.coffeescript ? ".js.coffee" : ".js"
|
59
59
|
end
|
60
60
|
|
61
|
-
def
|
62
|
-
rails_app_name.
|
61
|
+
def app_name
|
62
|
+
rails_app_name.camelize
|
63
63
|
end
|
64
64
|
|
65
65
|
def rails_app_name
|
66
66
|
Rails.application.class.name.split('::').first
|
67
67
|
end
|
68
68
|
|
69
|
+
def trackeable_directory(path)
|
70
|
+
empty_directory path
|
71
|
+
template ".gitkeep", "#{path}/.gitkeep"
|
72
|
+
end
|
69
73
|
end
|
70
74
|
end
|
71
75
|
end
|
@@ -22,15 +22,13 @@ module Md
|
|
22
22
|
desc: "Javascript manifest file to modify (or create)"
|
23
23
|
|
24
24
|
def create_dir_layout
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
trackeable_directory entities_path
|
26
|
+
trackeable_directory template_path
|
27
|
+
trackeable_directory apps_path
|
28
28
|
end
|
29
29
|
|
30
30
|
def create_app_file
|
31
|
-
|
32
|
-
ext = coffee ? ".js.coffee" : ".js"
|
33
|
-
template "app#{ext}", "#{javascript_path}/app#{ext}"
|
31
|
+
template "app#{extension}", "#{javascript_path}/app#{extension}"
|
34
32
|
end
|
35
33
|
|
36
34
|
def inject_required_files
|
File without changes
|
@@ -21,20 +21,15 @@ module Md
|
|
21
21
|
default: "",
|
22
22
|
desc: ""
|
23
23
|
|
24
|
-
def parse_options
|
25
|
-
coffee = options.coffeescript
|
26
|
-
@ext = coffee ? ".js.coffee" : ".js"
|
27
|
-
end
|
28
|
-
|
29
24
|
def create_marionette_entity
|
30
25
|
file = File.join(entities_path, singular_file_name)
|
31
|
-
template "entity#{
|
26
|
+
template "entity#{extension}", file
|
32
27
|
end
|
33
28
|
|
34
29
|
def create_marionette_app
|
35
30
|
empty_directory File.join(apps_path, file_name.downcase)
|
36
31
|
file = File.join(apps_path, file_name.downcase, sub_app_file_name)
|
37
|
-
template "app#{
|
32
|
+
template "app#{extension}", file
|
38
33
|
end
|
39
34
|
|
40
35
|
def create_subapp
|
@@ -48,10 +43,10 @@ module Md
|
|
48
43
|
end
|
49
44
|
end
|
50
45
|
|
51
|
-
|
46
|
+
protected
|
52
47
|
def create_asset(type)
|
53
48
|
file = File.join(apps_path, file_name.downcase, @submodule_name.downcase, asset_file_name(type))
|
54
|
-
template "#{type}#{
|
49
|
+
template "#{type}#{extension}", file
|
55
50
|
end
|
56
51
|
|
57
52
|
def create_dust_template
|
@@ -23,8 +23,6 @@ module Md
|
|
23
23
|
desc: "Parent app (required)"
|
24
24
|
|
25
25
|
def parse_options
|
26
|
-
coffee = options.coffeescript
|
27
|
-
@ext = coffee ? ".js.coffee" : ".js"
|
28
26
|
@parent_name = options.parent
|
29
27
|
@submodule_name = file_name
|
30
28
|
end
|
@@ -35,15 +33,21 @@ module Md
|
|
35
33
|
create_dust_template
|
36
34
|
end
|
37
35
|
|
38
|
-
|
36
|
+
protected
|
39
37
|
def create_asset(type)
|
40
|
-
file = File.join(apps_path, @parent_name.
|
41
|
-
|
38
|
+
file = File.join(apps_path, @parent_name.underscore, file_name,
|
39
|
+
asset_file_name(type))
|
40
|
+
|
41
|
+
template "#{type}#{extension}", file
|
42
42
|
end
|
43
43
|
|
44
44
|
def create_dust_template
|
45
|
-
empty_directory File.join(template_path, @parent_name,
|
46
|
-
|
45
|
+
empty_directory File.join(template_path, @parent_name.underscore,
|
46
|
+
@submodule_name.underscore)
|
47
|
+
|
48
|
+
file = File.join(template_path, @parent_name.underscore, @submodule_name,
|
49
|
+
"#{@submodule_name}.jst.dust")
|
50
|
+
|
47
51
|
template "template.jst.dust", file
|
48
52
|
end
|
49
53
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
// MarionetteJS (Backbone.Marionette)
|
2
2
|
// ----------------------------------
|
3
|
-
// v1.
|
3
|
+
// v1.6.2
|
4
4
|
//
|
5
|
-
// Copyright (c)
|
5
|
+
// Copyright (c)2014 Derick Bailey, Muted Solutions, LLC.
|
6
6
|
// Distributed under MIT license
|
7
7
|
//
|
8
8
|
// http://marionettejs.com
|
@@ -33,7 +33,7 @@
|
|
33
33
|
// shut down child views.
|
34
34
|
|
35
35
|
Backbone.ChildViewContainer = (function(Backbone, _){
|
36
|
-
|
36
|
+
|
37
37
|
// Container Constructor
|
38
38
|
// ---------------------
|
39
39
|
|
@@ -158,9 +158,9 @@ Backbone.ChildViewContainer = (function(Backbone, _){
|
|
158
158
|
//
|
159
159
|
// Mix in methods from Underscore, for iteration, and other
|
160
160
|
// collection related features.
|
161
|
-
var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
|
162
|
-
'select', 'reject', 'every', 'all', 'some', 'any', 'include',
|
163
|
-
'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
|
161
|
+
var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
|
162
|
+
'select', 'reject', 'every', 'all', 'some', 'any', 'include',
|
163
|
+
'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
|
164
164
|
'last', 'without', 'isEmpty', 'pluck'];
|
165
165
|
|
166
166
|
_.each(methods, function(method) {
|
@@ -195,14 +195,14 @@ Backbone.Wreqr = (function(Backbone, Marionette, _){
|
|
195
195
|
|
196
196
|
Wreqr.Handlers = (function(Backbone, _){
|
197
197
|
"use strict";
|
198
|
-
|
198
|
+
|
199
199
|
// Constructor
|
200
200
|
// -----------
|
201
201
|
|
202
202
|
var Handlers = function(options){
|
203
203
|
this.options = options;
|
204
204
|
this._wreqrHandlers = {};
|
205
|
-
|
205
|
+
|
206
206
|
if (_.isFunction(this.initialize)){
|
207
207
|
this.initialize(options);
|
208
208
|
}
|
@@ -308,7 +308,7 @@ Wreqr.CommandStorage = (function(){
|
|
308
308
|
|
309
309
|
// build the configuration
|
310
310
|
commands = {
|
311
|
-
command: commandName,
|
311
|
+
command: commandName,
|
312
312
|
instances: []
|
313
313
|
};
|
314
314
|
|
@@ -491,16 +491,35 @@ Marionette.getOption = function(target, optionName){
|
|
491
491
|
return value;
|
492
492
|
};
|
493
493
|
|
494
|
+
// Marionette.normalizeMethods
|
495
|
+
// ----------------------
|
496
|
+
|
497
|
+
// Pass in a mapping of events => functions or function names
|
498
|
+
// and return a mapping of events => functions
|
499
|
+
Marionette.normalizeMethods = function(hash) {
|
500
|
+
var normalizedHash = {}, method;
|
501
|
+
_.each(hash, function(fn, name) {
|
502
|
+
method = fn;
|
503
|
+
if (!_.isFunction(method)) {
|
504
|
+
method = this[method];
|
505
|
+
}
|
506
|
+
if (!method) {
|
507
|
+
return;
|
508
|
+
}
|
509
|
+
normalizedHash[name] = method;
|
510
|
+
}, this);
|
511
|
+
return normalizedHash;
|
512
|
+
};
|
494
513
|
// Trigger an event and/or a corresponding method name. Examples:
|
495
514
|
//
|
496
515
|
// `this.triggerMethod("foo")` will trigger the "foo" event and
|
497
516
|
// call the "onFoo" method.
|
498
517
|
//
|
499
|
-
// `this.triggerMethod("foo:bar") will trigger the "foo:bar" event and
|
518
|
+
// `this.triggerMethod("foo:bar")` will trigger the "foo:bar" event and
|
500
519
|
// call the "onFooBar" method.
|
501
520
|
Marionette.triggerMethod = (function(){
|
502
521
|
|
503
|
-
// split the event name on the :
|
522
|
+
// split the event name on the ":"
|
504
523
|
var splitter = /(^|:)(\w)/gi;
|
505
524
|
|
506
525
|
// take the event section ("section1:section2:section3")
|
@@ -509,7 +528,7 @@ Marionette.triggerMethod = (function(){
|
|
509
528
|
return eventName.toUpperCase();
|
510
529
|
}
|
511
530
|
|
512
|
-
// actual triggerMethod
|
531
|
+
// actual triggerMethod implementation
|
513
532
|
var triggerMethod = function(event) {
|
514
533
|
// get the method name from the event name
|
515
534
|
var methodName = 'on' + event.replace(splitter, getEventName);
|
@@ -537,7 +556,7 @@ Marionette.triggerMethod = (function(){
|
|
537
556
|
// in the DOM, trigger a "dom:refresh" event every time it is
|
538
557
|
// re-rendered.
|
539
558
|
|
540
|
-
Marionette.MonitorDOMRefresh = (function(){
|
559
|
+
Marionette.MonitorDOMRefresh = (function(documentElement){
|
541
560
|
// track when the view has been shown in the DOM,
|
542
561
|
// using a Marionette.Region (or by other means of triggering "show")
|
543
562
|
function handleShow(view){
|
@@ -553,13 +572,17 @@ Marionette.MonitorDOMRefresh = (function(){
|
|
553
572
|
|
554
573
|
// Trigger the "dom:refresh" event and corresponding "onDomRefresh" method
|
555
574
|
function triggerDOMRefresh(view){
|
556
|
-
if (view._isShown && view._isRendered){
|
575
|
+
if (view._isShown && view._isRendered && isInDOM(view)){
|
557
576
|
if (_.isFunction(view.triggerMethod)){
|
558
577
|
view.triggerMethod("dom:refresh");
|
559
578
|
}
|
560
579
|
}
|
561
580
|
}
|
562
581
|
|
582
|
+
function isInDOM(view) {
|
583
|
+
return documentElement.contains(view.el);
|
584
|
+
}
|
585
|
+
|
563
586
|
// Export public API
|
564
587
|
return function(view){
|
565
588
|
view.listenTo(view, "show", function(){
|
@@ -570,14 +593,14 @@ Marionette.MonitorDOMRefresh = (function(){
|
|
570
593
|
handleRender(view);
|
571
594
|
});
|
572
595
|
};
|
573
|
-
})();
|
596
|
+
})(document.documentElement);
|
574
597
|
|
575
598
|
|
576
599
|
// Marionette.bindEntityEvents & unbindEntityEvents
|
577
600
|
// ---------------------------
|
578
601
|
//
|
579
|
-
// These methods are used to bind/unbind a backbone "entity" (collection/model)
|
580
|
-
// to methods on a target object.
|
602
|
+
// These methods are used to bind/unbind a backbone "entity" (collection/model)
|
603
|
+
// to methods on a target object.
|
581
604
|
//
|
582
605
|
// The first parameter, `target`, must have a `listenTo` method from the
|
583
606
|
// EventBinder object.
|
@@ -587,7 +610,7 @@ Marionette.MonitorDOMRefresh = (function(){
|
|
587
610
|
//
|
588
611
|
// The third parameter is a hash of { "event:name": "eventHandler" }
|
589
612
|
// configuration. Multiple handlers can be separated by a space. A
|
590
|
-
// function can be supplied instead of a string handler name.
|
613
|
+
// function can be supplied instead of a string handler name.
|
591
614
|
|
592
615
|
(function(Marionette){
|
593
616
|
"use strict";
|
@@ -629,7 +652,7 @@ Marionette.MonitorDOMRefresh = (function(){
|
|
629
652
|
target.stopListening(entity, evt, method, target);
|
630
653
|
}
|
631
654
|
|
632
|
-
|
655
|
+
|
633
656
|
// generic looping function
|
634
657
|
function iterateEvents(target, entity, bindings, functionCallback, stringCallback){
|
635
658
|
if (!entity || !bindings) { return; }
|
@@ -642,7 +665,7 @@ Marionette.MonitorDOMRefresh = (function(){
|
|
642
665
|
// iterate the bindings and bind them
|
643
666
|
_.each(bindings, function(methods, evt){
|
644
667
|
|
645
|
-
// allow for a function as the handler,
|
668
|
+
// allow for a function as the handler,
|
646
669
|
// or a list of event names as a string
|
647
670
|
if (_.isFunction(methods)){
|
648
671
|
functionCallback(target, entity, evt, methods);
|
@@ -652,7 +675,7 @@ Marionette.MonitorDOMRefresh = (function(){
|
|
652
675
|
|
653
676
|
});
|
654
677
|
}
|
655
|
-
|
678
|
+
|
656
679
|
// Export Public API
|
657
680
|
Marionette.bindEntityEvents = function(target, entity, bindings){
|
658
681
|
iterateEvents(target, entity, bindings, bindToFunction, bindFromStrings);
|
@@ -679,7 +702,7 @@ Marionette.Callbacks = function(){
|
|
679
702
|
_.extend(Marionette.Callbacks.prototype, {
|
680
703
|
|
681
704
|
// Add a callback to be executed. Callbacks added here are
|
682
|
-
// guaranteed to execute, even if they are added after the
|
705
|
+
// guaranteed to execute, even if they are added after the
|
683
706
|
// `run` method is called.
|
684
707
|
add: function(callback, contextOverride){
|
685
708
|
this._callbacks.push({cb: callback, ctx: contextOverride});
|
@@ -690,8 +713,8 @@ _.extend(Marionette.Callbacks.prototype, {
|
|
690
713
|
});
|
691
714
|
},
|
692
715
|
|
693
|
-
// Run all registered callbacks with the context specified.
|
694
|
-
// Additional callbacks can be added after this has been run
|
716
|
+
// Run all registered callbacks with the context specified.
|
717
|
+
// Additional callbacks can be added after this has been run
|
695
718
|
// and they will still be executed.
|
696
719
|
run: function(options, context){
|
697
720
|
this._deferred.resolve(context, options);
|
@@ -703,7 +726,7 @@ _.extend(Marionette.Callbacks.prototype, {
|
|
703
726
|
var callbacks = this._callbacks;
|
704
727
|
this._deferred = Marionette.$.Deferred();
|
705
728
|
this._callbacks = [];
|
706
|
-
|
729
|
+
|
707
730
|
_.each(callbacks, function(cb){
|
708
731
|
this.add(cb.cb, cb.ctx);
|
709
732
|
}, this);
|
@@ -740,7 +763,7 @@ _.extend(Marionette.Controller.prototype, Backbone.Events, {
|
|
740
763
|
}
|
741
764
|
});
|
742
765
|
|
743
|
-
// Region
|
766
|
+
// Region
|
744
767
|
// ------
|
745
768
|
//
|
746
769
|
// Manage the visual regions of your composite application. See
|
@@ -748,7 +771,6 @@ _.extend(Marionette.Controller.prototype, Backbone.Events, {
|
|
748
771
|
|
749
772
|
Marionette.Region = function(options){
|
750
773
|
this.options = options || {};
|
751
|
-
|
752
774
|
this.el = Marionette.getOption(this, "el");
|
753
775
|
|
754
776
|
if (!this.el){
|
@@ -784,7 +806,6 @@ _.extend(Marionette.Region, {
|
|
784
806
|
// ```
|
785
807
|
//
|
786
808
|
buildRegion: function(regionConfig, defaultRegionType){
|
787
|
-
|
788
809
|
var regionIsString = (typeof regionConfig === "string");
|
789
810
|
var regionSelectorIsString = (typeof regionConfig.selector === "string");
|
790
811
|
var regionTypeIsUndefined = (typeof regionConfig.regionType === "undefined");
|
@@ -795,19 +816,20 @@ _.extend(Marionette.Region, {
|
|
795
816
|
}
|
796
817
|
|
797
818
|
var selector, RegionType;
|
798
|
-
|
819
|
+
|
799
820
|
// get the selector for the region
|
800
|
-
|
821
|
+
|
801
822
|
if (regionIsString) {
|
802
823
|
selector = regionConfig;
|
803
|
-
}
|
824
|
+
}
|
804
825
|
|
805
826
|
if (regionConfig.selector) {
|
806
827
|
selector = regionConfig.selector;
|
828
|
+
delete regionConfig.selector;
|
807
829
|
}
|
808
830
|
|
809
831
|
// get the type for the region
|
810
|
-
|
832
|
+
|
811
833
|
if (regionIsType){
|
812
834
|
RegionType = regionConfig;
|
813
835
|
}
|
@@ -818,12 +840,17 @@ _.extend(Marionette.Region, {
|
|
818
840
|
|
819
841
|
if (regionConfig.regionType) {
|
820
842
|
RegionType = regionConfig.regionType;
|
843
|
+
delete regionConfig.regionType;
|
844
|
+
}
|
845
|
+
|
846
|
+
if (regionIsString || regionIsType) {
|
847
|
+
regionConfig = {};
|
821
848
|
}
|
822
|
-
|
849
|
+
|
850
|
+
regionConfig.el = selector;
|
851
|
+
|
823
852
|
// build the region instance
|
824
|
-
var region = new RegionType(
|
825
|
-
el: selector
|
826
|
-
});
|
853
|
+
var region = new RegionType(regionConfig);
|
827
854
|
|
828
855
|
// override the `getEl` function if we have a parentEl
|
829
856
|
// this must be overridden to ensure the selector is found
|
@@ -832,7 +859,6 @@ _.extend(Marionette.Region, {
|
|
832
859
|
// literal to build the region, the element will not be
|
833
860
|
// guaranteed to be in the DOM already, and will cause problems
|
834
861
|
if (regionConfig.parentEl){
|
835
|
-
|
836
862
|
region.getEl = function(selector) {
|
837
863
|
var parentEl = regionConfig.parentEl;
|
838
864
|
if (_.isFunction(parentEl)){
|
@@ -858,11 +884,9 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
|
|
858
884
|
// `onShow` and `close` method on your view, just after showing
|
859
885
|
// or just before closing the view, respectively.
|
860
886
|
show: function(view){
|
861
|
-
|
862
887
|
this.ensureEl();
|
863
888
|
|
864
889
|
var isViewClosed = view.isClosed || _.isUndefined(view.$el);
|
865
|
-
|
866
890
|
var isDifferentView = view !== this.currentView;
|
867
891
|
|
868
892
|
if (isDifferentView) {
|
@@ -874,7 +898,7 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
|
|
874
898
|
if (isDifferentView || isViewClosed) {
|
875
899
|
this.open(view);
|
876
900
|
}
|
877
|
-
|
901
|
+
|
878
902
|
this.currentView = view;
|
879
903
|
|
880
904
|
Marionette.triggerMethod.call(this, "show", view);
|
@@ -909,13 +933,13 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
|
|
909
933
|
if (view.close) { view.close(); }
|
910
934
|
else if (view.remove) { view.remove(); }
|
911
935
|
|
912
|
-
Marionette.triggerMethod.call(this, "close");
|
936
|
+
Marionette.triggerMethod.call(this, "close", view);
|
913
937
|
|
914
938
|
delete this.currentView;
|
915
939
|
},
|
916
940
|
|
917
|
-
// Attach an existing view to the region. This
|
918
|
-
// will not call `render` or `onShow` for the new view,
|
941
|
+
// Attach an existing view to the region. This
|
942
|
+
// will not call `render` or `onShow` for the new view,
|
919
943
|
// and will not replace the current HTML for the `el`
|
920
944
|
// of the region.
|
921
945
|
attachView: function(view){
|
@@ -1052,9 +1076,9 @@ Marionette.RegionManager = (function(Marionette){
|
|
1052
1076
|
//
|
1053
1077
|
// Mix in methods from Underscore, for iteration, and other
|
1054
1078
|
// collection related features.
|
1055
|
-
var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
|
1056
|
-
'select', 'reject', 'every', 'all', 'some', 'any', 'include',
|
1057
|
-
'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
|
1079
|
+
var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
|
1080
|
+
'select', 'reject', 'every', 'all', 'some', 'any', 'include',
|
1081
|
+
'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
|
1058
1082
|
'last', 'without', 'isEmpty', 'pluck'];
|
1059
1083
|
|
1060
1084
|
_.each(methods, function(method) {
|
@@ -1079,7 +1103,7 @@ Marionette.TemplateCache = function(templateId){
|
|
1079
1103
|
};
|
1080
1104
|
|
1081
1105
|
// TemplateCache object-level methods. Manage the template
|
1082
|
-
// caches from these method calls instead of creating
|
1106
|
+
// caches from these method calls instead of creating
|
1083
1107
|
// your own TemplateCache instances
|
1084
1108
|
_.extend(Marionette.TemplateCache, {
|
1085
1109
|
templateCaches: {},
|
@@ -1102,7 +1126,7 @@ _.extend(Marionette.TemplateCache, {
|
|
1102
1126
|
// are specified, clears all templates:
|
1103
1127
|
// `clear()`
|
1104
1128
|
//
|
1105
|
-
// If arguments are specified, clears each of the
|
1129
|
+
// If arguments are specified, clears each of the
|
1106
1130
|
// specified templates from the cache:
|
1107
1131
|
// `clear("#t1", "#t2", "...")`
|
1108
1132
|
clear: function(){
|
@@ -1142,7 +1166,7 @@ _.extend(Marionette.TemplateCache.prototype, {
|
|
1142
1166
|
// Load a template from the DOM, by default. Override
|
1143
1167
|
// this method to provide your own template retrieval
|
1144
1168
|
// For asynchronous loading with AMD/RequireJS, consider
|
1145
|
-
// using a template-loader plugin as described here:
|
1169
|
+
// using a template-loader plugin as described here:
|
1146
1170
|
// https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs
|
1147
1171
|
loadTemplate: function(templateId){
|
1148
1172
|
var template = Marionette.$(templateId).html();
|
@@ -1211,7 +1235,10 @@ Marionette.View = Backbone.View.extend({
|
|
1211
1235
|
// this is a backfill since backbone removed the assignment
|
1212
1236
|
// of this.options
|
1213
1237
|
// at some point however this may be removed
|
1214
|
-
this.options = options
|
1238
|
+
this.options = _.extend({}, _.result(this, 'options'), _.isFunction(options) ? options.call(this) : options);
|
1239
|
+
|
1240
|
+
// parses out the @ui DSL for events
|
1241
|
+
this.events = this.normalizeUIKeys(_.result(this, 'events'));
|
1215
1242
|
Backbone.View.prototype.constructor.apply(this, args);
|
1216
1243
|
|
1217
1244
|
Marionette.MonitorDOMRefresh(this);
|
@@ -1222,6 +1249,10 @@ Marionette.View = Backbone.View.extend({
|
|
1222
1249
|
// methods if the method exists
|
1223
1250
|
triggerMethod: Marionette.triggerMethod,
|
1224
1251
|
|
1252
|
+
// Imports the "normalizeMethods" to transform hashes of
|
1253
|
+
// events=>function references/names to a hash of events=>function references
|
1254
|
+
normalizeMethods: Marionette.normalizeMethods,
|
1255
|
+
|
1225
1256
|
// Get the template for this view
|
1226
1257
|
// instance. You can set a `template` attribute in the view
|
1227
1258
|
// definition or pass a `template: "whatever"` parameter in
|
@@ -1244,6 +1275,25 @@ Marionette.View = Backbone.View.extend({
|
|
1244
1275
|
return _.extend(target, templateHelpers);
|
1245
1276
|
},
|
1246
1277
|
|
1278
|
+
// allows for the use of the @ui. syntax within
|
1279
|
+
// a given key for triggers and events
|
1280
|
+
// swaps the @ui with the associated selector
|
1281
|
+
normalizeUIKeys: function(hash) {
|
1282
|
+
if (typeof(hash) === "undefined") {
|
1283
|
+
return;
|
1284
|
+
}
|
1285
|
+
|
1286
|
+
_.each(_.keys(hash), function(v) {
|
1287
|
+
var split = v.split("@ui.");
|
1288
|
+
if (split.length === 2) {
|
1289
|
+
hash[split[0]+this.ui[split[1]]] = hash[v];
|
1290
|
+
delete hash[v];
|
1291
|
+
}
|
1292
|
+
}, this);
|
1293
|
+
|
1294
|
+
return hash;
|
1295
|
+
},
|
1296
|
+
|
1247
1297
|
// Configure `triggers` to forward DOM events to view
|
1248
1298
|
// events. `triggers: {"click .foo": "do:foo"}`
|
1249
1299
|
configureTriggers: function(){
|
@@ -1252,7 +1302,7 @@ Marionette.View = Backbone.View.extend({
|
|
1252
1302
|
var triggerEvents = {};
|
1253
1303
|
|
1254
1304
|
// Allow `triggers` to be configured as a function
|
1255
|
-
var triggers = _.result(this, "triggers");
|
1305
|
+
var triggers = this.normalizeUIKeys(_.result(this, "triggers"));
|
1256
1306
|
|
1257
1307
|
// Configure the triggers, prevent default
|
1258
1308
|
// action and stop propagation of DOM events
|
@@ -1398,8 +1448,8 @@ Marionette.View = Backbone.View.extend({
|
|
1398
1448
|
// with underscore.js templates, serializing the view's model or collection,
|
1399
1449
|
// and calling several methods on extended views, such as `onRender`.
|
1400
1450
|
Marionette.ItemView = Marionette.View.extend({
|
1401
|
-
|
1402
|
-
// Setting up the inheritance chain which allows changes to
|
1451
|
+
|
1452
|
+
// Setting up the inheritance chain which allows changes to
|
1403
1453
|
// Marionette.View.prototype.constructor which allows overriding
|
1404
1454
|
constructor: function(){
|
1405
1455
|
Marionette.View.prototype.constructor.apply(this, slice(arguments));
|
@@ -1480,11 +1530,40 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1480
1530
|
Marionette.View.prototype.constructor.apply(this, slice(arguments));
|
1481
1531
|
|
1482
1532
|
this._initialEvents();
|
1533
|
+
this.initRenderBuffer();
|
1534
|
+
},
|
1535
|
+
|
1536
|
+
// Instead of inserting elements one by one into the page,
|
1537
|
+
// it's much more performant to insert elements into a document
|
1538
|
+
// fragment and then insert that document fragment into the page
|
1539
|
+
initRenderBuffer: function() {
|
1540
|
+
this.elBuffer = document.createDocumentFragment();
|
1541
|
+
this._bufferedChildren = [];
|
1542
|
+
},
|
1543
|
+
|
1544
|
+
startBuffering: function() {
|
1545
|
+
this.initRenderBuffer();
|
1546
|
+
this.isBuffering = true;
|
1547
|
+
},
|
1548
|
+
|
1549
|
+
endBuffering: function() {
|
1550
|
+
this.isBuffering = false;
|
1551
|
+
this.appendBuffer(this, this.elBuffer);
|
1552
|
+
this._triggerShowBufferedChildren();
|
1553
|
+
this.initRenderBuffer();
|
1554
|
+
},
|
1555
|
+
|
1556
|
+
_triggerShowBufferedChildren: function () {
|
1557
|
+
if (this._isShown) {
|
1558
|
+
_.each(this._bufferedChildren, function (child) {
|
1559
|
+
Marionette.triggerMethod.call(child, "show");
|
1560
|
+
});
|
1561
|
+
this._bufferedChildren = [];
|
1562
|
+
}
|
1483
1563
|
},
|
1484
1564
|
|
1485
1565
|
// Configured the initial events that the collection view
|
1486
|
-
// binds to.
|
1487
|
-
// events, or to add your own initial events.
|
1566
|
+
// binds to.
|
1488
1567
|
_initialEvents: function(){
|
1489
1568
|
if (this.collection){
|
1490
1569
|
this.listenTo(this.collection, "add", this.addChildView, this);
|
@@ -1538,14 +1617,18 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1538
1617
|
// more control over events being triggered, around the rendering
|
1539
1618
|
// process
|
1540
1619
|
_renderChildren: function(){
|
1620
|
+
this.startBuffering();
|
1621
|
+
|
1541
1622
|
this.closeEmptyView();
|
1542
1623
|
this.closeChildren();
|
1543
1624
|
|
1544
|
-
if (this.
|
1625
|
+
if (!this.isEmpty(this.collection)) {
|
1545
1626
|
this.showCollection();
|
1546
1627
|
} else {
|
1547
1628
|
this.showEmptyView();
|
1548
1629
|
}
|
1630
|
+
|
1631
|
+
this.endBuffering();
|
1549
1632
|
},
|
1550
1633
|
|
1551
1634
|
// Internal method to loop through each item in the
|
@@ -1608,9 +1691,9 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1608
1691
|
itemViewOptions = itemViewOptions.call(this, item, index);
|
1609
1692
|
}
|
1610
1693
|
|
1611
|
-
// build the view
|
1694
|
+
// build the view
|
1612
1695
|
var view = this.buildItemView(item, ItemView, itemViewOptions);
|
1613
|
-
|
1696
|
+
|
1614
1697
|
// set up the child view event forwarding
|
1615
1698
|
this.addChildViewEventForwarding(view);
|
1616
1699
|
|
@@ -1626,12 +1709,14 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1626
1709
|
|
1627
1710
|
// call the "show" method if the collection view
|
1628
1711
|
// has already been shown
|
1629
|
-
if (this._isShown){
|
1712
|
+
if (this._isShown && !this.isBuffering){
|
1630
1713
|
Marionette.triggerMethod.call(view, "show");
|
1631
1714
|
}
|
1632
1715
|
|
1633
1716
|
// this view was added
|
1634
1717
|
this.triggerMethod("after:item:added", view);
|
1718
|
+
|
1719
|
+
return view;
|
1635
1720
|
},
|
1636
1721
|
|
1637
1722
|
// Set up the child view event forwarding. Uses an "itemview:"
|
@@ -1643,13 +1728,30 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1643
1728
|
// prepending "itemview:" to the event name
|
1644
1729
|
this.listenTo(view, "all", function(){
|
1645
1730
|
var args = slice(arguments);
|
1646
|
-
|
1731
|
+
var rootEvent = args[0];
|
1732
|
+
var itemEvents = this.normalizeMethods(this.getItemEvents());
|
1733
|
+
|
1734
|
+
args[0] = prefix + ":" + rootEvent;
|
1647
1735
|
args.splice(1, 0, view);
|
1648
1736
|
|
1737
|
+
// call collectionView itemEvent if defined
|
1738
|
+
if (typeof itemEvents !== "undefined" && _.isFunction(itemEvents[rootEvent])) {
|
1739
|
+
itemEvents[rootEvent].apply(this, args);
|
1740
|
+
}
|
1741
|
+
|
1649
1742
|
Marionette.triggerMethod.apply(this, args);
|
1650
1743
|
}, this);
|
1651
1744
|
},
|
1652
1745
|
|
1746
|
+
// returns the value of itemEvents depending on if a function
|
1747
|
+
getItemEvents: function() {
|
1748
|
+
if (_.isFunction(this.itemEvents)) {
|
1749
|
+
return this.itemEvents.call(this);
|
1750
|
+
}
|
1751
|
+
|
1752
|
+
return this.itemEvents;
|
1753
|
+
},
|
1754
|
+
|
1653
1755
|
// render the item view
|
1654
1756
|
renderItemView: function(view, index) {
|
1655
1757
|
view.render();
|
@@ -1687,20 +1789,40 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1687
1789
|
this.triggerMethod("item:removed", view);
|
1688
1790
|
},
|
1689
1791
|
|
1690
|
-
// helper to
|
1691
|
-
|
1692
|
-
// check if we're empty now
|
1693
|
-
|
1694
|
-
|
1792
|
+
// helper to check if the collection is empty
|
1793
|
+
isEmpty: function(collection){
|
1794
|
+
// check if we're empty now
|
1795
|
+
return !this.collection || this.collection.length === 0;
|
1796
|
+
},
|
1797
|
+
|
1798
|
+
// If empty, show the empty view
|
1799
|
+
checkEmpty: function (){
|
1800
|
+
if (this.isEmpty(this.collection)){
|
1695
1801
|
this.showEmptyView();
|
1696
1802
|
}
|
1697
1803
|
},
|
1698
1804
|
|
1805
|
+
// You might need to override this if you've overridden appendHtml
|
1806
|
+
appendBuffer: function(collectionView, buffer) {
|
1807
|
+
collectionView.$el.append(buffer);
|
1808
|
+
},
|
1809
|
+
|
1699
1810
|
// Append the HTML to the collection's `el`.
|
1700
1811
|
// Override this method to do something other
|
1701
1812
|
// then `.append`.
|
1702
1813
|
appendHtml: function(collectionView, itemView, index){
|
1703
|
-
collectionView
|
1814
|
+
if (collectionView.isBuffering) {
|
1815
|
+
// buffering happens on reset events and initial renders
|
1816
|
+
// in order to reduce the number of inserts into the
|
1817
|
+
// document, which are expensive.
|
1818
|
+
collectionView.elBuffer.appendChild(itemView.el);
|
1819
|
+
collectionView._bufferedChildren.push(itemView);
|
1820
|
+
}
|
1821
|
+
else {
|
1822
|
+
// If we've already rendered the main collection, just
|
1823
|
+
// append the new items directly into the element.
|
1824
|
+
collectionView.$el.append(itemView.el);
|
1825
|
+
}
|
1704
1826
|
},
|
1705
1827
|
|
1706
1828
|
// Internal method to set up the `children` object for
|
@@ -1750,11 +1872,17 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
1750
1872
|
// binds to. Override this method to prevent the initial
|
1751
1873
|
// events, or to add your own initial events.
|
1752
1874
|
_initialEvents: function(){
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1875
|
+
|
1876
|
+
// Bind only after composite view in rendered to avoid adding child views
|
1877
|
+
// to unexisting itemViewContainer
|
1878
|
+
this.once('render', function () {
|
1879
|
+
if (this.collection){
|
1880
|
+
this.listenTo(this.collection, "add", this.addChildView, this);
|
1881
|
+
this.listenTo(this.collection, "remove", this.removeItemView, this);
|
1882
|
+
this.listenTo(this.collection, "reset", this._renderChildren, this);
|
1883
|
+
}
|
1884
|
+
});
|
1885
|
+
|
1758
1886
|
},
|
1759
1887
|
|
1760
1888
|
// Retrieve the `itemView` to be used when rendering each of
|
@@ -1810,6 +1938,7 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
1810
1938
|
|
1811
1939
|
_renderChildren: function(){
|
1812
1940
|
if (this.isRendered){
|
1941
|
+
this.triggerMethod("composite:collection:before:render");
|
1813
1942
|
Marionette.CollectionView.prototype._renderChildren.call(this);
|
1814
1943
|
this.triggerMethod("composite:collection:rendered");
|
1815
1944
|
}
|
@@ -1827,15 +1956,31 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
1827
1956
|
return Marionette.Renderer.render(template, data);
|
1828
1957
|
},
|
1829
1958
|
|
1959
|
+
|
1960
|
+
// You might need to override this if you've overridden appendHtml
|
1961
|
+
appendBuffer: function(compositeView, buffer) {
|
1962
|
+
var $container = this.getItemViewContainer(compositeView);
|
1963
|
+
$container.append(buffer);
|
1964
|
+
},
|
1965
|
+
|
1830
1966
|
// Appends the `el` of itemView instances to the specified
|
1831
1967
|
// `itemViewContainer` (a jQuery selector). Override this method to
|
1832
1968
|
// provide custom logic of how the child item view instances have their
|
1833
1969
|
// HTML appended to the composite view instance.
|
1834
|
-
appendHtml: function(
|
1835
|
-
|
1836
|
-
|
1970
|
+
appendHtml: function(compositeView, itemView, index){
|
1971
|
+
if (compositeView.isBuffering) {
|
1972
|
+
compositeView.elBuffer.appendChild(itemView.el);
|
1973
|
+
compositeView._bufferedChildren.push(itemView);
|
1974
|
+
}
|
1975
|
+
else {
|
1976
|
+
// If we've already rendered the main collection, just
|
1977
|
+
// append the new items directly into the element.
|
1978
|
+
var $container = this.getItemViewContainer(compositeView);
|
1979
|
+
$container.append(itemView.el);
|
1980
|
+
}
|
1837
1981
|
},
|
1838
1982
|
|
1983
|
+
|
1839
1984
|
// Internal method to ensure an `$itemViewContainer` exists, for the
|
1840
1985
|
// `appendHtml` method to use.
|
1841
1986
|
getItemViewContainer: function(containerView){
|
@@ -1847,7 +1992,7 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
1847
1992
|
var itemViewContainer = Marionette.getOption(containerView, "itemViewContainer");
|
1848
1993
|
if (itemViewContainer){
|
1849
1994
|
|
1850
|
-
var selector = _.isFunction(itemViewContainer) ? itemViewContainer() : itemViewContainer;
|
1995
|
+
var selector = _.isFunction(itemViewContainer) ? itemViewContainer.call(this) : itemViewContainer;
|
1851
1996
|
container = containerView.$(selector);
|
1852
1997
|
if (container.length <= 0) {
|
1853
1998
|
throwError("The specified `itemViewContainer` was not found: " + containerView.itemViewContainer, "ItemViewContainerMissingError");
|
@@ -1881,7 +2026,7 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
1881
2026
|
// Used for composite view management and sub-application areas.
|
1882
2027
|
Marionette.Layout = Marionette.ItemView.extend({
|
1883
2028
|
regionType: Marionette.Region,
|
1884
|
-
|
2029
|
+
|
1885
2030
|
// Ensure the regions are available when the `initialize` method
|
1886
2031
|
// is called.
|
1887
2032
|
constructor: function (options) {
|
@@ -1889,7 +2034,7 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
1889
2034
|
|
1890
2035
|
this._firstRender = true;
|
1891
2036
|
this._initializeRegions(options);
|
1892
|
-
|
2037
|
+
|
1893
2038
|
Marionette.ItemView.prototype.constructor.call(this, options);
|
1894
2039
|
},
|
1895
2040
|
|
@@ -1900,7 +2045,7 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
1900
2045
|
render: function(){
|
1901
2046
|
|
1902
2047
|
if (this.isClosed){
|
1903
|
-
// a previously closed layout means we need to
|
2048
|
+
// a previously closed layout means we need to
|
1904
2049
|
// completely re-initialize the regions
|
1905
2050
|
this._initializeRegions();
|
1906
2051
|
}
|
@@ -1909,7 +2054,7 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
1909
2054
|
// reset the regions
|
1910
2055
|
this._firstRender = false;
|
1911
2056
|
} else if (!this.isClosed){
|
1912
|
-
// If this is not the first render call, then we need to
|
2057
|
+
// If this is not the first render call, then we need to
|
1913
2058
|
// re-initializing the `el` for each region
|
1914
2059
|
this._reInitializeRegions();
|
1915
2060
|
}
|
@@ -1960,7 +2105,7 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
1960
2105
|
},
|
1961
2106
|
|
1962
2107
|
// Internal method to initialize the regions that have been defined in a
|
1963
|
-
// `regions` attribute on this layout.
|
2108
|
+
// `regions` attribute on this layout.
|
1964
2109
|
_initializeRegions: function (options) {
|
1965
2110
|
var regions;
|
1966
2111
|
this._initRegionManager();
|
@@ -2011,7 +2156,7 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
2011
2156
|
//
|
2012
2157
|
// Configure an AppRouter with `appRoutes`.
|
2013
2158
|
//
|
2014
|
-
// App routers can only take one `controller` object.
|
2159
|
+
// App routers can only take one `controller` object.
|
2015
2160
|
// It is recommended that you divide your controller
|
2016
2161
|
// objects in to smaller pieces of related functionality
|
2017
2162
|
// and have multiple routers / controllers, instead of
|
@@ -2023,7 +2168,7 @@ Marionette.AppRouter = Backbone.Router.extend({
|
|
2023
2168
|
|
2024
2169
|
constructor: function(options){
|
2025
2170
|
Backbone.Router.prototype.constructor.apply(this, slice(arguments));
|
2026
|
-
|
2171
|
+
|
2027
2172
|
this.options = options || {};
|
2028
2173
|
|
2029
2174
|
var appRoutes = Marionette.getOption(this, "appRoutes");
|
@@ -2117,7 +2262,7 @@ _.extend(Marionette.Application.prototype, Backbone.Events, {
|
|
2117
2262
|
this.triggerMethod("start", options);
|
2118
2263
|
},
|
2119
2264
|
|
2120
|
-
// Add regions to your app.
|
2265
|
+
// Add regions to your app.
|
2121
2266
|
// Accepts a hash of named strings or Region objects
|
2122
2267
|
// addRegions({something: "#someRegion"})
|
2123
2268
|
// addRegions({something: Region.extend({el: "#someRegion"}) });
|
@@ -2136,7 +2281,7 @@ _.extend(Marionette.Application.prototype, Backbone.Events, {
|
|
2136
2281
|
removeRegion: function(region) {
|
2137
2282
|
this._regionManager.removeRegion(region);
|
2138
2283
|
},
|
2139
|
-
|
2284
|
+
|
2140
2285
|
// Provides alternative access to regions
|
2141
2286
|
// Accepts the region name
|
2142
2287
|
// getRegion('main')
|
@@ -2146,13 +2291,20 @@ _.extend(Marionette.Application.prototype, Backbone.Events, {
|
|
2146
2291
|
|
2147
2292
|
// Create a module, attached to the application
|
2148
2293
|
module: function(moduleNames, moduleDefinition){
|
2294
|
+
var ModuleClass = Marionette.Module;
|
2295
|
+
|
2296
|
+
// Overwrite the module class if the user specifies one
|
2297
|
+
if (moduleDefinition) {
|
2298
|
+
ModuleClass = moduleDefinition.moduleClass || ModuleClass;
|
2299
|
+
}
|
2300
|
+
|
2149
2301
|
// slice the args, and add this application object as the
|
2150
2302
|
// first argument of the array
|
2151
2303
|
var args = slice(arguments);
|
2152
2304
|
args.unshift(this);
|
2153
2305
|
|
2154
2306
|
// see the Marionette.Module object for more information
|
2155
|
-
return
|
2307
|
+
return ModuleClass.create.apply(ModuleClass, args);
|
2156
2308
|
},
|
2157
2309
|
|
2158
2310
|
// Internal method to set up the region manager
|
@@ -2177,8 +2329,10 @@ Marionette.Application.extend = Marionette.extend;
|
|
2177
2329
|
|
2178
2330
|
// A simple module system, used to create privacy and encapsulation in
|
2179
2331
|
// Marionette applications
|
2180
|
-
Marionette.Module = function(moduleName, app){
|
2332
|
+
Marionette.Module = function(moduleName, app, options){
|
2181
2333
|
this.moduleName = moduleName;
|
2334
|
+
this.options = _.extend({}, this.options, options);
|
2335
|
+
this.initialize = options.initialize || this.initialize;
|
2182
2336
|
|
2183
2337
|
// store sub-modules
|
2184
2338
|
this.submodules = {};
|
@@ -2190,12 +2344,22 @@ Marionette.Module = function(moduleName, app){
|
|
2190
2344
|
this.startWithParent = true;
|
2191
2345
|
|
2192
2346
|
this.triggerMethod = Marionette.triggerMethod;
|
2347
|
+
|
2348
|
+
if (_.isFunction(this.initialize)){
|
2349
|
+
this.initialize(this.options, moduleName, app);
|
2350
|
+
}
|
2193
2351
|
};
|
2194
2352
|
|
2353
|
+
Marionette.Module.extend = Marionette.extend;
|
2354
|
+
|
2195
2355
|
// Extend the Module prototype with events / listenTo, so that the module
|
2196
2356
|
// can be used as an event aggregator or pub/sub.
|
2197
2357
|
_.extend(Marionette.Module.prototype, Backbone.Events, {
|
2198
2358
|
|
2359
|
+
// Initialize is an empty function by default. Override it with your own
|
2360
|
+
// initialization logic when extending Marionette.Module.
|
2361
|
+
initialize: function(){},
|
2362
|
+
|
2199
2363
|
// Initializer for a specific module. Initializers are run when the
|
2200
2364
|
// module's `start` method is called.
|
2201
2365
|
addInitializer: function(callback){
|
@@ -2310,7 +2474,7 @@ _.extend(Marionette.Module, {
|
|
2310
2474
|
// Loop through all the parts of the module definition
|
2311
2475
|
_.each(moduleNames, function(moduleName, i){
|
2312
2476
|
var parentModule = module;
|
2313
|
-
module = this._getModule(parentModule, moduleName, app);
|
2477
|
+
module = this._getModule(parentModule, moduleName, app, moduleDefinition);
|
2314
2478
|
this._addModuleDefinition(parentModule, module, moduleDefinitions[i], customArgs);
|
2315
2479
|
}, this);
|
2316
2480
|
|
@@ -2319,12 +2483,18 @@ _.extend(Marionette.Module, {
|
|
2319
2483
|
},
|
2320
2484
|
|
2321
2485
|
_getModule: function(parentModule, moduleName, app, def, args){
|
2486
|
+
var ModuleClass = Marionette.Module;
|
2487
|
+
var options = _.extend({}, def);
|
2488
|
+
if (def) {
|
2489
|
+
ModuleClass = def.moduleClass || ModuleClass;
|
2490
|
+
}
|
2491
|
+
|
2322
2492
|
// Get an existing module of this name if we have one
|
2323
2493
|
var module = parentModule[moduleName];
|
2324
2494
|
|
2325
2495
|
if (!module){
|
2326
2496
|
// Create a new module if we don't have one
|
2327
|
-
module = new
|
2497
|
+
module = new ModuleClass(moduleName, app, options);
|
2328
2498
|
parentModule[moduleName] = module;
|
2329
2499
|
// store the module on the parent
|
2330
2500
|
parentModule.submodules[moduleName] = module;
|
@@ -2334,7 +2504,7 @@ _.extend(Marionette.Module, {
|
|
2334
2504
|
},
|
2335
2505
|
|
2336
2506
|
_addModuleDefinition: function(parentModule, module, def, args){
|
2337
|
-
var fn;
|
2507
|
+
var fn;
|
2338
2508
|
var startWithParent;
|
2339
2509
|
|
2340
2510
|
if (_.isFunction(def)){
|
@@ -2345,8 +2515,8 @@ _.extend(Marionette.Module, {
|
|
2345
2515
|
} else if (_.isObject(def)){
|
2346
2516
|
// if an object is supplied
|
2347
2517
|
fn = def.define;
|
2348
|
-
startWithParent = def.startWithParent;
|
2349
|
-
|
2518
|
+
startWithParent = (typeof def.startWithParent !== 'undefined') ? def.startWithParent : true;
|
2519
|
+
|
2350
2520
|
} else {
|
2351
2521
|
// if nothing is supplied
|
2352
2522
|
startWithParent = true;
|