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.
Files changed (129) hide show
  1. data/.gitignore +1 -0
  2. data/.rvmrc +1 -1
  3. data/CHANGELOG +46 -2
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +2 -2
  6. data/Guardfile +1 -1
  7. data/README.md +64 -27
  8. data/ROADMAP +17 -2
  9. data/Rakefile +49 -1
  10. data/app.rb +38 -2
  11. data/assets/javascripts/luca-ui-base.coffee +1 -20
  12. data/assets/javascripts/luca-ui-full.js +3 -0
  13. data/assets/javascripts/luca-ui.coffee +0 -5
  14. data/assets/javascripts/sandbox/application.coffee +24 -18
  15. data/assets/javascripts/sandbox/router.coffee +16 -6
  16. data/assets/javascripts/sandbox/templates/builder/component_list.luca +1 -0
  17. data/assets/javascripts/sandbox/templates/builder.luca +2 -0
  18. data/assets/javascripts/sandbox/templates/main.luca +4 -3
  19. data/assets/javascripts/sandbox/templates/sandbox/docs_index.luca +1 -0
  20. data/assets/javascripts/sandbox/templates/sandbox/navigation.luca +6 -1
  21. data/assets/javascripts/sandbox/templates/sandbox/readme.luca +30 -0
  22. data/assets/javascripts/sandbox/views/builder/builder_canvas.coffee +3 -0
  23. data/assets/javascripts/sandbox/views/builder/builder_editor.coffee +6 -0
  24. data/assets/javascripts/sandbox/views/builder/component_list.coffee +38 -0
  25. data/assets/javascripts/sandbox/views/builder/project_browser.coffee +14 -0
  26. data/assets/javascripts/sandbox/views/builder.coffee +133 -0
  27. data/assets/javascripts/sandbox/views/docs_controller.coffee +7 -0
  28. data/assets/javascripts/sandbox/views/inspector/instance_filter.coffee +18 -0
  29. data/assets/javascripts/sandbox/{collections/sample.coffee → views/inspector/instance_list.coffee} +0 -0
  30. data/assets/javascripts/sandbox/views/inspector.coffee +11 -0
  31. data/assets/javascripts/sandbox.coffee +2 -0
  32. data/assets/stylesheets/luca-ui-full.css +3 -0
  33. data/assets/stylesheets/sandbox/builder.scss +79 -0
  34. data/assets/stylesheets/sandbox/sandbox.scss +2 -1
  35. data/docs/application.md +41 -0
  36. data/docs/collection.md +79 -0
  37. data/docs/collection_manager.md +76 -0
  38. data/docs/container_philosophy.md +122 -0
  39. data/docs/event_binding_helpers.md +164 -0
  40. data/docs/method_caching_and_computed_properties.md +77 -0
  41. data/docs/view.md +119 -0
  42. data/lib/luca/rails/version.rb +1 -1
  43. data/lib/luca/template.rb +9 -9
  44. data/site/assets/bootstrap.min.js +7 -0
  45. data/site/assets/luca-ui-bootstrap.css +19 -1
  46. data/site/assets/luca-ui-development-tools.css +10 -0
  47. data/site/assets/luca-ui-development-tools.min.js +15 -0
  48. data/site/assets/luca-ui-full.min.js +8 -0
  49. data/site/assets/luca-ui.min.js +4 -0
  50. data/site/assets/sandbox.css +52 -4
  51. data/site/assets/sandbox.js +368 -30
  52. data/site/docs/application.html +41 -0
  53. data/site/docs/caching.html +43 -0
  54. data/site/docs/collection.html +75 -0
  55. data/site/docs/collection_manager.html +71 -0
  56. data/site/docs/containers.html +118 -0
  57. data/site/docs/events.html +153 -0
  58. data/site/docs/view.html +128 -0
  59. data/site/img/glyphicons-halflings-white.png +0 -0
  60. data/site/img/glyphicons-halflings.png +0 -0
  61. data/site/source-map.js +1 -0
  62. data/spec/core/view_spec.coffee +5 -17
  63. data/spec/managers/collection_manager_spec.coffee +4 -7
  64. data/src/components/application.coffee +202 -77
  65. data/src/components/base_toolbar.coffee +1 -1
  66. data/src/components/collection_view.coffee +38 -10
  67. data/src/components/controller.coffee +24 -1
  68. data/src/components/fields/checkbox_field.coffee +9 -12
  69. data/src/components/fields/label_field.coffee +14 -0
  70. data/src/components/fields/select_field.coffee +2 -2
  71. data/src/components/fields/text_field.coffee +12 -7
  72. data/src/components/fields/type_ahead_field.coffee +1 -0
  73. data/src/components/form_view.coffee +44 -25
  74. data/src/components/page_controller.coffee +2 -0
  75. data/src/containers/card_view.coffee +4 -1
  76. data/src/containers/column_view.coffee +2 -1
  77. data/src/containers/modal_view.coffee +6 -2
  78. data/src/containers/page_view.coffee +2 -0
  79. data/src/containers/panel_toolbar.coffee +0 -5
  80. data/src/containers/viewport.coffee +28 -10
  81. data/src/core/collection.coffee +7 -1
  82. data/src/core/container.coffee +57 -30
  83. data/src/core/core.coffee +0 -186
  84. data/src/core/field.coffee +11 -3
  85. data/src/core/model.coffee +31 -16
  86. data/src/core/panel.coffee +6 -46
  87. data/src/core/registry.coffee +19 -2
  88. data/src/core/script_loader.coffee +32 -0
  89. data/src/core/view.coffee +112 -139
  90. data/src/define.coffee +110 -0
  91. data/src/framework.coffee +8 -2
  92. data/src/luca.coffee +22 -0
  93. data/src/managers/collection_manager.coffee +65 -31
  94. data/src/modules/load_mask.coffee +47 -0
  95. data/src/plugins/development_tool_helpers.coffee +21 -0
  96. data/src/plugins/events.coffee +54 -0
  97. data/src/stylesheets/components/viewport.scss +15 -0
  98. data/src/stylesheets/containers/container.scss +1 -4
  99. data/src/stylesheets/tools/component_tester.scss +18 -0
  100. data/src/templates/fields/select_field.luca +6 -5
  101. data/src/templates/fields/text_field.luca +10 -9
  102. data/src/tools/application_inspector.coffee +2 -0
  103. data/src/tools/coffee_script_editor.coffee +28 -6
  104. data/src/tools/collections/components.coffee +59 -0
  105. data/src/tools/collections/instances.coffee +15 -0
  106. data/src/tools/component_tester.coffee +12 -22
  107. data/src/tools/console.coffee +22 -4
  108. data/src/tools/models/components.coffee +16 -54
  109. data/src/tools/models/instance.coffee +2 -0
  110. data/src/{core/util.coffee → util.coffee} +10 -1
  111. data/vendor/assets/javascripts/luca-ui-base.js +132 -137
  112. data/vendor/assets/javascripts/luca-ui-development-tools.js +191 -219
  113. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +2 -2
  114. data/vendor/assets/javascripts/luca-ui-full.js +4680 -0
  115. data/vendor/assets/javascripts/luca-ui-full.min.js +8 -0
  116. data/vendor/assets/javascripts/luca-ui-spec.js +291 -225
  117. data/vendor/assets/javascripts/luca-ui.js +1001 -724
  118. data/vendor/assets/javascripts/luca-ui.min.js +4 -4
  119. data/vendor/assets/stylesheets/luca-ui-bootstrap.css +19 -1
  120. data/vendor/assets/stylesheets/luca-ui-development-tools.css +10 -0
  121. data/vendor/assets/stylesheets/luca-ui-full.css +1334 -0
  122. data/vendor/assets/stylesheets/luca-ui-spec.css +19 -1
  123. data/vendor/assets/stylesheets/luca-ui.css +19 -1
  124. data/views/index.erb +2 -5
  125. metadata +58 -9
  126. data/lib/sprockets/luca_template.rb +0 -49
  127. data/src/tools/class_browser.coffee +0 -39
  128. data/src/tools/components/class_browser_detail.coffee +0 -10
  129. data/src/tools/components/class_browser_list.coffee +0 -74
@@ -47,6 +47,8 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
47
47
 
48
48
  bodyClassName: "form-view-body"
49
49
 
50
+ version: "0.9.33333333"
51
+
50
52
  initialize: (@options={})->
51
53
  @loadMask = Luca.enableBootstrap unless @loadMask?
52
54
 
@@ -105,19 +107,19 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
105
107
  _( @getFields() ).map( iterator )
106
108
 
107
109
  getField: (name)->
108
- _( @getFields('name', name) ).first()
110
+ passOne = _( @getFields('name', name) ).first()
111
+ return passOne if passOne?
112
+
113
+ _( @getFields('input_name', name) ).first()
109
114
 
110
115
  getFields: (attr,value)->
111
- # do a deep search of all of the nested components
112
- # to find the fields
113
- fields = @select("isField", true, true)
116
+ fields = @selectByAttribute("isField", true, true)
114
117
 
115
- return fields unless attr and value
116
- # if an optional attribute and value pair is passed
117
- # then you can limit the array of fields even further
118
- _(fields).select (field)->
119
- property = field[ attr ]
120
- property? and value is (if _.isFunction(property) then property() else property)
118
+ if attr? and value?
119
+ fields = _(fields).select (field)->
120
+ property = field[ attr ]
121
+ property = property.call(field) if _.isFunction(property)
122
+ property is value
121
123
 
122
124
  fields
123
125
 
@@ -172,30 +174,48 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
172
174
 
173
175
  @syncFormWithModel() unless options.silent? is true
174
176
 
177
+ # Public: returns a hash of values for the form fields in this view.
178
+ #
179
+ # options - An options Hash to control the behavior of values returned (default: {}):
180
+ # reject_blank: don't include values which are blank (default: true)
181
+ # skip_buttons: don't include button fields (default: true)
182
+ # blanks: an inverse alias for reject_blank (default: false)
175
183
  getValues: (options={})->
176
184
  options.reject_blank = true unless options.reject_blank?
177
185
  options.skip_buttons = true unless options.skip_buttons?
186
+ options.reject_blank = true if options.blanks is false
187
+
188
+ values = _( @getFields() ).inject (memo,field)=>
189
+ value = field.getValue()
190
+ key = field.input_name || field.name
191
+
192
+ valueIsBlank = !!(_.str.isBlank( value ) || _.isUndefined( value ))
178
193
 
179
- _( @getFields() ).inject (memo,field)->
180
- value = field.getValue()
181
- key = field.input_name || field.name
194
+ allowBlankValues = not options.reject_blank and not field.send_blanks
182
195
 
183
- skip = false
196
+ if options.debug
197
+ console.log "#{ key } Options", options, "Value", value, "Value Is Blank?", valueIsBlank, "Allow Blanks?", allowBlankValues
184
198
 
185
- # don't include the values of buttons in our values hash
186
- skip = true if options.skip_buttons and field.ctype is "button_field"
199
+ if options.skip_buttons and field.ctype is "button_field"
200
+ skip = true
201
+ else
202
+ if valueIsBlank and allowBlankValues is false
203
+ skip = true
187
204
 
188
- # if the value is blank and we are passed reject_blank in the options
189
- # then we should not include this field in our hash. however, if the
190
- # field is setup to send blanks, then we will send this value anyway
191
- if _.string.isBlank( value )
192
- skip = true if options.reject_blank and !field.send_blanks
193
- skip = true if field.input_name is "id"
205
+ if field.input_name is "id" and valueIsBlank is true
206
+ skip = true
194
207
 
195
- memo[ key ] = value unless skip is true
208
+ if options.debug
209
+ console.log "Skip is true on #{ key }"
210
+
211
+ if skip isnt true
212
+ memo[ key ] = value
196
213
 
197
214
  memo
198
- , {}
215
+
216
+ , (options.defaults || {})
217
+
218
+ values
199
219
 
200
220
  submit_success_handler: (model, response, xhr)->
201
221
  @trigger "after:submit", @, model, response
@@ -253,4 +273,3 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
253
273
  errorMessage: (message)->
254
274
  @$('.alert.alert-error').remove()
255
275
  @flash Luca.template("components/form_alert", className:"alert alert-error", message: message)
256
-
@@ -0,0 +1,2 @@
1
+ _.def("Luca.PageController").extends("Luca.components.Controller").with
2
+ version: 2
@@ -13,7 +13,7 @@ _.def("Luca.containers.CardView").extends("Luca.core.Container").with
13
13
  ]
14
14
 
15
15
  componentClass: 'luca-ui-card'
16
- appendContainers: true
16
+ generateComponentElements: true
17
17
 
18
18
  initialize: (@options)->
19
19
  Luca.core.Container::initialize.apply @,arguments
@@ -71,6 +71,9 @@ _.def("Luca.containers.CardView").extends("Luca.core.Container").with
71
71
  previous?.trigger?.apply(previous,["before:deactivation", @, previous, current])
72
72
  current?.trigger?.apply(previous,["before:activation", @, previous, current])
73
73
 
74
+ _.defer ()=>
75
+ @$el.data( @activeAttribute || "active-card", current.name)
76
+
74
77
  @componentElements().hide()
75
78
 
76
79
  unless current.previously_activated
@@ -6,6 +6,7 @@ _.def('Luca.containers.ColumnView').extends('Luca.core.Container').with
6
6
  components: []
7
7
 
8
8
  initialize: (@options={})->
9
+ console.log "Column Views are deprecated in favor of just using grid css on a normal container"
9
10
  Luca.core.Container::initialize.apply @, arguments
10
11
  @setColumnWidths()
11
12
 
@@ -13,7 +14,7 @@ _.def('Luca.containers.ColumnView').extends('Luca.core.Container').with
13
14
 
14
15
  containerTemplate: "containers/basic"
15
16
 
16
- appendContainers: true
17
+ generateComponentElements: true
17
18
 
18
19
  autoColumnWidths: ()->
19
20
  widths = []
@@ -1,4 +1,4 @@
1
- _.def("Luca.ModalView").extends("Luca.View").with
1
+ _.def("Luca.ModalView").extends("Luca.core.Container").with
2
2
 
3
3
  closeOnEscape: true
4
4
 
@@ -6,6 +6,8 @@ _.def("Luca.ModalView").extends("Luca.View").with
6
6
 
7
7
  backdrop: false
8
8
 
9
+ className: "luca-ui-container modal"
10
+
9
11
  container: ()->
10
12
  $('body')
11
13
 
@@ -23,10 +25,12 @@ _.def("Luca.ModalView").extends("Luca.View").with
23
25
  @$el.addClass 'fade' if @fade is true
24
26
 
25
27
  $('body').append( @$el )
26
-
28
+
27
29
  @$el.modal
28
30
  backdrop: @backdrop is true
29
31
  keyboard: @closeOnEscape is true
30
32
  show: @showOnInitialize is true
31
33
 
34
+ @
35
+
32
36
  _.def("Luca.containers.ModalView").extends("Luca.ModalView").with()
@@ -0,0 +1,2 @@
1
+ _.def("Luca.PageView").extends("Luca.containers.CardView").with
2
+ version: 2
@@ -149,8 +149,3 @@ _.def("Luca.containers.PanelToolbar").extends("Luca.View").with
149
149
  elements = prepareButtons(@buttons)
150
150
  _( elements ).each (element)=>
151
151
  @$el.append( element )
152
-
153
- afterRender: ()->
154
- @_super("afterRender", @, arguments)
155
- # @$('.toolbar-component label').remove()
156
- # @$('.toolbar-component').addClass('btn-group')
@@ -2,24 +2,36 @@ _.def('Luca.containers.Viewport').extend('Luca.containers.CardView').with
2
2
 
3
3
  activeItem: 0
4
4
 
5
- className: 'luca-ui-viewport'
5
+ additionalClassNames: 'luca-ui-viewport'
6
6
 
7
7
  fullscreen: true
8
8
 
9
9
  fluid: false
10
10
 
11
- wrapperClass: 'row'
12
11
 
13
12
  initialize: (@options={})->
14
13
  _.extend @, @options
15
14
 
16
15
  if Luca.enableBootstrap is true
17
- @wrapperClass = "row-fluid" if @fluid is true
18
- @$wrap( @wrapperClass )
16
+ @wrapperClass = if @fluid is true then Luca.containers.Viewport.fluidWrapperClass else Luca.containers.Viewport.defaultWrapperClass
19
17
 
20
18
  Luca.core.Container::initialize.apply(@, arguments)
21
19
 
22
- $('html,body').addClass('luca-ui-fullscreen') if @fullscreen
20
+ @enableFullscreen() if @fullscreen is true
21
+
22
+ enableFluid: ()->
23
+ @$el.parent().addClass( @wrapperClass )
24
+
25
+ disableFluid: ()->
26
+ @$el.parent().removeClass( @wrapperClass )
27
+
28
+ enableFullscreen: ()->
29
+ $('html,body').addClass('luca-ui-fullscreen')
30
+ @$el.addClass('fullscreen-enabled')
31
+
32
+ disableFullscreen: ()->
33
+ $('html,body').removeClass('luca-ui-fullscreen')
34
+ @$el.removeClass('fullscreen-enabled')
23
35
 
24
36
  beforeRender: ()->
25
37
  Luca.containers.CardView::beforeRender?.apply(@, arguments)
@@ -30,12 +42,18 @@ _.def('Luca.containers.Viewport').extend('Luca.containers.CardView').with
30
42
  @renderTopNavigation() if @topNav?
31
43
  @renderBottomNavigation() if @bottomNav?
32
44
 
45
+ height: ()->
46
+ @$el.height()
47
+
48
+ width: ()->
49
+ @$el.width()
50
+
33
51
  afterRender: ()->
34
52
  Luca.containers.CardView::after?.apply(@, arguments)
35
53
 
36
- if Luca.enableBootstrap is true
37
- @$el.children().wrap('<div class="container" />')
38
-
54
+ if Luca.enableBootstrap is true and @containerClassName
55
+ @$el.children().wrap('<div class="#{ containerClassName }" />')
56
+
39
57
  renderTopNavigation: ()->
40
58
  return unless @topNav?
41
59
 
@@ -51,9 +69,9 @@ _.def('Luca.containers.Viewport').extend('Luca.containers.CardView').with
51
69
 
52
70
  $('body').prepend( @topNav.render().el )
53
71
 
54
-
55
72
  renderBottomNavigation: ()->
56
73
  # IMPLEMENT
57
74
 
58
75
 
59
-
76
+ Luca.containers.Viewport.defaultWrapperClass = 'row'
77
+ Luca.containers.Viewport.fluidWrapperClass = 'row-fluid'
@@ -2,6 +2,7 @@ source = 'Backbone.Collection'
2
2
  source = 'Backbone.QueryCollection' if Backbone.QueryCollection?
3
3
 
4
4
  _.def("Luca.Collection").extends( source ).with
5
+ include: ['Luca.Events']
5
6
  # cachedMethods refers to a list of methods on the collection
6
7
  # whose value gets cached once it is ran. the collection then
7
8
  # binds to change, add, remove, and reset events and then expires
@@ -13,7 +14,7 @@ _.def("Luca.Collection").extends( source ).with
13
14
  cachedMethods: []
14
15
 
15
16
  # if filtering a collection should handle via a call to a REST API
16
- # and return the filtered results that way, then leave this true
17
+ # and return the filtered results that way, then set this to true
17
18
  remoteFilter: false
18
19
 
19
20
  initialize: (models=[], @options)->
@@ -90,6 +91,11 @@ _.def("Luca.Collection").extends( source ).with
90
91
  # and will automatically do this for you without you having
91
92
  # to write a special url handler. If you want to use a normal
92
93
  # url without this feature, just set @useNormalUrl = true
94
+
95
+ # TODO
96
+ #
97
+ # This has got to go. It is messing up URL for show actions
98
+ # for models part of luca collections when there are base query params
93
99
  __wrapUrl: ()->
94
100
  if _.isFunction(@url)
95
101
  @url = _.wrap @url, (fn)=>
@@ -151,10 +151,6 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
151
151
  @componentContainers = _( @components ).map (component, index)->
152
152
  applyDOMConfig.call(container, component, index)
153
153
 
154
- # prepare components is where each component gets assigned
155
- # a container to be rendered into. if @appendContainers is
156
- # set to true, then the view will automatically $append()
157
- # elements created via Backbone.View::make() to the body element of the view
158
154
  prepareComponents: ()->
159
155
  # accept components as an array of strings representing
160
156
  # the luca component type
@@ -162,17 +158,17 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
162
158
  component = (type: component)
163
159
 
164
160
  _( @components ).each (component, index)=>
165
- container = @componentContainers?[index]
161
+ ce = componentContainerElement = @componentContainers?[index]
166
162
 
167
163
  # support a variety of the bad naming conventions
168
- container.class = container.class || container.className || container.classes
164
+ ce.class = ce.class || ce.className || ce.classes
169
165
 
170
- if @appendContainers
171
- panel = @make(@componentTag, container, '')
166
+ if @generateComponentElements
167
+ panel = @make(@componentTag, componentContainerElement, '')
172
168
  @$append( panel )
173
169
 
174
170
  unless component.container?
175
- component.container = "##{ container.id }" if @appendContainers
171
+ component.container = "##{ componentContainerElement.id }" if @generateComponentElements
176
172
  component.container ||= @$bodyEl()
177
173
 
178
174
  # create components is responsible for turning the JSON syntax of the
@@ -208,6 +204,12 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
208
204
 
209
205
  Luca.util.lazyComponent( object )
210
206
 
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)
212
+
211
213
  # if we're using base backbone views, then they don't extend themselves
212
214
  # with their passed options, so this is a workaround to get them to
213
215
  # pick up the container config property
@@ -232,12 +234,15 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
232
234
  # components
233
235
  renderComponents: (@debugMode="")->
234
236
  @debug "container render components"
235
- _(@components).each (component)=>
236
- component.getParent = ()=> @
237
- $( component.container ).append $(component.el)
237
+
238
+ container = @
239
+ _(@components).each (component)->
240
+ component.getParent = ()->
241
+ container
238
242
 
239
243
  try
240
- component.render()
244
+ $( component.container ).append( component.el )
245
+ component.render()
241
246
  catch e
242
247
  console.log "Error Rendering Component #{ component.name || component.cid }", component
243
248
 
@@ -265,21 +270,16 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
265
270
  component?.trigger?.call component, "first:activation", component, activator
266
271
  component.previously_activated = true
267
272
 
268
- #### Component Finder Methods
269
- select: (attribute, value, deep=false)->
270
- components = _( @components ).map (component)->
271
- matches = []
272
- test = component[ attribute ]
273
-
274
- matches.push( component ) if test is value
275
-
276
- if deep is true and component.isContainer is true
277
- matches.push component.select(attribute, value, true)
273
+ #### Underscore Methods For Working with Components
274
+ pluck: (attribute)->
275
+ _( @components ).pluck attribute
278
276
 
279
- _.compact matches
280
-
281
- _.flatten( components )
277
+ invoke: (method)->
278
+ _( @components ).invoke method
282
279
 
280
+ map: (fn)->
281
+ _( @components ).map(fn)
282
+
283
283
  # event binding sugar for nested components
284
284
  #
285
285
  # you can define events like:
@@ -287,7 +287,6 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
287
287
  # _.def("MyContainer").extends("Luca.View").with
288
288
  # componentEvents:
289
289
  # "component_name before:load" : "mySpecialHandler"
290
- #
291
290
  componentEvents: {}
292
291
 
293
292
  registerComponentEvents: ()->
@@ -305,7 +304,6 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
305
304
  findComponent: (needle, haystack="name", deep=false)->
306
305
  @createComponents() unless @componentsCreated is true
307
306
 
308
-
309
307
  position = @componentIndex?[ haystack ][ needle ]
310
308
  component = @components?[ position ]
311
309
 
@@ -335,13 +333,42 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
335
333
  return @components[ @activeItem ]
336
334
 
337
335
  componentElements: ()->
338
- $(">.#{ @componentClass }", @el)
336
+ @$(">.#{ @componentClass }", @$bodyEl())
339
337
 
340
338
  getComponent: (needle)->
341
339
  @components[ needle ]
342
340
 
343
341
  rootComponent: ()->
342
+ console.log "Calling rootComponent will be deprecated. use isRootComponent instead"
343
+ !@getParent?
344
+
345
+ isRootComponent:()->
344
346
  !@getParent?
345
347
 
346
348
  getRootComponent: ()->
347
- if @rootComponent() then @ else @getParent().getRootComponent()
349
+ if @rootComponent() then @ else @getParent().getRootComponent()
350
+
351
+ selectByAttribute: (attribute, value, deep=false)->
352
+ components = _( @components ).map (component)->
353
+ matches = []
354
+ test = component[ attribute ]
355
+
356
+ matches.push( component ) if test is value
357
+
358
+ # recursively traverse our components
359
+ matches.push component.selectByAttribute?(attribute, value, true) if deep is true
360
+
361
+ _.compact matches
362
+
363
+ _.flatten( components )
364
+
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
+
369
+ # This is the method by which a container injects the rendered child views
370
+ # into the DOM. It will get passed the container object, and the component
371
+ # that is being rendered.
372
+ Luca.core.Container.componentRenderer = (container, component)->
373
+ attachMethod = $( component.container )[ component.attachWith || "append" ]
374
+ attachMethod( component.render().el )
data/src/core/core.coffee CHANGED
@@ -1,186 +0,0 @@
1
- # Component Definition Helpers
2
- #
3
- #
4
- # We have customized the core Backbone.extend process to use a slightly
5
- # different syntax, which allows us to intercept the component definition at
6
- # various points, and maintain information about classes being defined, and
7
- # the relationships between inherited classes, etc.
8
-
9
- # _.def, or Luca.define returns a chainable object which allows you to define
10
- # your components with a readable syntax. For example:
11
-
12
- # _.def("Luca.View").extends("Backbone.View").with the_good:"shit"
13
- # _.def("MyView").extends("Luca.View").with the_custom:"shit"
14
-
15
- Luca.define = (componentName)->
16
- new DefineProxy(componentName)
17
-
18
- Luca.component = Luca.define
19
-
20
- # The define proxy chain sets up a call to Luca.extend, which is a wrapper around Luca and Backbone component class' extend function.
21
- class DefineProxy
22
- constructor:(componentName)->
23
- @namespace = Luca.util.namespace()
24
- @componentId = @componentName = componentName
25
-
26
- if componentName.match(/\./)
27
- @namespaced = true
28
- parts = componentName.split('.')
29
- @componentId = parts.pop()
30
- @namespace = parts.join('.')
31
-
32
- # automatically add the namespace to the namespace registry
33
- Luca.registry.addNamespace( parts.join('.') )
34
-
35
- # allow for specifying the namespace
36
- in: (@namespace)-> @
37
-
38
- # allow for multiple ways of saying the same thing for readability purposes
39
- from: (@superClassName)-> @
40
- extends: (@superClassName)-> @
41
- extend: (@superClassName)-> @
42
-
43
- # an alias for with, or a readability helper in multi-line definitions
44
- enhance: (properties)->
45
- return @with(properties) if properties?
46
- @
47
-
48
- # which properties, methods, etc will you be extending the base class with?
49
- with: (properties)->
50
- at = if @namespaced
51
- Luca.util.resolve(@namespace, (window || global))
52
- else
53
- (window||global)
54
-
55
- # automatically create the namespace
56
- if @namespaced and not at?
57
- eval("(window||global).#{ @namespace } = {}")
58
- at = Luca.util.resolve(@namespace,(window || global))
59
-
60
- at[@componentId] = Luca.extend(@superClassName,@componentName, properties)
61
-
62
- if Luca.autoRegister is true
63
- componentType = "view" if Luca.isViewPrototype( at[@componentId] )
64
- componentType = "collection" if Luca.isCollectionPrototype( at[@componentId] )
65
- componentType = "model" if Luca.isModelPrototype( at[@componentId] )
66
-
67
- # automatically register this with the component registry
68
- Luca.register( _.string.underscored(@componentId), @componentName, componentType)
69
-
70
- at[@componentId]
71
-
72
- # The last method of the DefineProxy chain is always going to result in
73
- # a call to Luca.extend. Luca.extend wraps the call to Luca.View.extend,
74
- # or Backbone.Collection.extend, and accepts the names of the extending,
75
- # and extended classes as strings. This allows us to maintain information
76
- # and references to the classes and their prototypes, mainly for the purposes
77
- # of introspection and development tools
78
- Luca.extend = (superClassName, childName, properties={})->
79
- superClass = Luca.util.resolve( superClassName, (window || global) )
80
-
81
- unless _.isFunction(superClass?.extend)
82
- throw "#{ superClassName } is not a valid component to extend from"
83
-
84
- properties.displayName = childName
85
-
86
- properties._superClass = ()->
87
- superClass.displayName ||= superClassName
88
- superClass
89
-
90
- properties._super = (method, context, args)->
91
- @_superClass().prototype[method]?.apply(context, args)
92
-
93
- superClass.extend(properties)
94
-
95
- _.mixin
96
- def: Luca.define
97
-
98
-
99
- # Luca.Events
100
- #
101
- # These helpers will get mixed into Luca.Collection, Luca.View, and Luca.Model.
102
- #
103
- # They allow for syntactic sugar like:
104
- #
105
- # view.defer("someMethodOnTheView").until("collection","fetch")
106
- #
107
- # or
108
- #
109
- # view.defer( myCallback ).until("triggered:event")
110
- class DeferredBindingProxy
111
- constructor: (@object, operation, wrapWithUnderscore=true)->
112
- if _.isFunction(operation)
113
- fn = operation
114
-
115
- else if _.isString(operation) and _.isFunction(@object[operation])
116
- fn = @object[operation]
117
-
118
- unless _.isFunction(fn)
119
- throw "Must pass a function or a string representing one"
120
-
121
- if wrapWithUnderscore is true
122
- @fn = ()=>
123
- _.defer(fn)
124
- else
125
- @fn = fn
126
-
127
- @
128
-
129
- # until accepts an object to bind to, and a trigger to bind with
130
- # if you just pass a trigger, the object getting bound to
131
- # will implicitly be @object
132
- until: (watch, trigger)->
133
- if watch? and not trigger?
134
- trigger = watch
135
- watch = @object
136
-
137
- watch.once(trigger, @fn)
138
-
139
- @object
140
-
141
- Luca.Events =
142
- defer: (operation, wrapWithUnderscore=true)->
143
- new DeferredBindingProxy(@, operation, wrapWithUnderscore)
144
-
145
- once: (trigger, callback, context)->
146
- context ||= @
147
-
148
- onceFn = ()->
149
- callback.apply(context, arguments)
150
- @unbind(trigger, onceFn)
151
-
152
- @bind trigger, onceFn
153
-
154
- class Luca.ScriptLoader
155
- @loaded: {}
156
-
157
- constructor: (options={})->
158
- _.extend(@, Backbone.Events, Luca.Events)
159
- @autoStart = options.autoStart is true
160
- @scripts = options.scripts
161
-
162
- ready = ()-> @trigger("ready")
163
-
164
- @ready = _.after( @scripts.length, ready)
165
-
166
- _.bindAll @, "load", "ready"
167
-
168
- @defer("load").until(@, "start")
169
-
170
- if @autoStart is true
171
- @trigger("start")
172
-
173
- @bind "ready", @onReady
174
-
175
- applyPrefix: (script)->
176
- script
177
-
178
- onReady: ()->
179
- console.log "All dependencies loaded"
180
-
181
- start: ()->
182
- @trigger("start")
183
-
184
- load: ()->
185
- Luca.util.loadScript( @applyPrefix(script), @ready ) for script in @scripts
186
-
@@ -44,7 +44,7 @@ _.def('Luca.core.Field').extends('Luca.View').with
44
44
 
45
45
  @$el.addClass('required') if @required
46
46
 
47
- @$el.html Luca.templates[ @template ]( @ )
47
+ @$el.html Luca.template(@template, @)
48
48
  @input = $('input', @el)
49
49
 
50
50
  change_handler: (e)->
@@ -57,7 +57,15 @@ _.def('Luca.core.Field').extends('Luca.View').with
57
57
  $("input", @el).attr('disabled', false)
58
58
 
59
59
  getValue: ()->
60
- @input.attr('value')
60
+ raw = @input.attr('value')
61
+
62
+ return raw if _.str.isBlank( raw )
63
+
64
+ switch @valueType
65
+ when "integer" then parseInt(raw)
66
+ when "string" then "#{ raw }"
67
+ when "float" then parseFloat(raw)
68
+ else raw
61
69
 
62
70
  render: ()->
63
71
  $( @container ).append( @$el )
@@ -68,4 +76,4 @@ _.def('Luca.core.Field').extends('Luca.View').with
68
76
  updateState: (state)->
69
77
  _( @statuses ).each (cls)=>
70
78
  @$el.removeClass(cls)
71
- @$el.addClass(state)
79
+ @$el.addClass(state)