luca 0.9.42 → 0.9.65

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. data/CHANGELOG +50 -9
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +2 -0
  4. data/README.md +5 -0
  5. data/assets/javascripts/dependencies/underscore-min.js +5 -31
  6. data/lib/generators/luca/application/application_generator.rb +71 -0
  7. data/lib/generators/luca/application/templates/controller.rb +6 -0
  8. data/lib/generators/luca/application/templates/index.html.erb +7 -0
  9. data/lib/generators/luca/application/templates/index.html.haml +6 -0
  10. data/lib/generators/luca/application/templates/javascripts/application.js +28 -0
  11. data/lib/generators/luca/application/templates/javascripts/application.js.coffee +20 -0
  12. data/lib/generators/luca/application/templates/javascripts/config.js +15 -0
  13. data/lib/generators/luca/application/templates/javascripts/config.js.coffee +9 -0
  14. data/lib/generators/luca/application/templates/javascripts/dependencies.js +5 -0
  15. data/lib/generators/luca/application/templates/javascripts/dependencies.js.coffee +5 -0
  16. data/lib/generators/luca/application/templates/javascripts/index.js +9 -0
  17. data/lib/generators/luca/application/templates/javascripts/index.js.coffee +9 -0
  18. data/lib/generators/luca/application/templates/javascripts/main.js +8 -0
  19. data/lib/generators/luca/application/templates/javascripts/main.js.coffee +3 -0
  20. data/lib/generators/luca/application/templates/javascripts/main.jst.ejs +1 -0
  21. data/lib/generators/luca/application/templates/javascripts/router.js +12 -0
  22. data/lib/generators/luca/application/templates/javascripts/router.js.coffee +7 -0
  23. data/lib/luca/rails/version.rb +1 -1
  24. data/spec/components/collection_view_spec.coffee +59 -0
  25. data/spec/components/multi_collection_view_spec.coffee +5 -0
  26. data/{src/templates/components/form_alert → spec/components/pagination_control_spec.coffee} +0 -0
  27. data/spec/components/table_view_spec.coffee +17 -0
  28. data/spec/core/container_spec.coffee +127 -5
  29. data/spec/core/model_spec.coffee +21 -3
  30. data/spec/define_spec.coffee +19 -0
  31. data/spec/mixin_spec.coffee +49 -0
  32. data/spec/modules/filterable_spec.coffee +25 -0
  33. data/spec/modules/paginatable_spec.coffee +0 -0
  34. data/spec/modules/state_model_spec.coffee +0 -0
  35. data/src/components/application.coffee +52 -38
  36. data/src/components/collection_view.coffee +118 -45
  37. data/src/components/fields/checkbox_field.coffee +2 -2
  38. data/src/components/fields/file_upload_field.coffee +0 -3
  39. data/src/components/fields/hidden_field.coffee +0 -3
  40. data/src/components/fields/label_field.coffee +1 -4
  41. data/src/components/fields/select_field.coffee +6 -6
  42. data/src/components/fields/text_area_field.coffee +1 -0
  43. data/src/components/fields/text_field.coffee +4 -0
  44. data/src/components/fields/type_ahead_field.coffee +5 -9
  45. data/src/components/form_view.coffee +28 -23
  46. data/src/components/multi_collection_view.coffee +121 -0
  47. data/src/components/pagination_control.coffee +106 -0
  48. data/src/components/table_view.coffee +22 -13
  49. data/src/containers/card_view.coffee +44 -11
  50. data/src/containers/panel_toolbar.coffee +88 -82
  51. data/src/containers/tab_view.coffee +3 -3
  52. data/src/core/collection.coffee +11 -4
  53. data/src/core/container.coffee +206 -122
  54. data/src/core/field.coffee +13 -10
  55. data/src/core/model.coffee +23 -27
  56. data/src/core/registry.coffee +42 -29
  57. data/src/core/view.coffee +63 -149
  58. data/src/define.coffee +91 -19
  59. data/src/framework.coffee +11 -9
  60. data/src/managers/collection_manager.coffee +24 -8
  61. data/src/modules/application_event_bindings.coffee +19 -0
  62. data/src/modules/collection_event_bindings.coffee +26 -0
  63. data/src/modules/deferrable.coffee +3 -1
  64. data/src/modules/dom_helpers.coffee +49 -0
  65. data/src/modules/enhanced_properties.coffee +23 -0
  66. data/src/modules/filterable.coffee +82 -0
  67. data/src/modules/grid_layout.coffee +13 -1
  68. data/src/modules/{load_mask.coffee → loadmaskable.coffee} +10 -4
  69. data/src/modules/modal_view.coffee +38 -0
  70. data/src/modules/paginatable.coffee +87 -0
  71. data/src/modules/state_model.coffee +16 -0
  72. data/src/modules/templating.coffee +8 -0
  73. data/src/plugins/events.coffee +30 -2
  74. data/src/templates/components/bootstrap_form_controls.jst.ejs +10 -0
  75. data/src/templates/components/collection_loader_view.jst.ejs +6 -0
  76. data/src/templates/components/form_alert.jst.ejs +4 -0
  77. data/src/templates/components/grid_view.jst.ejs +11 -0
  78. data/src/templates/components/grid_view_empty_text.jst.ejs +3 -0
  79. data/src/templates/components/load_mask.jst.ejs +5 -0
  80. data/src/templates/components/nav_bar.jst.ejs +4 -0
  81. data/src/templates/components/pagination.jst.ejs +10 -0
  82. data/src/templates/containers/basic.jst.ejs +1 -0
  83. data/src/templates/containers/tab_selector_container.jst.ejs +12 -0
  84. data/src/templates/containers/tab_view.jst.ejs +2 -0
  85. data/src/templates/containers/toolbar_wrapper.jst.ejs +1 -0
  86. data/src/templates/fields/button_field.jst.ejs +2 -0
  87. data/src/templates/fields/button_field_link.jst.ejs +6 -0
  88. data/src/templates/fields/checkbox_array.jst.ejs +4 -0
  89. data/src/templates/fields/checkbox_array_item.jst.ejs +3 -0
  90. data/src/templates/fields/checkbox_field.jst.ejs +10 -0
  91. data/src/templates/fields/file_upload_field.jst.ejs +10 -0
  92. data/src/templates/fields/hidden_field.jst.ejs +1 -0
  93. data/src/templates/fields/select_field.jst.ejs +11 -0
  94. data/src/templates/fields/text_area_field.jst.ejs +11 -0
  95. data/src/templates/fields/text_field.jst.ejs +16 -0
  96. data/src/templates/table_view.jst.ejs +4 -0
  97. data/src/tools/console.coffee +51 -21
  98. data/src/util.coffee +17 -4
  99. data/vendor/assets/javascripts/luca-ui-base.js +5304 -0
  100. data/vendor/assets/javascripts/luca-ui-bootstrap.js +9 -0
  101. data/vendor/assets/javascripts/luca-ui-development-tools.js +52 -24
  102. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
  103. data/vendor/assets/javascripts/luca-ui-full.js +1700 -595
  104. data/vendor/assets/javascripts/luca-ui-full.min.js +7 -6
  105. data/vendor/assets/javascripts/luca-ui-spec.js +6815 -0
  106. data/vendor/assets/javascripts/luca-ui-templates.js +92 -24
  107. data/vendor/assets/javascripts/luca-ui.js +1695 -564
  108. data/vendor/assets/javascripts/luca-ui.min.js +4 -4
  109. metadata +69 -28
  110. data/src/templates/components/bootstrap_form_controls.luca +0 -7
  111. data/src/templates/components/collection_loader_view.luca +0 -5
  112. data/src/templates/components/form_alert.luca +0 -3
  113. data/src/templates/components/grid_view.luca +0 -7
  114. data/src/templates/components/grid_view_empty_text.luca +0 -3
  115. data/src/templates/components/load_mask.luca +0 -3
  116. data/src/templates/components/nav_bar.luca +0 -2
  117. data/src/templates/containers/basic.luca +0 -1
  118. data/src/templates/containers/tab_selector_container.luca +0 -8
  119. data/src/templates/containers/tab_view.luca +0 -2
  120. data/src/templates/containers/toolbar_wrapper.luca +0 -1
  121. data/src/templates/fields/button_field.luca +0 -2
  122. data/src/templates/fields/button_field_link.luca +0 -5
  123. data/src/templates/fields/checkbox_array.luca +0 -4
  124. data/src/templates/fields/checkbox_array_item.luca +0 -4
  125. data/src/templates/fields/checkbox_field.luca +0 -9
  126. data/src/templates/fields/file_upload_field.luca +0 -8
  127. data/src/templates/fields/hidden_field.luca +0 -1
  128. data/src/templates/fields/select_field.luca +0 -8
  129. data/src/templates/fields/text_area_field.luca +0 -8
  130. data/src/templates/fields/text_field.luca +0 -17
  131. data/src/templates/sample/contents.luca +0 -1
  132. data/src/templates/sample/welcome.luca +0 -1
  133. data/src/templates/table_view.luca +0 -4
@@ -1,90 +1,53 @@
1
- # The Component Container
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
- # Two: Component Creation
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
- @trigger "before:components", @, @components
44
- @prepareComponents()
45
- @createComponents()
46
- @trigger "before:render:components", @, @components
47
- @renderComponents()
48
- @trigger "after:components", @, @components
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
- "before:components"
82
- "before:render:components"
83
- "before:layout"
84
- "after:components"
85
- "after:layout"
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.isBackboneView( object )
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
- Luca.util.lazyComponent( object )
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
- # if you define a @getter property as a string on your component
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.container
183
+ if !component.container and component.options?.container
217
184
  component.container = component.options.container
218
185
 
219
- if map and component.cid?
220
- map.cid_index[ component.cid ] = index
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
- if map and component.name?
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
- $( component.container ).append( component.el )
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
- pluck: (attribute)->
275
- _( @components ).pluck attribute
239
+ _: ()-> _( @components )
240
+
241
+ pluck: (attribute)->
242
+ @_().pluck(attribute)
276
243
 
277
244
  invoke: (method)->
278
- _( @components ).invoke method
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
- _( @components ).map(fn)
282
-
283
- # event binding sugar for nested components
284
- #
285
- # you can define events like:
257
+ @_().map(fn)
286
258
 
287
- # _.def("MyContainer").extends("Luca.View").with
288
- # componentEvents:
289
- # "component_name before:load" : "mySpecialHandler"
290
- componentEvents: {}
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
- registerComponentEvents: ()->
293
- for listener, handler of @componentEvents
294
- [componentName,trigger] = listener.split(' ')
295
- component = @findComponentByName(componentName)
296
- component?.bind trigger, @[handler]
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
- @findComponent(name, "name_index", deep)
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?[ position ]
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)-> component?.findComponent?(needle, haystack, true)
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
- @$(">.#{ @componentClass }", @$bodyEl())
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 @rootComponent() then @ else @getParent().getRootComponent()
350
-
351
- selectByAttribute: (attribute, value, deep=false)->
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
@@ -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
- $("input",@el).attr('disabled', true)
57
+ @getInputElement().attr('disabled', true)
55
58
 
56
59
  enable: ()->
57
- $("input", @el).attr('disabled', false)
60
+ @getInputElement().attr('disabled', false)
58
61
 
59
62
  getValue: ()->
60
- raw = @input.attr('value')
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
- @input.attr('value', value)
74
+ @getInputElement()?.attr('value', value)
75
+
76
+ getInputElement: ()->
77
+ @input ||= @$('input').eq(0)
75
78
 
76
79
  updateState: (state)->
77
80
  _( @statuses ).each (cls)=>
@@ -1,16 +1,26 @@
1
- # Computed Properties Support
2
- # ###
3
- #
4
- # Luca.Model supports computed properties, which are
5
- # object methods which are composed of model attributes or
6
- # of calculations which are dependent on these attributes.
7
-
8
- # When these model attributes change, the computed property
9
- # needs to be re-evaluated.
10
- #
11
- # The configuration API for computed properties expects a hash
12
- # whose keys are the name of the method, and whose value is
13
- # an array of the attribute dependencies for that method.
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
@@ -4,29 +4,34 @@ registry =
4
4
  collection_classes: {}
5
5
  namespaces:['Luca.containers','Luca.components']
6
6
 
7
- component_cache =
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.defaultComponentType = 'view'
13
+ Luca.config.defaultComponentClass = Luca.defaultComponentClass = 'Luca.View'
14
+ Luca.config.defaultComponentType = Luca.defaultComponentType = 'view'
14
15
 
15
16
  Luca.registry.aliases =
16
- grid: "grid_view"
17
- form: "form_view"
18
- text: "text_field"
19
- button: "button_field"
20
- select: "select_field"
21
- card: "card_view"
22
- paged: "card_view"
23
- wizard: "card_view"
24
- collection: "collection_view"
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.register = (component, prototypeName, componentType="view")->
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.register( component, prototypeName )
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
- _( component_cache.cid_index ).values()
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 = (needle, component)->
112
- component_cache.cid_index[ needle ] = component if component?
122
+ Luca.cache = Luca.cacheInstance = (cacheKey, object)->
123
+ return unless cacheKey?
124
+ return object if object?.doNotCache is true
113
125
 
114
- component = component_cache.cid_index[ needle ]
126
+ if object?
127
+ componentCacheStore.cid_index[ cacheKey ] = object
115
128
 
116
- # optionally, cache it by tying its name to its cid for easier lookups
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
- # perform a lookup by name if the component_id didn't turn anything
125
- lookup_id = component_cache.name_index[ needle ]
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
- component_cache.cid_index[ lookup_id ]
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 ]