luca 0.9.2 → 0.9.4
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.
- data/.gitignore +1 -0
- data/.rvmrc +1 -1
- data/CHANGELOG +46 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/Guardfile +1 -1
- data/README.md +64 -27
- data/ROADMAP +17 -2
- data/Rakefile +49 -1
- data/app.rb +38 -2
- data/assets/javascripts/luca-ui-base.coffee +1 -20
- data/assets/javascripts/luca-ui-full.js +3 -0
- data/assets/javascripts/luca-ui.coffee +0 -5
- data/assets/javascripts/sandbox/application.coffee +24 -18
- data/assets/javascripts/sandbox/router.coffee +16 -6
- data/assets/javascripts/sandbox/templates/builder/component_list.luca +1 -0
- data/assets/javascripts/sandbox/templates/builder.luca +2 -0
- data/assets/javascripts/sandbox/templates/main.luca +4 -3
- data/assets/javascripts/sandbox/templates/sandbox/docs_index.luca +1 -0
- data/assets/javascripts/sandbox/templates/sandbox/navigation.luca +6 -1
- data/assets/javascripts/sandbox/templates/sandbox/readme.luca +30 -0
- data/assets/javascripts/sandbox/views/builder/builder_canvas.coffee +3 -0
- data/assets/javascripts/sandbox/views/builder/builder_editor.coffee +6 -0
- data/assets/javascripts/sandbox/views/builder/component_list.coffee +38 -0
- data/assets/javascripts/sandbox/views/builder/project_browser.coffee +14 -0
- data/assets/javascripts/sandbox/views/builder.coffee +133 -0
- data/assets/javascripts/sandbox/views/docs_controller.coffee +7 -0
- data/assets/javascripts/sandbox/views/inspector/instance_filter.coffee +18 -0
- data/assets/javascripts/sandbox/{collections/sample.coffee → views/inspector/instance_list.coffee} +0 -0
- data/assets/javascripts/sandbox/views/inspector.coffee +11 -0
- data/assets/javascripts/sandbox.coffee +2 -0
- data/assets/stylesheets/luca-ui-full.css +3 -0
- data/assets/stylesheets/sandbox/builder.scss +79 -0
- data/assets/stylesheets/sandbox/sandbox.scss +2 -1
- data/docs/application.md +41 -0
- data/docs/collection.md +79 -0
- data/docs/collection_manager.md +76 -0
- data/docs/container_philosophy.md +122 -0
- data/docs/event_binding_helpers.md +164 -0
- data/docs/method_caching_and_computed_properties.md +77 -0
- data/docs/view.md +119 -0
- data/lib/luca/rails/version.rb +1 -1
- data/lib/luca/template.rb +9 -9
- data/site/assets/bootstrap.min.js +7 -0
- data/site/assets/luca-ui-bootstrap.css +19 -1
- data/site/assets/luca-ui-development-tools.css +10 -0
- data/site/assets/luca-ui-development-tools.min.js +15 -0
- data/site/assets/luca-ui-full.min.js +8 -0
- data/site/assets/luca-ui.min.js +4 -0
- data/site/assets/sandbox.css +52 -4
- data/site/assets/sandbox.js +368 -30
- data/site/docs/application.html +41 -0
- data/site/docs/caching.html +43 -0
- data/site/docs/collection.html +75 -0
- data/site/docs/collection_manager.html +71 -0
- data/site/docs/containers.html +118 -0
- data/site/docs/events.html +153 -0
- data/site/docs/view.html +128 -0
- data/site/img/glyphicons-halflings-white.png +0 -0
- data/site/img/glyphicons-halflings.png +0 -0
- data/site/source-map.js +1 -0
- data/spec/core/view_spec.coffee +5 -17
- data/spec/managers/collection_manager_spec.coffee +4 -7
- data/src/components/application.coffee +202 -77
- data/src/components/base_toolbar.coffee +1 -1
- data/src/components/collection_view.coffee +38 -10
- data/src/components/controller.coffee +24 -1
- data/src/components/fields/checkbox_field.coffee +9 -12
- data/src/components/fields/label_field.coffee +14 -0
- data/src/components/fields/select_field.coffee +2 -2
- data/src/components/fields/text_field.coffee +12 -7
- data/src/components/fields/type_ahead_field.coffee +1 -0
- data/src/components/form_view.coffee +44 -25
- data/src/components/page_controller.coffee +2 -0
- data/src/containers/card_view.coffee +4 -1
- data/src/containers/column_view.coffee +2 -1
- data/src/containers/modal_view.coffee +6 -2
- data/src/containers/page_view.coffee +2 -0
- data/src/containers/panel_toolbar.coffee +0 -5
- data/src/containers/viewport.coffee +28 -10
- data/src/core/collection.coffee +7 -1
- data/src/core/container.coffee +57 -30
- data/src/core/core.coffee +0 -186
- data/src/core/field.coffee +11 -3
- data/src/core/model.coffee +31 -16
- data/src/core/panel.coffee +6 -46
- data/src/core/registry.coffee +19 -2
- data/src/core/script_loader.coffee +32 -0
- data/src/core/view.coffee +112 -139
- data/src/define.coffee +110 -0
- data/src/framework.coffee +8 -2
- data/src/luca.coffee +22 -0
- data/src/managers/collection_manager.coffee +65 -31
- data/src/modules/load_mask.coffee +47 -0
- data/src/plugins/development_tool_helpers.coffee +21 -0
- data/src/plugins/events.coffee +54 -0
- data/src/stylesheets/components/viewport.scss +15 -0
- data/src/stylesheets/containers/container.scss +1 -4
- data/src/stylesheets/tools/component_tester.scss +18 -0
- data/src/templates/fields/select_field.luca +6 -5
- data/src/templates/fields/text_field.luca +10 -9
- data/src/tools/application_inspector.coffee +2 -0
- data/src/tools/coffee_script_editor.coffee +28 -6
- data/src/tools/collections/components.coffee +59 -0
- data/src/tools/collections/instances.coffee +15 -0
- data/src/tools/component_tester.coffee +12 -22
- data/src/tools/console.coffee +22 -4
- data/src/tools/models/components.coffee +16 -54
- data/src/tools/models/instance.coffee +2 -0
- data/src/{core/util.coffee → util.coffee} +10 -1
- data/vendor/assets/javascripts/luca-ui-base.js +132 -137
- data/vendor/assets/javascripts/luca-ui-development-tools.js +191 -219
- data/vendor/assets/javascripts/luca-ui-development-tools.min.js +2 -2
- data/vendor/assets/javascripts/luca-ui-full.js +4680 -0
- data/vendor/assets/javascripts/luca-ui-full.min.js +8 -0
- data/vendor/assets/javascripts/luca-ui-spec.js +291 -225
- data/vendor/assets/javascripts/luca-ui.js +1001 -724
- data/vendor/assets/javascripts/luca-ui.min.js +4 -4
- data/vendor/assets/stylesheets/luca-ui-bootstrap.css +19 -1
- data/vendor/assets/stylesheets/luca-ui-development-tools.css +10 -0
- data/vendor/assets/stylesheets/luca-ui-full.css +1334 -0
- data/vendor/assets/stylesheets/luca-ui-spec.css +19 -1
- data/vendor/assets/stylesheets/luca-ui.css +19 -1
- data/views/index.erb +2 -5
- metadata +58 -9
- data/lib/sprockets/luca_template.rb +0 -49
- data/src/tools/class_browser.coffee +0 -39
- data/src/tools/components/class_browser_detail.coffee +0 -10
- data/src/tools/components/class_browser_list.coffee +0 -74
|
@@ -1,14 +1,52 @@
|
|
|
1
|
+
# Luca.Application
|
|
2
|
+
#
|
|
3
|
+
# The Application class is the global state tracking mechanism
|
|
4
|
+
# for your single page application, as well as the entry point.
|
|
5
|
+
#
|
|
6
|
+
# By default it contains a main controller which is a Luca.components.Controller instance.
|
|
7
|
+
#
|
|
8
|
+
# In a typical Luca application, the router will use the applications @navigate_to() method to switch
|
|
9
|
+
# from page to page on the main controller, or any other controllers nested inside of it.
|
|
10
|
+
#
|
|
11
|
+
# You would control flow when the controller fires activation events on the nested view components inside of it.
|
|
12
|
+
#
|
|
13
|
+
# Decoupling application control flow from the URL Fragment from Backbone.History and preventing
|
|
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.
|
|
16
|
+
|
|
17
|
+
startHistory = ()-> Backbone.history.start()
|
|
18
|
+
|
|
1
19
|
_.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
20
|
+
name: "MyApp"
|
|
21
|
+
|
|
22
|
+
# The Application uses a Backbone.Model as a state machine, which
|
|
23
|
+
# allows you to get / set attributes, persist them somewhere, and
|
|
24
|
+
# most importantly to bind to change events of certain attributes.
|
|
25
|
+
#
|
|
26
|
+
# the @defaultState property will be the default attributes
|
|
27
|
+
defaultState: {}
|
|
2
28
|
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
29
|
+
# if autoBoot is set to true, the application will
|
|
30
|
+
# attempt to boot on document ready.
|
|
31
|
+
autoBoot: false
|
|
32
|
+
|
|
33
|
+
# automatically starts the @router if it exists,
|
|
34
|
+
# once the components for the application have
|
|
35
|
+
# been created. Pass the event name you want to
|
|
36
|
+
# listen for on this component before you start history
|
|
37
|
+
autoStartHistory: "before:render"
|
|
7
38
|
|
|
8
39
|
# we will create a collection manager singleton
|
|
9
|
-
# by default unless otherwise specified
|
|
40
|
+
# by default unless otherwise specified.
|
|
10
41
|
useCollectionManager: true
|
|
11
42
|
|
|
43
|
+
# to pass options to the collection manager, set the @collectionManager
|
|
44
|
+
# hash which will get passed once the collection manager is created
|
|
45
|
+
collectionManager: {}
|
|
46
|
+
|
|
47
|
+
# by default we will use the standard collection manager which ships with
|
|
48
|
+
# 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.
|
|
12
50
|
collectionManagerClass: "Luca.CollectionManager"
|
|
13
51
|
|
|
14
52
|
# Luca plugin apps are apps which mount onto existing
|
|
@@ -22,7 +60,30 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
|
22
60
|
# with several 'pages' so to speak
|
|
23
61
|
useController: true
|
|
24
62
|
|
|
25
|
-
|
|
63
|
+
# Key Handler
|
|
64
|
+
#
|
|
65
|
+
# One responsibility of the application, since it is a viewport which monopolizes the entire screen
|
|
66
|
+
# is to relay keypress events from the document, to whatever views are interested in responding to them.
|
|
67
|
+
#
|
|
68
|
+
# This functionality is disabled by default.
|
|
69
|
+
useKeyHandler: false
|
|
70
|
+
|
|
71
|
+
# You can configure key events by specifying them by their name, as it exists in Luca.keyMap. For example:
|
|
72
|
+
#
|
|
73
|
+
keyEvents: {}
|
|
74
|
+
|
|
75
|
+
# keyEvents
|
|
76
|
+
# keyup: keyUpHandler
|
|
77
|
+
# enter: enterHandler
|
|
78
|
+
# meta:
|
|
79
|
+
# up: metaUpHandler
|
|
80
|
+
# control:
|
|
81
|
+
# forwardslash: controlSlashHandler
|
|
82
|
+
# keyup: controlUpHandler
|
|
83
|
+
# control_meta:
|
|
84
|
+
# keydown: metaControlKeyDownHandler
|
|
85
|
+
#
|
|
86
|
+
#
|
|
26
87
|
|
|
27
88
|
# applications have one component, the controller.
|
|
28
89
|
# any components defined on the application class directly
|
|
@@ -36,31 +97,36 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
|
36
97
|
]
|
|
37
98
|
|
|
38
99
|
initialize: (@options={})->
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
definedComponents = @components || []
|
|
100
|
+
app = @
|
|
101
|
+
appName = @name
|
|
102
|
+
alreadyRunning = Luca.getApplication?()
|
|
43
103
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
]
|
|
104
|
+
Luca.Application.instances ||= {}
|
|
105
|
+
Luca.Application.instances[ appName ] = app
|
|
106
|
+
|
|
107
|
+
Luca.containers.Viewport::initialize.apply @, arguments
|
|
49
108
|
|
|
50
|
-
|
|
51
|
-
@collectionManagerClass = Luca.util.resolve( @collectionManagerClass ) if _.isString( @collectionManagerClass )
|
|
109
|
+
@state = new Luca.Model( @defaultState )
|
|
52
110
|
|
|
53
|
-
|
|
54
|
-
|
|
111
|
+
# The Controller is the piece of the application that handles showing
|
|
112
|
+
# and hiding 'pages' of the app. The Application has a navigate_to
|
|
113
|
+
# method which delegates to the controller, and allows you to navigate
|
|
114
|
+
# to a given page, or component, by its name. The controller integrates
|
|
115
|
+
# with the state machine of the application
|
|
116
|
+
@setupMainController()
|
|
55
117
|
|
|
56
|
-
|
|
118
|
+
# The Collection Manager is responsible
|
|
119
|
+
@setupCollectionManager()
|
|
57
120
|
|
|
58
121
|
# we will render when all of the various components
|
|
59
122
|
# which handle our data dependencies determine that
|
|
60
123
|
# we are ready
|
|
61
|
-
@defer(()
|
|
124
|
+
@defer(()-> app.render()).until(@, "ready")
|
|
125
|
+
|
|
126
|
+
# Set up the Backbone Router
|
|
127
|
+
@setupRouter()
|
|
62
128
|
|
|
63
|
-
# the
|
|
129
|
+
# the keyHandler allows us to specify
|
|
64
130
|
# keyEvents on our application with an API very similar
|
|
65
131
|
# to the DOM events API for Backbone.View
|
|
66
132
|
#
|
|
@@ -69,52 +135,51 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
|
69
135
|
# keyEvents:
|
|
70
136
|
# meta:
|
|
71
137
|
# forwardslash: "altSlashHandler"
|
|
72
|
-
|
|
138
|
+
if @useKeyRouter is true
|
|
139
|
+
console.log "The useKeyRouter property is being deprecated. switch to useKeyHandler instead"
|
|
140
|
+
|
|
141
|
+
@setupKeyHandler() if (@useKeyHandler is true or @useKeyRouter is true) and @keyEvents?
|
|
73
142
|
|
|
74
143
|
# if the application is a plugin designed to modify the behavior
|
|
75
144
|
# of another app, then don't claim ownership. otherwise the most common
|
|
76
145
|
# use-case is that there will be one application instance
|
|
77
|
-
unless @plugin is true
|
|
78
|
-
Luca.getApplication = ()=>
|
|
146
|
+
unless @plugin is true or alreadyRunning
|
|
147
|
+
Luca.getApplication = (name)=>
|
|
148
|
+
return app unless name?
|
|
149
|
+
Luca.Application.instances[ name ]
|
|
150
|
+
|
|
151
|
+
if @autoBoot
|
|
152
|
+
if Luca.util.resolve(@name)
|
|
153
|
+
throw "Attempting to override window.#{ @name } when it already exists"
|
|
79
154
|
|
|
155
|
+
$ ->
|
|
156
|
+
window[ appName ] = app
|
|
157
|
+
app.boot()
|
|
158
|
+
|
|
159
|
+
# @activeView() returns a reference to the instance of the view
|
|
160
|
+
# which is currently monopolizing the viewport.
|
|
161
|
+
#
|
|
162
|
+
# this will be whicever component is active on the controllers
|
|
163
|
+
# nested within the main controller, if there are any, or the view
|
|
164
|
+
# itself which is active on the main controller.
|
|
80
165
|
activeView: ()->
|
|
81
166
|
if active = @activeSubSection()
|
|
82
167
|
@view( active )
|
|
83
168
|
else
|
|
84
169
|
@view( @activeSection() )
|
|
85
170
|
|
|
86
|
-
|
|
87
|
-
@get("active_sub_section")
|
|
88
|
-
|
|
171
|
+
# Returns the name of the active component on the main controller
|
|
89
172
|
activeSection: ()->
|
|
90
173
|
@get("active_section")
|
|
91
174
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if routerStartEvent is "before:render"
|
|
99
|
-
Backbone.history.start()
|
|
100
|
-
else
|
|
101
|
-
@bind routerStartEvent, ()-> Backbone.history.start()
|
|
102
|
-
|
|
103
|
-
afterComponents: ()->
|
|
104
|
-
Luca.containers.Viewport::afterComponents?.apply @, arguments
|
|
105
|
-
|
|
106
|
-
# any time the main controller card switches we should track
|
|
107
|
-
# the active card on the global state chart
|
|
108
|
-
@getMainController()?.bind "after:card:switch", (previous,current)=>
|
|
109
|
-
@state.set(active_section:current.name)
|
|
110
|
-
|
|
111
|
-
# any time the card switches on one of the sub controllers
|
|
112
|
-
# then we should track the active sub section on the global state chart
|
|
113
|
-
@getMainController()?.each (component)=>
|
|
114
|
-
if component.ctype.match(/controller$/)
|
|
115
|
-
component.bind "after:card:switch", (previous,current)=>
|
|
116
|
-
@state.set(active_sub_section:current.name)
|
|
175
|
+
# Returns the name of the active component on the nested controllers
|
|
176
|
+
# on the main controller, if there is one. These get set on the
|
|
177
|
+
# state machine in response to card switch events on the controller component
|
|
178
|
+
activeSubSection: ()->
|
|
179
|
+
@get("active_sub_section")
|
|
117
180
|
|
|
181
|
+
activePages: ()->
|
|
182
|
+
@$('.luca-ui-controller').map (index,element)=> $(element).data('active-section')
|
|
118
183
|
|
|
119
184
|
# boot should trigger the ready event, which will call the initial call
|
|
120
185
|
# to render() your application, which will have a cascading effect on every
|
|
@@ -135,12 +200,8 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
|
135
200
|
get: (attribute)->
|
|
136
201
|
@state.get(attribute)
|
|
137
202
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
Luca.cache('main_controller')
|
|
141
|
-
|
|
142
|
-
set: (attributes)->
|
|
143
|
-
@state.set(attributes)
|
|
203
|
+
set: (attribute, value, options)->
|
|
204
|
+
@state.set.apply(@state, arguments)
|
|
144
205
|
|
|
145
206
|
view: (name)->
|
|
146
207
|
Luca.cache(name)
|
|
@@ -151,23 +212,12 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
|
151
212
|
navigate_to: (component_name, callback)->
|
|
152
213
|
@getMainController().navigate_to(component_name, callback)
|
|
153
214
|
|
|
154
|
-
|
|
155
|
-
return
|
|
156
|
-
|
|
157
|
-
@keyEvents.control_meta ||= {}
|
|
158
|
-
|
|
159
|
-
# allow for both meta_control, control_meta for the combo
|
|
160
|
-
_.extend(@keyEvents.control_meta, @keyEvents.meta_control) if @keyEvents.meta_control
|
|
161
|
-
|
|
162
|
-
router = _.bind(@keyRouter, @)
|
|
163
|
-
|
|
164
|
-
$( document ).keydown( router )
|
|
215
|
+
getMainController: ()->
|
|
216
|
+
return @components[0] if @useController is true
|
|
217
|
+
Luca.cache('main_controller')
|
|
165
218
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
# TODO: Define a syntax for mapping combinations of meta, control, and keycodes
|
|
169
|
-
# to some sort of method delegation system that the application handles.
|
|
170
|
-
keyRouter: (e)->
|
|
219
|
+
#
|
|
220
|
+
keyHandler: (e)->
|
|
171
221
|
return unless e and @keyEvents
|
|
172
222
|
|
|
173
223
|
isInputEvent = $(e.target).is('input') || $(e.target).is('textarea')
|
|
@@ -187,7 +237,82 @@ _.def('Luca.Application').extends('Luca.containers.Viewport').with
|
|
|
187
237
|
source = if meta and control then @keyEvents.meta_control else source
|
|
188
238
|
|
|
189
239
|
if keyEvent = source?[keyname]
|
|
190
|
-
if @[keyEvent]?
|
|
240
|
+
if @[keyEvent]? and _.isFunction(@[keyEvent])
|
|
191
241
|
@[keyEvent]?.call(@)
|
|
192
242
|
else
|
|
193
|
-
@trigger(keyEvent)
|
|
243
|
+
@trigger(keyEvent, e, keyname)
|
|
244
|
+
|
|
245
|
+
setupControllerBindings: ()->
|
|
246
|
+
app = @
|
|
247
|
+
# any time the main controller card switches we should track
|
|
248
|
+
# the active card on the global state chart
|
|
249
|
+
@getMainController()?.bind "after:card:switch", (previous,current)=>
|
|
250
|
+
@state.set(active_section:current.name)
|
|
251
|
+
app.trigger "page:change"
|
|
252
|
+
|
|
253
|
+
# any time the card switches on one of the sub controllers
|
|
254
|
+
# then we should track the active sub section on the global state chart
|
|
255
|
+
@getMainController()?.each (component)=>
|
|
256
|
+
if component.ctype.match(/controller$/)
|
|
257
|
+
component.bind "after:card:switch", (previous,current)=>
|
|
258
|
+
@state.set(active_sub_section:current.name)
|
|
259
|
+
app.trigger "sub:page:change"
|
|
260
|
+
|
|
261
|
+
setupMainController: ()->
|
|
262
|
+
if @useController is true
|
|
263
|
+
definedComponents = @components || []
|
|
264
|
+
|
|
265
|
+
@components = [
|
|
266
|
+
ctype: 'controller'
|
|
267
|
+
name: "main_controller"
|
|
268
|
+
components: definedComponents
|
|
269
|
+
]
|
|
270
|
+
|
|
271
|
+
@defer( @setupControllerBindings, false ).until("after:components")
|
|
272
|
+
|
|
273
|
+
setupCollectionManager: ()->
|
|
274
|
+
if @useCollectionManager is true
|
|
275
|
+
@collectionManagerClass = Luca.util.resolve( @collectionManagerClass ) if _.isString( @collectionManagerClass )
|
|
276
|
+
|
|
277
|
+
collectionManagerOptions = @collectionManagerOptions
|
|
278
|
+
|
|
279
|
+
if _.isObject(@collectionManager) and not _.isFunction( @collectionManager?.get )
|
|
280
|
+
collectionManagerOptions = @collectionManager
|
|
281
|
+
@collectionManager = undefined
|
|
282
|
+
|
|
283
|
+
if _.isString(@collectionManager)
|
|
284
|
+
collectionManagerOptions =
|
|
285
|
+
name: @collectionManager
|
|
286
|
+
|
|
287
|
+
@collectionManager = Luca.CollectionManager.get?( collectionManagerOptions.name )
|
|
288
|
+
|
|
289
|
+
unless _.isFunction(@collectionManager?.get)
|
|
290
|
+
@collectionManager = new @collectionManagerClass( collectionManagerOptions )
|
|
291
|
+
|
|
292
|
+
setupRouter: ()->
|
|
293
|
+
app = @
|
|
294
|
+
|
|
295
|
+
if _.isString( @router )
|
|
296
|
+
routerClass = Luca.util.resolve(@router)
|
|
297
|
+
@router = new routerClass({app})
|
|
298
|
+
|
|
299
|
+
# if this application has a router associated with it
|
|
300
|
+
# then we need to start backbone history on a certain event.
|
|
301
|
+
# you can control which by setting the @startHistoryOn property
|
|
302
|
+
if @router and @autoStartHistory
|
|
303
|
+
@autoStartHistory = "before:render" if @autoStartHistory is true
|
|
304
|
+
@defer(startHistory, false).until(@, @autoStartHistory)
|
|
305
|
+
|
|
306
|
+
setupKeyHandler: ()->
|
|
307
|
+
return unless @keyEvents
|
|
308
|
+
|
|
309
|
+
@keyEvents.control_meta ||= {}
|
|
310
|
+
|
|
311
|
+
# allow for both meta_control, control_meta for the combo
|
|
312
|
+
_.extend(@keyEvents.control_meta, @keyEvents.meta_control) if @keyEvents.meta_control
|
|
313
|
+
|
|
314
|
+
handler = _.bind(@keyHandler, @)
|
|
315
|
+
|
|
316
|
+
for keyEvent in (@keypressEvents || ["keydown"])
|
|
317
|
+
$( document ).on( keyEvent, handler )
|
|
318
|
+
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
# Public: The CollectionView renders a collection of models into a list of items.
|
|
2
|
+
#
|
|
3
|
+
# Examples
|
|
4
|
+
#
|
|
5
|
+
# _.def('App.ListView').extends('Luca.components.CollectionView').with
|
|
6
|
+
# collection: new App.SampleCollection()
|
|
7
|
+
# itemTemplate: "list_view_item"
|
|
8
|
+
# loadMask: true
|
|
9
|
+
#
|
|
2
10
|
|
|
3
11
|
_.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
|
|
4
12
|
tagName: "div"
|
|
@@ -17,6 +25,10 @@ _.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
|
|
|
17
25
|
|
|
18
26
|
itemClassName: 'collection-item'
|
|
19
27
|
|
|
28
|
+
hooks:[
|
|
29
|
+
"empty:results"
|
|
30
|
+
]
|
|
31
|
+
|
|
20
32
|
initialize: (@options={})->
|
|
21
33
|
_.extend(@, @options)
|
|
22
34
|
|
|
@@ -31,12 +43,23 @@ _.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
|
|
|
31
43
|
Luca.components.Panel::initialize.apply(@, arguments)
|
|
32
44
|
|
|
33
45
|
if _.isString(@collection) and Luca.CollectionManager.get()
|
|
34
|
-
@collection = Luca.CollectionManager.get().
|
|
46
|
+
@collection = Luca.CollectionManager.get().getOrCreate(@collection)
|
|
35
47
|
|
|
36
48
|
if Luca.isBackboneCollection(@collection)
|
|
37
|
-
@collection.
|
|
49
|
+
@collection.on "before:fetch", ()=>
|
|
50
|
+
@trigger "enable:loadmask" if @loadMask is true
|
|
51
|
+
|
|
52
|
+
@collection.bind "reset", ()=>
|
|
53
|
+
@trigger "disable:loadmask" if @loadMask is true
|
|
54
|
+
@refresh()
|
|
55
|
+
|
|
38
56
|
@collection.bind "add", @refresh
|
|
39
57
|
@collection.bind "remove", @refresh
|
|
58
|
+
else
|
|
59
|
+
throw "Collection Views must have a valid backbone collection"
|
|
60
|
+
|
|
61
|
+
if @collection.length > 0
|
|
62
|
+
@refresh()
|
|
40
63
|
|
|
41
64
|
attributesForItem: (item)->
|
|
42
65
|
_.extend {}, class: @itemClassName, "data-index": item.index
|
|
@@ -46,7 +69,7 @@ _.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
|
|
|
46
69
|
content = templateFn.call(@, item)
|
|
47
70
|
|
|
48
71
|
if @itemRenderer? and _.isFunction( @itemRenderer )
|
|
49
|
-
content = @itemRenderer.call(@, item)
|
|
72
|
+
content = @itemRenderer.call(@, item, item.model, item.index)
|
|
50
73
|
|
|
51
74
|
if @itemProperty
|
|
52
75
|
content = item.model.get(@itemProperty) || item.model[ @itemProperty ]
|
|
@@ -56,7 +79,6 @@ _.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
|
|
|
56
79
|
|
|
57
80
|
makeItem: (model, index)->
|
|
58
81
|
item = if @prepareItem? then @prepareItem.call(@, model, index) else (model:model, index: index)
|
|
59
|
-
|
|
60
82
|
make(@itemTagName, @attributesForItem(item), @contentForItem(item))
|
|
61
83
|
|
|
62
84
|
getModels: ()->
|
|
@@ -66,12 +88,13 @@ _.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
|
|
|
66
88
|
@collection.models
|
|
67
89
|
|
|
68
90
|
refresh: ()->
|
|
69
|
-
panel = @
|
|
70
|
-
|
|
71
91
|
@$bodyEl().empty()
|
|
72
92
|
|
|
73
|
-
|
|
74
|
-
|
|
93
|
+
if @getModels().length is 0
|
|
94
|
+
@trigger("empty:results")
|
|
95
|
+
|
|
96
|
+
_( @getModels() ).each (model, index)=>
|
|
97
|
+
@$append( @makeItem(model, index) )
|
|
75
98
|
|
|
76
99
|
registerEvent: (domEvent, selector, handler)->
|
|
77
100
|
if !handler? and _.isFunction(selector)
|
|
@@ -83,4 +106,9 @@ _.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
|
|
|
83
106
|
|
|
84
107
|
render: ()->
|
|
85
108
|
@refresh()
|
|
86
|
-
@$attach() if @$el.parent().length > 0 and @container?
|
|
109
|
+
@$attach() if @$el.parent().length > 0 and @container?
|
|
110
|
+
@
|
|
111
|
+
|
|
112
|
+
# Private Helpers
|
|
113
|
+
|
|
114
|
+
make = Luca.View::make
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
_.def('Luca.components.Controller').extends('Luca.containers.CardView').with
|
|
2
|
+
|
|
3
|
+
additionalClassNames:['luca-ui-controller']
|
|
4
|
+
|
|
5
|
+
activeAttribute: "active-section"
|
|
6
|
+
|
|
2
7
|
initialize: (@options)->
|
|
3
8
|
Luca.containers.CardView::initialize.apply @, arguments
|
|
4
9
|
|
|
@@ -6,13 +11,31 @@ _.def('Luca.components.Controller').extends('Luca.containers.CardView').with
|
|
|
6
11
|
|
|
7
12
|
throw "Controllers must specify a defaultCard property and/or the first component must have a name" unless @defaultCard
|
|
8
13
|
|
|
9
|
-
@state = new Backbone.Model
|
|
14
|
+
@state = new Backbone.Model
|
|
10
15
|
active_section: @defaultCard
|
|
11
16
|
|
|
12
17
|
each: (fn)->
|
|
13
18
|
_( @components ).each (component)=>
|
|
14
19
|
fn.apply @, [component]
|
|
15
20
|
|
|
21
|
+
activeSection: ()->
|
|
22
|
+
@get("activeSection")
|
|
23
|
+
|
|
24
|
+
controllers:(deep=false)->
|
|
25
|
+
@select 'ctype', 'controller', deep
|
|
26
|
+
|
|
27
|
+
availableSections: ()->
|
|
28
|
+
base = {}
|
|
29
|
+
base[ @name ] = @sectionNames()
|
|
30
|
+
|
|
31
|
+
_( @controllers() ).reduce (memo,controller)=>
|
|
32
|
+
memo[ controller.name ] = controller.sectionNames()
|
|
33
|
+
memo
|
|
34
|
+
, base
|
|
35
|
+
|
|
36
|
+
sectionNames: (deep=false)->
|
|
37
|
+
@pluck('name')
|
|
38
|
+
|
|
16
39
|
default: (callback)->
|
|
17
40
|
@navigate_to(@defaultCard, callback)
|
|
18
41
|
|
|
@@ -3,23 +3,20 @@ _.def('Luca.fields.CheckboxField').extends('Luca.core.Field').with
|
|
|
3
3
|
events:
|
|
4
4
|
"change input" : "change_handler"
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
className: 'luca-ui-checkbox-field luca-ui-field'
|
|
7
|
+
template: 'fields/checkbox_field'
|
|
8
|
+
hooks: ["checked","unchecked"]
|
|
9
|
+
send_blanks: true
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
change_handler: (e)->
|
|
12
|
+
me = my = $(e.target)
|
|
10
13
|
|
|
11
|
-
if me.checked
|
|
14
|
+
if me.is(":checked")
|
|
12
15
|
@trigger "checked"
|
|
13
16
|
else
|
|
14
17
|
@trigger "unchecked"
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
template: 'fields/checkbox_field'
|
|
19
|
-
|
|
20
|
-
hooks: ["checked","unchecked"]
|
|
21
|
-
|
|
22
|
-
send_blanks: true
|
|
19
|
+
@trigger "on:change", @, e, me.is(":checked")
|
|
23
20
|
|
|
24
21
|
initialize: (@options={})->
|
|
25
22
|
_.extend @, @options
|
|
@@ -37,4 +34,4 @@ _.def('Luca.fields.CheckboxField').extends('Luca.core.Field').with
|
|
|
37
34
|
@input.attr('checked', checked)
|
|
38
35
|
|
|
39
36
|
getValue:()->
|
|
40
|
-
@input.
|
|
37
|
+
@input.is(":checked")
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
_.def("Luca.components.LabelField").extends("Luca.core.Field").with
|
|
2
|
+
className: "luca-ui-field luca-ui-label-field"
|
|
3
|
+
|
|
4
|
+
getValue: ()->
|
|
5
|
+
@$('input').attr('value')
|
|
6
|
+
|
|
7
|
+
formatter: (value)->
|
|
8
|
+
value ||= @getValue()
|
|
9
|
+
_.str.titleize( value )
|
|
10
|
+
|
|
11
|
+
setValue: (value)->
|
|
12
|
+
@trigger("change", value, @getValue())
|
|
13
|
+
@$('input').attr('value', value)
|
|
14
|
+
@$('.value').html( @formatter(value) )
|
|
@@ -50,13 +50,13 @@ _.def('Luca.fields.SelectField').extends('Luca.core.Field').with
|
|
|
50
50
|
parseData: ()->
|
|
51
51
|
@collection.data = _( @collection.data ).map (record)=>
|
|
52
52
|
return record if not _.isArray( record )
|
|
53
|
+
|
|
53
54
|
hash = {}
|
|
54
55
|
hash[ @valueField ] = record[0]
|
|
55
|
-
hash[ @displayField ] = record[1]
|
|
56
|
+
hash[ @displayField ] = record[1] || record[0]
|
|
56
57
|
|
|
57
58
|
hash
|
|
58
59
|
|
|
59
|
-
|
|
60
60
|
afterRender: ()->
|
|
61
61
|
@input = $('select', @el)
|
|
62
62
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
change_handler = (e)-> @trigger "on:change", @, e
|
|
2
1
|
|
|
3
2
|
_.def('Luca.fields.TextField').extends('Luca.core.Field').with
|
|
4
3
|
events:
|
|
@@ -12,8 +11,11 @@ _.def('Luca.fields.TextField').extends('Luca.core.Field').with
|
|
|
12
11
|
|
|
13
12
|
send_blanks: true
|
|
14
13
|
|
|
14
|
+
keyEventThrottle: 300
|
|
15
|
+
|
|
15
16
|
initialize: (@options={})->
|
|
16
|
-
|
|
17
|
+
if @enableKeyEvents
|
|
18
|
+
@registerEvent("keyup input","keyup_handler")
|
|
17
19
|
|
|
18
20
|
@input_id ||= _.uniqueId('field')
|
|
19
21
|
@input_name ||= @name
|
|
@@ -28,13 +30,16 @@ _.def('Luca.fields.TextField').extends('Luca.core.Field').with
|
|
|
28
30
|
@$el.addClass('input-append')
|
|
29
31
|
@addOn = @append
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
Luca.core.Field::initialize.apply @, arguments
|
|
34
|
+
|
|
35
|
+
keyup_handler: (e)->
|
|
36
|
+
@trigger "on:keyup", @, e
|
|
32
37
|
|
|
33
38
|
blur_handler: (e)->
|
|
34
|
-
|
|
39
|
+
@trigger "on:blur", @, e
|
|
35
40
|
|
|
36
41
|
focus_handler: (e)->
|
|
37
|
-
|
|
42
|
+
@trigger "on:focus", @, e
|
|
38
43
|
|
|
39
|
-
change_handler:
|
|
40
|
-
|
|
44
|
+
change_handler: (e)->
|
|
45
|
+
@trigger "on:change", @, e
|