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
data/src/core/container.coffee
CHANGED
@@ -1,90 +1,53 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# The Component Container is a nestable component
|
4
|
-
# which are responsible for handling communication between multiple
|
5
|
-
# nested views.
|
6
|
-
#
|
7
|
-
# One: Layout
|
8
|
-
#
|
9
|
-
# a container is responsible for laying out the nested views
|
10
|
-
# and rendering them in a special DOM element
|
11
|
-
doLayout = ()->
|
12
|
-
@trigger "before:layout", @
|
13
|
-
@prepareLayout()
|
14
|
-
@trigger "after:layout", @
|
15
|
-
|
16
|
-
# and displaying those elements in a way that is
|
17
|
-
# optimal for the desired user experience of that view
|
18
|
-
# ( i.e seeing only one of them at a time, seeing them side by side )
|
19
|
-
applyDOMConfig = (panel, panelIndex)->
|
20
|
-
style_declarations = []
|
21
|
-
|
22
|
-
style_declarations.push "height: #{ (if _.isNumber(panel.height) then panel.height + 'px' else panel.height ) }" if panel.height?
|
23
|
-
style_declarations.push "width: #{ (if _.isNumber(panel.width) then panel.width + 'px' else panel.width ) }" if panel.width?
|
24
|
-
style_declarations.push "float: #{ panel.float }" if panel.float
|
25
|
-
|
26
|
-
config =
|
27
|
-
class: panel?.classes || @componentClass
|
28
|
-
id: "#{ @cid }-#{ panelIndex }"
|
29
|
-
style: style_declarations.join(';')
|
30
|
-
"data-luca-owner" : @name || @cid
|
31
|
-
|
32
|
-
if @customizeContainerEl?
|
33
|
-
config = @customizeContainerEl( config, panel, panelIndex )
|
34
|
-
|
35
|
-
config
|
1
|
+
container = Luca.register "Luca.core.Container"
|
36
2
|
|
37
|
-
|
38
|
-
#
|
39
|
-
# A container is responsible for creating and storing references to the nested
|
40
|
-
# views that are required for its functioning.
|
41
|
-
doComponents = ()->
|
3
|
+
container.extends "Luca.components.Panel"
|
42
4
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
# Containers are central to Luca. They are what make it easy to structure
|
52
|
-
# your application in a logical way and to specify much of the behavior of
|
53
|
-
# complex / composite views at define time using JSON syntax combined with
|
54
|
-
# the meta data contained in the Luca component registry.
|
55
|
-
_.def('Luca.core.Container').extends('Luca.components.Panel').with
|
5
|
+
container.triggers "before:components",
|
6
|
+
"before:render:components",
|
7
|
+
"before:layout",
|
8
|
+
"after:components",
|
9
|
+
"after:layout",
|
10
|
+
"first:activation"
|
56
11
|
|
12
|
+
container.defines
|
57
13
|
className: 'luca-ui-container'
|
58
14
|
|
59
15
|
componentTag: 'div'
|
16
|
+
|
60
17
|
componentClass: 'luca-ui-panel'
|
61
18
|
|
62
19
|
isContainer: true
|
63
20
|
|
64
|
-
hooks:[
|
65
|
-
"before:components"
|
66
|
-
"before:render:components"
|
67
|
-
"before:layout"
|
68
|
-
"after:components"
|
69
|
-
"after:layout"
|
70
|
-
"first:activation"
|
71
|
-
]
|
72
|
-
|
73
21
|
rendered: false
|
74
22
|
|
75
23
|
components: []
|
76
24
|
|
25
|
+
# @componentEvents provides declarative syntax for responding to events on
|
26
|
+
# the components in this container. the format of the syntax is very similar
|
27
|
+
# to the other event binding helpers:
|
28
|
+
#
|
29
|
+
# component_accessor component:trigger
|
30
|
+
#
|
31
|
+
# where component_accessor is either the name of the role, or a method on the container
|
32
|
+
# which will find the component in question.
|
33
|
+
#
|
34
|
+
# myContainer = new Luca.core.Container
|
35
|
+
# componentEvents:
|
36
|
+
# "name component:trigger" : "handler"
|
37
|
+
# "role component:trigger" : "handler"
|
38
|
+
# "getter component:trigger" : "handler"
|
39
|
+
#
|
40
|
+
componentEvents: {}
|
41
|
+
|
77
42
|
initialize: (@options={})->
|
78
43
|
_.extend @, @options
|
79
44
|
|
80
|
-
@setupHooks
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
"first:activation"
|
87
|
-
]
|
45
|
+
@setupHooks( Luca.core.Container::hooks )
|
46
|
+
|
47
|
+
# aliases for the components property
|
48
|
+
@components ||= @fields ||= @pages ||= @cards ||= @views
|
49
|
+
|
50
|
+
validateContainerConfiguration(@)
|
88
51
|
|
89
52
|
Luca.View::initialize.apply @, arguments
|
90
53
|
|
@@ -183,6 +146,9 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
183
146
|
map = @componentIndex =
|
184
147
|
name_index: {}
|
185
148
|
cid_index: {}
|
149
|
+
role_index: {}
|
150
|
+
|
151
|
+
container = @
|
186
152
|
|
187
153
|
@components = _( @components ).map (object, index)=>
|
188
154
|
|
@@ -191,43 +157,42 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
191
157
|
# adding the views @$el to the appropriate @container.
|
192
158
|
|
193
159
|
# you can also just pass a string representing the component_type
|
194
|
-
component = if Luca.
|
160
|
+
component = if Luca.isComponent( object )
|
195
161
|
object
|
196
162
|
else
|
197
163
|
object.type ||= object.ctype
|
198
164
|
|
199
165
|
if !object.type?
|
166
|
+
# TODO
|
167
|
+
# Add support for all of the various components property aliases
|
200
168
|
if object.components?
|
201
169
|
object.type = object.ctype = 'container'
|
202
170
|
else
|
203
171
|
object.type = object.ctype = Luca.defaultComponentType
|
204
172
|
|
205
|
-
|
173
|
+
# if the container defines a @defaults property
|
174
|
+
# then we should make sure our child components inherit
|
175
|
+
# these values unless specifically defined
|
176
|
+
object = _.defaults(object, (container.defaults || {}))
|
206
177
|
|
207
|
-
|
208
|
-
# we will create a function with that name on this container that
|
209
|
-
# allows you to access this component
|
210
|
-
if _.isString( component.getter )
|
211
|
-
@[ component.getter ] = (()-> component)
|
178
|
+
created = Luca.util.lazyComponent( object )
|
212
179
|
|
213
180
|
# if we're using base backbone views, then they don't extend themselves
|
214
181
|
# with their passed options, so this is a workaround to get them to
|
215
182
|
# pick up the container config property
|
216
|
-
if !component.container and component.options
|
183
|
+
if !component.container and component.options?.container
|
217
184
|
component.container = component.options.container
|
218
185
|
|
219
|
-
if
|
220
|
-
|
186
|
+
if not component.container?
|
187
|
+
console.log component,index,@
|
188
|
+
console.error "could not assign container property to component on container #{ @name || @cid }"
|
221
189
|
|
222
|
-
|
223
|
-
map.name_index[ component.name ] = index
|
190
|
+
indexComponent( component ).at(index).in( @componentIndex )
|
224
191
|
|
225
192
|
component
|
226
193
|
|
227
194
|
@componentsCreated = true
|
228
195
|
|
229
|
-
@registerComponentEvents() unless _.isEmpty(@componentEvents)
|
230
|
-
|
231
196
|
map
|
232
197
|
|
233
198
|
# Trigger the Rendering Pipeline process on all of the nested
|
@@ -235,14 +200,14 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
235
200
|
renderComponents: (@debugMode="")->
|
236
201
|
@debug "container render components"
|
237
202
|
|
238
|
-
container = @
|
203
|
+
container = @
|
239
204
|
_(@components).each (component)->
|
240
|
-
component.getParent = ()->
|
241
|
-
container
|
205
|
+
component.getParent = ()->
|
206
|
+
container
|
242
207
|
|
243
208
|
try
|
244
|
-
|
245
|
-
component.render()
|
209
|
+
@$( component.container ).eq(0).append( component.el )
|
210
|
+
component.render()
|
246
211
|
catch e
|
247
212
|
console.log "Error Rendering Component #{ component.name || component.cid }", component
|
248
213
|
|
@@ -271,32 +236,74 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
271
236
|
component.previously_activated = true
|
272
237
|
|
273
238
|
#### Underscore Methods For Working with Components
|
274
|
-
|
275
|
-
|
239
|
+
_: ()-> _( @components )
|
240
|
+
|
241
|
+
pluck: (attribute)->
|
242
|
+
@_().pluck(attribute)
|
276
243
|
|
277
244
|
invoke: (method)->
|
278
|
-
_(
|
245
|
+
@_().invoke(method)
|
246
|
+
|
247
|
+
select: (fn)->
|
248
|
+
@_().select(fn)
|
249
|
+
|
250
|
+
detect: (fn)->
|
251
|
+
@_().detect(attribute)
|
252
|
+
|
253
|
+
reject: (fn)->
|
254
|
+
@_().reject(fn)
|
279
255
|
|
280
256
|
map: (fn)->
|
281
|
-
_(
|
282
|
-
|
283
|
-
# event binding sugar for nested components
|
284
|
-
#
|
285
|
-
# you can define events like:
|
257
|
+
@_().map(fn)
|
286
258
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
259
|
+
registerComponentEvents: (eventList)->
|
260
|
+
container = @
|
261
|
+
|
262
|
+
for listener, handler of (eventList || @componentEvents||{})
|
263
|
+
[componentNameOrRole,eventId] = listener.split(' ')
|
264
|
+
|
265
|
+
unless _.isFunction( @[handler] )
|
266
|
+
console.log "Error registering component event", listener, componentNameOrRole, eventId
|
267
|
+
throw "Invalid component event definition #{ listener }. Specified handler is not a method on the container"
|
268
|
+
|
269
|
+
if componentNameOrRole is "*"
|
270
|
+
@eachComponent (component)=> component.on(eventId, @[handler], container)
|
271
|
+
else
|
272
|
+
component = @findComponentForEventBinding( componentNameOrRole )
|
273
|
+
|
274
|
+
unless component? and Luca.isComponent(component)
|
275
|
+
console.log "Error registering component event", listener, componentNameOrRole, eventId
|
276
|
+
throw "Invalid component event definition: #{ componentNameOrRole }"
|
291
277
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
278
|
+
component?.bind eventId, @[handler], container
|
279
|
+
|
280
|
+
|
281
|
+
subContainers: ()->
|
282
|
+
@select (component)->
|
283
|
+
component.isContainer is true
|
284
|
+
|
285
|
+
roles: ()->
|
286
|
+
_( @allChildren() ).pluck('role')
|
287
|
+
|
288
|
+
allChildren: ()->
|
289
|
+
children = @components
|
290
|
+
grandchildren = _( @subContainers() ).invoke('allChildren')
|
291
|
+
_([children,grandchildren]).chain().compact().flatten().value()
|
292
|
+
|
293
|
+
findComponentForEventBinding: (nameRoleOrGetter, deep=true)->
|
294
|
+
@findComponentByName(nameRoleOrGetter, deep) || @findComponentByGetter( nameRoleOrGetter, deep ) || @findComponentByRole( nameRoleOrGetter, deep )
|
295
|
+
|
296
|
+
findComponentByGetter: (getter, deep=false)->
|
297
|
+
_( @allChildren() ).detect (component)->
|
298
|
+
component.getter is getter
|
299
|
+
|
300
|
+
findComponentByRole: (role,deep=false)->
|
301
|
+
_( @allChildren() ).detect (component)->
|
302
|
+
component.role is role or component.type is role or component.ctype is role
|
297
303
|
|
298
304
|
findComponentByName: (name, deep=false)->
|
299
|
-
@
|
305
|
+
_( @allChildren() ).detect (component)->
|
306
|
+
component.name is name
|
300
307
|
|
301
308
|
findComponentById: (id, deep=false)->
|
302
309
|
@findComponent(id, "cid_index", deep)
|
@@ -305,12 +312,14 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
305
312
|
@createComponents() unless @componentsCreated is true
|
306
313
|
|
307
314
|
position = @componentIndex?[ haystack ][ needle ]
|
308
|
-
component = @components
|
315
|
+
component = @components[ position ]
|
309
316
|
|
310
317
|
return component if component
|
311
318
|
|
312
319
|
if deep is true
|
313
|
-
sub_container = _( @components ).detect (component)->
|
320
|
+
sub_container = _( @components ).detect (component)->
|
321
|
+
component?.findComponent?(needle, haystack, true)
|
322
|
+
|
314
323
|
sub_container?.findComponent?(needle, haystack, true)
|
315
324
|
|
316
325
|
each: (fn)->
|
@@ -333,27 +342,24 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
333
342
|
return @components[ @activeItem ]
|
334
343
|
|
335
344
|
componentElements: ()->
|
336
|
-
@$("
|
345
|
+
@$("[data-luca-parent='#{ @name || @cid }']")
|
337
346
|
|
338
347
|
getComponent: (needle)->
|
339
348
|
@components[ needle ]
|
340
349
|
|
341
|
-
rootComponent: ()->
|
342
|
-
console.log "Calling rootComponent will be deprecated. use isRootComponent instead"
|
343
|
-
!@getParent?
|
344
|
-
|
345
350
|
isRootComponent:()->
|
346
351
|
!@getParent?
|
347
352
|
|
348
353
|
getRootComponent: ()->
|
349
|
-
if @
|
350
|
-
|
351
|
-
|
354
|
+
if @isRootComponent() then @ else @getParent().getRootComponent()
|
355
|
+
|
356
|
+
|
357
|
+
selectByAttribute: (attribute, value=undefined, deep=false)->
|
352
358
|
components = _( @components ).map (component)->
|
353
359
|
matches = []
|
354
360
|
test = component[ attribute ]
|
355
361
|
|
356
|
-
matches.push( component ) if test is value
|
362
|
+
matches.push( component ) if test is value or (not value? and test?)
|
357
363
|
|
358
364
|
# recursively traverse our components
|
359
365
|
matches.push component.selectByAttribute?(attribute, value, true) if deep is true
|
@@ -362,13 +368,91 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
362
368
|
|
363
369
|
_.flatten( components )
|
364
370
|
|
365
|
-
select: (attribute, value, deep=false)->
|
366
|
-
console.log "Container.select will be replaced by selectByAttribute in 1.0"
|
367
|
-
Luca.core.Container::selectByAttribute.apply(@, arguments)
|
368
371
|
|
369
372
|
# This is the method by which a container injects the rendered child views
|
370
373
|
# into the DOM. It will get passed the container object, and the component
|
371
|
-
# that is being rendered.
|
374
|
+
# that is being rendered.
|
372
375
|
Luca.core.Container.componentRenderer = (container, component)->
|
373
376
|
attachMethod = $( component.container )[ component.attachWith || "append" ]
|
374
377
|
attachMethod( component.render().el )
|
378
|
+
|
379
|
+
|
380
|
+
#### Private Helpers
|
381
|
+
|
382
|
+
doLayout = ()->
|
383
|
+
@trigger "before:layout", @
|
384
|
+
@prepareLayout()
|
385
|
+
@trigger "after:layout", @
|
386
|
+
|
387
|
+
applyDOMConfig = (panel, panelIndex)->
|
388
|
+
style_declarations = []
|
389
|
+
|
390
|
+
style_declarations.push "height: #{ (if _.isNumber(panel.height) then panel.height + 'px' else panel.height ) }" if panel.height?
|
391
|
+
style_declarations.push "width: #{ (if _.isNumber(panel.width) then panel.width + 'px' else panel.width ) }" if panel.width?
|
392
|
+
style_declarations.push "float: #{ panel.float }" if panel.float
|
393
|
+
|
394
|
+
config =
|
395
|
+
class: panel?.classes || @componentClass
|
396
|
+
id: "#{ @cid }-#{ panelIndex }"
|
397
|
+
style: style_declarations.join(';')
|
398
|
+
"data-luca-parent" : @name || @cid
|
399
|
+
|
400
|
+
if @customizeContainerEl?
|
401
|
+
config = @customizeContainerEl( config, panel, panelIndex )
|
402
|
+
|
403
|
+
config
|
404
|
+
|
405
|
+
|
406
|
+
|
407
|
+
createGetterMethods = ()->
|
408
|
+
container = @
|
409
|
+
|
410
|
+
childrenWithGetter = _( @allChildren() ).select (component)->
|
411
|
+
component.getter?
|
412
|
+
|
413
|
+
_( childrenWithGetter ).each (component)->
|
414
|
+
container[ component.getter ] ||= ()->
|
415
|
+
console.log component.getter, component, container
|
416
|
+
component
|
417
|
+
|
418
|
+
createMethodsToGetComponentsByRole = ()->
|
419
|
+
container = @
|
420
|
+
|
421
|
+
childrenWithRole = _( @allChildren() ).select (component)->
|
422
|
+
component.role?
|
423
|
+
|
424
|
+
_( childrenWithRole ).each (component)->
|
425
|
+
getter = _.str.camelize( "get_" + component.role )
|
426
|
+
container[ getter ] ||= ()->
|
427
|
+
component
|
428
|
+
|
429
|
+
doComponents = ()->
|
430
|
+
@trigger "before:components", @, @components
|
431
|
+
@prepareComponents()
|
432
|
+
@createComponents()
|
433
|
+
@trigger "before:render:components", @, @components
|
434
|
+
@renderComponents()
|
435
|
+
@trigger "after:components", @, @components
|
436
|
+
|
437
|
+
unless @skipGetterMethods is true
|
438
|
+
createGetterMethods.call(@)
|
439
|
+
createMethodsToGetComponentsByRole.call(@)
|
440
|
+
|
441
|
+
@registerComponentEvents()
|
442
|
+
|
443
|
+
validateContainerConfiguration = ()->
|
444
|
+
true
|
445
|
+
|
446
|
+
|
447
|
+
# Private Helpers
|
448
|
+
#
|
449
|
+
# indexComponent( component ).at( index ).in( componentsInternalIndexMap )
|
450
|
+
indexComponent = (component)->
|
451
|
+
at: (index)->
|
452
|
+
in: (map)->
|
453
|
+
if component.cid?
|
454
|
+
map.cid_index[ component.cid ] = index
|
455
|
+
if component.role?
|
456
|
+
map.role_index[ component.role ] = index
|
457
|
+
if component.name?
|
458
|
+
map.name_index[ component.name ] = index
|
data/src/core/field.coffee
CHANGED
@@ -27,15 +27,21 @@ _.def('Luca.core.Field').extends('Luca.View').with
|
|
27
27
|
@input_id ||= _.uniqueId('field')
|
28
28
|
@input_name ||= @name
|
29
29
|
@input_class ||= ""
|
30
|
+
@input_type ||= ""
|
30
31
|
@helperText ||= ""
|
31
32
|
@label ||= "*#{ @label }" if @required and not @label?.match(/^\*/)
|
32
33
|
@inputStyles ||= ""
|
34
|
+
@input_value ||= @value || ""
|
33
35
|
|
34
36
|
@disable() if @disabled
|
35
37
|
|
36
38
|
@updateState( @state )
|
37
39
|
@placeHolder ||= ""
|
38
40
|
|
41
|
+
# In order to support using Luca.View template properties everywhere.
|
42
|
+
|
43
|
+
# Will need to work around how the field classes
|
44
|
+
# apply templates to themselves.
|
39
45
|
Luca.View::initialize.apply(@, arguments)
|
40
46
|
|
41
47
|
beforeRender: ()->
|
@@ -44,20 +50,17 @@ _.def('Luca.core.Field').extends('Luca.View').with
|
|
44
50
|
|
45
51
|
@$el.addClass('required') if @required
|
46
52
|
|
47
|
-
@$el.html Luca.template(@template, @)
|
48
|
-
@input = $('input', @el)
|
49
|
-
|
50
53
|
change_handler: (e)->
|
51
54
|
@trigger "on:change", @, e
|
52
55
|
|
53
56
|
disable: ()->
|
54
|
-
|
57
|
+
@getInputElement().attr('disabled', true)
|
55
58
|
|
56
59
|
enable: ()->
|
57
|
-
|
60
|
+
@getInputElement().attr('disabled', false)
|
58
61
|
|
59
62
|
getValue: ()->
|
60
|
-
raw = @
|
63
|
+
raw = @getInputElement()?.attr('value')
|
61
64
|
|
62
65
|
return raw if _.str.isBlank( raw )
|
63
66
|
|
@@ -67,11 +70,11 @@ _.def('Luca.core.Field').extends('Luca.View').with
|
|
67
70
|
when "float" then parseFloat(raw)
|
68
71
|
else raw
|
69
72
|
|
70
|
-
render: ()->
|
71
|
-
$( @container ).append( @$el )
|
72
|
-
|
73
73
|
setValue: (value)->
|
74
|
-
@
|
74
|
+
@getInputElement()?.attr('value', value)
|
75
|
+
|
76
|
+
getInputElement: ()->
|
77
|
+
@input ||= @$('input').eq(0)
|
75
78
|
|
76
79
|
updateState: (state)->
|
77
80
|
_( @statuses ).each (cls)=>
|
data/src/core/model.coffee
CHANGED
@@ -1,16 +1,26 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
model = Luca.define 'Luca.Model'
|
2
|
+
|
3
|
+
model.extends 'Backbone.Model'
|
4
|
+
|
5
|
+
model.includes 'Luca.Events'
|
6
|
+
|
7
|
+
model.defines
|
8
|
+
initialize: ()->
|
9
|
+
Backbone.Model::initialize(@, arguments)
|
10
|
+
setupComputedProperties.call(@)
|
11
|
+
|
12
|
+
read: (attr)->
|
13
|
+
if _.isFunction(@[attr])
|
14
|
+
@[attr].call(@)
|
15
|
+
else
|
16
|
+
@get(attr)
|
17
|
+
|
18
|
+
get: (attr)->
|
19
|
+
if @computed?.hasOwnProperty(attr)
|
20
|
+
@_computed[attr]
|
21
|
+
else
|
22
|
+
Backbone.Model::get.call @, attr
|
23
|
+
|
14
24
|
setupComputedProperties = ()->
|
15
25
|
return if _.isUndefined(@computed)
|
16
26
|
|
@@ -27,17 +37,3 @@ setupComputedProperties = ()->
|
|
27
37
|
@trigger "change:#{attr}"
|
28
38
|
|
29
39
|
@trigger "change:#{attr}" if @has(dep)
|
30
|
-
|
31
|
-
_.def('Luca.Model').extends('Backbone.Model').with
|
32
|
-
|
33
|
-
include: ['Luca.Events']
|
34
|
-
|
35
|
-
initialize: ()->
|
36
|
-
Backbone.Model::initialize(@, arguments)
|
37
|
-
setupComputedProperties.call(@)
|
38
|
-
|
39
|
-
get: (attr)->
|
40
|
-
if @computed?.hasOwnProperty(attr)
|
41
|
-
@_computed[attr]
|
42
|
-
else
|
43
|
-
Backbone.Model::get.call @, attr
|
data/src/core/registry.coffee
CHANGED
@@ -4,29 +4,34 @@ registry =
|
|
4
4
|
collection_classes: {}
|
5
5
|
namespaces:['Luca.containers','Luca.components']
|
6
6
|
|
7
|
-
|
7
|
+
componentCacheStore =
|
8
8
|
cid_index: {}
|
9
9
|
name_index: {}
|
10
10
|
|
11
11
|
# For container views, if a component is defined with no ctype
|
12
12
|
# then we will pick this one when using
|
13
|
-
Luca.
|
13
|
+
Luca.config.defaultComponentClass = Luca.defaultComponentClass = 'Luca.View'
|
14
|
+
Luca.config.defaultComponentType = Luca.defaultComponentType = 'view'
|
14
15
|
|
15
16
|
Luca.registry.aliases =
|
16
|
-
grid:
|
17
|
-
form:
|
18
|
-
text:
|
19
|
-
button:
|
20
|
-
select:
|
21
|
-
card:
|
22
|
-
paged:
|
23
|
-
wizard:
|
24
|
-
collection:
|
17
|
+
grid: "grid_view"
|
18
|
+
form: "form_view"
|
19
|
+
text: "text_field"
|
20
|
+
button: "button_field"
|
21
|
+
select: "select_field"
|
22
|
+
card: "card_view"
|
23
|
+
paged: "card_view"
|
24
|
+
wizard: "card_view"
|
25
|
+
collection: "collection_view"
|
26
|
+
list: "collection_view"
|
27
|
+
multi: "collection_multi_view"
|
28
|
+
table: "table_view"
|
29
|
+
|
25
30
|
|
26
31
|
# When you use _.def to define a component, you say
|
27
32
|
# which class it extends() from, and with() which enhancements.
|
28
33
|
# We register that component class for you:
|
29
|
-
Luca.
|
34
|
+
Luca.registerComponent = (component, prototypeName, componentType="view")->
|
30
35
|
Luca.trigger "component:registered", component, prototypeName
|
31
36
|
|
32
37
|
switch componentType
|
@@ -48,7 +53,7 @@ Luca.development_mode_register = (component, prototypeName)->
|
|
48
53
|
_( liveInstances ).each (instance)->
|
49
54
|
instance?.refreshCode?.call(instance, prototypeDefinition)
|
50
55
|
|
51
|
-
Luca.
|
56
|
+
Luca.registerComponent( component, prototypeName )
|
52
57
|
|
53
58
|
# We create a @ctype alias for this component definition, and register
|
54
59
|
# the class in a registry.
|
@@ -56,7 +61,7 @@ Luca.development_mode_register = (component, prototypeName)->
|
|
56
61
|
# If you use a custom namespace like MyApp.views.ListView,
|
57
62
|
# then we will register MyApp.views as a namespace. You can
|
58
63
|
# do this yourself too.
|
59
|
-
Luca.registry.addNamespace = (identifier)->
|
64
|
+
Luca.registry.addNamespace = Luca.registry.namespace = (identifier)->
|
60
65
|
registry.namespaces.push( identifier )
|
61
66
|
registry.namespaces = _( registry.namespaces ).uniq()
|
62
67
|
|
@@ -93,11 +98,17 @@ Luca.registry.lookup = (ctype)->
|
|
93
98
|
.compact().value()?[0]
|
94
99
|
|
95
100
|
Luca.registry.instances = ()->
|
96
|
-
_(
|
97
|
-
|
101
|
+
_( componentCacheStore.cid_index ).values()
|
102
|
+
|
103
|
+
Luca.registry.findInstancesByClass = (componentClass)->
|
104
|
+
Luca.registry.findInstancesByClassName( componentClass.displayName )
|
105
|
+
|
98
106
|
Luca.registry.findInstancesByClassName = (className)->
|
107
|
+
className = className.displayName if not _.isString( className )
|
99
108
|
instances = Luca.registry.instances()
|
100
109
|
_( instances ).select (instance)->
|
110
|
+
isClass = instance.displayName is className
|
111
|
+
|
101
112
|
instance.displayName is className or instance._superClass?()?.displayName is className
|
102
113
|
|
103
114
|
Luca.registry.classes = (toString=false)->
|
@@ -108,22 +119,24 @@ Luca.registry.classes = (toString=false)->
|
|
108
119
|
className: className
|
109
120
|
ctype: ctype
|
110
121
|
|
111
|
-
Luca.cache = (
|
112
|
-
|
122
|
+
Luca.cache = Luca.cacheInstance = (cacheKey, object)->
|
123
|
+
return unless cacheKey?
|
124
|
+
return object if object?.doNotCache is true
|
113
125
|
|
114
|
-
|
126
|
+
if object?
|
127
|
+
componentCacheStore.cid_index[ cacheKey ] = object
|
115
128
|
|
116
|
-
|
117
|
-
if component?.component_name?
|
118
|
-
component_cache.name_index[ component.component_name ] = component.cid
|
119
|
-
else if component?.name?
|
120
|
-
component_cache.name_index[ component.name ] = component.cid
|
121
|
-
|
122
|
-
return component if component?
|
129
|
+
object = componentCacheStore.cid_index[ cacheKey ]
|
123
130
|
|
124
|
-
#
|
125
|
-
|
131
|
+
# optionally, cache it by tying its name to its cid for easier lookups
|
132
|
+
if object?.component_name?
|
133
|
+
componentCacheStore.name_index[ object.component_name ] = object.cid
|
134
|
+
else if object?.name?
|
135
|
+
componentCacheStore.name_index[ object.name ] = object.cid
|
126
136
|
|
127
|
-
|
137
|
+
return object if object?
|
128
138
|
|
139
|
+
# perform a lookup by name if the cid lookup didn't turn anything
|
140
|
+
lookup_id = componentCacheStore.name_index[ cacheKey ]
|
129
141
|
|
142
|
+
componentCacheStore.cid_index[ lookup_id ]
|