luca 0.9.4 → 0.9.6

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 (144) hide show
  1. data/CHANGELOG +41 -1
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +2 -0
  4. data/README.md +5 -0
  5. data/Rakefile +4 -0
  6. data/assets/javascripts/dependencies/underscore-min.js +5 -31
  7. data/assets/javascripts/luca-templates.js +1 -0
  8. data/assets/javascripts/luca-ui-base.coffee +1 -1
  9. data/assets/javascripts/luca-ui-development-tools.coffee +1 -1
  10. data/assets/javascripts/luca-ui-full.js +1 -1
  11. data/assets/javascripts/luca-ui-spec.coffee +1 -1
  12. data/assets/javascripts/luca-ui.js +3 -0
  13. data/assets/javascripts/luca/index.coffee +1 -0
  14. data/lib/generators/luca/application/application_generator.rb +71 -0
  15. data/lib/generators/luca/application/templates/controller.rb +6 -0
  16. data/lib/generators/luca/application/templates/index.html.erb +7 -0
  17. data/lib/generators/luca/application/templates/index.html.haml +6 -0
  18. data/lib/generators/luca/application/templates/javascripts/application.js +28 -0
  19. data/lib/generators/luca/application/templates/javascripts/application.js.coffee +20 -0
  20. data/lib/generators/luca/application/templates/javascripts/config.js +15 -0
  21. data/lib/generators/luca/application/templates/javascripts/config.js.coffee +9 -0
  22. data/lib/generators/luca/application/templates/javascripts/dependencies.js +5 -0
  23. data/lib/generators/luca/application/templates/javascripts/dependencies.js.coffee +5 -0
  24. data/lib/generators/luca/application/templates/javascripts/index.js +9 -0
  25. data/lib/generators/luca/application/templates/javascripts/index.js.coffee +9 -0
  26. data/lib/generators/luca/application/templates/javascripts/main.js +8 -0
  27. data/lib/generators/luca/application/templates/javascripts/main.js.coffee +3 -0
  28. data/lib/generators/luca/application/templates/javascripts/main.jst.ejs +1 -0
  29. data/lib/generators/luca/application/templates/javascripts/router.js +12 -0
  30. data/lib/generators/luca/application/templates/javascripts/router.js.coffee +7 -0
  31. data/lib/luca/rails/version.rb +1 -1
  32. data/lib/luca/template.rb +1 -1
  33. data/spec/components/collection_view_spec.coffee +37 -0
  34. data/spec/components/multi_collection_view_spec.coffee +5 -0
  35. data/spec/components/table_view_spec.coffee +17 -0
  36. data/spec/core/container_spec.coffee +112 -5
  37. data/spec/core/model_spec.coffee +21 -3
  38. data/spec/define_spec.coffee +19 -0
  39. data/spec/mixin_spec.coffee +49 -0
  40. data/src/components/application.coffee +33 -19
  41. data/src/components/collection_view.coffee +109 -38
  42. data/src/components/fields/checkbox_field.coffee +2 -2
  43. data/src/components/fields/file_upload_field.coffee +0 -3
  44. data/src/components/fields/hidden_field.coffee +0 -3
  45. data/src/components/fields/label_field.coffee +1 -4
  46. data/src/components/fields/select_field.coffee +6 -6
  47. data/src/components/fields/text_area_field.coffee +1 -0
  48. data/src/components/fields/text_field.coffee +4 -0
  49. data/src/components/fields/type_ahead_field.coffee +5 -9
  50. data/src/components/form_view.coffee +2 -0
  51. data/src/components/index.coffee +1 -0
  52. data/src/components/multi_collection_view.coffee +94 -0
  53. data/src/components/pagination_control.coffee +100 -0
  54. data/src/components/table_view.coffee +62 -0
  55. data/src/containers/card_view.coffee +44 -11
  56. data/src/containers/panel_toolbar.coffee +88 -82
  57. data/src/containers/tab_view.coffee +3 -3
  58. data/src/containers/viewport.coffee +10 -4
  59. data/src/core/collection.coffee +11 -4
  60. data/src/core/container.coffee +189 -113
  61. data/src/core/field.coffee +13 -10
  62. data/src/core/model.coffee +23 -27
  63. data/src/core/registry.coffee +48 -35
  64. data/src/core/view.coffee +60 -140
  65. data/src/define.coffee +91 -19
  66. data/src/framework.coffee +10 -8
  67. data/src/index.coffee +23 -0
  68. data/src/managers/collection_manager.coffee +24 -8
  69. data/src/modules/application_event_bindings.coffee +19 -0
  70. data/src/modules/collection_event_bindings.coffee +26 -0
  71. data/src/modules/deferrable.coffee +3 -1
  72. data/src/modules/dom_helpers.coffee +49 -0
  73. data/src/modules/enhanced_properties.coffee +23 -0
  74. data/src/modules/filterable.coffee +60 -0
  75. data/src/modules/grid_layout.coffee +15 -0
  76. data/src/modules/{load_mask.coffee → loadmaskable.coffee} +10 -4
  77. data/src/modules/modal_view.coffee +38 -0
  78. data/src/modules/paginatable.coffee +79 -0
  79. data/src/modules/state_model.coffee +16 -0
  80. data/src/modules/templating.coffee +8 -0
  81. data/src/plugins/events.coffee +30 -2
  82. data/src/templates/components/bootstrap_form_controls.jst.ejs +10 -0
  83. data/src/templates/components/collection_loader_view.jst.ejs +6 -0
  84. data/src/templates/components/form_alert.jst.ejs +4 -0
  85. data/src/templates/components/grid_view.jst.ejs +11 -0
  86. data/src/templates/components/grid_view_empty_text.jst.ejs +3 -0
  87. data/src/templates/components/load_mask.jst.ejs +5 -0
  88. data/src/templates/components/nav_bar.jst.ejs +4 -0
  89. data/src/templates/components/pagination.jst.ejs +10 -0
  90. data/src/templates/containers/basic.jst.ejs +1 -0
  91. data/src/templates/containers/tab_selector_container.jst.ejs +12 -0
  92. data/src/templates/containers/tab_view.jst.ejs +2 -0
  93. data/src/templates/containers/toolbar_wrapper.jst.ejs +1 -0
  94. data/src/templates/fields/button_field.jst.ejs +2 -0
  95. data/src/templates/fields/button_field_link.jst.ejs +6 -0
  96. data/src/templates/fields/checkbox_array.jst.ejs +4 -0
  97. data/src/templates/fields/checkbox_array_item.jst.ejs +3 -0
  98. data/src/templates/fields/checkbox_field.jst.ejs +10 -0
  99. data/src/templates/fields/file_upload_field.jst.ejs +10 -0
  100. data/src/templates/fields/hidden_field.jst.ejs +1 -0
  101. data/src/templates/fields/select_field.jst.ejs +11 -0
  102. data/src/templates/fields/text_area_field.jst.ejs +11 -0
  103. data/src/templates/fields/text_field.jst.ejs +16 -0
  104. data/src/templates/table_view.jst.ejs +4 -0
  105. data/src/tools/console.coffee +51 -21
  106. data/src/util.coffee +17 -4
  107. data/vendor/assets/javascripts/luca-ui-base.js +3288 -613
  108. data/vendor/assets/javascripts/luca-ui-development-tools.js +49 -21
  109. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
  110. data/vendor/assets/javascripts/luca-ui-full.js +1704 -554
  111. data/vendor/assets/javascripts/luca-ui-full.min.js +7 -6
  112. data/vendor/assets/javascripts/luca-ui-spec.js +1783 -830
  113. data/vendor/assets/javascripts/luca-ui-templates.js +92 -0
  114. data/vendor/assets/javascripts/luca-ui.js +1694 -523
  115. data/vendor/assets/javascripts/luca-ui.min.js +4 -4
  116. metadata +69 -31
  117. data/assets/javascripts/luca-ui.coffee +0 -3
  118. data/src/luca.coffee +0 -22
  119. data/src/templates/components/bootstrap_form_controls.luca +0 -7
  120. data/src/templates/components/collection_loader_view.luca +0 -5
  121. data/src/templates/components/form_alert +0 -0
  122. data/src/templates/components/form_alert.luca +0 -3
  123. data/src/templates/components/grid_view.luca +0 -7
  124. data/src/templates/components/grid_view_empty_text.luca +0 -3
  125. data/src/templates/components/load_mask.luca +0 -3
  126. data/src/templates/components/nav_bar.luca +0 -2
  127. data/src/templates/containers/basic.luca +0 -1
  128. data/src/templates/containers/tab_selector_container.luca +0 -8
  129. data/src/templates/containers/tab_view.luca +0 -2
  130. data/src/templates/containers/toolbar_wrapper.luca +0 -1
  131. data/src/templates/fields/button_field.luca +0 -2
  132. data/src/templates/fields/button_field_link.luca +0 -5
  133. data/src/templates/fields/checkbox_array.luca +0 -4
  134. data/src/templates/fields/checkbox_array_item.luca +0 -4
  135. data/src/templates/fields/checkbox_field.luca +0 -9
  136. data/src/templates/fields/file_upload_field.luca +0 -8
  137. data/src/templates/fields/hidden_field.luca +0 -1
  138. data/src/templates/fields/select_field.luca +0 -8
  139. data/src/templates/fields/text_area_field.luca +0 -8
  140. data/src/templates/fields/text_field.luca +0 -17
  141. data/src/templates/sample/contents.luca +0 -1
  142. data/src/templates/sample/welcome.luca +0 -1
  143. data/vendor/assets/javascripts/luca-spec-dependencies.js +0 -6135
  144. data/vendor/assets/javascripts/luca-ui-development-dependencies.js +0 -12845
data/src/define.coffee CHANGED
@@ -11,17 +11,15 @@
11
11
 
12
12
  # _.def("Luca.View").extends("Backbone.View").with the_good:"shit"
13
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
14
+ _.mixin
15
+ def: Luca.component = Luca.define = Luca.register = (componentName)-> new DefineProxy(componentName)
19
16
 
20
17
  # The define proxy chain sets up a call to Luca.extend, which is a wrapper around Luca and Backbone component class' extend function.
21
18
  class DefineProxy
22
19
  constructor:(componentName)->
23
20
  @namespace = Luca.util.namespace()
24
21
  @componentId = @componentName = componentName
22
+ @superClassName = 'Luca.View'
25
23
 
26
24
  if componentName.match(/\./)
27
25
  @namespaced = true
@@ -40,13 +38,30 @@ class DefineProxy
40
38
  extends: (@superClassName)-> @
41
39
  extend: (@superClassName)-> @
42
40
 
43
- # an alias for with, or a readability helper in multi-line definitions
44
- enhance: (properties)->
45
- return @with(properties) if properties?
41
+ triggers: (hooks...)->
42
+ _.defaults(@properties ||= {}, hooks: [])
43
+ for hook in hooks
44
+ @properties.hooks.push(hook)
45
+ @properties.hooks = _.uniq(@properties.hooks)
46
+ @
47
+
48
+ includes: (includes...)->
49
+ _.defaults(@properties ||= {}, include: [])
50
+ for include in includes
51
+ @properties.include.push(include)
52
+ @properties.include = _.uniq(@properties.include)
53
+ @
54
+
55
+ mixesIn: (mixins...)->
56
+ _.defaults(@properties ||= {}, mixins: [])
57
+ for mixin in mixins
58
+ @properties.mixins.push(mixin)
59
+ @properties.mixins = _.uniq(@properties.mixins)
46
60
  @
47
61
 
48
- # which properties, methods, etc will you be extending the base class with?
49
- with: (properties)->
62
+ defaultProperties: (properties={})->
63
+ _.defaults((@properties||={}), properties)
64
+
50
65
  at = if @namespaced
51
66
  Luca.util.resolve(@namespace, (window || global))
52
67
  else
@@ -57,7 +72,7 @@ class DefineProxy
57
72
  eval("(window||global).#{ @namespace } = {}")
58
73
  at = Luca.util.resolve(@namespace,(window || global))
59
74
 
60
- at[@componentId] = Luca.extend(@superClassName,@componentName, properties)
75
+ at[@componentId] = Luca.extend(@superClassName,@componentName, @properties)
61
76
 
62
77
  if Luca.autoRegister is true
63
78
  componentType = "view" if Luca.isViewPrototype( at[@componentId] )
@@ -70,10 +85,17 @@ class DefineProxy
70
85
  componentType = "model" if Luca.isModelPrototype( at[@componentId] )
71
86
 
72
87
  # automatically register this with the component registry
73
- Luca.register( _.string.underscored(@componentId), @componentName, componentType)
88
+ Luca.registerComponent( _.string.underscored(@componentId), @componentName, componentType)
74
89
 
75
90
  at[@componentId]
76
91
 
92
+ # Aliases for the mixin definition
93
+ DefineProxy::behavesAs = DefineProxy::uses = DefineProxy::mixesIn
94
+
95
+ # Aliases for the final call on the define proxy
96
+ DefineProxy::defines = DefineProxy::defaults = DefineProxy::exports = DefineProxy::defaultProperties
97
+ DefineProxy::defaultsTo = DefineProxy::enhance = DefineProxy::with = DefineProxy::defaultProperties
98
+
77
99
  # The last method of the DefineProxy chain is always going to result in
78
100
  # a call to Luca.extend. Luca.extend wraps the call to Luca.View.extend,
79
101
  # or Backbone.Collection.extend, and accepts the names of the extending,
@@ -83,8 +105,10 @@ class DefineProxy
83
105
  Luca.extend = (superClassName, childName, properties={})->
84
106
  superClass = Luca.util.resolve( superClassName, (window || global) )
85
107
 
108
+ superClass.__initializers ||= []
109
+
86
110
  unless _.isFunction(superClass?.extend)
87
- throw "#{ superClassName } is not a valid component to extend from"
111
+ throw "Error defining #{ childName }. #{ superClassName } is not a valid component to extend from"
88
112
 
89
113
  properties.displayName = childName
90
114
 
@@ -92,7 +116,10 @@ Luca.extend = (superClassName, childName, properties={})->
92
116
  superClass.displayName ||= superClassName
93
117
  superClass
94
118
 
95
- properties._super = (method, context, args)->
119
+ properties._super = (method, context=@, args=[])->
120
+ # protect against a stack too deep error in weird cases
121
+ # TODO: debug this better
122
+
96
123
  @_superClass().prototype[method]?.apply(context, args)
97
124
 
98
125
  definition = superClass.extend(properties)
@@ -100,11 +127,56 @@ Luca.extend = (superClassName, childName, properties={})->
100
127
  # _.def("MyView").extends("View").with
101
128
  # include: ['Luca.Events']
102
129
  if _.isArray( properties?.include )
103
- for mixin in properties.include
104
- mixin = Luca.util.resolve(mixin) if _.isString(mixin)
105
- _.extend(definition::, mixin)
130
+ for include in properties.include
131
+ include = Luca.util.resolve(include) if _.isString(include)
132
+ _.extend(definition::, include)
106
133
 
107
134
  definition
108
135
 
109
- _.mixin
110
- def: Luca.define
136
+
137
+ Luca.mixin = (mixinName)->
138
+ namespace = _( Luca.mixin.namespaces ).detect (space)->
139
+ Luca.util.resolve(space)?[ mixinName ]?
140
+
141
+ namespace ||= "Luca.modules"
142
+
143
+ resolved = Luca.util.resolve(namespace)[ mixinName ]
144
+
145
+ console.log "Could not find #{ mixinName } in ", Luca.mixin.namespaces unless resolved?
146
+
147
+ resolved
148
+
149
+ Luca.mixin.namespaces = [
150
+ "Luca.modules"
151
+ ]
152
+
153
+ Luca.mixin.namespace = (namespace)->
154
+ Luca.mixin.namespaces.push(namespace)
155
+ Luca.mixin.namespaces = _( Luca.mixin.namespaces ).uniq()
156
+
157
+ # Luca.decorate('Luca.View').with('Luca.modules.MyCustomMixin')
158
+ Luca.decorate = (componentPrototype)->
159
+ componentPrototype = Luca.util.resolve(componentPrototype).prototype if _.isString(componentPrototype)
160
+
161
+ return with: (mixin)->
162
+ mixinDefinition = Luca.mixin(mixin)
163
+
164
+ mixinPrivates = _( mixinDefinition ).chain().keys().select (key)->
165
+ "#{ key }".match(/^__/)
166
+
167
+ sanitized = _( mixinDefinition ).omit( mixinPrivates.value() )
168
+
169
+ _.extend(componentPrototype, sanitized)
170
+
171
+ # When a mixin is included, we may want to do things
172
+ mixinDefinition?.__included?.call(mixinDefinition, mixin)
173
+
174
+ superclassMixins = componentPrototype._superClass()::mixins
175
+
176
+ componentPrototype.mixins ||= []
177
+ componentPrototype.mixins.push( mixin )
178
+ componentPrototype.mixins = componentPrototype.mixins.concat( superclassMixins )
179
+
180
+ componentPrototype.mixins = _( componentPrototype.mixins ).chain().uniq().compact().value()
181
+
182
+ componentPrototype
data/src/framework.coffee CHANGED
@@ -19,7 +19,7 @@
19
19
  return fallback()
20
20
 
21
21
  _.extend Luca,
22
- VERSION: "0.9.4"
22
+ VERSION: "0.9.6"
23
23
  core: {}
24
24
  containers: {}
25
25
  components: {}
@@ -28,27 +28,30 @@ _.extend Luca,
28
28
  fields: {}
29
29
  registry:{}
30
30
  options: {}
31
+ config: {}
31
32
 
32
33
  # for triggering / binding to component definitions
33
34
  _.extend Luca, Backbone.Events
34
35
 
35
36
  # When using Luca.define() should we automatically register
36
37
  # the component with the registry?
37
- Luca.autoRegister = true
38
+ Luca.autoRegister = Luca.config.autoRegister = true
38
39
 
39
40
  # if developmentMode is true, you have access to some neat development tools
40
- Luca.developmentMode = false
41
+ Luca.developmentMode = Luca.config.developmentMode = false
41
42
 
42
43
  # The Global Observer is very helpful in development
43
44
  # it observes every event triggered on every view, collection, model
44
45
  # and allows you to inspect / respond to them. Use in production
45
46
  # may have performance impacts which has not been tested
46
- Luca.enableGlobalObserver = false
47
+ Luca.enableGlobalObserver = Luca.config.enableGlobalObserver = false
47
48
 
48
49
  # let's use the Twitter 2.0 Bootstrap Framework
49
50
  # for what it is best at, and not try to solve this
50
51
  # problem on our own!
51
- Luca.enableBootstrap = true
52
+ Luca.enableBootstrap = Luca.config.enableBootstrap = true
53
+
54
+ Luca.config.enhancedViewProperties = true
52
55
 
53
56
  Luca.keys =
54
57
  ENTER: 13
@@ -66,9 +69,8 @@ Luca.keyMap = _( Luca.keys ).inject (memo, value, symbol)->
66
69
  memo
67
70
  , {}
68
71
 
69
- Luca.find = ()->
70
- # TODO Implement
71
- undefined
72
+ Luca.find = (el)->
73
+ Luca( $(el).data('luca-id') )
72
74
 
73
75
  Luca.supportsEvents = Luca.supportsBackboneEvents = (obj)->
74
76
  Luca.isComponent(obj) or (_.isFunction( obj?.trigger ) or _.isFunction(obj?.bind))
data/src/index.coffee CHANGED
@@ -0,0 +1,23 @@
1
+ #= require ./util
2
+ #= require_tree ./plugins
3
+ #= require ./define
4
+
5
+ #= require_tree ./modules
6
+
7
+ #= require ./core/registry
8
+ #= require ./core/observer
9
+ #= require ./core/view
10
+ #= require ./core/model
11
+ #= require ./core/collection
12
+ #= require ./core/panel
13
+ #= require ./core/field
14
+ #= require ./core/container
15
+
16
+ #= require_tree ./managers
17
+
18
+ #= require ./containers/split_view
19
+ #= require ./containers/column_view
20
+ #= require_tree ./containers
21
+
22
+ #= require ./components/template
23
+ #= require_tree ./components
@@ -45,7 +45,11 @@ class Luca.CollectionManager
45
45
  CollectionClass ||= guessCollectionClass.call(@, key)
46
46
  collectionOptions.name = "" if collectionOptions.private
47
47
 
48
- collection = new CollectionClass(initialModels,collectionOptions)
48
+ try
49
+ collection = new CollectionClass(initialModels,collectionOptions)
50
+ catch e
51
+ console.log "Error creating collection", CollectionClass, collectionOptions, key
52
+ throw(e)
49
53
 
50
54
  @add(key, collection)
51
55
 
@@ -97,9 +101,23 @@ class Luca.CollectionManager
97
101
  private: (key, collectionOptions={}, initialModels=[])->
98
102
  @create(key,collectionOptions,initialModels,true)
99
103
 
104
+ #### Helpers
105
+
106
+ Luca.CollectionManager.isRunning = ()->
107
+ _.isEmpty( Luca.CollectionManager.instances ) isnt true
108
+
100
109
  Luca.CollectionManager.destroyAll = ()->
101
110
  Luca.CollectionManager.instances = {}
102
111
 
112
+ Luca.CollectionManager.loadCollectionsByName = (set, callback)->
113
+ for name in set
114
+ collection = @getOrCreate(name)
115
+ collection.once "reset", ()->
116
+ callback(collection)
117
+ collection.fetch()
118
+
119
+
120
+ #### Private Methods
103
121
  guessCollectionClass = (key)->
104
122
  classified = Luca.util.classify( key )
105
123
  # support our naming convention of Books
@@ -120,16 +138,13 @@ guessCollectionClass = (key)->
120
138
  loadInitialCollections = ()->
121
139
  collectionDidLoad = (collection) =>
122
140
  current = @state.get("loaded_collections_count")
123
-
124
141
  @state.set("loaded_collections_count", current + 1)
125
142
  @trigger "collection_loaded", collection.name
126
143
  collection.unbind "reset"
127
144
 
128
- _(@initialCollections).each (name) =>
129
- collection = @getOrCreate(name)
130
- collection.once "reset", ()->
131
- collectionDidLoad(collection)
132
- collection.fetch()
145
+ set = @initialCollections
146
+ Luca.CollectionManager.loadCollectionsByName.call(@, set, collectionDidLoad)
147
+
133
148
 
134
149
  handleInitialCollections = ()->
135
150
  @state.set({loaded_collections_count: 0, collections_count: @initialCollections.length })
@@ -140,4 +155,5 @@ handleInitialCollections = ()->
140
155
 
141
156
  loadInitialCollections.call(@)
142
157
 
143
- @
158
+ @initialCollectionsLoadedu
159
+ @
@@ -0,0 +1,19 @@
1
+ Luca.modules.ApplicationEventBindings =
2
+ __initializer: ()->
3
+ return if _.isEmpty(@applicationEvents)
4
+
5
+ app = @app
6
+
7
+ if _.isString( app ) or _.isUndefined( app )
8
+ app = Luca.Application?.get?(app)
9
+
10
+ unless Luca.supportsEvents( app )
11
+ throw "Error binding to the application object on #{ @name || @cid }"
12
+
13
+ for eventTrigger, handler in @applicationEvents
14
+ handler = @[handler] if _.isString(handler)
15
+
16
+ unless _.isFunction(handler)
17
+ throw "Error registering application event #{ eventTrigger } on #{ @name || @cid }"
18
+
19
+ app.on(eventTrigger, handler)
@@ -0,0 +1,26 @@
1
+ Luca.modules.CollectionEventBindings =
2
+ __initializer: ()->
3
+ return if _.isEmpty( @collectionEvents )
4
+
5
+ manager = @collectionManager || Luca.CollectionManager.get()
6
+
7
+ for signature, handler of @collectionEvents
8
+ [key,eventTrigger] = signature.split(" ")
9
+
10
+ collection = manager.getOrCreate( key )
11
+
12
+ if !collection
13
+ throw "Could not find collection specified by #{ key }"
14
+
15
+ if _.isString(handler)
16
+ handler = @[handler]
17
+
18
+ unless _.isFunction(handler)
19
+ throw "invalid collectionEvents configuration"
20
+
21
+ try
22
+ collection.on(eventTrigger, handler, collection)
23
+ catch e
24
+ console.log "Error Binding To Collection in registerCollectionEvents", @
25
+ throw e
26
+
@@ -1,4 +1,6 @@
1
- # TODO THis module is going to be deprecated as it has been gradually gut over time
1
+ # TODO
2
+ #
3
+ # This is horrendous code. I need to replace it ASAP
2
4
  Luca.modules.Deferrable =
3
5
  configure_collection: (setAsDeferrable=true)->
4
6
  return unless @collection
@@ -0,0 +1,49 @@
1
+ Luca.modules.DomHelpers =
2
+ __initializer: ()->
3
+ additionalClasses = _( @additionalClassNames || [] ).clone()
4
+
5
+ @$wrap( @wrapperClass ) if @wrapperClass?
6
+
7
+ if _.isString additionalClasses
8
+ additionalClasses = additionalClasses.split(" ")
9
+
10
+ if @gridSpan
11
+ additionalClasses.push "span#{ @gridSpan }"
12
+
13
+ if @gridOffset
14
+ additionalClasses.push "offset#{ @gridOffset }"
15
+
16
+ if @gridRowFluid
17
+ additionalClasses.push "row-fluid"
18
+
19
+ if @gridRow
20
+ additionalClasses.push "row"
21
+
22
+ return unless additionalClasses?
23
+
24
+ for additional in additionalClasses
25
+ @$el.addClass( additional )
26
+
27
+ $wrap: (wrapper)->
28
+ if _.isString(wrapper) and not wrapper.match(/[<>]/)
29
+ wrapper = @make("div",class:wrapper)
30
+
31
+ @$el.wrap( wrapper )
32
+
33
+ $template: (template, variables={})->
34
+ @$el.html( Luca.template(template,variables) )
35
+
36
+ $html: (content)->
37
+ @$el.html( content )
38
+
39
+ $append: (content)->
40
+ @$el.append( content )
41
+
42
+ $attach: ()->
43
+ @$container().append( @el )
44
+
45
+ $bodyEl: ()->
46
+ @$el
47
+
48
+ $container: ()->
49
+ $(@container)
@@ -0,0 +1,23 @@
1
+ Luca.modules.EnhancedProperties =
2
+ __initializer: ()->
3
+ return unless Luca.config.enhancedViewProperties is true
4
+
5
+ # The @collection property.
6
+ #
7
+ # If the @collection property is a string, then upon initialization
8
+ # of the view, that @collection property will be swapped out
9
+ # with the instance of the collection of that name in the main
10
+ # Luca.CollectionManager
11
+ if _.isString(@collection) and Luca.CollectionManager.get()
12
+ @collection = Luca.CollectionManager.get().getOrCreate(@collection)
13
+
14
+ # The @template property.
15
+ #
16
+ # For simple views which only need a template, you can specify the
17
+ # template by its name, and we will render it for you.
18
+ if @template?
19
+ @$template(@template, @)
20
+
21
+ # The @collectionManager property is also configurable by string
22
+ if _.isString( @collectionManager )
23
+ @collectionManager = Luca.CollectionManager.get( @collectionManager )
@@ -0,0 +1,60 @@
1
+ Luca.modules.Filterable =
2
+ __included: (component, module)->
3
+ _.extend(Luca.Collection::, __filters:{})
4
+
5
+ __initializer: (component, module)->
6
+ return if @filterable is false or not Luca.isBackboneCollection(@collection)
7
+
8
+ @getCollection ||= ()-> @collection
9
+
10
+ filter = @getFilterState()
11
+
12
+ filter.on "change", (state)=>
13
+ @trigger "collection:change:filter", state, @getCollection()
14
+ @trigger "refresh"
15
+
16
+ if @getQuery?
17
+ @getQuery = _.compose @getQuery, (query={})->
18
+ obj = _.clone(query)
19
+ _.extend(obj, filter.toQuery() )
20
+ else
21
+ @getQuery = ()=>
22
+ filter.toQuery()
23
+
24
+ if @getQueryOptions?
25
+ @getQueryOptions = _.compose @getQueryOptions, (options={})->
26
+ obj = _.clone(options)
27
+ _.extend(obj, filter.toOptions() )
28
+ else
29
+ @getQueryOptions = ()-> filter.toOptions()
30
+
31
+ getFilterState: ()->
32
+ @collection.__filters[ @cid ] ||= new FilterModel(@filterable)
33
+
34
+ setSortBy: (sortBy, options={})->
35
+ @getFilterState().setOption('sortBy', sortBy, options)
36
+
37
+ applyFilter: (query={}, options={})->
38
+ options = _.defaults(options, @getQueryOptions())
39
+ query = _.defaults(query, @getQuery())
40
+
41
+ silent = _( options ).delete('silent') is true
42
+
43
+ @getFilterState().set({query,options}, silent: silent)
44
+
45
+ class FilterModel extends Backbone.Model
46
+ setOption: (option, value, options)->
47
+ payload = {}
48
+ payload[option] = value
49
+ @set 'options', _.extend(@toOptions(), payload), options
50
+
51
+ setQueryOption: (option, value, options)->
52
+ payload = {}
53
+ payload[option] = value
54
+ @set 'query', _.extend(@toQuery(), payload), options
55
+
56
+ toOptions: ()->
57
+ @toJSON().options
58
+
59
+ toQuery: ()->
60
+ @toJSON().query