luca 0.9.6 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +37 -14
- data/lib/luca/rails/version.rb +1 -1
- data/spec/components/collection_view_spec.coffee +24 -2
- data/spec/components/pagination_control_spec.coffee +0 -0
- data/spec/concerns/dom_helpers_spec.coffee +16 -0
- data/spec/concerns/filterable_spec.coffee +25 -0
- data/spec/concerns/model_presenter_spec.coffee +31 -0
- data/spec/concerns/paginatable_spec.coffee +0 -0
- data/spec/concerns/state_model_spec.coffee +0 -0
- data/spec/concerns_spec.coffee +88 -0
- data/spec/core/container_spec.coffee +74 -12
- data/spec/core/model_spec.coffee +6 -1
- data/spec/define_spec.coffee +0 -6
- data/spec/util_spec.coffee +24 -0
- data/src/components/application.coffee +32 -30
- data/src/components/base_toolbar.coffee +6 -4
- data/src/components/collection_loader_view.coffee +3 -1
- data/src/components/collection_view.coffee +42 -21
- data/src/components/controller.coffee +3 -1
- data/src/components/fields/button_field.coffee +19 -12
- data/src/components/fields/checkbox_array.coffee +8 -2
- data/src/components/fields/checkbox_field.coffee +18 -9
- data/src/components/fields/file_upload_field.coffee +5 -1
- data/src/components/fields/hidden_field.coffee +3 -1
- data/src/components/fields/label_field.coffee +4 -3
- data/src/components/fields/select_field.coffee +7 -8
- data/src/components/fields/text_field.coffee +3 -1
- data/src/components/fields/type_ahead_field.coffee +4 -2
- data/src/components/form_button_toolbar.coffee +4 -1
- data/src/components/form_view.coffee +49 -44
- data/src/components/grid_view.coffee +1 -1
- data/src/components/multi_collection_view.coffee +49 -22
- data/src/components/pagination_control.coffee +17 -13
- data/src/{modules → concerns}/application_event_bindings.coffee +1 -1
- data/src/{modules → concerns}/collection_event_bindings.coffee +1 -1
- data/src/{modules → concerns}/deferrable.coffee +1 -1
- data/src/{modules → concerns}/dom_helpers.coffee +11 -2
- data/src/{modules → concerns}/enhanced_properties.coffee +1 -1
- data/src/concerns/filterable.coffee +82 -0
- data/src/{modules → concerns}/grid_layout.coffee +1 -1
- data/src/{modules → concerns}/loadmaskable.coffee +1 -1
- data/src/{modules → concerns}/local_storage.coffee +0 -0
- data/src/{modules → concerns}/modal_view.coffee +1 -1
- data/src/concerns/model_presenter.coffee +23 -0
- data/src/concerns/paginatable.coffee +87 -0
- data/src/{modules → concerns}/state_model.coffee +1 -1
- data/src/{modules → concerns}/templating.coffee +1 -1
- data/src/concerns.coffee +70 -0
- data/src/containers/tab_view.coffee +7 -10
- data/src/core/collection.coffee +17 -1
- data/src/core/container.coffee +56 -31
- data/src/core/field.coffee +39 -38
- data/src/core/meta_data.coffee +37 -0
- data/src/core/model.coffee +18 -1
- data/src/core/view.coffee +25 -29
- data/src/define.coffee +54 -66
- data/src/framework.coffee +23 -18
- data/src/index.coffee +3 -1
- data/src/stylesheets/components/checkbox_array.scss +1 -1
- data/src/stylesheets/components/form_view.scss +5 -5
- data/src/stylesheets/components/viewport.scss +2 -1
- data/src/stylesheets/containers/container.scss +0 -5
- data/src/stylesheets/containers/tab_view.scss +5 -5
- data/src/tools/console.coffee +5 -5
- data/src/util.coffee +47 -0
- data/vendor/assets/javascripts/luca-ui-development-tools.js +5 -5
- data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
- data/vendor/assets/javascripts/luca-ui-full.js +905 -416
- data/vendor/assets/javascripts/luca-ui-full.min.js +5 -5
- data/vendor/assets/javascripts/luca-ui.js +905 -416
- data/vendor/assets/javascripts/luca-ui.min.js +5 -4
- data/vendor/assets/stylesheets/luca-ui.css +15 -15
- metadata +27 -17
- data/spec/mixin_spec.coffee +0 -49
- data/src/modules/filterable.coffee +0 -60
- data/src/modules/paginatable.coffee +0 -79
data/src/concerns.coffee
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
Luca.concern = (mixinName)->
|
2
|
+
namespace = _( Luca.concern.namespaces ).detect (space)->
|
3
|
+
Luca.util.resolve(space)?[ mixinName ]?
|
4
|
+
|
5
|
+
namespace ||= "Luca.concerns"
|
6
|
+
|
7
|
+
resolved = Luca.util.resolve(namespace)[ mixinName ]
|
8
|
+
|
9
|
+
console.log "Could not find #{ mixinName } in ", Luca.concern.namespaces unless resolved?
|
10
|
+
|
11
|
+
resolved
|
12
|
+
|
13
|
+
Luca.concern.namespaces = [
|
14
|
+
"Luca.concerns"
|
15
|
+
]
|
16
|
+
|
17
|
+
Luca.concern.namespace = (namespace)->
|
18
|
+
Luca.concern.namespaces.push(namespace)
|
19
|
+
Luca.concern.namespaces = _( Luca.concern.namespaces ).uniq()
|
20
|
+
|
21
|
+
Luca.concern.setup = ()->
|
22
|
+
if @concerns?.length > 0
|
23
|
+
for module in @concerns
|
24
|
+
Luca.concern(module)?.__initializer?.call(@, @, module)
|
25
|
+
|
26
|
+
# Luca.decorate('Luca.View').with('Luca.concerns.MyCustomMixin')
|
27
|
+
Luca.decorate = (target)->
|
28
|
+
try
|
29
|
+
if _.isString(target)
|
30
|
+
componentName = target
|
31
|
+
componentClass = Luca.util.resolve(componentName)
|
32
|
+
|
33
|
+
componentClass = target if _.isFunction(target)
|
34
|
+
componentPrototype = componentClass.prototype
|
35
|
+
componentName = componentName || componentClass.displayName
|
36
|
+
componentName ||= componentPrototype.displayName
|
37
|
+
catch e
|
38
|
+
console.log e.message
|
39
|
+
console.log e.stack
|
40
|
+
console.log "Error calling Luca.decorate on ", componentClass, componentPrototype, componentName
|
41
|
+
|
42
|
+
throw(e)
|
43
|
+
|
44
|
+
return with: (mixinName)->
|
45
|
+
mixinDefinition = Luca.concern(mixinName)
|
46
|
+
mixinDefinition.__displayName ||= mixinName
|
47
|
+
|
48
|
+
mixinPrivates = _( mixinDefinition ).chain().keys().select (key)->
|
49
|
+
"#{ key }".match(/^__/) or key is "classMethods"
|
50
|
+
|
51
|
+
sanitized = _( mixinDefinition ).omit( mixinPrivates.value() )
|
52
|
+
|
53
|
+
_.extend(componentPrototype, sanitized)
|
54
|
+
|
55
|
+
if mixinDefinition.classMethods?
|
56
|
+
for method, fn of mixinDefinition.classMethods
|
57
|
+
componentClass[ method ] = _.bind(fn, componentClass)
|
58
|
+
|
59
|
+
# When a mixin is included, we may want to do things
|
60
|
+
mixinDefinition?.__included?(componentName, componentClass, mixinDefinition)
|
61
|
+
|
62
|
+
superclassMixins = componentPrototype._superClass()::concerns
|
63
|
+
|
64
|
+
componentPrototype.concerns ||= []
|
65
|
+
componentPrototype.concerns.push( mixinName )
|
66
|
+
componentPrototype.concerns = componentPrototype.concerns.concat( superclassMixins )
|
67
|
+
|
68
|
+
componentPrototype.concerns = _( componentPrototype.concerns ).chain().uniq().compact().value()
|
69
|
+
|
70
|
+
componentPrototype
|
@@ -1,23 +1,20 @@
|
|
1
1
|
_.def('Luca.containers.TabView').extends('Luca.containers.CardView').with
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
]
|
7
|
-
|
8
|
-
componentType: 'tab_view'
|
9
|
-
|
10
|
-
className: 'luca-ui-tab-view tabbable'
|
3
|
+
tabView = Luca.register "Luca.containers.TabView"
|
4
|
+
tabView.triggers "before:select",
|
5
|
+
"after:select"
|
11
6
|
|
7
|
+
tabView.publicConfiguration
|
12
8
|
tab_position: 'top'
|
13
|
-
|
14
9
|
tabVerticalOffset: '50px'
|
15
10
|
|
11
|
+
tabView.privateConfiguration
|
12
|
+
additionalClassNames: 'tabbable'
|
16
13
|
navClass: "nav-tabs"
|
17
|
-
|
18
14
|
bodyTemplate: "containers/tab_view"
|
19
15
|
bodyEl: "div.tab-content"
|
20
16
|
|
17
|
+
tabView.defines
|
21
18
|
initialize: (@options={})->
|
22
19
|
@navClass = "nav-list"if @navStyle is "list"
|
23
20
|
|
data/src/core/collection.coffee
CHANGED
@@ -91,6 +91,8 @@ collection.defines
|
|
91
91
|
if models
|
92
92
|
@reset models, silent: true, parse: options?.parse
|
93
93
|
|
94
|
+
Luca.concern.setup.call(@)
|
95
|
+
|
94
96
|
@trigger "after:initialize"
|
95
97
|
|
96
98
|
# Luca.Collections will append a query string to the URL
|
@@ -211,7 +213,7 @@ collection.defines
|
|
211
213
|
# fetch will try to pull from the bootstrap if it is setup to do so
|
212
214
|
# you can actually make the roundtrip to the server anyway if you pass
|
213
215
|
# refresh = true in the options hash
|
214
|
-
return @bootstrap() if @cached_models().length and not options.refresh
|
216
|
+
return @bootstrap() if @cached_models().length and not (options.refresh is true or options.remote is true)
|
215
217
|
|
216
218
|
url = if _.isFunction(@url) then @url() else @url
|
217
219
|
|
@@ -350,6 +352,20 @@ _.extend Luca.Collection.prototype,
|
|
350
352
|
|
351
353
|
Backbone.View.prototype.trigger.apply @, arguments
|
352
354
|
|
355
|
+
Luca.Collection._originalExtend = Backbone.Collection.extend
|
356
|
+
|
357
|
+
Luca.Collection.extend = (definition={})->
|
358
|
+
# for backward compatibility
|
359
|
+
definition.concerns ||= definition.concerns if definition.concerns?
|
360
|
+
|
361
|
+
componentClass = Luca.Collection._originalExtend.call(@, definition)
|
362
|
+
|
363
|
+
if definition.concerns? and _.isArray( definition.concerns )
|
364
|
+
for module in definition.concerns
|
365
|
+
Luca.decorate( componentClass ).with( module )
|
366
|
+
|
367
|
+
componentClass
|
368
|
+
|
353
369
|
# Always include these parameters in every request to your REST API.
|
354
370
|
#
|
355
371
|
# either specify a function which returns a hash, or just a normal hash
|
data/src/core/container.coffee
CHANGED
@@ -9,7 +9,7 @@ container.triggers "before:components",
|
|
9
9
|
"after:layout",
|
10
10
|
"first:activation"
|
11
11
|
|
12
|
-
container.defines
|
12
|
+
container.defines
|
13
13
|
className: 'luca-ui-container'
|
14
14
|
|
15
15
|
componentTag: 'div'
|
@@ -25,7 +25,7 @@ container.defines
|
|
25
25
|
# @componentEvents provides declarative syntax for responding to events on
|
26
26
|
# the components in this container. the format of the syntax is very similar
|
27
27
|
# to the other event binding helpers:
|
28
|
-
#
|
28
|
+
#
|
29
29
|
# component_accessor component:trigger
|
30
30
|
#
|
31
31
|
# where component_accessor is either the name of the role, or a method on the container
|
@@ -115,6 +115,8 @@ container.defines
|
|
115
115
|
applyDOMConfig.call(container, component, index)
|
116
116
|
|
117
117
|
prepareComponents: ()->
|
118
|
+
container = @
|
119
|
+
|
118
120
|
# accept components as an array of strings representing
|
119
121
|
# the luca component type
|
120
122
|
for component in @components when _.isString(component)
|
@@ -130,6 +132,26 @@ container.defines
|
|
130
132
|
panel = @make(@componentTag, componentContainerElement, '')
|
131
133
|
@$append( panel )
|
132
134
|
|
135
|
+
# if the container defines a @defaults property
|
136
|
+
# then we should make sure our child components inherit
|
137
|
+
# these values unless specifically defined
|
138
|
+
if container.defaults?
|
139
|
+
component = _.defaults(component, (container.defaults || {}))
|
140
|
+
|
141
|
+
# if the container defines an @extensions property as an array of
|
142
|
+
# configuration objects, then we will extend the component config with
|
143
|
+
# the object in the matching position of the @extensions array.
|
144
|
+
if _.isArray(container.extensions) and _.isObject(container.extensions?[ index ])
|
145
|
+
componentExtension = container.extensions[index]
|
146
|
+
component = _.extend(component, componentExtension)
|
147
|
+
|
148
|
+
# if the container defines an @extensions property as an object of nested hashes,
|
149
|
+
# then extensions is a key/value pair whose key represents the role of the component
|
150
|
+
# that we wish to extend / customize
|
151
|
+
if component.role? and _.isObject(container.extensions) and _.isObject(container.extensions[component.role])
|
152
|
+
componentExtension = container.extensions[component.role]
|
153
|
+
component = _.extend(component, componentExtension)
|
154
|
+
|
133
155
|
unless component.container?
|
134
156
|
component.container = "##{ componentContainerElement.id }" if @generateComponentElements
|
135
157
|
component.container ||= @$bodyEl()
|
@@ -157,30 +179,31 @@ container.defines
|
|
157
179
|
# adding the views @$el to the appropriate @container.
|
158
180
|
|
159
181
|
# you can also just pass a string representing the component_type
|
160
|
-
component = if Luca.
|
182
|
+
component = if Luca.isComponent( object )
|
161
183
|
object
|
162
184
|
else
|
163
185
|
object.type ||= object.ctype
|
164
186
|
|
165
187
|
if !object.type?
|
188
|
+
# TODO
|
189
|
+
# Add support for all of the various components property aliases
|
166
190
|
if object.components?
|
167
191
|
object.type = object.ctype = 'container'
|
168
192
|
else
|
169
193
|
object.type = object.ctype = Luca.defaultComponentType
|
170
194
|
|
171
|
-
# if the container defines a @defaults property
|
172
|
-
# then we should make sure our child components inherit
|
173
|
-
# these values unless specifically defined
|
174
|
-
object = _.defaults(object, (container.defaults || {}))
|
175
|
-
|
176
195
|
created = Luca.util.lazyComponent( object )
|
177
196
|
|
178
197
|
# if we're using base backbone views, then they don't extend themselves
|
179
198
|
# with their passed options, so this is a workaround to get them to
|
180
199
|
# pick up the container config property
|
181
|
-
if !component.container and component.options
|
200
|
+
if !component.container and component.options?.container
|
182
201
|
component.container = component.options.container
|
183
202
|
|
203
|
+
if not component.container?
|
204
|
+
console.log component,index,@
|
205
|
+
console.error "could not assign container property to component on container #{ @name || @cid }"
|
206
|
+
|
184
207
|
indexComponent( component ).at(index).in( @componentIndex )
|
185
208
|
|
186
209
|
component
|
@@ -194,14 +217,14 @@ container.defines
|
|
194
217
|
renderComponents: (@debugMode="")->
|
195
218
|
@debug "container render components"
|
196
219
|
|
197
|
-
container = @
|
220
|
+
container = @
|
198
221
|
_(@components).each (component)->
|
199
|
-
component.getParent = ()->
|
200
|
-
container
|
222
|
+
component.getParent = ()->
|
223
|
+
container
|
201
224
|
|
202
225
|
try
|
203
|
-
|
204
|
-
component.render()
|
226
|
+
@$( component.container ).eq(0).append( component.el )
|
227
|
+
component.render()
|
205
228
|
catch e
|
206
229
|
console.log "Error Rendering Component #{ component.name || component.cid }", component
|
207
230
|
|
@@ -232,7 +255,7 @@ container.defines
|
|
232
255
|
#### Underscore Methods For Working with Components
|
233
256
|
_: ()-> _( @components )
|
234
257
|
|
235
|
-
pluck: (attribute)->
|
258
|
+
pluck: (attribute)->
|
236
259
|
@_().pluck(attribute)
|
237
260
|
|
238
261
|
invoke: (method)->
|
@@ -243,17 +266,17 @@ container.defines
|
|
243
266
|
|
244
267
|
detect: (fn)->
|
245
268
|
@_().detect(attribute)
|
246
|
-
|
269
|
+
|
247
270
|
reject: (fn)->
|
248
271
|
@_().reject(fn)
|
249
272
|
|
250
273
|
map: (fn)->
|
251
274
|
@_().map(fn)
|
252
275
|
|
253
|
-
registerComponentEvents: ()->
|
276
|
+
registerComponentEvents: (eventList)->
|
254
277
|
container = @
|
255
278
|
|
256
|
-
for listener, handler of (@componentEvents||{})
|
279
|
+
for listener, handler of (eventList || @componentEvents||{})
|
257
280
|
[componentNameOrRole,eventId] = listener.split(' ')
|
258
281
|
|
259
282
|
unless _.isFunction( @[handler] )
|
@@ -262,7 +285,7 @@ container.defines
|
|
262
285
|
|
263
286
|
if componentNameOrRole is "*"
|
264
287
|
@eachComponent (component)=> component.on(eventId, @[handler], container)
|
265
|
-
else
|
288
|
+
else
|
266
289
|
component = @findComponentForEventBinding( componentNameOrRole )
|
267
290
|
|
268
291
|
unless component? and Luca.isComponent(component)
|
@@ -273,18 +296,18 @@ container.defines
|
|
273
296
|
|
274
297
|
|
275
298
|
subContainers: ()->
|
276
|
-
@select (component)->
|
299
|
+
@select (component)->
|
277
300
|
component.isContainer is true
|
278
301
|
|
279
302
|
roles: ()->
|
280
303
|
_( @allChildren() ).pluck('role')
|
281
|
-
|
304
|
+
|
282
305
|
allChildren: ()->
|
283
306
|
children = @components
|
284
307
|
grandchildren = _( @subContainers() ).invoke('allChildren')
|
285
|
-
|
308
|
+
_([children,grandchildren]).chain().compact().flatten().value()
|
286
309
|
|
287
|
-
findComponentForEventBinding: (nameRoleOrGetter, deep=
|
310
|
+
findComponentForEventBinding: (nameRoleOrGetter, deep=true)->
|
288
311
|
@findComponentByName(nameRoleOrGetter, deep) || @findComponentByGetter( nameRoleOrGetter, deep ) || @findComponentByRole( nameRoleOrGetter, deep )
|
289
312
|
|
290
313
|
findComponentByGetter: (getter, deep=false)->
|
@@ -293,7 +316,7 @@ container.defines
|
|
293
316
|
|
294
317
|
findComponentByRole: (role,deep=false)->
|
295
318
|
_( @allChildren() ).detect (component)->
|
296
|
-
component.role is role
|
319
|
+
component.role is role or component.type is role or component.ctype is role
|
297
320
|
|
298
321
|
findComponentByName: (name, deep=false)->
|
299
322
|
_( @allChildren() ).detect (component)->
|
@@ -311,7 +334,7 @@ container.defines
|
|
311
334
|
return component if component
|
312
335
|
|
313
336
|
if deep is true
|
314
|
-
sub_container = _( @components ).detect (component)->
|
337
|
+
sub_container = _( @components ).detect (component)->
|
315
338
|
component?.findComponent?(needle, haystack, true)
|
316
339
|
|
317
340
|
sub_container?.findComponent?(needle, haystack, true)
|
@@ -346,7 +369,7 @@ container.defines
|
|
346
369
|
|
347
370
|
getRootComponent: ()->
|
348
371
|
if @isRootComponent() then @ else @getParent().getRootComponent()
|
349
|
-
|
372
|
+
|
350
373
|
|
351
374
|
selectByAttribute: (attribute, value=undefined, deep=false)->
|
352
375
|
components = _( @components ).map (component)->
|
@@ -365,7 +388,7 @@ container.defines
|
|
365
388
|
|
366
389
|
# This is the method by which a container injects the rendered child views
|
367
390
|
# into the DOM. It will get passed the container object, and the component
|
368
|
-
# that is being rendered.
|
391
|
+
# that is being rendered.
|
369
392
|
Luca.core.Container.componentRenderer = (container, component)->
|
370
393
|
attachMethod = $( component.container )[ component.attachWith || "append" ]
|
371
394
|
attachMethod( component.render().el )
|
@@ -406,7 +429,6 @@ createGetterMethods = ()->
|
|
406
429
|
|
407
430
|
_( childrenWithGetter ).each (component)->
|
408
431
|
container[ component.getter ] ||= ()->
|
409
|
-
console.log "getter is being deprecated in favor of role"
|
410
432
|
console.log component.getter, component, container
|
411
433
|
component
|
412
434
|
|
@@ -428,8 +450,11 @@ doComponents = ()->
|
|
428
450
|
@trigger "before:render:components", @, @components
|
429
451
|
@renderComponents()
|
430
452
|
@trigger "after:components", @, @components
|
431
|
-
|
432
|
-
|
453
|
+
|
454
|
+
unless @skipGetterMethods is true
|
455
|
+
createGetterMethods.call(@)
|
456
|
+
createMethodsToGetComponentsByRole.call(@)
|
457
|
+
|
433
458
|
@registerComponentEvents()
|
434
459
|
|
435
460
|
validateContainerConfiguration = ()->
|
@@ -447,4 +472,4 @@ indexComponent = (component)->
|
|
447
472
|
if component.role?
|
448
473
|
map.role_index[ component.role ] = index
|
449
474
|
if component.name?
|
450
|
-
map.name_index[ component.name ] = index
|
475
|
+
map.name_index[ component.name ] = index
|
data/src/core/field.coffee
CHANGED
@@ -1,26 +1,51 @@
|
|
1
|
-
|
1
|
+
field = Luca.register "Luca.core.Field"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
isField: true
|
3
|
+
field.extends "Luca.View"
|
6
4
|
|
7
|
-
|
5
|
+
field.triggers "before:validation",
|
6
|
+
"after:validation",
|
7
|
+
"on:change"
|
8
8
|
|
9
|
+
field.publicConfiguration
|
9
10
|
labelAlign: 'top'
|
10
|
-
|
11
|
-
hooks:[
|
12
|
-
"before:validation",
|
13
|
-
"after:validation",
|
14
|
-
"on:change"
|
15
|
-
]
|
16
|
-
|
17
|
-
# see: http://twitter.github.com/bootstrap/base-css.html
|
11
|
+
className: 'luca-ui-text-field luca-ui-field'
|
18
12
|
statuses: [
|
19
13
|
"warning"
|
20
14
|
"error"
|
21
15
|
"success"
|
22
16
|
]
|
23
17
|
|
18
|
+
field.publicInterface
|
19
|
+
disable: ()->
|
20
|
+
@getInputElement().attr('disabled', true)
|
21
|
+
|
22
|
+
enable: ()->
|
23
|
+
@getInputElement().attr('disabled', false)
|
24
|
+
|
25
|
+
getValue: ()->
|
26
|
+
raw = @getInputElement()?.attr('value')
|
27
|
+
|
28
|
+
return raw if _.str.isBlank( raw )
|
29
|
+
|
30
|
+
switch @valueType
|
31
|
+
when "integer" then parseInt(raw)
|
32
|
+
when "string" then "#{ raw }"
|
33
|
+
when "float" then parseFloat(raw)
|
34
|
+
else raw
|
35
|
+
|
36
|
+
setValue: (value)->
|
37
|
+
@getInputElement()?.attr('value', value)
|
38
|
+
|
39
|
+
updateState: (state)->
|
40
|
+
_( @statuses ).each (cls)=>
|
41
|
+
@$el.removeClass(cls)
|
42
|
+
@$el.addClass(state)
|
43
|
+
|
44
|
+
field.privateConfiguration
|
45
|
+
isField: true
|
46
|
+
template: 'fields/text_field'
|
47
|
+
|
48
|
+
field.defines
|
24
49
|
initialize: (@options={})->
|
25
50
|
_.extend @, @options
|
26
51
|
|
@@ -29,6 +54,7 @@ _.def('Luca.core.Field').extends('Luca.View').with
|
|
29
54
|
@input_class ||= ""
|
30
55
|
@input_type ||= ""
|
31
56
|
@helperText ||= ""
|
57
|
+
@label = @name if not @label? or @label.length is 0
|
32
58
|
@label ||= "*#{ @label }" if @required and not @label?.match(/^\*/)
|
33
59
|
@inputStyles ||= ""
|
34
60
|
@input_value ||= @value || ""
|
@@ -53,30 +79,5 @@ _.def('Luca.core.Field').extends('Luca.View').with
|
|
53
79
|
change_handler: (e)->
|
54
80
|
@trigger "on:change", @, e
|
55
81
|
|
56
|
-
disable: ()->
|
57
|
-
@getInputElement().attr('disabled', true)
|
58
|
-
|
59
|
-
enable: ()->
|
60
|
-
@getInputElement().attr('disabled', false)
|
61
|
-
|
62
|
-
getValue: ()->
|
63
|
-
raw = @getInputElement()?.attr('value')
|
64
|
-
|
65
|
-
return raw if _.str.isBlank( raw )
|
66
|
-
|
67
|
-
switch @valueType
|
68
|
-
when "integer" then parseInt(raw)
|
69
|
-
when "string" then "#{ raw }"
|
70
|
-
when "float" then parseFloat(raw)
|
71
|
-
else raw
|
72
|
-
|
73
|
-
setValue: (value)->
|
74
|
-
@getInputElement()?.attr('value', value)
|
75
|
-
|
76
82
|
getInputElement: ()->
|
77
83
|
@input ||= @$('input').eq(0)
|
78
|
-
|
79
|
-
updateState: (state)->
|
80
|
-
_( @statuses ).each (cls)=>
|
81
|
-
@$el.removeClass(cls)
|
82
|
-
@$el.addClass(state)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Luca.registry.componentMetaData = {}
|
2
|
+
|
3
|
+
Luca.registry.getMetaDataFor = (componentName)->
|
4
|
+
new MetaDataProxy(Luca.registry.componentMetaData[ componentName ])
|
5
|
+
|
6
|
+
Luca.registry.addMetaData = (componentName, key, value)->
|
7
|
+
data = Luca.registry.componentMetaData[ componentName ] ||= {}
|
8
|
+
data[ key ] = _(value).clone()
|
9
|
+
data
|
10
|
+
|
11
|
+
|
12
|
+
class MetaDataProxy
|
13
|
+
constructor: (@meta={})->
|
14
|
+
@
|
15
|
+
|
16
|
+
superClass: ()->
|
17
|
+
Luca.util.resolve(@meta["super class name"])
|
18
|
+
|
19
|
+
componentDefinition: ()->
|
20
|
+
Luca.util.resolve(@meta["display name"])
|
21
|
+
|
22
|
+
styleHierarchy: ()->
|
23
|
+
list = _( @classHierarchy() ).map (cls)->
|
24
|
+
Luca.util.toCssClass(cls, 'views', 'components', 'core','fields','containers')
|
25
|
+
|
26
|
+
_( list ).without('backbone-view','luca-view')
|
27
|
+
|
28
|
+
classHierarchy: ()->
|
29
|
+
list = [ @meta["display name"], @meta["super class name"]]
|
30
|
+
|
31
|
+
proxy = @superClass()?.prototype?.componentMetaData?()
|
32
|
+
|
33
|
+
until not proxy
|
34
|
+
list = list.concat( proxy?.classHierarchy() )
|
35
|
+
proxy = proxy.superClass()?.prototype?.componentMetaData?()
|
36
|
+
|
37
|
+
_( list ).uniq()
|
data/src/core/model.coffee
CHANGED
@@ -8,12 +8,13 @@ model.defines
|
|
8
8
|
initialize: ()->
|
9
9
|
Backbone.Model::initialize(@, arguments)
|
10
10
|
setupComputedProperties.call(@)
|
11
|
+
Luca.concern.setup.call(@)
|
11
12
|
|
12
13
|
read: (attr)->
|
13
14
|
if _.isFunction(@[attr])
|
14
15
|
@[attr].call(@)
|
15
16
|
else
|
16
|
-
@get(attr)
|
17
|
+
@get(attr) || @[attr]
|
17
18
|
|
18
19
|
get: (attr)->
|
19
20
|
if @computed?.hasOwnProperty(attr)
|
@@ -37,3 +38,19 @@ setupComputedProperties = ()->
|
|
37
38
|
@trigger "change:#{attr}"
|
38
39
|
|
39
40
|
@trigger "change:#{attr}" if @has(dep)
|
41
|
+
|
42
|
+
|
43
|
+
Luca.Model._originalExtend = Backbone.Model.extend
|
44
|
+
|
45
|
+
Luca.Model.extend = (definition={})->
|
46
|
+
# for backward compatibility
|
47
|
+
definition.concerns ||= definition.concerns if definition.concerns?
|
48
|
+
|
49
|
+
componentClass = Luca.Model._originalExtend.call(@, definition)
|
50
|
+
|
51
|
+
if definition.concerns? and _.isArray( definition.concerns )
|
52
|
+
for module in definition.concerns
|
53
|
+
Luca.decorate( componentClass ).with( module )
|
54
|
+
|
55
|
+
componentClass
|
56
|
+
|
data/src/core/view.coffee
CHANGED
@@ -4,9 +4,9 @@ view.extends "Backbone.View"
|
|
4
4
|
|
5
5
|
# includes are extensions to the prototype, and have no special behavior
|
6
6
|
view.includes "Luca.Events",
|
7
|
-
"Luca.
|
7
|
+
"Luca.concerns.DomHelpers"
|
8
8
|
|
9
|
-
#
|
9
|
+
# concerns are includes with special property / method conventions
|
10
10
|
# which customize the components through the use of __initializer and
|
11
11
|
# __included method names. These will be called every time an instance
|
12
12
|
# is created, and the first time the mixin is used to enhance a component.
|
@@ -48,12 +48,10 @@ view.defines
|
|
48
48
|
|
49
49
|
@setupHooks _( Luca.View::hooks.concat( @hooks ) ).uniq()
|
50
50
|
|
51
|
-
|
52
|
-
for module in @mixins
|
53
|
-
Luca.mixin(module)?.__initializer?.call(@, @, module)
|
51
|
+
Luca.concern.setup.call(@)
|
54
52
|
|
55
53
|
@delegateEvents()
|
56
|
-
|
54
|
+
|
57
55
|
@trigger "after:initialize", @
|
58
56
|
|
59
57
|
#### Hooks or Auto Event Binding
|
@@ -69,18 +67,7 @@ view.defines
|
|
69
67
|
# after:render : afterRender()
|
70
68
|
# after:initialize : afterInitialize()
|
71
69
|
# first:activation : firstActivation()
|
72
|
-
setupHooks:
|
73
|
-
set ||= @hooks
|
74
|
-
|
75
|
-
_(set).each (eventId)=>
|
76
|
-
fn = Luca.util.hook( eventId )
|
77
|
-
|
78
|
-
callback = ()->
|
79
|
-
@[fn]?.apply @, arguments
|
80
|
-
|
81
|
-
callback = _.once(callback) if eventId?.match(/once:/)
|
82
|
-
|
83
|
-
@on eventId, callback, @
|
70
|
+
setupHooks: Luca.util.setupHooks
|
84
71
|
|
85
72
|
registerEvent: (selector, handler)->
|
86
73
|
@events ||= {}
|
@@ -90,13 +77,18 @@ view.defines
|
|
90
77
|
definitionClass: ()->
|
91
78
|
Luca.util.resolve(@displayName, window)?.prototype
|
92
79
|
|
93
|
-
collections: ()->
|
94
|
-
|
95
|
-
views: ()-> Luca.util.selectProperties( Luca.isBackboneView, @ )
|
80
|
+
collections: ()->
|
81
|
+
Luca.util.selectProperties( Luca.isBackboneCollection, @ )
|
96
82
|
|
97
|
-
|
83
|
+
models: ()->
|
84
|
+
Luca.util.selectProperties( Luca.isBackboneModel, @ )
|
85
|
+
|
86
|
+
views: ()->
|
87
|
+
Luca.util.selectProperties( Luca.isBackboneView, @ )
|
88
|
+
|
89
|
+
debug: (args...)->
|
98
90
|
return unless @debugMode or window.LucaDebugMode?
|
99
|
-
console.log [(@name || @cid),
|
91
|
+
console.log [(@name || @cid), args...]
|
100
92
|
|
101
93
|
trigger: ()->
|
102
94
|
if Luca.enableGlobalObserver
|
@@ -163,14 +155,18 @@ bindEventHandlers = (events={})->
|
|
163
155
|
if _.isString(handler)
|
164
156
|
_.bindAll @, handler
|
165
157
|
|
166
|
-
Luca.View.
|
158
|
+
Luca.View.deferrableEvent = "reset"
|
159
|
+
|
160
|
+
Luca.View.extend = (definition={})->
|
167
161
|
definition = Luca.View.renderWrapper( definition )
|
162
|
+
# for backward compatibility
|
163
|
+
definition.concerns ||= definition.concerns if definition.concerns?
|
168
164
|
|
169
|
-
|
170
|
-
for module in definition.mixins
|
171
|
-
Luca.decorate( definition ).with( module )
|
165
|
+
componentClass = Luca.View._originalExtend.call(@, definition)
|
172
166
|
|
173
|
-
|
167
|
+
if definition.concerns? and _.isArray( definition.concerns )
|
168
|
+
for module in definition.concerns
|
169
|
+
Luca.decorate( componentClass ).with( module )
|
174
170
|
|
171
|
+
componentClass
|
175
172
|
|
176
|
-
Luca.View.deferrableEvent = "reset"
|