marionette_dust 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|
-
[](http://githalytics.com/
|
118
|
+
[](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
|
+
[](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;
|