luca 0.9.42 → 0.9.65
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +50 -9
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/README.md +5 -0
- data/assets/javascripts/dependencies/underscore-min.js +5 -31
- data/lib/generators/luca/application/application_generator.rb +71 -0
- data/lib/generators/luca/application/templates/controller.rb +6 -0
- data/lib/generators/luca/application/templates/index.html.erb +7 -0
- data/lib/generators/luca/application/templates/index.html.haml +6 -0
- data/lib/generators/luca/application/templates/javascripts/application.js +28 -0
- data/lib/generators/luca/application/templates/javascripts/application.js.coffee +20 -0
- data/lib/generators/luca/application/templates/javascripts/config.js +15 -0
- data/lib/generators/luca/application/templates/javascripts/config.js.coffee +9 -0
- data/lib/generators/luca/application/templates/javascripts/dependencies.js +5 -0
- data/lib/generators/luca/application/templates/javascripts/dependencies.js.coffee +5 -0
- data/lib/generators/luca/application/templates/javascripts/index.js +9 -0
- data/lib/generators/luca/application/templates/javascripts/index.js.coffee +9 -0
- data/lib/generators/luca/application/templates/javascripts/main.js +8 -0
- data/lib/generators/luca/application/templates/javascripts/main.js.coffee +3 -0
- data/lib/generators/luca/application/templates/javascripts/main.jst.ejs +1 -0
- data/lib/generators/luca/application/templates/javascripts/router.js +12 -0
- data/lib/generators/luca/application/templates/javascripts/router.js.coffee +7 -0
- data/lib/luca/rails/version.rb +1 -1
- data/spec/components/collection_view_spec.coffee +59 -0
- data/spec/components/multi_collection_view_spec.coffee +5 -0
- data/{src/templates/components/form_alert → spec/components/pagination_control_spec.coffee} +0 -0
- data/spec/components/table_view_spec.coffee +17 -0
- data/spec/core/container_spec.coffee +127 -5
- data/spec/core/model_spec.coffee +21 -3
- data/spec/define_spec.coffee +19 -0
- data/spec/mixin_spec.coffee +49 -0
- data/spec/modules/filterable_spec.coffee +25 -0
- data/spec/modules/paginatable_spec.coffee +0 -0
- data/spec/modules/state_model_spec.coffee +0 -0
- data/src/components/application.coffee +52 -38
- data/src/components/collection_view.coffee +118 -45
- data/src/components/fields/checkbox_field.coffee +2 -2
- data/src/components/fields/file_upload_field.coffee +0 -3
- data/src/components/fields/hidden_field.coffee +0 -3
- data/src/components/fields/label_field.coffee +1 -4
- data/src/components/fields/select_field.coffee +6 -6
- data/src/components/fields/text_area_field.coffee +1 -0
- data/src/components/fields/text_field.coffee +4 -0
- data/src/components/fields/type_ahead_field.coffee +5 -9
- data/src/components/form_view.coffee +28 -23
- data/src/components/multi_collection_view.coffee +121 -0
- data/src/components/pagination_control.coffee +106 -0
- data/src/components/table_view.coffee +22 -13
- data/src/containers/card_view.coffee +44 -11
- data/src/containers/panel_toolbar.coffee +88 -82
- data/src/containers/tab_view.coffee +3 -3
- data/src/core/collection.coffee +11 -4
- data/src/core/container.coffee +206 -122
- data/src/core/field.coffee +13 -10
- data/src/core/model.coffee +23 -27
- data/src/core/registry.coffee +42 -29
- data/src/core/view.coffee +63 -149
- data/src/define.coffee +91 -19
- data/src/framework.coffee +11 -9
- data/src/managers/collection_manager.coffee +24 -8
- data/src/modules/application_event_bindings.coffee +19 -0
- data/src/modules/collection_event_bindings.coffee +26 -0
- data/src/modules/deferrable.coffee +3 -1
- data/src/modules/dom_helpers.coffee +49 -0
- data/src/modules/enhanced_properties.coffee +23 -0
- data/src/modules/filterable.coffee +82 -0
- data/src/modules/grid_layout.coffee +13 -1
- data/src/modules/{load_mask.coffee → loadmaskable.coffee} +10 -4
- data/src/modules/modal_view.coffee +38 -0
- data/src/modules/paginatable.coffee +87 -0
- data/src/modules/state_model.coffee +16 -0
- data/src/modules/templating.coffee +8 -0
- data/src/plugins/events.coffee +30 -2
- data/src/templates/components/bootstrap_form_controls.jst.ejs +10 -0
- data/src/templates/components/collection_loader_view.jst.ejs +6 -0
- data/src/templates/components/form_alert.jst.ejs +4 -0
- data/src/templates/components/grid_view.jst.ejs +11 -0
- data/src/templates/components/grid_view_empty_text.jst.ejs +3 -0
- data/src/templates/components/load_mask.jst.ejs +5 -0
- data/src/templates/components/nav_bar.jst.ejs +4 -0
- data/src/templates/components/pagination.jst.ejs +10 -0
- data/src/templates/containers/basic.jst.ejs +1 -0
- data/src/templates/containers/tab_selector_container.jst.ejs +12 -0
- data/src/templates/containers/tab_view.jst.ejs +2 -0
- data/src/templates/containers/toolbar_wrapper.jst.ejs +1 -0
- data/src/templates/fields/button_field.jst.ejs +2 -0
- data/src/templates/fields/button_field_link.jst.ejs +6 -0
- data/src/templates/fields/checkbox_array.jst.ejs +4 -0
- data/src/templates/fields/checkbox_array_item.jst.ejs +3 -0
- data/src/templates/fields/checkbox_field.jst.ejs +10 -0
- data/src/templates/fields/file_upload_field.jst.ejs +10 -0
- data/src/templates/fields/hidden_field.jst.ejs +1 -0
- data/src/templates/fields/select_field.jst.ejs +11 -0
- data/src/templates/fields/text_area_field.jst.ejs +11 -0
- data/src/templates/fields/text_field.jst.ejs +16 -0
- data/src/templates/table_view.jst.ejs +4 -0
- data/src/tools/console.coffee +51 -21
- data/src/util.coffee +17 -4
- data/vendor/assets/javascripts/luca-ui-base.js +5304 -0
- data/vendor/assets/javascripts/luca-ui-bootstrap.js +9 -0
- data/vendor/assets/javascripts/luca-ui-development-tools.js +52 -24
- data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
- data/vendor/assets/javascripts/luca-ui-full.js +1700 -595
- data/vendor/assets/javascripts/luca-ui-full.min.js +7 -6
- data/vendor/assets/javascripts/luca-ui-spec.js +6815 -0
- data/vendor/assets/javascripts/luca-ui-templates.js +92 -24
- data/vendor/assets/javascripts/luca-ui.js +1695 -564
- data/vendor/assets/javascripts/luca-ui.min.js +4 -4
- metadata +69 -28
- data/src/templates/components/bootstrap_form_controls.luca +0 -7
- data/src/templates/components/collection_loader_view.luca +0 -5
- data/src/templates/components/form_alert.luca +0 -3
- data/src/templates/components/grid_view.luca +0 -7
- data/src/templates/components/grid_view_empty_text.luca +0 -3
- data/src/templates/components/load_mask.luca +0 -3
- data/src/templates/components/nav_bar.luca +0 -2
- data/src/templates/containers/basic.luca +0 -1
- data/src/templates/containers/tab_selector_container.luca +0 -8
- data/src/templates/containers/tab_view.luca +0 -2
- data/src/templates/containers/toolbar_wrapper.luca +0 -1
- data/src/templates/fields/button_field.luca +0 -2
- data/src/templates/fields/button_field_link.luca +0 -5
- data/src/templates/fields/checkbox_array.luca +0 -4
- data/src/templates/fields/checkbox_array_item.luca +0 -4
- data/src/templates/fields/checkbox_field.luca +0 -9
- data/src/templates/fields/file_upload_field.luca +0 -8
- data/src/templates/fields/hidden_field.luca +0 -1
- data/src/templates/fields/select_field.luca +0 -8
- data/src/templates/fields/text_area_field.luca +0 -8
- data/src/templates/fields/text_field.luca +0 -17
- data/src/templates/sample/contents.luca +0 -1
- data/src/templates/sample/welcome.luca +0 -1
- data/src/templates/table_view.luca +0 -4
@@ -1,13 +1,18 @@
|
|
1
1
|
describe 'The Luca Container', ->
|
2
2
|
beforeEach ->
|
3
|
-
@container = new Luca.core.Container
|
3
|
+
c = @container = new Luca.core.Container
|
4
|
+
defaults:
|
5
|
+
defaultProperty: 'it_works'
|
4
6
|
components:[
|
5
7
|
name: "component_one"
|
6
8
|
ctype: "view"
|
9
|
+
defaultProperty: "oh_yeah"
|
7
10
|
bodyTemplate: ()-> "markup for component one"
|
8
11
|
id: "c1"
|
9
12
|
value: 1
|
13
|
+
getter: "getOne"
|
10
14
|
spy: sinon.spy()
|
15
|
+
role: "role_one"
|
11
16
|
,
|
12
17
|
name: "component_two"
|
13
18
|
ctype: "view"
|
@@ -15,6 +20,8 @@ describe 'The Luca Container', ->
|
|
15
20
|
id: "c2"
|
16
21
|
value: 0
|
17
22
|
spy: sinon.spy()
|
23
|
+
role: "role_two"
|
24
|
+
getter: "getComponentTwo"
|
18
25
|
,
|
19
26
|
name: "component_three"
|
20
27
|
ctype: "container"
|
@@ -29,6 +36,23 @@ describe 'The Luca Container', ->
|
|
29
36
|
]
|
30
37
|
]
|
31
38
|
|
39
|
+
@container.render()
|
40
|
+
|
41
|
+
it "should create getter methods on the for components with roles", ->
|
42
|
+
expect( @container.getRoleTwo ).toBeDefined()
|
43
|
+
|
44
|
+
it "should create getter methods on the for components with roles", ->
|
45
|
+
expect( @container.getRoleTwo().name ).toEqual 'component_two'
|
46
|
+
|
47
|
+
it "should create a getter function on the container", ->
|
48
|
+
expect( @container.getOne().name ).toEqual 'component_one'
|
49
|
+
|
50
|
+
it "should apply default properties to components", ->
|
51
|
+
defaults = @container.selectByAttribute('defaultProperty','it_works')
|
52
|
+
custom = @container.selectByAttribute('defaultProperty','oh_yeah')
|
53
|
+
expect( defaults.length ).toEqual(2)
|
54
|
+
expect( custom.length ).toEqual(1)
|
55
|
+
|
32
56
|
it "should trigger after initialize", ->
|
33
57
|
expect( @container ).toHaveTriggered "after:initialize"
|
34
58
|
|
@@ -47,7 +71,7 @@ describe 'The Luca Container', ->
|
|
47
71
|
expect( html ).toContain "markup for component four"
|
48
72
|
|
49
73
|
it "should select all components matching a key/value combo", ->
|
50
|
-
components = @container.
|
74
|
+
components = @container.selectByAttribute("value",1)
|
51
75
|
expect( components.length ).toEqual 2
|
52
76
|
|
53
77
|
it "should run a function on each component", ->
|
@@ -61,6 +85,104 @@ describe 'The Luca Container', ->
|
|
61
85
|
@container.eachComponent (c)-> c.spy()
|
62
86
|
expect( Luca.cache("component_four").spy ).toHaveBeenCalled()
|
63
87
|
|
64
|
-
|
65
|
-
|
66
|
-
|
88
|
+
|
89
|
+
describe 'Component Event Binding', ->
|
90
|
+
beforeEach ->
|
91
|
+
@container = new Luca.core.Container
|
92
|
+
componentEvents:
|
93
|
+
"haha trigger:one" : "one"
|
94
|
+
"alpha trigger:two" : "two"
|
95
|
+
"getAlphaComponent trigger:three" : "three"
|
96
|
+
"* trigger:four" : "four"
|
97
|
+
"beta trigger:five" : "five"
|
98
|
+
|
99
|
+
one: ()->
|
100
|
+
@trigger "one"
|
101
|
+
|
102
|
+
two: ()->
|
103
|
+
@trigger "two"
|
104
|
+
|
105
|
+
three: ()->
|
106
|
+
@trigger "three"
|
107
|
+
|
108
|
+
four: ()->
|
109
|
+
@trigger "four"
|
110
|
+
|
111
|
+
five: ()->
|
112
|
+
@trigger "five"
|
113
|
+
|
114
|
+
afterRender: ()->
|
115
|
+
@getGamma().trigger("after:render:gamma")
|
116
|
+
|
117
|
+
registerComponentEvents: ()->
|
118
|
+
Luca.core.Container::registerComponentEvents.apply(@, arguments)
|
119
|
+
|
120
|
+
components:[
|
121
|
+
name: "component_alpha"
|
122
|
+
role: "alpha"
|
123
|
+
getter: "getAlphaComponent"
|
124
|
+
,
|
125
|
+
name: "container_tester"
|
126
|
+
type: "container"
|
127
|
+
components:[
|
128
|
+
name: "beta_view"
|
129
|
+
role: "beta"
|
130
|
+
components:[
|
131
|
+
role: "gamma"
|
132
|
+
name: "haha"
|
133
|
+
]
|
134
|
+
]
|
135
|
+
]
|
136
|
+
|
137
|
+
@container.render()
|
138
|
+
|
139
|
+
it "should give me all of the components", ->
|
140
|
+
names = _( @container.allChildren() ).pluck('name')
|
141
|
+
expect( names ).toEqual ['component_alpha','container_tester','beta_view','haha']
|
142
|
+
|
143
|
+
it "should drill down into nested components", ->
|
144
|
+
expect( @container.getBeta ).toBeDefined()
|
145
|
+
expect( @container.getBeta().name ).toEqual 'beta_view'
|
146
|
+
|
147
|
+
it "should observe the right rendering order", ->
|
148
|
+
expect( @container.getGamma() ).toHaveTriggered("after:render:gamma")
|
149
|
+
|
150
|
+
it "should pick up events on nested components", ->
|
151
|
+
@container.getBeta().trigger("trigger:five")
|
152
|
+
expect( @container ).toHaveTriggered("five")
|
153
|
+
|
154
|
+
it "should recursively define role based getters", ->
|
155
|
+
expect( @container.getAlpha ).toBeDefined()
|
156
|
+
expect( @container.getBeta ).toBeDefined()
|
157
|
+
expect( @container.getGamma ).toBeDefined()
|
158
|
+
|
159
|
+
it "should define a getter", ->
|
160
|
+
expect( @container.getAlphaComponent ).toBeDefined()
|
161
|
+
|
162
|
+
it "should find a nested component by name", ->
|
163
|
+
expect( @container.findComponentByName('haha') ).toBeDefined()
|
164
|
+
|
165
|
+
it "should find the component by its name", ->
|
166
|
+
expect( @container.findComponentByName("beta_view") ).toBeDefined()
|
167
|
+
|
168
|
+
it "should find the component by its role", ->
|
169
|
+
expect( @container.findComponentByRole("alpha") ).toBeDefined()
|
170
|
+
|
171
|
+
it "should find the component by its getter", ->
|
172
|
+
expect( @container.findComponentByGetter('getAlphaComponent') ).toBeDefined()
|
173
|
+
|
174
|
+
it "should accept wildcard for component", ->
|
175
|
+
@container.getAlphaComponent().trigger "trigger:four"
|
176
|
+
expect( @container ).toHaveTriggered("four")
|
177
|
+
|
178
|
+
it "should accept component events with a component name", ->
|
179
|
+
@container.getGamma().trigger "trigger:one"
|
180
|
+
expect(@container).toHaveTriggered("one")
|
181
|
+
|
182
|
+
it "should accept component events with a component role", ->
|
183
|
+
@container.getAlphaComponent().trigger "trigger:two"
|
184
|
+
expect(@container).toHaveTriggered("two")
|
185
|
+
|
186
|
+
it "should accept component events with a component getter", ->
|
187
|
+
@container.getAlphaComponent().trigger "trigger:three"
|
188
|
+
expect(@container).toHaveTriggered("three")
|
data/spec/core/model_spec.coffee
CHANGED
@@ -14,15 +14,15 @@ describe "Luca.Model with computed attribute", ->
|
|
14
14
|
computed:
|
15
15
|
fullName: ['firstName', 'lastName']
|
16
16
|
|
17
|
-
it "should
|
17
|
+
it "should be undefined if dependences are not set", ->
|
18
18
|
model = new App.models.Sample
|
19
19
|
expect(model.get("fullName")).toEqual(undefined)
|
20
20
|
|
21
|
-
it "should
|
21
|
+
it "should be undefined if callback function is not present", ->
|
22
22
|
model = new App.models.SampleWithoutCallback
|
23
23
|
expect(model.get("fullName")).toEqual(undefined)
|
24
24
|
|
25
|
-
it "should not call
|
25
|
+
it "should not call the callback if dependences are not set", ->
|
26
26
|
model = new App.models.Sample
|
27
27
|
spy = sinon.spy(model, "fullName")
|
28
28
|
expect( spy.called ).toEqual(false)
|
@@ -48,3 +48,21 @@ describe "Luca.Model with computed attribute", ->
|
|
48
48
|
it "should have it set on constructor if dependencies are supplied", ->
|
49
49
|
model = new App.models.Sample({firstName:"Nickolay", lastName: "Schwarz"})
|
50
50
|
expect(model.get("fullName")).toEqual('Nickolay Schwarz')
|
51
|
+
|
52
|
+
|
53
|
+
describe 'The Read Method', ->
|
54
|
+
|
55
|
+
ModelClass = Luca.Model.extend
|
56
|
+
defaults:
|
57
|
+
attribute: "attribute"
|
58
|
+
reader: ()->
|
59
|
+
"reader"
|
60
|
+
|
61
|
+
it "should read an attribute", ->
|
62
|
+
model = new ModelClass()
|
63
|
+
expect( model.read('attribute') ).toEqual "attribute"
|
64
|
+
|
65
|
+
it "should read functions", ->
|
66
|
+
model = new ModelClass()
|
67
|
+
expect( model.read('attribute') ).toEqual "attribute"
|
68
|
+
expect( model.read('reader') ).toEqual 'reader'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
describe 'The Component Definition System', ->
|
2
|
+
beforeEach ->
|
3
|
+
Luca.components.SampleComponentDefinition = undefined
|
4
|
+
|
5
|
+
it "should define a component", ->
|
6
|
+
Luca.register("Luca.components.SampleComponentDefinition").defines(version: 1)
|
7
|
+
expect( Luca.isComponentPrototype(Luca.components.SampleComponentDefinition) ).toEqual true
|
8
|
+
|
9
|
+
it "should default to Luca.View for the extends portion", ->
|
10
|
+
Luca.register("Luca.components.SampleComponentDefinition").defines(version: 1)
|
11
|
+
expect( Luca.parentClasses(Luca.components.SampleComponentDefinition) ).toContain 'Luca.View'
|
12
|
+
|
13
|
+
it "should track the parent classes", ->
|
14
|
+
Luca.register("Luca.components.SampleComponentDefinition").defines(version: 1)
|
15
|
+
expect( Luca.parentClasses(Luca.components.SampleComponentDefinition) ).toEqual ['Luca.View','Backbone.View']
|
16
|
+
|
17
|
+
xit "should defer component extension until dependencies are defined", ->
|
18
|
+
|
19
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
describe 'The Mixin System', ->
|
2
|
+
|
3
|
+
window.Luca ||= {}
|
4
|
+
|
5
|
+
Luca.mixin.namespace 'Luca.test_modules'
|
6
|
+
|
7
|
+
Luca.test_modules =
|
8
|
+
SecondMixin:
|
9
|
+
__included: ()->
|
10
|
+
window.secondMixinIncluded = true
|
11
|
+
__initializer: ()->
|
12
|
+
@trigger "second:mixin"
|
13
|
+
FirstMixin:
|
14
|
+
__initializer: ()->
|
15
|
+
@trigger "first:mixin"
|
16
|
+
__privateMethod: ()->
|
17
|
+
true
|
18
|
+
publicMethod: ()->
|
19
|
+
true
|
20
|
+
|
21
|
+
sampleView = Luca.register('Luca.components.FirstView')
|
22
|
+
|
23
|
+
sampleView.mixesIn 'FirstMixin'
|
24
|
+
|
25
|
+
sampleView.defines
|
26
|
+
sampleMethod: ()->
|
27
|
+
"sample"
|
28
|
+
|
29
|
+
secondView = Luca.register("Luca.components.SecondView")
|
30
|
+
secondView.extends 'Luca.components.FirstView'
|
31
|
+
secondView.mixesIn 'SecondMixin'
|
32
|
+
secondView.defines
|
33
|
+
version: 2
|
34
|
+
|
35
|
+
it "should omit the private methods defined on the mixin", ->
|
36
|
+
sampleView = new Luca.components.FirstView
|
37
|
+
expect( sampleView.__privateMethod ).not.toBeDefined()
|
38
|
+
|
39
|
+
it "should extend the prototype with the mixins normal methods", ->
|
40
|
+
sampleView = new Luca.components.FirstView
|
41
|
+
expect( sampleView.publicMethod ).toBeDefined()
|
42
|
+
|
43
|
+
it "should call the initializer for that module on the instance", ->
|
44
|
+
secondView = new Luca.components.SecondView
|
45
|
+
expect( secondView ).toHaveTriggered("second:mixin")
|
46
|
+
|
47
|
+
it "should call the initializers up the prototype chain", ->
|
48
|
+
secondView = new Luca.components.SecondView
|
49
|
+
expect( secondView ).toHaveTriggered("first:mixin")
|
@@ -0,0 +1,25 @@
|
|
1
|
+
describe 'The Filterable Plugin', ->
|
2
|
+
describe 'Through the CollectionView', ->
|
3
|
+
beforeEach ->
|
4
|
+
@collection = new Luca.Collection [{name:"name"},{name:"filterable"}]
|
5
|
+
|
6
|
+
@view = new Luca.components.TableView
|
7
|
+
collection:@collection
|
8
|
+
columns:[reader:"name"]
|
9
|
+
|
10
|
+
it 'should generate a Backbone.QueryCollection query payload', ->
|
11
|
+
expect( @view.getFilterState().toQuery() ).toBeDefined()
|
12
|
+
|
13
|
+
it "should have a toRemote method which merges params", ->
|
14
|
+
expect( @view.getFilterState().toRemote() ).toBeDefined()
|
15
|
+
|
16
|
+
it 'should apply filter values', ->
|
17
|
+
@view.applyFilter(filter:"value")
|
18
|
+
expect( @view.getFilterState().toQuery().filter ).toEqual('value')
|
19
|
+
|
20
|
+
it 'should generate a Backbone.QueryCollection options payload', ->
|
21
|
+
expect( @view.getFilterState().toOptions() ).toBeDefined()
|
22
|
+
|
23
|
+
it "should trigger a refresh event on filter change", ->
|
24
|
+
@view.applyFilter(filter:"value")
|
25
|
+
expect( @view ).toHaveTriggered("refresh")
|
File without changes
|
File without changes
|
@@ -1,9 +1,9 @@
|
|
1
|
-
# Luca.Application
|
1
|
+
# Luca.Application
|
2
2
|
#
|
3
3
|
# The Application class is the global state tracking mechanism
|
4
4
|
# for your single page application, as well as the entry point.
|
5
5
|
#
|
6
|
-
# By default it contains a main controller which is a Luca.components.Controller instance.
|
6
|
+
# By default it contains a main controller which is a Luca.components.Controller instance.
|
7
7
|
#
|
8
8
|
# In a typical Luca application, the router will use the applications @navigate_to() method to switch
|
9
9
|
# from page to page on the main controller, or any other controllers nested inside of it.
|
@@ -12,9 +12,10 @@
|
|
12
12
|
#
|
13
13
|
# Decoupling application control flow from the URL Fragment from Backbone.History and preventing
|
14
14
|
# your components from directly caring about the URL Fragment, allows you to build applications as
|
15
|
-
# isolated components which can run separately or nested inside of other applications.
|
15
|
+
# isolated components which can run separately or nested inside of other applications.
|
16
16
|
|
17
|
-
startHistory = ()->
|
17
|
+
Luca.util.startHistory = ()->
|
18
|
+
Backbone.history.start()
|
18
19
|
|
19
20
|
_.def('Luca.Application').extends('Luca.containers.Viewport').with
|
20
21
|
name: "MyApp"
|
@@ -26,18 +27,18 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
26
27
|
# the @defaultState property will be the default attributes
|
27
28
|
defaultState: {}
|
28
29
|
|
29
|
-
# if autoBoot is set to true, the application will
|
30
|
+
# if autoBoot is set to true, the application will
|
30
31
|
# attempt to boot on document ready.
|
31
32
|
autoBoot: false
|
32
33
|
|
33
|
-
# automatically starts the @router if it exists,
|
34
|
-
# once the components for the application have
|
34
|
+
# automatically starts the @router if it exists,
|
35
|
+
# once the components for the application have
|
35
36
|
# been created. Pass the event name you want to
|
36
37
|
# listen for on this component before you start history
|
37
38
|
autoStartHistory: "before:render"
|
38
39
|
|
39
40
|
# we will create a collection manager singleton
|
40
|
-
# by default unless otherwise specified.
|
41
|
+
# by default unless otherwise specified.
|
41
42
|
useCollectionManager: true
|
42
43
|
|
43
44
|
# to pass options to the collection manager, set the @collectionManager
|
@@ -46,7 +47,7 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
46
47
|
|
47
48
|
# by default we will use the standard collection manager which ships with
|
48
49
|
# Luca. If you would like to use your own extension of the collection manager
|
49
|
-
# just pass a reference to the class you would like to use.
|
50
|
+
# just pass a reference to the class you would like to use.
|
50
51
|
collectionManagerClass: "Luca.CollectionManager"
|
51
52
|
|
52
53
|
# Luca plugin apps are apps which mount onto existing
|
@@ -61,7 +62,7 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
61
62
|
useController: true
|
62
63
|
|
63
64
|
# Key Handler
|
64
|
-
#
|
65
|
+
#
|
65
66
|
# One responsibility of the application, since it is a viewport which monopolizes the entire screen
|
66
67
|
# is to relay keypress events from the document, to whatever views are interested in responding to them.
|
67
68
|
#
|
@@ -70,7 +71,7 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
70
71
|
|
71
72
|
# You can configure key events by specifying them by their name, as it exists in Luca.keyMap. For example:
|
72
73
|
#
|
73
|
-
keyEvents: {}
|
74
|
+
keyEvents: {}
|
74
75
|
|
75
76
|
# keyEvents
|
76
77
|
# keyup: keyUpHandler
|
@@ -103,7 +104,7 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
103
104
|
|
104
105
|
Luca.Application.instances ||= {}
|
105
106
|
Luca.Application.instances[ appName ] = app
|
106
|
-
|
107
|
+
|
107
108
|
Luca.containers.Viewport::initialize.apply @, arguments
|
108
109
|
|
109
110
|
@state = new Luca.Model( @defaultState )
|
@@ -113,9 +114,9 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
113
114
|
# method which delegates to the controller, and allows you to navigate
|
114
115
|
# to a given page, or component, by its name. The controller integrates
|
115
116
|
# with the state machine of the application
|
116
|
-
@setupMainController()
|
117
|
+
@setupMainController() if @useController is true
|
117
118
|
|
118
|
-
# The Collection Manager is responsible
|
119
|
+
# The Collection Manager is responsible
|
119
120
|
@setupCollectionManager()
|
120
121
|
|
121
122
|
# we will render when all of the various components
|
@@ -137,23 +138,23 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
137
138
|
# forwardslash: "altSlashHandler"
|
138
139
|
if @useKeyRouter is true
|
139
140
|
console.log "The useKeyRouter property is being deprecated. switch to useKeyHandler instead"
|
140
|
-
|
141
|
+
|
141
142
|
@setupKeyHandler() if (@useKeyHandler is true or @useKeyRouter is true) and @keyEvents?
|
142
143
|
|
143
144
|
# if the application is a plugin designed to modify the behavior
|
144
145
|
# of another app, then don't claim ownership. otherwise the most common
|
145
146
|
# use-case is that there will be one application instance
|
146
147
|
unless @plugin is true or alreadyRunning
|
147
|
-
Luca.getApplication = (name)=>
|
148
|
+
Luca.getApplication = (name)=>
|
148
149
|
return app unless name?
|
149
|
-
Luca.Application.instances[ name ]
|
150
|
+
Luca.Application.instances[ name ]
|
150
151
|
|
151
152
|
if @autoBoot
|
152
153
|
if Luca.util.resolve(@name)
|
153
154
|
throw "Attempting to override window.#{ @name } when it already exists"
|
154
155
|
|
155
156
|
$ ->
|
156
|
-
window[ appName ] = app
|
157
|
+
window[ appName ] = app
|
157
158
|
app.boot()
|
158
159
|
|
159
160
|
# @activeView() returns a reference to the instance of the view
|
@@ -161,14 +162,14 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
161
162
|
#
|
162
163
|
# this will be whicever component is active on the controllers
|
163
164
|
# nested within the main controller, if there are any, or the view
|
164
|
-
# itself which is active on the main controller.
|
165
|
+
# itself which is active on the main controller.
|
165
166
|
activeView: ()->
|
166
167
|
if active = @activeSubSection()
|
167
168
|
@view( active )
|
168
169
|
else
|
169
170
|
@view( @activeSection() )
|
170
171
|
|
171
|
-
# Returns the name of the active component on the main controller
|
172
|
+
# Returns the name of the active component on the main controller
|
172
173
|
activeSection: ()->
|
173
174
|
@get("active_section")
|
174
175
|
|
@@ -216,7 +217,7 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
216
217
|
return @components[0] if @useController is true
|
217
218
|
Luca.cache('main_controller')
|
218
219
|
|
219
|
-
#
|
220
|
+
#
|
220
221
|
keyHandler: (e)->
|
221
222
|
return unless e and @keyEvents
|
222
223
|
|
@@ -253,9 +254,10 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
253
254
|
# any time the card switches on one of the sub controllers
|
254
255
|
# then we should track the active sub section on the global state chart
|
255
256
|
@getMainController()?.each (component)=>
|
256
|
-
|
257
|
+
type = component.type || component.type
|
258
|
+
if type.match(/controller$/)
|
257
259
|
component.bind "after:card:switch", (previous,current)=>
|
258
|
-
@state.set(active_sub_section:current.name)
|
260
|
+
@state.set(active_sub_section:current.name)
|
259
261
|
app.trigger "sub:page:change"
|
260
262
|
|
261
263
|
setupMainController: ()->
|
@@ -263,7 +265,7 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
263
265
|
definedComponents = @components || []
|
264
266
|
|
265
267
|
@components = [
|
266
|
-
|
268
|
+
type: 'controller'
|
267
269
|
name: "main_controller"
|
268
270
|
components: definedComponents
|
269
271
|
]
|
@@ -271,23 +273,36 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
271
273
|
@defer( @setupControllerBindings, false ).until("after:components")
|
272
274
|
|
273
275
|
setupCollectionManager: ()->
|
274
|
-
|
275
|
-
@collectionManagerClass = Luca.util.resolve( @collectionManagerClass ) if _.isString( @collectionManagerClass )
|
276
|
+
return unless @useCollectionManager is true
|
276
277
|
|
277
|
-
|
278
|
+
return if @collectionManager? and @collectionManager?.get?
|
278
279
|
|
279
|
-
|
280
|
-
|
281
|
-
@collectionManager = undefined
|
280
|
+
if _.isString( @collectionManagerClass )
|
281
|
+
@collectionManagerClass = Luca.util.resolve( @collectionManagerClass )
|
282
282
|
|
283
|
-
|
284
|
-
collectionManagerOptions =
|
285
|
-
name: @collectionManager
|
283
|
+
collectionManagerOptions = @collectionManagerOptions || {}
|
286
284
|
|
287
|
-
|
285
|
+
# if the collectionManager property is present, and it
|
286
|
+
# isn't a reference to a collection manager instance, then
|
287
|
+
# it is being used as a configuration hash for when we do create
|
288
|
+
# the collection manager. so let's stash it.
|
289
|
+
if _.isObject(@collectionManager) and not _.isFunction( @collectionManager?.get )
|
290
|
+
collectionManagerOptions = @collectionManager
|
291
|
+
@collectionManager = undefined
|
288
292
|
|
289
|
-
|
290
|
-
|
293
|
+
# if the collection manager property is a string, then it is a
|
294
|
+
# reference to a name of a collection manager to use. so let's
|
295
|
+
# stash it
|
296
|
+
if _.isString(@collectionManager)
|
297
|
+
collectionManagerOptions =
|
298
|
+
name: @collectionManager
|
299
|
+
|
300
|
+
# let's try and get the collection manager by name if we can
|
301
|
+
@collectionManager = Luca.CollectionManager.get?( collectionManagerOptions.name )
|
302
|
+
|
303
|
+
# if we can't, then we will have to create one ourselves
|
304
|
+
unless _.isFunction(@collectionManager?.get)
|
305
|
+
@collectionManager = new @collectionManagerClass( collectionManagerOptions )
|
291
306
|
|
292
307
|
setupRouter: ()->
|
293
308
|
app = @
|
@@ -301,7 +316,7 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
301
316
|
# you can control which by setting the @startHistoryOn property
|
302
317
|
if @router and @autoStartHistory
|
303
318
|
@autoStartHistory = "before:render" if @autoStartHistory is true
|
304
|
-
@defer(startHistory, false).until(@, @autoStartHistory)
|
319
|
+
@defer( Luca.util.startHistory, false).until(@, @autoStartHistory)
|
305
320
|
|
306
321
|
setupKeyHandler: ()->
|
307
322
|
return unless @keyEvents
|
@@ -315,4 +330,3 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
315
330
|
|
316
331
|
for keyEvent in (@keypressEvents || ["keydown"])
|
317
332
|
$( document ).on( keyEvent, handler )
|
318
|
-
|