luca 0.9.65 → 0.9.76

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 (86) hide show
  1. data/CHANGELOG +30 -0
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +27 -0
  4. data/lib/luca/rails/version.rb +1 -1
  5. data/spec/components/controller_spec.coffee +58 -0
  6. data/spec/components/form_view_spec.coffee +4 -0
  7. data/spec/concerns/dom_helpers_spec.coffee +16 -0
  8. data/spec/{modules → concerns}/filterable_spec.coffee +0 -0
  9. data/spec/concerns/model_presenter_spec.coffee +31 -0
  10. data/spec/{modules → concerns}/paginatable_spec.coffee +0 -0
  11. data/spec/{modules → concerns}/state_model_spec.coffee +0 -0
  12. data/spec/concerns_spec.coffee +88 -0
  13. data/spec/core/container_spec.coffee +103 -6
  14. data/spec/core/field_spec.coffee +4 -0
  15. data/spec/core/model_spec.coffee +6 -1
  16. data/spec/define_spec.coffee +104 -7
  17. data/spec/framework_spec.coffee +30 -1
  18. data/spec/util_spec.coffee +24 -0
  19. data/src/components/application.coffee +62 -25
  20. data/src/components/base_toolbar.coffee +6 -4
  21. data/src/components/collection_loader_view.coffee +3 -1
  22. data/src/components/collection_view.coffee +36 -73
  23. data/src/components/controller.coffee +73 -35
  24. data/src/components/fields/button_field.coffee +20 -12
  25. data/src/components/fields/checkbox_array.coffee +8 -2
  26. data/src/components/fields/checkbox_field.coffee +18 -9
  27. data/src/components/fields/file_upload_field.coffee +5 -1
  28. data/src/components/fields/hidden_field.coffee +3 -1
  29. data/src/components/fields/label_field.coffee +4 -3
  30. data/src/components/fields/select_field.coffee +7 -8
  31. data/src/components/fields/text_area_field.coffee +3 -2
  32. data/src/components/fields/text_field.coffee +5 -4
  33. data/src/components/fields/type_ahead_field.coffee +4 -2
  34. data/src/components/form_button_toolbar.coffee +4 -1
  35. data/src/components/form_view.coffee +26 -24
  36. data/src/components/grid_view.coffee +3 -3
  37. data/src/components/multi_collection_view.coffee +6 -35
  38. data/src/components/pagination_control.coffee +1 -3
  39. data/src/components/router.coffee +2 -0
  40. data/src/components/table_view.coffee +7 -0
  41. data/src/concerns.coffee +70 -0
  42. data/src/{modules → concerns}/application_event_bindings.coffee +1 -1
  43. data/src/{modules → concerns}/collection_event_bindings.coffee +1 -1
  44. data/src/{modules → concerns}/deferrable.coffee +1 -1
  45. data/src/{modules → concerns}/dom_helpers.coffee +11 -2
  46. data/src/{modules → concerns}/enhanced_properties.coffee +1 -1
  47. data/src/{modules → concerns}/filterable.coffee +11 -11
  48. data/src/{modules → concerns}/grid_layout.coffee +1 -1
  49. data/src/{modules → concerns}/loadmaskable.coffee +1 -1
  50. data/src/{modules → concerns}/local_storage.coffee +0 -0
  51. data/src/{modules → concerns}/modal_view.coffee +1 -1
  52. data/src/concerns/model_presenter.coffee +23 -0
  53. data/src/{modules → concerns}/paginatable.coffee +9 -3
  54. data/src/concerns/query_collection_bindings.coffee +44 -0
  55. data/src/{modules → concerns}/state_model.coffee +1 -1
  56. data/src/{modules → concerns}/templating.coffee +1 -1
  57. data/src/containers/card_view.coffee +16 -9
  58. data/src/containers/tab_view.coffee +8 -11
  59. data/src/containers/viewport.coffee +3 -3
  60. data/src/core/collection.coffee +39 -28
  61. data/src/core/container.coffee +37 -15
  62. data/src/core/field.coffee +40 -39
  63. data/src/core/meta_data.coffee +93 -0
  64. data/src/core/model.coffee +18 -1
  65. data/src/core/registry.coffee +4 -3
  66. data/src/core/view.coffee +24 -30
  67. data/src/define.coffee +165 -79
  68. data/src/framework.coffee +97 -21
  69. data/src/index.coffee +4 -2
  70. data/src/managers/collection_manager.coffee +7 -3
  71. data/src/stylesheets/components/checkbox_array.scss +1 -1
  72. data/src/stylesheets/components/form_view.scss +5 -5
  73. data/src/stylesheets/components/viewport.scss +2 -1
  74. data/src/stylesheets/containers/container.scss +0 -5
  75. data/src/stylesheets/containers/tab_view.scss +5 -5
  76. data/src/templates/fields/text_area_field.jst.ejs +1 -1
  77. data/src/templates/fields/text_field.jst.ejs +1 -1
  78. data/src/util.coffee +47 -0
  79. data/vendor/assets/javascripts/luca-ui-full.js +1279 -494
  80. data/vendor/assets/javascripts/luca-ui-full.min.js +5 -5
  81. data/vendor/assets/javascripts/luca-ui-templates.js +2 -2
  82. data/vendor/assets/javascripts/luca-ui.js +1279 -494
  83. data/vendor/assets/javascripts/luca-ui.min.js +5 -4
  84. data/vendor/assets/stylesheets/luca-ui.css +15 -15
  85. metadata +27 -20
  86. data/spec/mixin_spec.coffee +0 -49
data/src/framework.coffee CHANGED
@@ -1,13 +1,22 @@
1
1
  # the Luca() browser utility function is meant to be a smart wrapper around various
2
2
  # types of input which will return what the developer would expect given the
3
3
  # context it is used.
4
- (window || global).Luca = (payload, args...)->
4
+ lucaUtilityHelper = (payload, args...)->
5
+ unless payload?
6
+ return _( Luca.Application.instances ).values()?[0]
7
+
5
8
  if _.isString(payload) and result = Luca.cache(payload)
6
9
  return result
7
10
 
8
11
  if _.isString(payload) and result = Luca.find(payload)
9
12
  return result
10
13
 
14
+ if _.isString(payload) and result = Luca.registry.find(payload)
15
+ return result
16
+
17
+ if payload instanceof jQuery and result = Luca.find(payload)
18
+ return result
19
+
11
20
  if _.isObject(payload) and payload.ctype?
12
21
  return Luca.util.lazyComponent( payload )
13
22
 
@@ -18,21 +27,31 @@
18
27
  if _.isFunction( fallback = _(args).last() )
19
28
  return fallback()
20
29
 
30
+ (window || global).Luca = ()-> lucaUtilityHelper.apply(@, arguments)
31
+
21
32
  _.extend Luca,
22
- VERSION: "0.9.65"
33
+ VERSION: "0.9.76"
23
34
  core: {}
35
+ collections: {}
24
36
  containers: {}
25
37
  components: {}
26
- modules: {}
38
+ models: {}
39
+ concerns: {}
27
40
  util: {}
28
41
  fields: {}
29
42
  registry:{}
30
43
  options: {}
31
44
  config: {}
45
+ getHelper: ()->
46
+ ()-> lucaUtilityHelper.apply(@, arguments)
32
47
 
33
48
  # for triggering / binding to component definitions
34
49
  _.extend Luca, Backbone.Events
35
50
 
51
+ Luca.config.maintainStyleHierarchy = true
52
+ Luca.config.maintainClassHierarchy = true
53
+ Luca.config.autoApplyClassHierarchyAsCssClasses = true
54
+
36
55
  # When using Luca.define() should we automatically register
37
56
  # the component with the registry?
38
57
  Luca.autoRegister = Luca.config.autoRegister = true
@@ -49,11 +68,11 @@ Luca.enableGlobalObserver = Luca.config.enableGlobalObserver = false
49
68
  # let's use the Twitter 2.0 Bootstrap Framework
50
69
  # for what it is best at, and not try to solve this
51
70
  # problem on our own!
52
- Luca.enableBootstrap = Luca.config.enableBootstrap = true
71
+ Luca.config.enableBoostrap = Luca.config.enableBootstrap = true
53
72
 
54
73
  Luca.config.enhancedViewProperties = true
55
74
 
56
- Luca.keys =
75
+ Luca.keys = Luca.config.keys =
57
76
  ENTER: 13
58
77
  ESCAPE: 27
59
78
  KEYLEFT: 37
@@ -64,11 +83,69 @@ Luca.keys =
64
83
  FORWARDSLASH: 191
65
84
 
66
85
  # build a reverse map
67
- Luca.keyMap = _( Luca.keys ).inject (memo, value, symbol)->
86
+ Luca.keyMap = Luca.config.keyMap = _( Luca.keys ).inject (memo, value, symbol)->
68
87
  memo[value] = symbol.toLowerCase()
69
88
  memo
70
89
  , {}
71
90
 
91
+ Luca.config.showWarnings = true
92
+
93
+ Luca.setupCollectionSpace = (options={})->
94
+ {baseParams, modelBootstrap} = options
95
+
96
+ if baseParams?
97
+ Luca.Collection.baseParams( baseParams )
98
+ else
99
+ Luca.warn('You should remember to set the base params for Luca.Collection class. You can do this by defining a property or function on Luca.config.baseParams')
100
+
101
+ if modelBootstrap?
102
+ Luca.Collection.bootstrap( modelBootstrap )
103
+ else
104
+ Luca.warn("You should remember to set the model bootstrap location for Luca.Collection. You can do this by defining a property or function on Luca.config.modelBootstrap")
105
+
106
+ # Creates a basic Namespace for you to begin defining
107
+ # your application and all of its components.
108
+ Luca.initialize = (namespace, options={})->
109
+ defaults =
110
+ views: {}
111
+ collections: {}
112
+ models: {}
113
+ components: {}
114
+ lib: {}
115
+ util: {}
116
+ concerns: {}
117
+ register: ()->
118
+ Luca.register.apply(@, arguments)
119
+ onReady: ()->
120
+ Luca.onReady.apply(@, arguments)
121
+ getApplication: ()->
122
+ Luca.getApplication?.apply(@, arguments)
123
+ getCollectionManager: ()->
124
+ Luca.CollectionManager.get?.apply(@, arguments)
125
+
126
+
127
+ object = {}
128
+ object[ namespace ] = _.extend(Luca.getHelper(), defaults)
129
+
130
+ _.extend(Luca.config, options)
131
+ _.extend (window || global), object
132
+
133
+ Luca.concern.namespace "#{ namespace }.concerns"
134
+ Luca.registry.namespace "#{ namespace }.views"
135
+ Luca.Collection.namespace "#{ namespace }.collections"
136
+
137
+ Luca.on "ready", ()->
138
+ Luca.define.close()
139
+ Luca.setupCollectionSpace(options)
140
+
141
+ Luca.onReady = (callback)->
142
+ Luca.trigger("ready")
143
+
144
+ $ -> callback.apply(@, arguments)
145
+
146
+ Luca.warn = (message)->
147
+ console.log(message) if Luca.config.showWarnings is true
148
+
72
149
  Luca.find = (el)->
73
150
  Luca( $(el).data('luca-id') )
74
151
 
@@ -106,7 +183,7 @@ Luca.isCollectionPrototype = (obj)->
106
183
  obj? and obj::? and !Luca.isModelPrototype(obj) and obj::reset? and obj::select? and obj::reject?
107
184
 
108
185
  Luca.inheritanceChain = (obj)->
109
- _( Luca.parentClasses(obj) ).map (className)-> Luca.util.resolve(className)
186
+ Luca.parentClasses(obj)
110
187
 
111
188
  Luca.parentClasses = (obj)->
112
189
  list = []
@@ -114,26 +191,22 @@ Luca.parentClasses = (obj)->
114
191
  if _.isString(obj)
115
192
  obj = Luca.util.resolve(obj)
116
193
 
117
- list.push( obj.displayName || obj::?.displayName || Luca.parentClass(obj) )
118
-
119
- classes = until not Luca.parentClass(obj)?
120
- obj = Luca.parentClass(obj)
121
-
122
- list = list.concat(classes)
194
+ metaData = obj.componentMetaData?()
195
+ metaData ||= obj::componentMetaData?()
123
196
 
124
- _.uniq list
125
-
126
- Luca.parentClass = (obj)->
127
- list = []
197
+ list = metaData?.classHierarchy() || [obj.displayName || obj::displayName]
128
198
 
199
+ Luca.parentClass = (obj, resolve=true)->
129
200
  if _.isString( obj )
130
201
  obj = Luca.util.resolve(obj)
131
202
 
132
- if Luca.isComponent(obj)
133
- obj.displayName
203
+ parent = obj.componentMetaData?()?.meta["super class name"]
204
+ parent ||= obj::componentMetaData?()?.meta["super class name"]
205
+
206
+ parent || obj.displayName || obj.prototype?.displayName
207
+
208
+ if resolve then Luca.util.resolve(parent) else parent
134
209
 
135
- else if Luca.isComponentPrototype(obj)
136
- obj::_superClass?()?.displayName
137
210
 
138
211
  # This is a convenience method for accessing the templates
139
212
  # available to the client side app, either the ones which ship with Luca
@@ -191,6 +264,9 @@ UnderscoreExtensions =
191
264
  # this function will ensure a function gets called at least once
192
265
  # afrer x delay. by setting defaults, we can use this on backbone
193
266
  # view definitions
267
+ #
268
+ # Note: I am not sure if this is the same as _.debounce or not. I will need
269
+ # to look into it
194
270
  idle: (code, delay=1000)->
195
271
  delay = 0 if window.DISABLE_IDLE
196
272
  handle = undefined
data/src/index.coffee CHANGED
@@ -1,10 +1,12 @@
1
1
  #= require ./util
2
2
  #= require_tree ./plugins
3
+ #= require ./concerns
3
4
  #= require ./define
4
5
 
5
- #= require_tree ./modules
6
+ #= require_tree ./concerns
6
7
 
7
8
  #= require ./core/registry
9
+ #= require ./core/meta_data
8
10
  #= require ./core/observer
9
11
  #= require ./core/view
10
12
  #= require ./core/model
@@ -20,4 +22,4 @@
20
22
  #= require_tree ./containers
21
23
 
22
24
  #= require ./components/template
23
- #= require_tree ./components
25
+ #= require_tree ./components
@@ -1,8 +1,6 @@
1
1
  class Luca.CollectionManager
2
2
  name: "primary"
3
3
 
4
- collectionNamespace: Luca.Collection.namespace
5
-
6
4
  __collections: {}
7
5
 
8
6
  relayEvents: true
@@ -15,6 +13,8 @@ class Luca.CollectionManager
15
13
  if existing = Luca.CollectionManager.get?(@name)
16
14
  throw 'Attempt to create a collection manager with a name which already exists'
17
15
 
16
+ @collectionNamespace ||= Luca.util.read( Luca.Collection.namespace )
17
+
18
18
  Luca.CollectionManager.instances ||= {}
19
19
 
20
20
  _.extend @, Backbone.Events
@@ -116,12 +116,16 @@ Luca.CollectionManager.loadCollectionsByName = (set, callback)->
116
116
  callback(collection)
117
117
  collection.fetch()
118
118
 
119
-
120
119
  #### Private Methods
121
120
  guessCollectionClass = (key)->
122
121
  classified = Luca.util.classify( key )
122
+
123
+ if _.isString( @collectionNamespace )
124
+ @collectionNamespace = Luca.util.resolve(@collectionNamespace)
125
+
123
126
  # support our naming convention of Books
124
127
  guess = (@collectionNamespace || (window || global) )[ classified ]
128
+
125
129
  # support naming covention like BooksCollection
126
130
  guess ||= (@collectionNamespace || (window || global) )[ "#{classified}Collection" ]
127
131
 
@@ -1,4 +1,4 @@
1
- .luca-ui-checkbox-array {
1
+ .luca-ui-checkbox-array, .luca-checkbox-array {
2
2
  input.array-checkbox {
3
3
  display: inline-block;
4
4
  }
@@ -1,4 +1,4 @@
1
- .luca-ui-form-view-wrapper {
1
+ .luca-form-view {
2
2
  width: 100%;
3
3
  float: left;
4
4
  display: block;
@@ -7,7 +7,7 @@
7
7
  }
8
8
 
9
9
 
10
- .luca-ui-form-view {
10
+ .luca-form-view {
11
11
  .luca-ui-field {
12
12
  margin: 5px;
13
13
  padding: 5px;
@@ -19,7 +19,7 @@
19
19
  }
20
20
  }
21
21
 
22
- .luca-ui-form-view.label-align-top {
22
+ .luca-form-view.label-align-top {
23
23
  .luca-ui-field {
24
24
  label, input, select, textarea {
25
25
  margin: 5px 0px;
@@ -28,13 +28,13 @@
28
28
  }
29
29
  }
30
30
 
31
- .luca-ui-form-view.column-layout {
31
+ .luca-form-view.column-layout {
32
32
  .luca-ui-field {
33
33
  float: left;
34
34
  }
35
35
  }
36
36
 
37
- .luca-ui-form-view {
37
+ .luca-form-view {
38
38
  .toolbar-container {
39
39
  padding-right: 12px;
40
40
  }
@@ -6,7 +6,8 @@ html.luca-ui-fullscreen, body.luca-ui-fullscreen {
6
6
  .fluid-viewport-wrapper {
7
7
  padding-top:40px;
8
8
  }
9
- .luca-ui-viewport, .fullscreen-container {
9
+
10
+ .luca-viewport, .luca-ui-viewport, .fullscreen-container {
10
11
  min-height: 100%;
11
12
  height: auto !important;
12
13
  height: 100%;
@@ -1,8 +1,3 @@
1
- .luca-ui-container {}
2
-
3
- .luca-ui-card {
4
- }
5
-
6
1
  .toolbar-container {
7
2
  clear: both;
8
3
  }
@@ -1,19 +1,19 @@
1
- .luca-ui-tab-view {
1
+ .luca-tab-view {
2
2
  .luca-ui-card {
3
- .luca-ui-grid-view, .luca-ui-form-view, .luca-ui-card {
3
+ .luca-ui-grid-view, .luca-form-view, .luca-ui-card {
4
4
  overflow: hidden;
5
5
  }
6
6
  }
7
7
  }
8
8
 
9
- .luca-ui-tab-view.tabs-below, .luca-ui-tab-view.tabs-right {
9
+ .luca-tab-view.tabs-below, .luca-tab-view.tabs-right {
10
10
  .tab-selector-container {
11
11
  display: block;
12
12
  clear: both;
13
13
  }
14
14
  }
15
15
 
16
- .luca-ui-tab-view.tabs-left {
16
+ .luca-tab-view.tabs-left {
17
17
  .tab-selector-container {
18
18
  ul.nav-tabs {
19
19
  padding: 0px;
@@ -26,7 +26,7 @@
26
26
  }
27
27
  }
28
28
 
29
- .luca-ui-tab-view.tabs-right {
29
+ .luca-tab-view.tabs-right {
30
30
  .tab-selector-container {
31
31
  float: right;
32
32
  }
@@ -2,7 +2,7 @@
2
2
  <%= label %>
3
3
  </label>
4
4
  <div class="controls">
5
- <textarea name="<%= input_name %>" style="<%= inputStyles %>" ><%= input_value %></textarea>
5
+ <textarea placeholder="<%= placeHolder %>" name="<%= input_name %>" style="<%= inputStyles %>" ><%= input_value %></textarea>
6
6
  <% if(helperText) { %>
7
7
  <p class="helper-text help-block">
8
8
  <%= helperText %>
@@ -6,7 +6,7 @@
6
6
  <% if( typeof(addOn) !== "undefined" ) { %>
7
7
  <span class="add-on"><%= addOn %></span>
8
8
  <% } %>
9
- <input type="text" name="<%= input_name %>" style="<%= inputStyles %>" value="<%= input_value %>" />
9
+ <input type="text" placeholder="<%= placeHolder %>" name="<%= input_name %>" style="<%= inputStyles %>" value="<%= input_value %>" />
10
10
  <% if(helperText) { %>
11
11
  <p class="helper-text help-block">
12
12
  <%= helperText %>
data/src/util.coffee CHANGED
@@ -36,6 +36,16 @@ Luca.util.hook = (eventId="")->
36
36
  parts = _( parts ).map (p)-> _.string.capitalize(p)
37
37
  fn = prefix + parts.join('')
38
38
 
39
+ Luca.util.toCssClass = (componentName, exclusions...)->
40
+ parts = componentName.split('.')
41
+
42
+ transformed = for part in parts when _( exclusions ).indexOf(part) is -1
43
+ part = _.str.underscored(part)
44
+ part = part.replace(/_/g,'-')
45
+ part
46
+
47
+ transformed.join '-'
48
+
39
49
  Luca.util.isIE = ()->
40
50
  try
41
51
  Object.defineProperty({}, '', {})
@@ -118,3 +128,40 @@ Luca.util.badge = (contents="", type, baseClass="badge")->
118
128
  cssClass += " #{ baseClass }-#{ type }" if type?
119
129
  Luca.util.make("span",{class:cssClass},contents)
120
130
 
131
+ Luca.util.setupHooks = (set)->
132
+ set ||= @hooks
133
+
134
+ _(set).each (eventId)=>
135
+ fn = Luca.util.hook( eventId )
136
+
137
+ callback = ()->
138
+ @[fn]?.apply @, arguments
139
+
140
+ callback = _.once(callback) if eventId?.match(/once:/)
141
+
142
+ @on eventId, callback, @
143
+
144
+ Luca.util.setupHooksAdvanced = (set)->
145
+ set ||= @hooks
146
+
147
+ _(set).each (eventId)=>
148
+ hookSetup = @[ Luca.util.hook( eventId ) ]
149
+
150
+ unless _.isArray(hookSetup)
151
+ hookSetup = [hookSetup]
152
+
153
+ for entry in hookSetup
154
+ fn = if _.isString(entry)
155
+ @[ entry ]
156
+
157
+ if _.isFunction(entry)
158
+ fn = entry
159
+
160
+ callback = ()->
161
+ @[fn]?.apply @, arguments
162
+
163
+ if eventId?.match(/once:/)
164
+ callback = _.once(callback)
165
+
166
+ @on eventId, callback, @
167
+
@@ -76,14 +76,21 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
76
76
  !function(a){a(function(){a.support.transition=function(){var a=function(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",msTransition:"MSTransitionEnd",transition:"transitionend"},c;for(c in b)if(a.style[c]!==undefined)return b[c]}();return a&&{end:a}}()})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('<div class="modal-backdrop '+d+'" />').appendTo(document.body),this.options.backdrop!="static"&&this.$backdrop.click(a.proxy(this.hide,this)),e&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),e?this.$backdrop.one(a.support.transition.end,b):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,a.proxy(f,this)):f.call(this)):b&&b()}function f(){this.$backdrop.remove(),this.$backdrop=null}function g(){var b=this;this.isShown&&this.options.keyboard?a(document).on("keyup.dismiss.modal",function(a){a.which==27&&b.hide()}):this.isShown||a(document).off("keyup.dismiss.modal")}var b=function(b,c){this.options=c,this.$element=a(b).delegate('[data-dismiss="modal"]',"click.dismiss.modal",a.proxy(this.hide,this))};b.prototype={constructor:b,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var b=this,c=a.Event("show");this.$element.trigger(c);if(this.isShown||c.isDefaultPrevented())return;a("body").addClass("modal-open"),this.isShown=!0,g.call(this),e.call(this,function(){var c=a.support.transition&&b.$element.hasClass("fade");b.$element.parent().length||b.$element.appendTo(document.body),b.$element.show(),c&&b.$element[0].offsetWidth,b.$element.addClass("in"),c?b.$element.one(a.support.transition.end,function(){b.$element.trigger("shown")}):b.$element.trigger("shown")})},hide:function(b){b&&b.preventDefault();var e=this;b=a.Event("hide"),this.$element.trigger(b);if(!this.isShown||b.isDefaultPrevented())return;this.isShown=!1,a("body").removeClass("modal-open"),g.call(this),this.$element.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?c.call(this):d.call(this)}},a.fn.modal=function(c){return this.each(function(){var d=a(this),e=d.data("modal"),f=a.extend({},a.fn.modal.defaults,d.data(),typeof c=="object"&&c);e||d.data("modal",e=new b(this,f)),typeof c=="string"?e[c]():f.show&&e.show()})},a.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},a.fn.modal.Constructor=b,a(function(){a("body").on("click.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("modal")?"toggle":a.extend({},e.data(),c.data());b.preventDefault(),e.modal(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e,f,g;if(c.is(".disabled, :disabled"))return;return f=c.attr("data-target"),f||(f=c.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,"")),e=a(f),e.length||(e=c.parent()),g=e.hasClass("open"),d(),g||e.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown",".dropdown form",function(a){a.stopPropagation()}).on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){var b=function(a,b){this.init("tooltip",a,b)};b.prototype={constructor:b,init:function(b,c,d){var e,f;this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.enabled=!0,this.options.trigger!="manual"&&(e=this.options.trigger=="hover"?"mouseenter":"focus",f=this.options.trigger=="hover"?"mouseleave":"blur",this.$element.on(e,this.options.selector,a.proxy(this.enter,this)),this.$element.on(f,this.options.selector,a.proxy(this.leave,this))),this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(b){return b=a.extend({},a.fn[this.type].defaults,b,this.$element.data()),b.delay&&typeof b.delay=="number"&&(b.delay={show:b.delay,hide:b.delay}),b},enter:function(b){var c=a(b.currentTarget)[this.type](this._options).data(this.type);if(!c.options.delay||!c.options.delay.show)return c.show();clearTimeout(this.timeout),c.hoverState="in",this.timeout=setTimeout(function(){c.hoverState=="in"&&c.show()},c.options.delay.show)},leave:function(b){var c=a(b.currentTarget)[this.type](this._options).data(this.type);if(!c.options.delay||!c.options.delay.hide)return c.hide();clearTimeout(this.timeout),c.hoverState="out",this.timeout=setTimeout(function(){c.hoverState=="out"&&c.hide()},c.options.delay.hide)},show:function(){var a,b,c,d,e,f,g;if(this.hasContent()&&this.enabled){a=this.tip(),this.setContent(),this.options.animation&&a.addClass("fade"),f=typeof this.options.placement=="function"?this.options.placement.call(this,a[0],this.$element[0]):this.options.placement,b=/in/.test(f),a.remove().css({top:0,left:0,display:"block"}).appendTo(b?this.$element:document.body),c=this.getPosition(b),d=a[0].offsetWidth,e=a[0].offsetHeight;switch(b?f.split(" ")[1]:f){case"bottom":g={top:c.top+c.height,left:c.left+c.width/2-d/2};break;case"top":g={top:c.top-e,left:c.left+c.width/2-d/2};break;case"left":g={top:c.top+c.height/2-e/2,left:c.left-d};break;case"right":g={top:c.top+c.height/2-e/2,left:c.left+c.width}}a.css(g).addClass(f).addClass("in")}},isHTML:function(a){return typeof a!="string"||a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3||/^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(a)},setContent:function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.isHTML(b)?"html":"text"](b),a.removeClass("fade in top bottom left right")},hide:function(){function d(){var b=setTimeout(function(){c.off(a.support.transition.end).remove()},500);c.one(a.support.transition.end,function(){clearTimeout(b),c.remove()})}var b=this,c=this.tip();c.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d():c.remove()},fixTitle:function(){var a=this.$element;(a.attr("title")||typeof a.attr("data-original-title")!="string")&&a.attr("data-original-title",a.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(b){return a.extend({},b?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||(typeof c.title=="function"?c.title.call(b[0]):c.title),a},tip:function(){return this.$tip=this.$tip||a(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(){this[this.tip().hasClass("in")?"hide":"show"]()}},a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("tooltip"),f=typeof c=="object"&&c;e||d.data("tooltip",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.tooltip.Constructor=b,a.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover",title:"",delay:0}}(window.jQuery),!function(a){var b=function(a,b){this.init("popover",a,b)};b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype,{constructor:b,setContent:function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.isHTML(b)?"html":"text"](b),a.find(".popover-content > *")[this.isHTML(c)?"html":"text"](c),a.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var a,b=this.$element,c=this.options;return a=b.attr("data-content")||(typeof c.content=="function"?c.content.call(b[0]):c.content),a},tip:function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip}}),a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("popover"),f=typeof c=="object"&&c;e||d.data("popover",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.defaults=a.extend({},a.fn.tooltip.defaults,{placement:"right",content:"",template:'<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'})}(window.jQuery),!function(a){var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function f(){e.trigger("closed").remove()}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger(b=a.Event("close"));if(b.isDefaultPrevented())return;e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(function(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle")})})}(window.jQuery),!function(a){var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b,c,d,e;if(this.transitioning)return;b=this.dimension(),c=a.camelCase(["scroll",b].join("-")),d=this.$parent&&this.$parent.find("> .accordion-group > .in");if(d&&d.length){e=d.data("collapse");if(e&&e.transitioning)return;d.collapse("hide"),e||d.data("collapse",null)}this.$element[b](0),this.transition("addClass",a.Event("show"),"shown"),this.$element[b](this.$element[0][c])},hide:function(){var b;if(this.transitioning)return;b=this.dimension(),this.reset(this.$element[b]()),this.transition("removeClass",a.Event("hide"),"hidden"),this.$element[b](0)},reset:function(a){var b=this.dimension();return this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element[a!==null?"addClass":"removeClass"]("collapse"),this},transition:function(b,c,d){var e=this,f=function(){c.type=="show"&&e.reset(),e.transitioning=0,e.$element.trigger(d)};this.$element.trigger(c);if(c.isDefaultPrevented())return;this.transitioning=1,this.$element[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.typeahead.defaults,c),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.$menu=a(this.options.menu).appendTo("body"),this.source=this.options.source,this.shown=!1,this.listen()};b.prototype={constructor:b,select:function(){var a=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(a)).change(),this.hide()},updater:function(a){return a},show:function(){var b=a.extend({},this.$element.offset(),{height:this.$element[0].offsetHeight});return this.$menu.css({top:b.top+b.height,left:b.left}),this.$menu.show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(b){var c=this,d,e;return this.query=this.$element.val(),this.query?(d=a.grep(this.source,function(a){return c.matcher(a)}),d=this.sorter(d),d.length?this.render(d.slice(0,this.options.items)).show():this.shown?this.hide():this):this.shown?this.hide():this},matcher:function(a){return~a.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(a){var b=[],c=[],d=[],e;while(e=a.shift())e.toLowerCase().indexOf(this.query.toLowerCase())?~e.indexOf(this.query)?c.push(e):d.push(e):b.push(e);return b.concat(c,d)},highlighter:function(a){var b=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return a.replace(new RegExp("("+b+")","ig"),function(a,b){return"<strong>"+b+"</strong>"})},render:function(b){var c=this;return b=a(b).map(function(b,d){return b=a(c.options.item).attr("data-value",d),b.find("a").html(c.highlighter(d)),b[0]}),b.first().addClass("active"),this.$menu.html(b),this},next:function(b){var c=this.$menu.find(".active").removeClass("active"),d=c.next();d.length||(d=a(this.$menu.find("li")[0])),d.addClass("active")},prev:function(a){var b=this.$menu.find(".active").removeClass("active"),c=b.prev();c.length||(c=this.$menu.find("li").last()),c.addClass("active")},listen:function(){this.$element.on("blur",a.proxy(this.blur,this)).on("keypress",a.proxy(this.keypress,this)).on("keyup",a.proxy(this.keyup,this)),(a.browser.webkit||a.browser.msie)&&this.$element.on("keydown",a.proxy(this.keypress,this)),this.$menu.on("click",a.proxy(this.click,this)).on("mouseenter","li",a.proxy(this.mouseenter,this))},keyup:function(a){switch(a.keyCode){case 40:case 38:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}a.stopPropagation(),a.preventDefault()},keypress:function(a){if(!this.shown)return;switch(a.keyCode){case 9:case 13:case 27:a.preventDefault();break;case 38:if(a.type!="keydown")break;a.preventDefault(),this.prev();break;case 40:if(a.type!="keydown")break;a.preventDefault(),this.next()}a.stopPropagation()},blur:function(a){var b=this;setTimeout(function(){b.hide()},150)},click:function(a){a.stopPropagation(),a.preventDefault(),this.select()},mouseenter:function(b){this.$menu.find(".active").removeClass("active"),a(b.currentTarget).addClass("active")}},a.fn.typeahead=function(c){return this.each(function(){var d=a(this),e=d.data("typeahead"),f=typeof c=="object"&&c;e||d.data("typeahead",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>'},a.fn.typeahead.Constructor=b,a(function(){a("body").on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(b){var c=a(this);if(c.data("typeahead"))return;b.preventDefault(),c.typeahead(c.data())})})}(window.jQuery)
77
77
  ;
78
78
  (function() {
79
- var UnderscoreExtensions,
79
+ var UnderscoreExtensions, lucaUtilityHelper,
80
80
  __slice = Array.prototype.slice;
81
81
 
82
- (window || global).Luca = function() {
83
- var args, definition, fallback, inheritsFrom, payload, result;
82
+ lucaUtilityHelper = function() {
83
+ var args, definition, fallback, inheritsFrom, payload, result, _ref;
84
84
  payload = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
85
+ if (payload == null) {
86
+ return (_ref = _(Luca.Application.instances).values()) != null ? _ref[0] : void 0;
87
+ }
85
88
  if (_.isString(payload) && (result = Luca.cache(payload))) return result;
86
89
  if (_.isString(payload) && (result = Luca.find(payload))) return result;
90
+ if (_.isString(payload) && (result = Luca.registry.find(payload))) {
91
+ return result;
92
+ }
93
+ if (payload instanceof jQuery && (result = Luca.find(payload))) return result;
87
94
  if (_.isObject(payload) && (payload.ctype != null)) {
88
95
  return Luca.util.lazyComponent(payload);
89
96
  }
@@ -94,32 +101,49 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
94
101
  if (_.isFunction(fallback = _(args).last())) return fallback();
95
102
  };
96
103
 
104
+ (window || global).Luca = function() {
105
+ return lucaUtilityHelper.apply(this, arguments);
106
+ };
107
+
97
108
  _.extend(Luca, {
98
- VERSION: "0.9.65",
109
+ VERSION: "0.9.75",
99
110
  core: {},
111
+ collections: {},
100
112
  containers: {},
101
113
  components: {},
102
- modules: {},
114
+ models: {},
115
+ concerns: {},
103
116
  util: {},
104
117
  fields: {},
105
118
  registry: {},
106
119
  options: {},
107
- config: {}
120
+ config: {},
121
+ getHelper: function() {
122
+ return function() {
123
+ return lucaUtilityHelper.apply(this, arguments);
124
+ };
125
+ }
108
126
  });
109
127
 
110
128
  _.extend(Luca, Backbone.Events);
111
129
 
130
+ Luca.config.maintainStyleHierarchy = true;
131
+
132
+ Luca.config.maintainClassHierarchy = true;
133
+
134
+ Luca.config.autoApplyClassHierarchyAsCssClasses = true;
135
+
112
136
  Luca.autoRegister = Luca.config.autoRegister = true;
113
137
 
114
138
  Luca.developmentMode = Luca.config.developmentMode = false;
115
139
 
116
140
  Luca.enableGlobalObserver = Luca.config.enableGlobalObserver = false;
117
141
 
118
- Luca.enableBootstrap = Luca.config.enableBootstrap = true;
142
+ Luca.config.enableBoostrap = Luca.config.enableBootstrap = true;
119
143
 
120
144
  Luca.config.enhancedViewProperties = true;
121
145
 
122
- Luca.keys = {
146
+ Luca.keys = Luca.config.keys = {
123
147
  ENTER: 13,
124
148
  ESCAPE: 27,
125
149
  KEYLEFT: 37,
@@ -130,11 +154,79 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
130
154
  FORWARDSLASH: 191
131
155
  };
132
156
 
133
- Luca.keyMap = _(Luca.keys).inject(function(memo, value, symbol) {
157
+ Luca.keyMap = Luca.config.keyMap = _(Luca.keys).inject(function(memo, value, symbol) {
134
158
  memo[value] = symbol.toLowerCase();
135
159
  return memo;
136
160
  }, {});
137
161
 
162
+ Luca.config.showWarnings = true;
163
+
164
+ Luca.setupCollectionSpace = function(options) {
165
+ var baseParams, modelBootstrap;
166
+ if (options == null) options = {};
167
+ baseParams = options.baseParams, modelBootstrap = options.modelBootstrap;
168
+ if (baseParams != null) {
169
+ Luca.Collection.baseParams(baseParams);
170
+ } else {
171
+ Luca.warn('You should remember to set the base params for Luca.Collection class. You can do this by defining a property or function on Luca.config.baseParams');
172
+ }
173
+ if (modelBootstrap != null) {
174
+ return Luca.Collection.bootstrap(modelBootstrap);
175
+ } else {
176
+ return Luca.warn("You should remember to set the model bootstrap location for Luca.Collection. You can do this by defining a property or function on Luca.config.modelBootstrap");
177
+ }
178
+ };
179
+
180
+ Luca.initialize = function(namespace, options) {
181
+ var defaults, object;
182
+ if (options == null) options = {};
183
+ defaults = {
184
+ views: {},
185
+ collections: {},
186
+ models: {},
187
+ components: {},
188
+ lib: {},
189
+ util: {},
190
+ concerns: {},
191
+ register: function() {
192
+ return Luca.register.apply(this, arguments);
193
+ },
194
+ onReady: function() {
195
+ return Luca.onReady.apply(this, arguments);
196
+ },
197
+ getApplication: function() {
198
+ var _ref;
199
+ return (_ref = Luca.getApplication) != null ? _ref.apply(this, arguments) : void 0;
200
+ },
201
+ getCollectionManager: function() {
202
+ var _ref;
203
+ return (_ref = Luca.CollectionManager.get) != null ? _ref.apply(this, arguments) : void 0;
204
+ }
205
+ };
206
+ object = {};
207
+ object[namespace] = _.extend(Luca.getHelper(), defaults);
208
+ _.extend(Luca.config, options);
209
+ _.extend(window || global, object);
210
+ Luca.concern.namespace("" + namespace + ".concerns");
211
+ Luca.registry.namespace("" + namespace + ".views");
212
+ Luca.Collection.namespace("" + namespace + ".collections");
213
+ return Luca.on("ready", function() {
214
+ Luca.define.close();
215
+ return Luca.setupCollectionSpace(options);
216
+ });
217
+ };
218
+
219
+ Luca.onReady = function(callback) {
220
+ Luca.trigger("ready");
221
+ return $(function() {
222
+ return callback.apply(this, arguments);
223
+ });
224
+ };
225
+
226
+ Luca.warn = function(message) {
227
+ if (Luca.config.showWarnings === true) return console.log(message);
228
+ };
229
+
138
230
  Luca.find = function(el) {
139
231
  return Luca($(el).data('luca-id'));
140
232
  };
@@ -182,36 +274,29 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
182
274
  };
183
275
 
184
276
  Luca.inheritanceChain = function(obj) {
185
- return _(Luca.parentClasses(obj)).map(function(className) {
186
- return Luca.util.resolve(className);
187
- });
277
+ return Luca.parentClasses(obj);
188
278
  };
189
279
 
190
280
  Luca.parentClasses = function(obj) {
191
- var classes, list, _ref;
281
+ var list, metaData, _base;
192
282
  list = [];
193
283
  if (_.isString(obj)) obj = Luca.util.resolve(obj);
194
- list.push(obj.displayName || ((_ref = obj.prototype) != null ? _ref.displayName : void 0) || Luca.parentClass(obj));
195
- classes = (function() {
196
- var _results;
197
- _results = [];
198
- while (!!(Luca.parentClass(obj) != null)) {
199
- _results.push(obj = Luca.parentClass(obj));
200
- }
201
- return _results;
202
- })();
203
- list = list.concat(classes);
204
- return _.uniq(list);
284
+ metaData = typeof obj.componentMetaData === "function" ? obj.componentMetaData() : void 0;
285
+ metaData || (metaData = typeof (_base = obj.prototype).componentMetaData === "function" ? _base.componentMetaData() : void 0);
286
+ return list = (metaData != null ? metaData.classHierarchy() : void 0) || [obj.displayName || obj.prototype.displayName];
205
287
  };
206
288
 
207
- Luca.parentClass = function(obj) {
208
- var list, _base, _ref;
209
- list = [];
289
+ Luca.parentClass = function(obj, resolve) {
290
+ var parent, _base, _ref, _ref2, _ref3;
291
+ if (resolve == null) resolve = true;
210
292
  if (_.isString(obj)) obj = Luca.util.resolve(obj);
211
- if (Luca.isComponent(obj)) {
212
- return obj.displayName;
213
- } else if (Luca.isComponentPrototype(obj)) {
214
- return typeof (_base = obj.prototype)._superClass === "function" ? (_ref = _base._superClass()) != null ? _ref.displayName : void 0 : void 0;
293
+ parent = typeof obj.componentMetaData === "function" ? (_ref = obj.componentMetaData()) != null ? _ref.meta["super class name"] : void 0 : void 0;
294
+ parent || (parent = typeof (_base = obj.prototype).componentMetaData === "function" ? (_ref2 = _base.componentMetaData()) != null ? _ref2.meta["super class name"] : void 0 : void 0);
295
+ parent || obj.displayName || ((_ref3 = obj.prototype) != null ? _ref3.displayName : void 0);
296
+ if (resolve) {
297
+ return Luca.util.resolve(parent);
298
+ } else {
299
+ return parent;
215
300
  }
216
301
  };
217
302
 
@@ -389,11 +474,11 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
389
474
  }).call(this);
390
475
  (function() {
391
476
  this.JST || (this.JST = {});
392
- this.JST["luca-src/templates/fields/text_area_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label for="', input_id ,'">\n ', label ,'\n</label>\n<div class="controls">\n <textarea name="', input_name ,'" style="', inputStyles ,'" >', input_value ,'</textarea>\n '); if(helperText) { __p.push('\n <p class="helper-text help-block">\n ', helperText ,'\n </p>\n '); } __p.push('\n</div>\n');}return __p.join('');};
477
+ this.JST["luca-src/templates/fields/text_area_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label for="', input_id ,'">\n ', label ,'\n</label>\n<div class="controls">\n <textarea placeholder="', placeHolder ,'" name="', input_name ,'" style="', inputStyles ,'" >', input_value ,'</textarea>\n '); if(helperText) { __p.push('\n <p class="helper-text help-block">\n ', helperText ,'\n </p>\n '); } __p.push('\n</div>\n');}return __p.join('');};
393
478
  }).call(this);
394
479
  (function() {
395
480
  this.JST || (this.JST = {});
396
- this.JST["luca-src/templates/fields/text_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push(''); if(typeof(label)!=="undefined" && (typeof(hideLabel) !== "undefined" && !hideLabel) || (typeof(hideLabel)==="undefined")) {__p.push('\n<label class="control-label" for="', input_id ,'">', label ,'</label>\n'); } __p.push('\n\n<div class="controls">\n'); if( typeof(addOn) !== "undefined" ) { __p.push('\n <span class="add-on">', addOn ,'</span>\n'); } __p.push('\n<input type="text" name="', input_name ,'" style="', inputStyles ,'" value="', input_value ,'" />\n'); if(helperText) { __p.push('\n<p class="helper-text help-block">\n ', helperText ,'\n</p>\n'); } __p.push('\n\n</div>\n');}return __p.join('');};
481
+ this.JST["luca-src/templates/fields/text_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push(''); if(typeof(label)!=="undefined" && (typeof(hideLabel) !== "undefined" && !hideLabel) || (typeof(hideLabel)==="undefined")) {__p.push('\n<label class="control-label" for="', input_id ,'">', label ,'</label>\n'); } __p.push('\n\n<div class="controls">\n'); if( typeof(addOn) !== "undefined" ) { __p.push('\n <span class="add-on">', addOn ,'</span>\n'); } __p.push('\n<input type="text" placeholder="', placeHolder ,'" name="', input_name ,'" style="', inputStyles ,'" value="', input_value ,'" />\n'); if(helperText) { __p.push('\n<p class="helper-text help-block">\n ', helperText ,'\n</p>\n'); } __p.push('\n\n</div>\n');}return __p.join('');};
397
482
  }).call(this);
398
483
  (function() {
399
484
  this.JST || (this.JST = {});
@@ -451,6 +536,25 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
451
536
  return fn = prefix + parts.join('');
452
537
  };
453
538
 
539
+ Luca.util.toCssClass = function() {
540
+ var componentName, exclusions, part, parts, transformed;
541
+ componentName = arguments[0], exclusions = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
542
+ parts = componentName.split('.');
543
+ transformed = (function() {
544
+ var _i, _len, _results;
545
+ _results = [];
546
+ for (_i = 0, _len = parts.length; _i < _len; _i++) {
547
+ part = parts[_i];
548
+ if (!(_(exclusions).indexOf(part) === -1)) continue;
549
+ part = _.str.underscored(part);
550
+ part = part.replace(/_/g, '-');
551
+ _results.push(part);
552
+ }
553
+ return _results;
554
+ })();
555
+ return transformed.join('-');
556
+ };
557
+
454
558
  Luca.util.isIE = function() {
455
559
  try {
456
560
  Object.defineProperty({}, '', {});
@@ -545,6 +649,48 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
545
649
  }, contents);
546
650
  };
547
651
 
652
+ Luca.util.setupHooks = function(set) {
653
+ var _this = this;
654
+ set || (set = this.hooks);
655
+ return _(set).each(function(eventId) {
656
+ var callback, fn;
657
+ fn = Luca.util.hook(eventId);
658
+ callback = function() {
659
+ var _ref;
660
+ return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
661
+ };
662
+ if (eventId != null ? eventId.match(/once:/) : void 0) {
663
+ callback = _.once(callback);
664
+ }
665
+ return _this.on(eventId, callback, _this);
666
+ });
667
+ };
668
+
669
+ Luca.util.setupHooksAdvanced = function(set) {
670
+ var _this = this;
671
+ set || (set = this.hooks);
672
+ return _(set).each(function(eventId) {
673
+ var callback, entry, fn, hookSetup, _i, _len, _results;
674
+ hookSetup = _this[Luca.util.hook(eventId)];
675
+ if (!_.isArray(hookSetup)) hookSetup = [hookSetup];
676
+ _results = [];
677
+ for (_i = 0, _len = hookSetup.length; _i < _len; _i++) {
678
+ entry = hookSetup[_i];
679
+ fn = _.isString(entry) ? _this[entry] : void 0;
680
+ if (_.isFunction(entry)) fn = entry;
681
+ callback = function() {
682
+ var _ref;
683
+ return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
684
+ };
685
+ if (eventId != null ? eventId.match(/once:/) : void 0) {
686
+ callback = _.once(callback);
687
+ }
688
+ _results.push(_this.on(eventId, callback, _this));
689
+ }
690
+ return _results;
691
+ });
692
+ };
693
+
548
694
  }).call(this);
549
695
  (function() {
550
696
 
@@ -703,22 +849,105 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
703
849
 
704
850
  }).call(this);
705
851
  (function() {
706
- var DefineProxy,
707
- __slice = Array.prototype.slice;
708
852
 
709
- _.mixin({
710
- def: Luca.component = Luca.define = Luca.register = function(componentName) {
711
- return new DefineProxy(componentName);
853
+ Luca.concern = function(mixinName) {
854
+ var namespace, resolved;
855
+ namespace = _(Luca.concern.namespaces).detect(function(space) {
856
+ var _ref;
857
+ return ((_ref = Luca.util.resolve(space)) != null ? _ref[mixinName] : void 0) != null;
858
+ });
859
+ namespace || (namespace = "Luca.concerns");
860
+ resolved = Luca.util.resolve(namespace)[mixinName];
861
+ if (resolved == null) {
862
+ console.log("Could not find " + mixinName + " in ", Luca.concern.namespaces);
712
863
  }
713
- });
864
+ return resolved;
865
+ };
714
866
 
715
- DefineProxy = (function() {
867
+ Luca.concern.namespaces = ["Luca.concerns"];
868
+
869
+ Luca.concern.namespace = function(namespace) {
870
+ Luca.concern.namespaces.push(namespace);
871
+ return Luca.concern.namespaces = _(Luca.concern.namespaces).uniq();
872
+ };
716
873
 
717
- function DefineProxy(componentName) {
874
+ Luca.concern.setup = function() {
875
+ var module, _i, _len, _ref, _ref2, _ref3, _ref4, _results;
876
+ if (((_ref = this.concerns) != null ? _ref.length : void 0) > 0) {
877
+ _ref2 = this.concerns;
878
+ _results = [];
879
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
880
+ module = _ref2[_i];
881
+ _results.push((_ref3 = Luca.concern(module)) != null ? (_ref4 = _ref3.__initializer) != null ? _ref4.call(this, this, module) : void 0 : void 0);
882
+ }
883
+ return _results;
884
+ }
885
+ };
886
+
887
+ Luca.decorate = function(target) {
888
+ var componentClass, componentName, componentPrototype;
889
+ try {
890
+ if (_.isString(target)) {
891
+ componentName = target;
892
+ componentClass = Luca.util.resolve(componentName);
893
+ }
894
+ if (_.isFunction(target)) componentClass = target;
895
+ componentPrototype = componentClass.prototype;
896
+ componentName = componentName || componentClass.displayName;
897
+ componentName || (componentName = componentPrototype.displayName);
898
+ } catch (e) {
899
+ console.log(e.message);
900
+ console.log(e.stack);
901
+ console.log("Error calling Luca.decorate on ", componentClass, componentPrototype, componentName);
902
+ throw e;
903
+ }
904
+ return {
905
+ "with": function(mixinName) {
906
+ var fn, method, mixinDefinition, mixinPrivates, sanitized, superclassMixins, _ref;
907
+ mixinDefinition = Luca.concern(mixinName);
908
+ mixinDefinition.__displayName || (mixinDefinition.__displayName = mixinName);
909
+ mixinPrivates = _(mixinDefinition).chain().keys().select(function(key) {
910
+ return ("" + key).match(/^__/) || key === "classMethods";
911
+ });
912
+ sanitized = _(mixinDefinition).omit(mixinPrivates.value());
913
+ _.extend(componentPrototype, sanitized);
914
+ if (mixinDefinition.classMethods != null) {
915
+ _ref = mixinDefinition.classMethods;
916
+ for (method in _ref) {
917
+ fn = _ref[method];
918
+ componentClass[method] = _.bind(fn, componentClass);
919
+ }
920
+ }
921
+ if (mixinDefinition != null) {
922
+ if (typeof mixinDefinition.__included === "function") {
923
+ mixinDefinition.__included(componentName, componentClass, mixinDefinition);
924
+ }
925
+ }
926
+ superclassMixins = componentPrototype._superClass().prototype.concerns;
927
+ componentPrototype.concerns || (componentPrototype.concerns = []);
928
+ componentPrototype.concerns.push(mixinName);
929
+ componentPrototype.concerns = componentPrototype.concerns.concat(superclassMixins);
930
+ componentPrototype.concerns = _(componentPrototype.concerns).chain().uniq().compact().value();
931
+ return componentPrototype;
932
+ }
933
+ };
934
+ };
935
+
936
+ }).call(this);
937
+ (function() {
938
+ var ComponentDefinition, cd,
939
+ __slice = Array.prototype.slice;
940
+
941
+ ComponentDefinition = (function() {
942
+
943
+ function ComponentDefinition(componentName, autoRegister) {
718
944
  var parts;
945
+ this.autoRegister = autoRegister != null ? autoRegister : true;
719
946
  this.namespace = Luca.util.namespace();
720
947
  this.componentId = this.componentName = componentName;
721
948
  this.superClassName = 'Luca.View';
949
+ this.properties || (this.properties = {});
950
+ this._classProperties || (this._classProperties = {});
722
951
  if (componentName.match(/\./)) {
723
952
  this.namespaced = true;
724
953
  parts = componentName.split('.');
@@ -726,29 +955,60 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
726
955
  this.namespace = parts.join('.');
727
956
  Luca.registry.addNamespace(parts.join('.'));
728
957
  }
958
+ Luca.define.__definitions.push(this);
729
959
  }
730
960
 
731
- DefineProxy.prototype["in"] = function(namespace) {
961
+ ComponentDefinition.create = function(componentName, autoRegister) {
962
+ if (autoRegister == null) autoRegister = Luca.config.autoRegister;
963
+ return new ComponentDefinition(componentName, autoRegister);
964
+ };
965
+
966
+ ComponentDefinition.prototype.isValid = function() {
967
+ if (!_.isObject(this.properties)) return false;
968
+ if (Luca.util.resolve(this.superClassName) == null) return false;
969
+ if (this.componentName == null) return false;
970
+ return true;
971
+ };
972
+
973
+ ComponentDefinition.prototype.isDefined = function() {
974
+ return this.defined === true;
975
+ };
976
+
977
+ ComponentDefinition.prototype.isOpen = function() {
978
+ return !!(this.isValid() && !this.isDefined());
979
+ };
980
+
981
+ ComponentDefinition.prototype.meta = function(key, value) {
982
+ var data, metaKey;
983
+ metaKey = this.namespace + '.' + this.componentId;
984
+ metaKey = metaKey.replace(/^\./, '');
985
+ data = Luca.registry.addMetaData(metaKey, key, value);
986
+ return this.properties.componentMetaData = function() {
987
+ return Luca.registry.getMetaDataFor(metaKey);
988
+ };
989
+ };
990
+
991
+ ComponentDefinition.prototype["in"] = function(namespace) {
732
992
  this.namespace = namespace;
733
993
  return this;
734
994
  };
735
995
 
736
- DefineProxy.prototype.from = function(superClassName) {
996
+ ComponentDefinition.prototype.from = function(superClassName) {
737
997
  this.superClassName = superClassName;
738
998
  return this;
739
999
  };
740
1000
 
741
- DefineProxy.prototype["extends"] = function(superClassName) {
1001
+ ComponentDefinition.prototype["extends"] = function(superClassName) {
742
1002
  this.superClassName = superClassName;
743
1003
  return this;
744
1004
  };
745
1005
 
746
- DefineProxy.prototype.extend = function(superClassName) {
1006
+ ComponentDefinition.prototype.extend = function(superClassName) {
747
1007
  this.superClassName = superClassName;
748
1008
  return this;
749
1009
  };
750
1010
 
751
- DefineProxy.prototype.triggers = function() {
1011
+ ComponentDefinition.prototype.triggers = function() {
752
1012
  var hook, hooks, _i, _len;
753
1013
  hooks = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
754
1014
  _.defaults(this.properties || (this.properties = {}), {
@@ -759,10 +1019,11 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
759
1019
  this.properties.hooks.push(hook);
760
1020
  }
761
1021
  this.properties.hooks = _.uniq(this.properties.hooks);
1022
+ this.meta("hooks", this.properties.hooks);
762
1023
  return this;
763
1024
  };
764
1025
 
765
- DefineProxy.prototype.includes = function() {
1026
+ ComponentDefinition.prototype.includes = function() {
766
1027
  var include, includes, _i, _len;
767
1028
  includes = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
768
1029
  _.defaults(this.properties || (this.properties = {}), {
@@ -773,25 +1034,96 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
773
1034
  this.properties.include.push(include);
774
1035
  }
775
1036
  this.properties.include = _.uniq(this.properties.include);
1037
+ this.meta("includes", this.properties.include);
776
1038
  return this;
777
1039
  };
778
1040
 
779
- DefineProxy.prototype.mixesIn = function() {
780
- var mixin, mixins, _i, _len;
781
- mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
1041
+ ComponentDefinition.prototype.mixesIn = function() {
1042
+ var concern, concerns, _i, _len;
1043
+ concerns = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
782
1044
  _.defaults(this.properties || (this.properties = {}), {
783
- mixins: []
1045
+ concerns: []
784
1046
  });
785
- for (_i = 0, _len = mixins.length; _i < _len; _i++) {
786
- mixin = mixins[_i];
787
- this.properties.mixins.push(mixin);
1047
+ for (_i = 0, _len = concerns.length; _i < _len; _i++) {
1048
+ concern = concerns[_i];
1049
+ this.properties.concerns.push(concern);
788
1050
  }
789
- this.properties.mixins = _.uniq(this.properties.mixins);
1051
+ this.properties.concerns = _.uniq(this.properties.concerns);
1052
+ this.meta("concerns", this.properties.concerns);
1053
+ return this;
1054
+ };
1055
+
1056
+ ComponentDefinition.prototype.contains = function() {
1057
+ var components;
1058
+ components = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
1059
+ _.defaults(this.properties, {
1060
+ components: []
1061
+ });
1062
+ this.properties.components = components;
1063
+ return this;
1064
+ };
1065
+
1066
+ ComponentDefinition.prototype.validatesConfigurationWith = function(validationConfiguration) {
1067
+ if (validationConfiguration == null) validationConfiguration = {};
1068
+ this.meta("configuration validations", validationConfiguration);
1069
+ this.properties.validatable = true;
1070
+ return this;
1071
+ };
1072
+
1073
+ ComponentDefinition.prototype.beforeDefinition = function(callback) {
1074
+ this._classProperties.beforeDefinition = callback;
790
1075
  return this;
791
1076
  };
792
1077
 
793
- DefineProxy.prototype.defaultProperties = function(properties) {
794
- var at, componentType, _base;
1078
+ ComponentDefinition.prototype.afterDefinition = function(callback) {
1079
+ this._classProperties.afterDefinition = callback;
1080
+ return this;
1081
+ };
1082
+
1083
+ ComponentDefinition.prototype.classConfiguration = function(properties) {
1084
+ if (properties == null) properties = {};
1085
+ this.meta("class configuration", _.keys(properties));
1086
+ _.defaults((this._classProperties || (this._classProperties = {})), properties);
1087
+ return this;
1088
+ };
1089
+
1090
+ ComponentDefinition.prototype.publicConfiguration = function(properties) {
1091
+ if (properties == null) properties = {};
1092
+ this.meta("public configuration", _.keys(properties));
1093
+ _.defaults((this.properties || (this.properties = {})), properties);
1094
+ return this;
1095
+ };
1096
+
1097
+ ComponentDefinition.prototype.privateConfiguration = function(properties) {
1098
+ if (properties == null) properties = {};
1099
+ this.meta("private configuration", _.keys(properties));
1100
+ _.defaults((this.properties || (this.properties = {})), properties);
1101
+ return this;
1102
+ };
1103
+
1104
+ ComponentDefinition.prototype.classInterface = function(properties) {
1105
+ if (properties == null) properties = {};
1106
+ this.meta("class interface", _.keys(properties));
1107
+ _.defaults((this._classProperties || (this._classProperties = {})), properties);
1108
+ return this;
1109
+ };
1110
+
1111
+ ComponentDefinition.prototype.publicInterface = function(properties) {
1112
+ if (properties == null) properties = {};
1113
+ this.meta("public interface", _.keys(properties));
1114
+ _.defaults((this.properties || (this.properties = {})), properties);
1115
+ return this;
1116
+ };
1117
+
1118
+ ComponentDefinition.prototype.privateInterface = function(properties) {
1119
+ if (properties == null) properties = {};
1120
+ this.meta("private interface", _.keys(properties));
1121
+ _.defaults((this.properties || (this.properties = {})), properties);
1122
+ return this;
1123
+ };
1124
+
1125
+ ComponentDefinition.prototype.definePrototype = function(properties) {
1126
+ var at, componentType, definition, _base, _ref, _ref2;
795
1127
  if (properties == null) properties = {};
796
1128
  _.defaults((this.properties || (this.properties = {})), properties);
797
1129
  at = this.namespaced ? Luca.util.resolve(this.namespace, window || global) : window || global;
@@ -799,35 +1131,93 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
799
1131
  eval("(window||global)." + this.namespace + " = {}");
800
1132
  at = Luca.util.resolve(this.namespace, window || global);
801
1133
  }
802
- at[this.componentId] = Luca.extend(this.superClassName, this.componentName, this.properties);
803
- if (Luca.autoRegister === true) {
804
- if (Luca.isViewPrototype(at[this.componentId])) componentType = "view";
805
- if (Luca.isCollectionPrototype(at[this.componentId])) {
1134
+ this.meta("super class name", this.superClassName);
1135
+ this.meta("display name", this.componentName);
1136
+ this.properties.displayName = this.componentName;
1137
+ this.properties.componentMetaData = function() {
1138
+ return Luca.registry.getMetaDataFor(this.displayName);
1139
+ };
1140
+ if ((_ref = this._classProperties) != null) {
1141
+ if (typeof _ref.beforeDefinition === "function") {
1142
+ _ref.beforeDefinition(this);
1143
+ }
1144
+ }
1145
+ definition = at[this.componentId] = Luca.extend(this.superClassName, this.componentName, this.properties);
1146
+ if (this.autoRegister === true) {
1147
+ if (Luca.isViewPrototype(definition)) componentType = "view";
1148
+ if (Luca.isCollectionPrototype(definition)) {
806
1149
  (_base = Luca.Collection).namespaces || (_base.namespaces = []);
807
1150
  Luca.Collection.namespaces.push(this.namespace);
808
1151
  componentType = "collection";
809
1152
  }
810
- if (Luca.isModelPrototype(at[this.componentId])) componentType = "model";
1153
+ if (Luca.isModelPrototype(definition)) componentType = "model";
811
1154
  Luca.registerComponent(_.string.underscored(this.componentId), this.componentName, componentType);
812
1155
  }
813
- return at[this.componentId];
1156
+ this.defined = true;
1157
+ if (!_.isEmpty(this._classProperties)) {
1158
+ _.extend(definition, this._classProperties);
1159
+ }
1160
+ if (definition != null) {
1161
+ if ((_ref2 = definition.afterDefinition) != null) {
1162
+ _ref2.call(definition, this);
1163
+ }
1164
+ }
1165
+ return definition;
814
1166
  };
815
1167
 
816
- return DefineProxy;
1168
+ return ComponentDefinition;
817
1169
 
818
1170
  })();
819
1171
 
820
- DefineProxy.prototype.behavesAs = DefineProxy.prototype.uses = DefineProxy.prototype.mixesIn;
1172
+ cd = ComponentDefinition.prototype;
1173
+
1174
+ cd.concerns = cd.behavesAs = cd.uses = cd.mixesIn;
1175
+
1176
+ cd.register = cd.defines = cd.defaults = cd.exports = cd.defaultProperties = cd.definePrototype;
1177
+
1178
+ cd.defaultsTo = cd.enhance = cd["with"] = cd.definePrototype;
1179
+
1180
+ cd.publicMethods = cd.publicInterface;
1181
+
1182
+ cd.privateMethods = cd.privateInterface;
1183
+
1184
+ cd.classMethods = cd.classInterface;
1185
+
1186
+ _.extend((Luca.define = ComponentDefinition.create), {
1187
+ __definitions: [],
1188
+ incomplete: function() {
1189
+ return _(Luca.define.__definitions).select(function(definition) {
1190
+ return definition.isOpen();
1191
+ });
1192
+ },
1193
+ close: function() {
1194
+ var open, _i, _len, _ref;
1195
+ _ref = Luca.define.incomplete();
1196
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1197
+ open = _ref[_i];
1198
+ if (open.isValid()) open.register();
1199
+ }
1200
+ return Luca.define.__definitions.length = 0;
1201
+ },
1202
+ findDefinition: function(componentName) {
1203
+ return _(Luca.define.__definitions).detect(function(definition) {
1204
+ return definition.componentName === componentName;
1205
+ });
1206
+ }
1207
+ });
821
1208
 
822
- DefineProxy.prototype.defines = DefineProxy.prototype.defaults = DefineProxy.prototype.exports = DefineProxy.prototype.defaultProperties;
1209
+ Luca.register = function(componentName) {
1210
+ return new ComponentDefinition(componentName, true);
1211
+ };
823
1212
 
824
- DefineProxy.prototype.defaultsTo = DefineProxy.prototype.enhance = DefineProxy.prototype["with"] = DefineProxy.prototype.defaultProperties;
1213
+ _.mixin({
1214
+ def: Luca.define
1215
+ });
825
1216
 
826
1217
  Luca.extend = function(superClassName, childName, properties) {
827
1218
  var definition, include, superClass, _i, _len, _ref;
828
1219
  if (properties == null) properties = {};
829
1220
  superClass = Luca.util.resolve(superClassName, window || global);
830
- superClass.__initializers || (superClass.__initializers = []);
831
1221
  if (!_.isFunction(superClass != null ? superClass.extend : void 0)) {
832
1222
  throw "Error defining " + childName + ". " + superClassName + " is not a valid component to extend from";
833
1223
  }
@@ -854,59 +1244,10 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
854
1244
  return definition;
855
1245
  };
856
1246
 
857
- Luca.mixin = function(mixinName) {
858
- var namespace, resolved;
859
- namespace = _(Luca.mixin.namespaces).detect(function(space) {
860
- var _ref;
861
- return ((_ref = Luca.util.resolve(space)) != null ? _ref[mixinName] : void 0) != null;
862
- });
863
- namespace || (namespace = "Luca.modules");
864
- resolved = Luca.util.resolve(namespace)[mixinName];
865
- if (resolved == null) {
866
- console.log("Could not find " + mixinName + " in ", Luca.mixin.namespaces);
867
- }
868
- return resolved;
869
- };
870
-
871
- Luca.mixin.namespaces = ["Luca.modules"];
872
-
873
- Luca.mixin.namespace = function(namespace) {
874
- Luca.mixin.namespaces.push(namespace);
875
- return Luca.mixin.namespaces = _(Luca.mixin.namespaces).uniq();
876
- };
877
-
878
- Luca.decorate = function(componentPrototype) {
879
- if (_.isString(componentPrototype)) {
880
- componentPrototype = Luca.util.resolve(componentPrototype).prototype;
881
- }
882
- return {
883
- "with": function(mixin) {
884
- var mixinDefinition, mixinPrivates, sanitized, superclassMixins, _ref;
885
- mixinDefinition = Luca.mixin(mixin);
886
- mixinPrivates = _(mixinDefinition).chain().keys().select(function(key) {
887
- return ("" + key).match(/^__/);
888
- });
889
- sanitized = _(mixinDefinition).omit(mixinPrivates.value());
890
- _.extend(componentPrototype, sanitized);
891
- if (mixinDefinition != null) {
892
- if ((_ref = mixinDefinition.__included) != null) {
893
- _ref.call(mixinDefinition, mixin);
894
- }
895
- }
896
- superclassMixins = componentPrototype._superClass().prototype.mixins;
897
- componentPrototype.mixins || (componentPrototype.mixins = []);
898
- componentPrototype.mixins.push(mixin);
899
- componentPrototype.mixins = componentPrototype.mixins.concat(superclassMixins);
900
- componentPrototype.mixins = _(componentPrototype.mixins).chain().uniq().compact().value();
901
- return componentPrototype;
902
- }
903
- };
904
- };
905
-
906
1247
  }).call(this);
907
1248
  (function() {
908
1249
 
909
- Luca.modules.ApplicationEventBindings = {
1250
+ Luca.concerns.ApplicationEventBindings = {
910
1251
  __initializer: function() {
911
1252
  var app, eventTrigger, handler, _len, _ref, _ref2, _results;
912
1253
  if (_.isEmpty(this.applicationEvents)) return;
@@ -934,7 +1275,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
934
1275
  }).call(this);
935
1276
  (function() {
936
1277
 
937
- Luca.modules.CollectionEventBindings = {
1278
+ Luca.concerns.CollectionEventBindings = {
938
1279
  __initializer: function() {
939
1280
  var collection, eventTrigger, handler, key, manager, signature, _ref, _ref2, _results;
940
1281
  if (_.isEmpty(this.collectionEvents)) return;
@@ -962,7 +1303,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
962
1303
  }).call(this);
963
1304
  (function() {
964
1305
 
965
- Luca.modules.Deferrable = {
1306
+ Luca.concerns.Deferrable = {
966
1307
  configure_collection: function(setAsDeferrable) {
967
1308
  var collectionManager, _ref, _ref2;
968
1309
  if (setAsDeferrable == null) setAsDeferrable = true;
@@ -983,9 +1324,9 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
983
1324
  }).call(this);
984
1325
  (function() {
985
1326
 
986
- Luca.modules.DomHelpers = {
1327
+ Luca.concerns.DomHelpers = {
987
1328
  __initializer: function() {
988
- var additional, additionalClasses, _i, _len, _results;
1329
+ var additional, additionalClasses, classes, cssClass, _i, _j, _len, _len2, _ref, _results;
989
1330
  additionalClasses = _(this.additionalClassNames || []).clone();
990
1331
  if (this.wrapperClass != null) this.$wrap(this.wrapperClass);
991
1332
  if (_.isString(additionalClasses)) {
@@ -996,21 +1337,34 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
996
1337
  if (this.gridRowFluid) additionalClasses.push("row-fluid");
997
1338
  if (this.gridRow) additionalClasses.push("row");
998
1339
  if (additionalClasses == null) return;
999
- _results = [];
1000
1340
  for (_i = 0, _len = additionalClasses.length; _i < _len; _i++) {
1001
1341
  additional = additionalClasses[_i];
1002
- _results.push(this.$el.addClass(additional));
1342
+ this.$el.addClass(additional);
1343
+ }
1344
+ if (Luca.config.autoApplyClassHierarchyAsCssClasses === true) {
1345
+ classes = (typeof this.componentMetaData === "function" ? (_ref = this.componentMetaData()) != null ? _ref.styleHierarchy() : void 0 : void 0) || [];
1346
+ _results = [];
1347
+ for (_j = 0, _len2 = classes.length; _j < _len2; _j++) {
1348
+ cssClass = classes[_j];
1349
+ if (cssClass !== "luca-view" && cssClass !== "backbone-view") {
1350
+ _results.push(this.$el.addClass(cssClass));
1351
+ }
1352
+ }
1353
+ return _results;
1003
1354
  }
1004
- return _results;
1005
1355
  },
1006
1356
  $wrap: function(wrapper) {
1007
1357
  if (_.isString(wrapper) && !wrapper.match(/[<>]/)) {
1008
1358
  wrapper = this.make("div", {
1009
- "class": wrapper
1359
+ "class": wrapper,
1360
+ "data-wrapper": true
1010
1361
  });
1011
1362
  }
1012
1363
  return this.$el.wrap(wrapper);
1013
1364
  },
1365
+ $wrapper: function() {
1366
+ return this.$el.parent('[data-wrapper="true"]');
1367
+ },
1014
1368
  $template: function(template, variables) {
1015
1369
  if (variables == null) variables = {};
1016
1370
  return this.$el.html(Luca.template(template, variables));
@@ -1035,7 +1389,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1035
1389
  }).call(this);
1036
1390
  (function() {
1037
1391
 
1038
- Luca.modules.EnhancedProperties = {
1392
+ Luca.concerns.EnhancedProperties = {
1039
1393
  __initializer: function() {
1040
1394
  if (Luca.config.enhancedViewProperties !== true) return;
1041
1395
  if (_.isString(this.collection) && Luca.CollectionManager.get()) {
@@ -1054,7 +1408,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1054
1408
  __hasProp = Object.prototype.hasOwnProperty,
1055
1409
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
1056
1410
 
1057
- Luca.modules.Filterable = {
1411
+ Luca.concerns.Filterable = {
1058
1412
  __included: function(component, module) {
1059
1413
  return _.extend(Luca.Collection.prototype, {
1060
1414
  __filters: {}
@@ -1080,22 +1434,25 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1080
1434
  this.optionsSources || (this.optionsSources = []);
1081
1435
  this.query || (this.query = {});
1082
1436
  this.queryOptions || (this.queryOptions = {});
1083
- this.querySources.push((function() {
1084
- return filter.toQuery();
1437
+ this.querySources.push((function(options) {
1438
+ if (options == null) options = {};
1439
+ return _this.getFilterState().toQuery();
1085
1440
  }));
1086
- this.optionsSources.push((function() {
1087
- return filter.toOptions();
1441
+ this.optionsSources.push((function(options) {
1442
+ if (options == null) options = {};
1443
+ return _this.getFilterState().toOptions();
1088
1444
  }));
1089
- if (this.debugMode === true) {
1090
- console.log("Filterable");
1091
- console.log(this.querySources);
1092
- console.log(this.optionsSources);
1093
- }
1094
1445
  filter.on("change", function() {
1095
- var merged;
1446
+ var options;
1447
+ filter = _.clone(_this.getQuery());
1448
+ options = _.clone(_this.getQueryOptions());
1449
+ if (options.limit != null) filter.limit = options.limit;
1450
+ if (options.page != null) filter.page = options.page;
1451
+ if (options.sortBy != null) filter.sortBy = options.sortBy;
1096
1452
  if (_this.isRemote()) {
1097
- merged = _.extend(_this.getQuery(), _this.getQueryOptions());
1098
- return _this.collection.applyFilter(merged, _this.getQueryOptions());
1453
+ return _this.collection.applyFilter(filter, {
1454
+ remote: true
1455
+ });
1099
1456
  } else {
1100
1457
  return _this.trigger("refresh");
1101
1458
  }
@@ -1177,7 +1534,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1177
1534
  }).call(this);
1178
1535
  (function() {
1179
1536
 
1180
- Luca.modules.GridLayout = {
1537
+ Luca.concerns.GridLayout = {
1181
1538
  _initializer: function() {
1182
1539
  if (this.gridSpan) this.$el.addClass("span" + this.gridSpan);
1183
1540
  if (this.gridOffset) this.$el.addClass("offset" + this.gridOffset);
@@ -1189,7 +1546,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1189
1546
  }).call(this);
1190
1547
  (function() {
1191
1548
 
1192
- Luca.modules.LoadMaskable = {
1549
+ Luca.concerns.LoadMaskable = {
1193
1550
  __initializer: function() {
1194
1551
  var _this = this;
1195
1552
  if (this.loadMask !== true) return;
@@ -1336,7 +1693,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1336
1693
  (function() {
1337
1694
  var applyModalConfig;
1338
1695
 
1339
- Luca.modules.ModalView = {
1696
+ Luca.concerns.ModalView = {
1340
1697
  closeOnEscape: true,
1341
1698
  showOnInitialize: false,
1342
1699
  backdrop: false,
@@ -1374,7 +1731,38 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1374
1731
  }).call(this);
1375
1732
  (function() {
1376
1733
 
1377
- Luca.modules.Paginatable = {
1734
+ Luca.concerns.ModelPresenter = {
1735
+ classMethods: {
1736
+ getPresenter: function(format) {
1737
+ var _ref;
1738
+ return (_ref = this.presenters) != null ? _ref[format] : void 0;
1739
+ },
1740
+ registerPresenter: function(format, config) {
1741
+ this.presenters || (this.presenters = {});
1742
+ return this.presenters[format] = config;
1743
+ }
1744
+ },
1745
+ presentAs: function(format) {
1746
+ var attributeList,
1747
+ _this = this;
1748
+ try {
1749
+ attributeList = this.componentMetaData().componentDefinition().getPresenter(format);
1750
+ if (attributeList == null) return this.toJSON();
1751
+ return _(attributeList).reduce(function(memo, attribute) {
1752
+ memo[attribute] = _this.read(attribute);
1753
+ return memo;
1754
+ }, {});
1755
+ } catch (e) {
1756
+ console.log("Error presentAs", e.stack, e.message);
1757
+ return this.toJSON();
1758
+ }
1759
+ }
1760
+ };
1761
+
1762
+ }).call(this);
1763
+ (function() {
1764
+
1765
+ Luca.concerns.Paginatable = {
1378
1766
  paginatorViewClass: 'Luca.components.PaginationControl',
1379
1767
  paginationSelector: ".toolbar.bottom",
1380
1768
  __included: function() {
@@ -1410,9 +1798,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1410
1798
  });
1411
1799
  });
1412
1800
  paginationState.on("change:page", function(state) {
1413
- var filter;
1801
+ var filter, options;
1802
+ filter = _.clone(_this.getQuery());
1803
+ options = _.clone(_this.getQueryOptions());
1804
+ if (options.limit != null) filter.limit = options.limit;
1805
+ if (options.page != null) filter.page = options.page;
1806
+ if (options.sortBy != null) filter.sortBy = options.sortBy;
1414
1807
  if (_this.isRemote()) {
1415
- filter = _.extend(_this.toQuery(), _this.toQueryOptions());
1416
1808
  return _this.collection.applyFilter(filter, {
1417
1809
  remote: true
1418
1810
  });
@@ -1480,7 +1872,62 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1480
1872
  }).call(this);
1481
1873
  (function() {
1482
1874
 
1483
- Luca.modules.StateModel = {
1875
+ Luca.concerns.QueryCollectionBindings = {
1876
+ getCollection: function() {
1877
+ return this.collection;
1878
+ },
1879
+ loadModels: function(models, options) {
1880
+ var _ref;
1881
+ if (models == null) models = [];
1882
+ if (options == null) options = {};
1883
+ return (_ref = this.getCollection()) != null ? _ref.reset(models, options) : void 0;
1884
+ },
1885
+ applyQuery: function(query, queryOptions) {
1886
+ if (query == null) query = {};
1887
+ if (queryOptions == null) queryOptions = {};
1888
+ this.query = query;
1889
+ this.queryOptions = queryOptions;
1890
+ this.refresh();
1891
+ return this;
1892
+ },
1893
+ getQuery: function(options) {
1894
+ var query, querySource, _i, _len, _ref;
1895
+ if (options == null) options = {};
1896
+ query = this.query || (this.query = {});
1897
+ _ref = _(this.querySources || []).compact();
1898
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1899
+ querySource = _ref[_i];
1900
+ query = _.extend(query, querySource(options) || {});
1901
+ }
1902
+ return query;
1903
+ },
1904
+ getQueryOptions: function(options) {
1905
+ var optionSource, _i, _len, _ref;
1906
+ if (options == null) options = {};
1907
+ options = this.queryOptions || (this.queryOptions = {});
1908
+ _ref = _(this.optionsSources || []).compact();
1909
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1910
+ optionSource = _ref[_i];
1911
+ options = _.extend(options, optionSource(options) || {});
1912
+ }
1913
+ return options;
1914
+ },
1915
+ getModels: function(query, options) {
1916
+ var _ref;
1917
+ if ((_ref = this.collection) != null ? _ref.query : void 0) {
1918
+ query || (query = this.getQuery());
1919
+ options || (options = this.getQueryOptions());
1920
+ return this.collection.query(query, options);
1921
+ } else {
1922
+ return this.collection.models;
1923
+ }
1924
+ }
1925
+ };
1926
+
1927
+ }).call(this);
1928
+ (function() {
1929
+
1930
+ Luca.concerns.StateModel = {
1484
1931
  __initializer: function() {
1485
1932
  var _this = this;
1486
1933
  if (this.stateful !== true) return;
@@ -1510,7 +1957,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1510
1957
  }).call(this);
1511
1958
  (function() {
1512
1959
 
1513
- Luca.modules.Templating = {
1960
+ Luca.concerns.Templating = {
1514
1961
  __initializer: function() {
1515
1962
  var template, templateContent, templateVars;
1516
1963
  templateVars = Luca.util.read.call(this, this.bodyTemplateVars) || {};
@@ -1645,6 +2092,10 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1645
2092
  });
1646
2093
  };
1647
2094
 
2095
+ Luca.registry.find = function(search) {
2096
+ return Luca.util.resolve(search) || Luca.define.findDefinition(search);
2097
+ };
2098
+
1648
2099
  Luca.cache = Luca.cacheInstance = function(cacheKey, object) {
1649
2100
  var lookup_id;
1650
2101
  if (cacheKey == null) return;
@@ -1661,6 +2112,137 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1661
2112
  return componentCacheStore.cid_index[lookup_id];
1662
2113
  };
1663
2114
 
2115
+ }).call(this);
2116
+ (function() {
2117
+ var MetaDataProxy;
2118
+
2119
+ Luca.registry.componentMetaData = {};
2120
+
2121
+ Luca.registry.getMetaDataFor = function(componentName) {
2122
+ return new MetaDataProxy(Luca.registry.componentMetaData[componentName]);
2123
+ };
2124
+
2125
+ Luca.registry.addMetaData = function(componentName, key, value) {
2126
+ var data, _base;
2127
+ data = (_base = Luca.registry.componentMetaData)[componentName] || (_base[componentName] = {});
2128
+ data[key] = _(value).clone();
2129
+ return data;
2130
+ };
2131
+
2132
+ MetaDataProxy = (function() {
2133
+
2134
+ function MetaDataProxy(meta) {
2135
+ this.meta = meta != null ? meta : {};
2136
+ _.defaults(this.meta, {
2137
+ "super class name": "",
2138
+ "display name": "",
2139
+ "public interface": [],
2140
+ "public configuration": [],
2141
+ "private interface": [],
2142
+ "private configuration": [],
2143
+ "class configuration": [],
2144
+ "class interface": []
2145
+ });
2146
+ }
2147
+
2148
+ MetaDataProxy.prototype.superClass = function() {
2149
+ return Luca.util.resolve(this.meta["super class name"]);
2150
+ };
2151
+
2152
+ MetaDataProxy.prototype.componentDefinition = function() {
2153
+ return Luca.registry.find(this.meta["display name"]);
2154
+ };
2155
+
2156
+ MetaDataProxy.prototype.componentPrototype = function() {
2157
+ var _ref;
2158
+ return (_ref = this.componentDefinition()) != null ? _ref.prototype : void 0;
2159
+ };
2160
+
2161
+ MetaDataProxy.prototype.prototypeFunctions = function() {
2162
+ return _.functions(this.componentPrototype());
2163
+ };
2164
+
2165
+ MetaDataProxy.prototype.classAttributes = function() {
2166
+ return _.uniq(this.classInterface().concat(this.classConfiguration()));
2167
+ };
2168
+
2169
+ MetaDataProxy.prototype.publicAttributes = function() {
2170
+ return _.uniq(this.publicInterface().concat(this.publicConfiguration()));
2171
+ };
2172
+
2173
+ MetaDataProxy.prototype.privateAttributes = function() {
2174
+ return _.uniq(this.privateInterface().concat(this.privateConfiguration()));
2175
+ };
2176
+
2177
+ MetaDataProxy.prototype.classMethods = function() {
2178
+ var list;
2179
+ list = _.functions(this.componentDefinition());
2180
+ return _(list).intersection(this.classAttributes());
2181
+ };
2182
+
2183
+ MetaDataProxy.prototype.publicMethods = function() {
2184
+ return _(this.prototypeFunctions()).intersection(this.publicAttributes());
2185
+ };
2186
+
2187
+ MetaDataProxy.prototype.privateMethods = function() {
2188
+ return _(this.prototypeFunctions()).intersection(this.privateAttributes());
2189
+ };
2190
+
2191
+ MetaDataProxy.prototype.classConfiguration = function() {
2192
+ return this.meta["class configuration"];
2193
+ };
2194
+
2195
+ MetaDataProxy.prototype.publicConfiguration = function() {
2196
+ return this.meta["public configuration"];
2197
+ };
2198
+
2199
+ MetaDataProxy.prototype.privateConfiguration = function() {
2200
+ return this.meta["private configuration"];
2201
+ };
2202
+
2203
+ MetaDataProxy.prototype.classInterface = function() {
2204
+ return this.meta["class interface"];
2205
+ };
2206
+
2207
+ MetaDataProxy.prototype.publicInterface = function() {
2208
+ return this.meta["public interface"];
2209
+ };
2210
+
2211
+ MetaDataProxy.prototype.privateInterface = function() {
2212
+ return this.meta["private interface"];
2213
+ };
2214
+
2215
+ MetaDataProxy.prototype.triggers = function() {
2216
+ return this.meta["hooks"];
2217
+ };
2218
+
2219
+ MetaDataProxy.prototype.hooks = function() {
2220
+ return this.meta["hooks"];
2221
+ };
2222
+
2223
+ MetaDataProxy.prototype.styleHierarchy = function() {
2224
+ var list;
2225
+ list = _(this.classHierarchy()).map(function(cls) {
2226
+ return Luca.util.toCssClass(cls, 'views', 'components', 'core', 'fields', 'containers');
2227
+ });
2228
+ return _(list).without('backbone-view', 'luca-view');
2229
+ };
2230
+
2231
+ MetaDataProxy.prototype.classHierarchy = function() {
2232
+ var list, proxy, _ref, _ref2, _ref3, _ref4;
2233
+ list = [this.meta["display name"], this.meta["super class name"]];
2234
+ proxy = (_ref = this.superClass()) != null ? (_ref2 = _ref.prototype) != null ? typeof _ref2.componentMetaData === "function" ? _ref2.componentMetaData() : void 0 : void 0 : void 0;
2235
+ while (!!proxy) {
2236
+ list = list.concat(proxy != null ? proxy.classHierarchy() : void 0);
2237
+ proxy = (_ref3 = proxy.superClass()) != null ? (_ref4 = _ref3.prototype) != null ? typeof _ref4.componentMetaData === "function" ? _ref4.componentMetaData() : void 0 : void 0 : void 0;
2238
+ }
2239
+ return _(list).uniq();
2240
+ };
2241
+
2242
+ return MetaDataProxy;
2243
+
2244
+ })();
2245
+
1664
2246
  }).call(this);
1665
2247
  (function() {
1666
2248
  var __slice = Array.prototype.slice;
@@ -1711,7 +2293,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1711
2293
 
1712
2294
  view["extends"]("Backbone.View");
1713
2295
 
1714
- view.includes("Luca.Events", "Luca.modules.DomHelpers");
2296
+ view.includes("Luca.Events", "Luca.concerns.DomHelpers");
1715
2297
 
1716
2298
  view.mixesIn("DomHelpers", "Templating", "EnhancedProperties", "CollectionEventBindings", "ApplicationEventBindings", "StateModel");
1717
2299
 
@@ -1729,38 +2311,11 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1729
2311
  this.$el.attr("data-luca-id", this.name || this.cid);
1730
2312
  Luca.cacheInstance(this.cid, this);
1731
2313
  this.setupHooks(_(Luca.View.prototype.hooks.concat(this.hooks)).uniq());
1732
- this.setupMixins();
2314
+ Luca.concern.setup.call(this);
1733
2315
  this.delegateEvents();
1734
2316
  return this.trigger("after:initialize", this);
1735
2317
  },
1736
- setupMixins: function() {
1737
- var module, _i, _len, _ref, _ref2, _ref3, _ref4, _results;
1738
- if (((_ref = this.mixins) != null ? _ref.length : void 0) > 0) {
1739
- _ref2 = this.mixins;
1740
- _results = [];
1741
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1742
- module = _ref2[_i];
1743
- _results.push((_ref3 = Luca.mixin(module)) != null ? (_ref4 = _ref3.__initializer) != null ? _ref4.call(this, this, module) : void 0 : void 0);
1744
- }
1745
- return _results;
1746
- }
1747
- },
1748
- setupHooks: function(set) {
1749
- var _this = this;
1750
- set || (set = this.hooks);
1751
- return _(set).each(function(eventId) {
1752
- var callback, fn;
1753
- fn = Luca.util.hook(eventId);
1754
- callback = function() {
1755
- var _ref;
1756
- return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
1757
- };
1758
- if (eventId != null ? eventId.match(/once:/) : void 0) {
1759
- callback = _.once(callback);
1760
- }
1761
- return _this.on(eventId, callback, _this);
1762
- });
1763
- },
2318
+ setupHooks: Luca.util.setupHooks,
1764
2319
  registerEvent: function(selector, handler) {
1765
2320
  this.events || (this.events = {});
1766
2321
  this.events[selector] = handler;
@@ -1868,21 +2423,26 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1868
2423
  return _results;
1869
2424
  };
1870
2425
 
2426
+ Luca.View.deferrableEvent = "reset";
2427
+
1871
2428
  Luca.View.extend = function(definition) {
1872
- var module, _i, _len, _ref;
2429
+ var componentClass, module, _i, _len, _ref;
2430
+ if (definition == null) definition = {};
1873
2431
  definition = Luca.View.renderWrapper(definition);
1874
- if ((definition.mixins != null) && _.isArray(definition.mixins)) {
1875
- _ref = definition.mixins;
2432
+ if (definition.concerns != null) {
2433
+ definition.concerns || (definition.concerns = definition.concerns);
2434
+ }
2435
+ componentClass = Luca.View._originalExtend.call(this, definition);
2436
+ if ((definition.concerns != null) && _.isArray(definition.concerns)) {
2437
+ _ref = definition.concerns;
1876
2438
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1877
2439
  module = _ref[_i];
1878
- Luca.decorate(definition)["with"](module);
2440
+ Luca.decorate(componentClass)["with"](module);
1879
2441
  }
1880
2442
  }
1881
- return Luca.View._originalExtend.call(this, definition);
2443
+ return componentClass;
1882
2444
  };
1883
2445
 
1884
- Luca.View.deferrableEvent = "reset";
1885
-
1886
2446
  }).call(this);
1887
2447
  (function() {
1888
2448
  var model, setupComputedProperties;
@@ -1896,13 +2456,14 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1896
2456
  model.defines({
1897
2457
  initialize: function() {
1898
2458
  Backbone.Model.prototype.initialize(this, arguments);
1899
- return setupComputedProperties.call(this);
2459
+ setupComputedProperties.call(this);
2460
+ return Luca.concern.setup.call(this);
1900
2461
  },
1901
2462
  read: function(attr) {
1902
2463
  if (_.isFunction(this[attr])) {
1903
2464
  return this[attr].call(this);
1904
2465
  } else {
1905
- return this.get(attr);
2466
+ return this.get(attr) || this[attr];
1906
2467
  }
1907
2468
  },
1908
2469
  get: function(attr) {
@@ -1938,20 +2499,37 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1938
2499
  return _results;
1939
2500
  };
1940
2501
 
2502
+ Luca.Model._originalExtend = Backbone.Model.extend;
2503
+
2504
+ Luca.Model.extend = function(definition) {
2505
+ var componentClass, module, _i, _len, _ref;
2506
+ if (definition == null) definition = {};
2507
+ if (definition.concerns != null) {
2508
+ definition.concerns || (definition.concerns = definition.concerns);
2509
+ }
2510
+ componentClass = Luca.Model._originalExtend.call(this, definition);
2511
+ if ((definition.concerns != null) && _.isArray(definition.concerns)) {
2512
+ _ref = definition.concerns;
2513
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2514
+ module = _ref[_i];
2515
+ Luca.decorate(componentClass)["with"](module);
2516
+ }
2517
+ }
2518
+ return componentClass;
2519
+ };
2520
+
1941
2521
  }).call(this);
1942
2522
  (function() {
1943
2523
  var collection;
1944
2524
 
1945
2525
  collection = Luca.define('Luca.Collection');
1946
2526
 
1947
- if (Backbone.QueryCollection != null) {
1948
- collection["extends"]('Backbone.QueryCollection');
1949
- } else {
1950
- collection["extends"]('Backbone.Collection');
1951
- }
2527
+ collection["extends"]('Backbone.QueryCollection');
1952
2528
 
1953
2529
  collection.includes('Luca.Events');
1954
2530
 
2531
+ collection.triggers("after:initialize", "before:fetch", "after:response");
2532
+
1955
2533
  collection.defines({
1956
2534
  model: Luca.Model,
1957
2535
  cachedMethods: [],
@@ -2002,6 +2580,8 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2002
2580
  parse: options != null ? options.parse : void 0
2003
2581
  });
2004
2582
  }
2583
+ Luca.concern.setup.call(this);
2584
+ Luca.util.setupHooks.call(this, this.hooks);
2005
2585
  return this.trigger("after:initialize");
2006
2586
  },
2007
2587
  __wrapUrl: function() {
@@ -2045,13 +2625,15 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2045
2625
  applyFilter: function(filter, options) {
2046
2626
  if (filter == null) filter = {};
2047
2627
  if (options == null) options = {};
2628
+ options = _(options).clone();
2048
2629
  if ((options.remote != null) === true || this.remoteFilter === true) {
2049
2630
  this.applyParams(filter);
2050
2631
  return this.fetch(_.extend(options, {
2051
- refresh: true
2632
+ refresh: true,
2633
+ remote: true
2052
2634
  }));
2053
2635
  } else {
2054
- return this.reset(this.query(filter));
2636
+ return this.reset(this.query(filter, options));
2055
2637
  }
2056
2638
  },
2057
2639
  applyParams: function(params) {
@@ -2097,7 +2679,9 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2097
2679
  if (options == null) options = {};
2098
2680
  this.trigger("before:fetch", this);
2099
2681
  if (this.memoryCollection === true) return this.reset(this.data);
2100
- if (this.cached_models().length && !options.refresh) return this.bootstrap();
2682
+ if (this.cached_models().length && !(options.refresh === true || options.remote === true)) {
2683
+ return this.bootstrap();
2684
+ }
2101
2685
  url = _.isFunction(this.url) ? this.url() : this.url;
2102
2686
  if (!((url && url.length > 1) || this.localStorage)) return true;
2103
2687
  this.fetching = true;
@@ -2111,11 +2695,10 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2111
2695
  onceLoaded: function(fn, options) {
2112
2696
  var wrapped,
2113
2697
  _this = this;
2114
- if (options == null) {
2115
- options = {
2116
- autoFetch: true
2117
- };
2118
- }
2698
+ if (options == null) options = {};
2699
+ _.defaults(options, {
2700
+ autoFetch: true
2701
+ });
2119
2702
  if (this.length > 0 && !this.fetching) {
2120
2703
  fn.apply(this, [this]);
2121
2704
  return;
@@ -2246,14 +2829,37 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2246
2829
  }
2247
2830
  });
2248
2831
 
2249
- Luca.Collection.baseParams = function(obj) {
2250
- if (obj) return Luca.Collection._baseParams = obj;
2251
- if (_.isFunction(Luca.Collection._baseParams)) {
2252
- return Luca.Collection._baseParams();
2832
+ Luca.Collection._originalExtend = Backbone.Collection.extend;
2833
+
2834
+ Luca.Collection.extend = function(definition) {
2835
+ var componentClass, module, _i, _len, _ref;
2836
+ if (definition == null) definition = {};
2837
+ if (definition.concerns != null) {
2838
+ definition.concerns || (definition.concerns = definition.concerns);
2253
2839
  }
2254
- if (_.isObject(Luca.Collection._baseParams)) {
2255
- return Luca.Collection._baseParams;
2840
+ componentClass = Luca.Collection._originalExtend.call(this, definition);
2841
+ if ((definition.concerns != null) && _.isArray(definition.concerns)) {
2842
+ _ref = definition.concerns;
2843
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2844
+ module = _ref[_i];
2845
+ Luca.decorate(componentClass)["with"](module);
2846
+ }
2256
2847
  }
2848
+ return componentClass;
2849
+ };
2850
+
2851
+ Luca.Collection.namespace = function(namespace) {
2852
+ var _base;
2853
+ if (_.isString(namespace)) namespace = Luca.util.resolve(namespace);
2854
+ if (namespace != null) Luca.Collection.__defaultNamespace = namespace;
2855
+ (_base = Luca.Collection).__defaultNamespace || (_base.__defaultNamespace = window || global);
2856
+ return Luca.util.read(Luca.Collection.__defaultNamespace);
2857
+ };
2858
+
2859
+ Luca.Collection.baseParams = function(obj) {
2860
+ if (_.isString(obj)) obj = Luca.util.resolve(obj);
2861
+ if (obj) Luca.Collection._baseParams = obj;
2862
+ return Luca.util.read(Luca.Collection._baseParams);
2257
2863
  };
2258
2864
 
2259
2865
  Luca.Collection._bootstrapped_models = {};
@@ -2394,40 +3000,21 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2394
3000
 
2395
3001
  }).call(this);
2396
3002
  (function() {
3003
+ var field;
2397
3004
 
2398
- _.def('Luca.core.Field')["extends"]('Luca.View')["with"]({
2399
- className: 'luca-ui-text-field luca-ui-field',
2400
- isField: true,
2401
- template: 'fields/text_field',
3005
+ field = Luca.register("Luca.core.Field");
3006
+
3007
+ field["extends"]("Luca.View");
3008
+
3009
+ field.triggers("before:validation", "after:validation", "on:change");
3010
+
3011
+ field.publicConfiguration({
2402
3012
  labelAlign: 'top',
2403
- hooks: ["before:validation", "after:validation", "on:change"],
2404
- statuses: ["warning", "error", "success"],
2405
- initialize: function(options) {
2406
- var _ref;
2407
- this.options = options != null ? options : {};
2408
- _.extend(this, this.options);
2409
- this.input_id || (this.input_id = _.uniqueId('field'));
2410
- this.input_name || (this.input_name = this.name);
2411
- this.input_class || (this.input_class = "");
2412
- this.input_type || (this.input_type = "");
2413
- this.helperText || (this.helperText = "");
2414
- if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) {
2415
- this.label || (this.label = "*" + this.label);
2416
- }
2417
- this.inputStyles || (this.inputStyles = "");
2418
- this.input_value || (this.input_value = this.value || "");
2419
- if (this.disabled) this.disable();
2420
- this.updateState(this.state);
2421
- this.placeHolder || (this.placeHolder = "");
2422
- return Luca.View.prototype.initialize.apply(this, arguments);
2423
- },
2424
- beforeRender: function() {
2425
- if (Luca.enableBootstrap) this.$el.addClass('control-group');
2426
- if (this.required) return this.$el.addClass('required');
2427
- },
2428
- change_handler: function(e) {
2429
- return this.trigger("on:change", this, e);
2430
- },
3013
+ className: 'luca-ui-text-field luca-ui-field',
3014
+ statuses: ["warning", "error", "success"]
3015
+ });
3016
+
3017
+ field.publicInterface({
2431
3018
  disable: function() {
2432
3019
  return this.getInputElement().attr('disabled', true);
2433
3020
  },
@@ -2453,9 +3040,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2453
3040
  var _ref;
2454
3041
  return (_ref = this.getInputElement()) != null ? _ref.attr('value', value) : void 0;
2455
3042
  },
2456
- getInputElement: function() {
2457
- return this.input || (this.input = this.$('input').eq(0));
2458
- },
2459
3043
  updateState: function(state) {
2460
3044
  var _this = this;
2461
3045
  return _(this.statuses).each(function(cls) {
@@ -2465,6 +3049,44 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2465
3049
  }
2466
3050
  });
2467
3051
 
3052
+ field.privateConfiguration({
3053
+ isField: true,
3054
+ template: 'fields/text_field'
3055
+ });
3056
+
3057
+ field.defines({
3058
+ initialize: function(options) {
3059
+ var _ref;
3060
+ this.options = options != null ? options : {};
3061
+ _.extend(this, this.options);
3062
+ this.input_id || (this.input_id = _.uniqueId('field'));
3063
+ this.input_name || (this.input_name = this.name);
3064
+ this.input_class || (this.input_class = "");
3065
+ this.input_type || (this.input_type = "");
3066
+ this.helperText || (this.helperText = "");
3067
+ if (!(this.label != null) || this.label.length === 0) this.label = this.name;
3068
+ if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) {
3069
+ this.label || (this.label = "*" + this.label);
3070
+ }
3071
+ this.inputStyles || (this.inputStyles = "");
3072
+ this.input_value || (this.input_value = this.value || "");
3073
+ if (this.disabled) this.disable();
3074
+ this.updateState(this.state);
3075
+ this.placeHolder || (this.placeHolder = "");
3076
+ return Luca.View.prototype.initialize.apply(this, arguments);
3077
+ },
3078
+ beforeRender: function() {
3079
+ if (Luca.config.enableBoostrap) this.$el.addClass('control-group');
3080
+ if (this.required) return this.$el.addClass('required');
3081
+ },
3082
+ change_handler: function(e) {
3083
+ return this.trigger("on:change", this, e);
3084
+ },
3085
+ getInputElement: function() {
3086
+ return this.input || (this.input = this.$('input').eq(0));
3087
+ }
3088
+ });
3089
+
2468
3090
  }).call(this);
2469
3091
  (function() {
2470
3092
  var applyDOMConfig, container, createGetterMethods, createMethodsToGetComponentsByRole, doComponents, doLayout, indexComponent, validateContainerConfiguration;
@@ -2484,10 +3106,23 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2484
3106
  components: [],
2485
3107
  componentEvents: {},
2486
3108
  initialize: function(options) {
3109
+ var component, _i, _len, _ref;
2487
3110
  this.options = options != null ? options : {};
2488
3111
  _.extend(this, this.options);
2489
- this.setupHooks(Luca.core.Container.prototype.hooks);
2490
3112
  this.components || (this.components = this.fields || (this.fields = this.pages || (this.pages = this.cards || (this.cards = this.views))));
3113
+ _ref = this.components;
3114
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3115
+ component = _ref[_i];
3116
+ if (_.isString(component)) {
3117
+ component = {
3118
+ type: component,
3119
+ role: component,
3120
+ name: component
3121
+ };
3122
+ }
3123
+ }
3124
+ _.bindAll(this, "beforeRender");
3125
+ this.setupHooks(Luca.core.Container.prototype.hooks);
2491
3126
  validateContainerConfiguration(this);
2492
3127
  return Luca.View.prototype.initialize.apply(this, arguments);
2493
3128
  },
@@ -2507,25 +3142,27 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2507
3142
  });
2508
3143
  },
2509
3144
  prepareComponents: function() {
2510
- var component, _i, _len, _ref,
2511
- _this = this;
2512
- _ref = this.components;
2513
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2514
- component = _ref[_i];
2515
- if (_.isString(component)) {
2516
- component = {
2517
- type: component
2518
- };
2519
- }
2520
- }
3145
+ var _this = this;
3146
+ container = this;
2521
3147
  return _(this.components).each(function(component, index) {
2522
- var ce, componentContainerElement, panel, _ref2;
2523
- ce = componentContainerElement = (_ref2 = _this.componentContainers) != null ? _ref2[index] : void 0;
3148
+ var ce, componentContainerElement, componentExtension, panel, _ref, _ref2;
3149
+ ce = componentContainerElement = (_ref = _this.componentContainers) != null ? _ref[index] : void 0;
2524
3150
  ce["class"] = ce["class"] || ce.className || ce.classes;
2525
3151
  if (_this.generateComponentElements) {
2526
3152
  panel = _this.make(_this.componentTag, componentContainerElement, '');
2527
3153
  _this.$append(panel);
2528
3154
  }
3155
+ if (container.defaults != null) {
3156
+ component = _.defaults(component, container.defaults || {});
3157
+ }
3158
+ if (_.isArray(container.extensions) && _.isObject((_ref2 = container.extensions) != null ? _ref2[index] : void 0)) {
3159
+ componentExtension = container.extensions[index];
3160
+ component = _.extend(component, componentExtension);
3161
+ }
3162
+ if ((component.role != null) && _.isObject(container.extensions) && _.isObject(container.extensions[component.role])) {
3163
+ componentExtension = container.extensions[component.role];
3164
+ component = _.extend(component, componentExtension);
3165
+ }
2529
3166
  if (component.container == null) {
2530
3167
  if (_this.generateComponentElements) {
2531
3168
  component.container = "#" + componentContainerElement.id;
@@ -2546,10 +3183,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2546
3183
  container = this;
2547
3184
  this.components = _(this.components).map(function(object, index) {
2548
3185
  var component, created, _ref;
2549
- component = Luca.isComponent(object) ? object : (object.type || (object.type = object.ctype), !(object.type != null) ? object.components != null ? object.type = object.ctype = 'container' : object.type = object.ctype = Luca.defaultComponentType : void 0, object = _.defaults(object, container.defaults || {}), created = Luca.util.lazyComponent(object));
3186
+ component = Luca.isComponent(object) ? object : (object.type || (object.type = object.ctype), !(object.type != null) ? object.components != null ? object.type = object.ctype = 'container' : object.type = object.ctype = Luca.defaultComponentType : void 0, object._parentCid || (object._parentCid = container.cid), created = Luca.util.lazyComponent(object));
2550
3187
  if (!component.container && ((_ref = component.options) != null ? _ref.container : void 0)) {
2551
3188
  component.container = component.options.container;
2552
3189
  }
3190
+ component.getParent || (component.getParent = function() {
3191
+ return Luca(component._parentCid);
3192
+ });
2553
3193
  if (!(component.container != null)) {
2554
3194
  console.log(component, index, _this);
2555
3195
  console.error("could not assign container property to component on container " + (_this.name || _this.cid));
@@ -2565,9 +3205,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2565
3205
  this.debug("container render components");
2566
3206
  container = this;
2567
3207
  return _(this.components).each(function(component) {
2568
- component.getParent = function() {
2569
- return container;
2570
- };
2571
3208
  try {
2572
3209
  this.$(component.container).eq(0).append(component.el);
2573
3210
  return component.render();
@@ -2730,7 +3367,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2730
3367
  return this.components[needle];
2731
3368
  },
2732
3369
  isRootComponent: function() {
2733
- return !(this.getParent != null);
3370
+ return this.rootComponent === true || !(this.getParent != null);
2734
3371
  },
2735
3372
  getRootComponent: function() {
2736
3373
  if (this.isRootComponent()) {
@@ -2865,8 +3502,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2865
3502
 
2866
3503
  CollectionManager.prototype.name = "primary";
2867
3504
 
2868
- CollectionManager.prototype.collectionNamespace = Luca.Collection.namespace;
2869
-
2870
3505
  CollectionManager.prototype.__collections = {};
2871
3506
 
2872
3507
  CollectionManager.prototype.relayEvents = true;
@@ -2879,6 +3514,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2879
3514
  if (existing = typeof (_base = Luca.CollectionManager).get === "function" ? _base.get(this.name) : void 0) {
2880
3515
  throw 'Attempt to create a collection manager with a name which already exists';
2881
3516
  }
3517
+ this.collectionNamespace || (this.collectionNamespace = Luca.util.read(Luca.Collection.namespace));
2882
3518
  (_base2 = Luca.CollectionManager).instances || (_base2.instances = {});
2883
3519
  _.extend(this, Backbone.Events);
2884
3520
  _.extend(this, Luca.Events);
@@ -3011,6 +3647,9 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3011
3647
  guessCollectionClass = function(key) {
3012
3648
  var classified, guess, guesses, _ref;
3013
3649
  classified = Luca.util.classify(key);
3650
+ if (_.isString(this.collectionNamespace)) {
3651
+ this.collectionNamespace = Luca.util.resolve(this.collectionNamespace);
3652
+ }
3014
3653
  guess = (this.collectionNamespace || (window || global))[classified];
3015
3654
  guess || (guess = (this.collectionNamespace || (window || global))["" + classified + "Collection"]);
3016
3655
  if (!(guess != null) && ((_ref = Luca.Collection.namespaces) != null ? _ref.length : void 0) > 0) {
@@ -3181,9 +3820,9 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3181
3820
  generateComponentElements: true,
3182
3821
  initialize: function(options) {
3183
3822
  this.options = options;
3823
+ this.components || (this.components = this.pages || (this.pages = this.cards));
3184
3824
  Luca.core.Container.prototype.initialize.apply(this, arguments);
3185
- this.setupHooks(this.hooks);
3186
- return this.components || (this.components = this.pages || (this.pages = this.cards));
3825
+ return this.setupHooks(this.hooks);
3187
3826
  },
3188
3827
  prepareComponents: function() {
3189
3828
  var _ref;
@@ -3229,7 +3868,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3229
3868
  return this.activeComponent().trigger("first:activation", this, this.activeComponent());
3230
3869
  },
3231
3870
  activate: function(index, silent, callback) {
3232
- var current, previous, _ref, _ref2, _ref3, _ref4,
3871
+ var activationContext, current, previous,
3233
3872
  _this = this;
3234
3873
  if (silent == null) silent = false;
3235
3874
  if (_.isFunction(silent)) {
@@ -3244,44 +3883,46 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3244
3883
  current = this.getComponent(index);
3245
3884
  }
3246
3885
  if (!current) return;
3247
- if (!silent) {
3886
+ if (silent !== true) {
3248
3887
  this.trigger("before:card:switch", previous, current);
3249
3888
  if (previous != null) {
3250
- if ((_ref = previous.trigger) != null) {
3251
- _ref.apply(previous, ["before:deactivation", this, previous, current]);
3252
- }
3889
+ previous.trigger("before:deactivation", this, previous, current);
3253
3890
  }
3254
3891
  if (current != null) {
3255
- if ((_ref2 = current.trigger) != null) {
3256
- _ref2.apply(previous, ["before:activation", this, previous, current]);
3257
- }
3892
+ current.trigger("before:activation", this, previous, current);
3258
3893
  }
3259
3894
  _.defer(function() {
3260
3895
  return _this.$el.data(_this.activeAttribute || "active-card", current.name);
3261
3896
  });
3262
3897
  }
3263
3898
  this.componentElements().hide();
3264
- if (!current.previously_activated) {
3899
+ if (current.previously_activated !== true) {
3265
3900
  current.trigger("first:activation");
3266
3901
  current.previously_activated = true;
3267
3902
  }
3268
3903
  this.activeCard = index;
3269
3904
  this.activeComponentElement().show();
3270
- if (!silent) {
3905
+ if (silent !== true) {
3271
3906
  this.trigger("after:card:switch", previous, current);
3272
- if ((_ref3 = previous.trigger) != null) {
3273
- _ref3.apply(previous, ["deactivation", this, previous, current]);
3907
+ if (previous != null) {
3908
+ previous.trigger("deactivation", this, previous, current);
3274
3909
  }
3275
- if ((_ref4 = current.trigger) != null) {
3276
- _ref4.apply(current, ["activation", this, previous, current]);
3910
+ if (current != null) {
3911
+ current.trigger("activation", this, previous, current);
3277
3912
  }
3278
3913
  }
3914
+ activationContext = this;
3915
+ if (Luca.containers.CardView.activationContext === "current") {
3916
+ activationContext = current;
3917
+ }
3279
3918
  if (_.isFunction(callback)) {
3280
- return callback.apply(this, [this, previous, current]);
3919
+ return callback.apply(activationContext, [this, previous, current]);
3281
3920
  }
3282
3921
  }
3283
3922
  });
3284
3923
 
3924
+ Luca.containers.CardView.activationContext = "current";
3925
+
3285
3926
  }).call(this);
3286
3927
  (function() {
3287
3928
 
@@ -3516,16 +4157,27 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3516
4157
 
3517
4158
  }).call(this);
3518
4159
  (function() {
4160
+ var tabView;
3519
4161
 
3520
- _.def('Luca.containers.TabView')["extends"]('Luca.containers.CardView')["with"]({
3521
- hooks: ["before:select", "after:select"],
3522
- componentType: 'tab_view',
3523
- className: 'luca-ui-tab-view tabbable',
4162
+ _.def('Luca.containers.TabView')["extends"]('Luca.containers.CardView')["with"];
4163
+
4164
+ tabView = Luca.register("Luca.containers.TabView");
4165
+
4166
+ tabView.triggers("before:select", "after:select");
4167
+
4168
+ tabView.publicConfiguration({
3524
4169
  tab_position: 'top',
3525
- tabVerticalOffset: '50px',
4170
+ tabVerticalOffset: '50px'
4171
+ });
4172
+
4173
+ tabView.privateConfiguration({
4174
+ additionalClassNames: 'tabbable',
3526
4175
  navClass: "nav-tabs",
3527
4176
  bodyTemplate: "containers/tab_view",
3528
- bodyEl: "div.tab-content",
4177
+ bodyEl: "div.tab-content"
4178
+ });
4179
+
4180
+ tabView.defines({
3529
4181
  initialize: function(options) {
3530
4182
  this.options = options != null ? options : {};
3531
4183
  if (this.navStyle === "list") this.navClass = "nav-list";
@@ -3551,13 +4203,12 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3551
4203
  }
3552
4204
  tabContainerId = this.tabContainer().attr("id");
3553
4205
  this.registerEvent("click #" + tabContainerId + " li a", "select");
3554
- if (Luca.enableBootstrap && (this.tab_position === "left" || this.tab_position === "right")) {
4206
+ if (Luca.config.enableBoostrap && (this.tab_position === "left" || this.tab_position === "right")) {
3555
4207
  this.tabContainerWrapper().addClass("span2");
3556
4208
  return this.tabContentWrapper().addClass("span9");
3557
4209
  }
3558
4210
  },
3559
4211
  createTabSelectors: function() {
3560
- var tabView;
3561
4212
  tabView = this;
3562
4213
  return this.each(function(component, index) {
3563
4214
  var icon, link, selector, _ref;
@@ -3619,7 +4270,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3619
4270
  initialize: function(options) {
3620
4271
  this.options = options != null ? options : {};
3621
4272
  _.extend(this, this.options);
3622
- if (Luca.enableBootstrap === true) {
4273
+ if (Luca.config.enableBoostrap === true) {
3623
4274
  this.wrapperClass = this.fluid === true ? Luca.containers.Viewport.fluidWrapperClass : Luca.containers.Viewport.defaultWrapperClass;
3624
4275
  }
3625
4276
  Luca.core.Container.prototype.initialize.apply(this, arguments);
@@ -3668,7 +4319,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3668
4319
  if ((_ref = Luca.containers.CardView.prototype.after) != null) {
3669
4320
  _ref.apply(this, arguments);
3670
4321
  }
3671
- if (Luca.enableBootstrap === true && this.containerClassName) {
4322
+ if (Luca.config.enableBoostrap === true && this.containerClassName) {
3672
4323
  return this.$el.children().wrap('<div class="#{ containerClassName }" />');
3673
4324
  }
3674
4325
  },
@@ -3707,12 +4358,16 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3707
4358
 
3708
4359
  }).call(this);
3709
4360
  (function() {
4361
+ var application,
4362
+ __slice = Array.prototype.slice;
3710
4363
 
3711
- Luca.util.startHistory = function() {
3712
- return Backbone.history.start();
3713
- };
4364
+ application = Luca.register("Luca.Application");
4365
+
4366
+ application["extends"]("Luca.containers.Viewport");
3714
4367
 
3715
- _.def('Luca.Application')["extends"]('Luca.containers.Viewport')["with"]({
4368
+ application.triggers("controller:change", "action:change");
4369
+
4370
+ application.publicInterface({
3716
4371
  name: "MyApp",
3717
4372
  defaultState: {},
3718
4373
  autoBoot: false,
@@ -3726,21 +4381,20 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3726
4381
  keyEvents: {},
3727
4382
  components: [
3728
4383
  {
3729
- ctype: 'template',
4384
+ type: 'template',
3730
4385
  name: 'welcome',
3731
4386
  template: 'sample/welcome',
3732
4387
  templateContainer: "Luca.templates"
3733
4388
  }
3734
4389
  ],
3735
4390
  initialize: function(options) {
3736
- var alreadyRunning, app, appName, _base,
4391
+ var alreadyRunning, app, appName,
3737
4392
  _this = this;
3738
4393
  this.options = options != null ? options : {};
3739
4394
  app = this;
3740
4395
  appName = this.name;
3741
4396
  alreadyRunning = typeof Luca.getApplication === "function" ? Luca.getApplication() : void 0;
3742
- (_base = Luca.Application).instances || (_base.instances = {});
3743
- Luca.Application.instances[appName] = app;
4397
+ Luca.Application.registerInstance(this);
3744
4398
  Luca.containers.Viewport.prototype.initialize.apply(this, arguments);
3745
4399
  this.state = new Luca.Model(this.defaultState);
3746
4400
  if (this.useController === true) this.setupMainController();
@@ -3808,11 +4462,10 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3808
4462
  },
3809
4463
  navigate_to: function(component_name, callback) {
3810
4464
  return this.getMainController().navigate_to(component_name, callback);
3811
- },
3812
- getMainController: function() {
3813
- if (this.useController === true) return this.components[0];
3814
- return Luca.cache('main_controller');
3815
- },
4465
+ }
4466
+ });
4467
+
4468
+ application.privateInterface({
3816
4469
  keyHandler: function(e) {
3817
4470
  var control, isInputEvent, keyEvent, keyname, meta, source, _ref;
3818
4471
  if (!(e && this.keyEvents)) return;
@@ -3843,7 +4496,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3843
4496
  _this.state.set({
3844
4497
  active_section: current.name
3845
4498
  });
3846
- return app.trigger("page:change");
4499
+ return app.trigger("controller:change");
3847
4500
  });
3848
4501
  }
3849
4502
  return (_ref2 = this.getMainController()) != null ? _ref2.each(function(component) {
@@ -3854,22 +4507,27 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3854
4507
  _this.state.set({
3855
4508
  active_sub_section: current.name
3856
4509
  });
3857
- return app.trigger("sub:page:change");
4510
+ return app.trigger("action:change");
3858
4511
  });
3859
4512
  }
3860
4513
  }) : void 0;
3861
4514
  },
3862
4515
  setupMainController: function() {
3863
- var definedComponents;
4516
+ var definedComponents,
4517
+ _this = this;
3864
4518
  if (this.useController === true) {
3865
4519
  definedComponents = this.components || [];
3866
4520
  this.components = [
3867
4521
  {
3868
4522
  type: 'controller',
3869
4523
  name: "main_controller",
4524
+ role: "main_controller",
3870
4525
  components: definedComponents
3871
4526
  }
3872
4527
  ];
4528
+ this.getMainController = function() {
4529
+ return _this.findComponentByRole('main_controller');
4530
+ };
3873
4531
  return this.defer(this.setupControllerBindings, false).until("after:components");
3874
4532
  }
3875
4533
  },
@@ -3910,7 +4568,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3910
4568
  if (this.autoStartHistory === true) {
3911
4569
  this.autoStartHistory = "before:render";
3912
4570
  }
3913
- return this.defer(Luca.util.startHistory, false).until(this, this.autoStartHistory);
4571
+ return this.defer(Luca.Application.startHistory, false).until(this, this.autoStartHistory);
3914
4572
  }
3915
4573
  },
3916
4574
  setupKeyHandler: function() {
@@ -3931,16 +4589,74 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3931
4589
  }
3932
4590
  });
3933
4591
 
4592
+ application.classInterface({
4593
+ instances: {},
4594
+ registerInstance: function(app) {
4595
+ return Luca.Application.instances[app.name] = app;
4596
+ },
4597
+ routeTo: function() {
4598
+ var callback, first, last, pages, routeHelper, specifiedAction;
4599
+ pages = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
4600
+ last = _(pages).last();
4601
+ first = _(pages).first();
4602
+ callback = void 0;
4603
+ specifiedAction = void 0;
4604
+ return routeHelper = function() {
4605
+ var action, args, index, nextItem, page, path, routeHandler, target, _i, _len, _ref;
4606
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
4607
+ path = this.app || Luca();
4608
+ index = 0;
4609
+ if (pages.length === 1 && (target = Luca(first))) {
4610
+ pages = target.controllerPath();
4611
+ }
4612
+ for (_i = 0, _len = pages.length; _i < _len; _i++) {
4613
+ page = pages[_i];
4614
+ if (!(_.isString(page))) continue;
4615
+ nextItem = pages[++index];
4616
+ action = void 0;
4617
+ if (_.isFunction(nextItem)) {
4618
+ action = nextItem;
4619
+ } else if (_.isObject(nextItem) && (nextItem.action != null)) {
4620
+ action = nextItem.action;
4621
+ } else if (page === last && (routeHandler = (_ref = Luca(last)) != null ? _ref.routeHandler : void 0)) {
4622
+ action = Luca.util.read(routeHandler);
4623
+ }
4624
+ if (_.isString(action)) {
4625
+ callback = function() {
4626
+ return this[action].apply(this, args);
4627
+ };
4628
+ }
4629
+ if (_.isFunction(action)) callback = nextItem;
4630
+ path = path.navigate_to(page, callback);
4631
+ }
4632
+ routeHelper.action = function(action) {
4633
+ return pages.push({
4634
+ action: action
4635
+ });
4636
+ };
4637
+ return routeHelper;
4638
+ };
4639
+ },
4640
+ startHistory: function() {
4641
+ return Backbone.history.start();
4642
+ }
4643
+ });
4644
+
4645
+ application.register();
4646
+
3934
4647
  }).call(this);
3935
4648
  (function() {
4649
+ var toolbar;
4650
+
4651
+ _.def('Luca.components.Toolbar')["extends"]('Luca.core.Container')["with"];
3936
4652
 
3937
- _.def('Luca.components.Toolbar')["extends"]('Luca.core.Container')["with"]({
4653
+ toolbar = Luca.register("Luca.components.Toolbar");
4654
+
4655
+ toolbar["extends"]("Luca.core.Container");
4656
+
4657
+ toolbar.defines({
3938
4658
  className: 'luca-ui-toolbar toolbar',
3939
4659
  position: 'bottom',
3940
- initialize: function(options) {
3941
- this.options = options != null ? options : {};
3942
- return Luca.core.Container.prototype.initialize.apply(this, arguments);
3943
- },
3944
4660
  prepareComponents: function() {
3945
4661
  var _this = this;
3946
4662
  return _(this.components).each(function(component) {
@@ -3948,14 +4664,20 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3948
4664
  });
3949
4665
  },
3950
4666
  render: function() {
3951
- return $(this.container).append(this.el);
4667
+ $(this.container).append(this.el);
4668
+ return this;
3952
4669
  }
3953
4670
  });
3954
4671
 
3955
4672
  }).call(this);
3956
4673
  (function() {
4674
+ var loaderView;
4675
+
4676
+ loaderView = Luca.register("Luca.components.CollectionLoaderView");
3957
4677
 
3958
- _.def('Luca.components.CollectionLoaderView')["extends"]('Luca.components.Template')["with"]({
4678
+ loaderView["extends"]("Luca.View");
4679
+
4680
+ loaderView.defines({
3959
4681
  className: 'luca-ui-collection-loader-view',
3960
4682
  template: "components/collection_loader_view",
3961
4683
  initialize: function(options) {
@@ -3992,22 +4714,25 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3992
4714
  (function() {
3993
4715
  var collectionView, make;
3994
4716
 
3995
- collectionView = Luca.define("Luca.components.CollectionView");
4717
+ collectionView = Luca.register("Luca.components.CollectionView");
3996
4718
 
3997
4719
  collectionView["extends"]("Luca.components.Panel");
3998
4720
 
3999
- collectionView.behavesAs("LoadMaskable", "Filterable", "Paginatable");
4721
+ collectionView.mixesIn("QueryCollectionBindings", "LoadMaskable", "Filterable", "Paginatable");
4000
4722
 
4001
4723
  collectionView.triggers("before:refresh", "after:refresh", "refresh", "empty:results");
4002
4724
 
4003
- collectionView.defaults({
4725
+ collectionView.publicConfiguration({
4004
4726
  tagName: "ol",
4005
- className: "luca-ui-collection-view",
4006
4727
  bodyClassName: "collection-ui-panel",
4007
- itemTemplate: void 0,
4008
- itemRenderer: void 0,
4009
4728
  itemTagName: 'li',
4010
4729
  itemClassName: 'collection-item',
4730
+ itemTemplate: void 0,
4731
+ itemRenderer: void 0,
4732
+ itemProperty: void 0
4733
+ });
4734
+
4735
+ collectionView.defines({
4011
4736
  initialize: function(options) {
4012
4737
  var _this = this;
4013
4738
  this.options = options != null ? options : {};
@@ -4030,29 +4755,24 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4030
4755
  if (!Luca.isBackboneCollection(this.collection)) {
4031
4756
  console.log("Missing Collection on " + (this.name || this.cid), this, this.collection);
4032
4757
  throw "Collection Views must have a valid backbone collection";
4033
- this.collection.on("before:fetch", function() {
4034
- return _this.trigger("enable:loadmask");
4035
- });
4036
- this.collection.bind("reset", function() {
4037
- _this.refresh();
4038
- return _this.trigger("disable:loadmask");
4039
- });
4040
- this.collection.bind("remove", function() {
4041
- return _this.refresh();
4042
- });
4043
- this.collection.bind("add", function() {
4044
- return _this.refresh();
4045
- });
4046
- if (this.observeChanges === true) {
4047
- this.collection.on("change", this.refreshModel, this);
4048
- }
4049
4758
  }
4050
- Luca.components.Panel.prototype.initialize.apply(this, arguments);
4051
- if (this.autoRefreshOnModelsPresent !== false) {
4052
- this.defer(function() {
4053
- if (_this.collection.length > 0) return _this.refresh();
4054
- }).until("after:render");
4759
+ this.collection.on("before:fetch", function() {
4760
+ return _this.trigger("enable:loadmask");
4761
+ });
4762
+ this.collection.bind("reset", function() {
4763
+ _this.refresh();
4764
+ return _this.trigger("disable:loadmask");
4765
+ });
4766
+ this.collection.bind("remove", function() {
4767
+ return _this.refresh();
4768
+ });
4769
+ this.collection.bind("add", function() {
4770
+ return _this.refresh();
4771
+ });
4772
+ if (this.observeChanges === true) {
4773
+ this.collection.on("change", this.refreshModel, this);
4055
4774
  }
4775
+ Luca.components.Panel.prototype.initialize.apply(this, arguments);
4056
4776
  return this.on("refresh", this.refresh, this);
4057
4777
  },
4058
4778
  attributesForItem: function(item, model) {
@@ -4090,47 +4810,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4090
4810
  return console.log("Error generating DOM element for CollectionView", this, model, index);
4091
4811
  }
4092
4812
  },
4093
- getCollection: function() {
4094
- return this.collection;
4095
- },
4096
- applyQuery: function(query, queryOptions) {
4097
- if (query == null) query = {};
4098
- if (queryOptions == null) queryOptions = {};
4099
- this.query = query;
4100
- this.queryOptions = queryOptions;
4101
- this.refresh();
4102
- return this;
4103
- },
4104
- getQuery: function() {
4105
- var query, querySource, _i, _len, _ref;
4106
- query = this.query || (this.query = {});
4107
- _ref = _(this.querySources || []).compact();
4108
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4109
- querySource = _ref[_i];
4110
- query = _.extend(query, querySource() || {});
4111
- }
4112
- return query;
4113
- },
4114
- getQueryOptions: function() {
4115
- var optionSource, options, _i, _len, _ref;
4116
- options = this.queryOptions || (this.queryOptions = {});
4117
- _ref = _(this.optionsSources || []).compact();
4118
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4119
- optionSource = _ref[_i];
4120
- options = _.extend(options, optionSource() || {});
4121
- }
4122
- return options;
4123
- },
4124
- getModels: function(query, options) {
4125
- var _ref;
4126
- if ((_ref = this.collection) != null ? _ref.query : void 0) {
4127
- query || (query = this.getQuery());
4128
- options || (options = this.getQueryOptions());
4129
- return this.collection.query(query, options);
4130
- } else {
4131
- return this.collection.models;
4132
- }
4133
- },
4134
4813
  locateItemElement: function(id) {
4135
4814
  return this.$("." + this.itemClassName + "[data-model-id='" + id + "']");
4136
4815
  },
@@ -4179,34 +4858,92 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4179
4858
 
4180
4859
  }).call(this);
4181
4860
  (function() {
4861
+ var controller;
4862
+
4863
+ controller = Luca.register("Luca.components.Controller");
4864
+
4865
+ controller["extends"]("Luca.containers.CardView");
4866
+
4867
+ controller.publicInterface({
4868
+ "default": function(callback) {
4869
+ return this.navigate_to(this.defaultPage || this.defaultCard, callback);
4870
+ },
4871
+ activePage: function() {
4872
+ return this.activeSection();
4873
+ },
4874
+ navigate_to: function(section, callback) {
4875
+ var _this = this;
4876
+ section || (section = this.defaultCard);
4877
+ this.activate(section, false, function(activator, previous, current) {
4878
+ _this.state.set({
4879
+ active_section: current.name
4880
+ });
4881
+ if (_.isFunction(callback)) return callback.apply(current);
4882
+ });
4883
+ return this.find(section);
4884
+ }
4885
+ });
4886
+
4887
+ controller.classMethods({
4888
+ controllerPath: function() {
4889
+ var atBase, component, list;
4890
+ component = this;
4891
+ list = [component.name];
4892
+ atBase = false;
4893
+ while (component && !atBase) {
4894
+ component = typeof component.getParent === "function" ? component.getParent() : void 0;
4895
+ if ((component != null ? component.role : void 0) === "main_controller") {
4896
+ atBase = true;
4897
+ }
4898
+ if ((component != null) && !atBase) list.push(component.name);
4899
+ }
4900
+ return list.reverse();
4901
+ }
4902
+ });
4182
4903
 
4183
- _.def('Luca.components.Controller')["extends"]('Luca.containers.CardView')["with"]({
4184
- additionalClassNames: ['luca-ui-controller'],
4904
+ controller.defines({
4905
+ additionalClassNames: 'luca-ui-controller',
4185
4906
  activeAttribute: "active-section",
4907
+ stateful: true,
4186
4908
  initialize: function(options) {
4187
4909
  var _ref;
4188
4910
  this.options = options;
4911
+ this.defaultCard || (this.defaultCard = this.defaultPage || (this.defaultPage = ((_ref = this.components[0]) != null ? _ref.name : void 0) || 0));
4912
+ this.defaultPage || (this.defaultPage = this.defaultCard);
4913
+ this.defaultState || (this.defaultState = {
4914
+ active_section: this.defaultPage
4915
+ });
4189
4916
  Luca.containers.CardView.prototype.initialize.apply(this, arguments);
4190
- this.defaultCard || (this.defaultCard = (_ref = this.components[0]) != null ? _ref.name : void 0);
4191
- if (!this.defaultCard) {
4917
+ if (this.defaultCard == null) {
4192
4918
  throw "Controllers must specify a defaultCard property and/or the first component must have a name";
4193
4919
  }
4194
- return this.state = new Backbone.Model({
4195
- active_section: this.defaultCard
4920
+ return this._().each(function(component) {
4921
+ return component.controllerPath = Luca.components.Controller.controllerPath;
4196
4922
  });
4197
4923
  },
4198
4924
  each: function(fn) {
4199
4925
  var _this = this;
4200
4926
  return _(this.components).each(function(component) {
4201
- return fn.apply(_this, [component]);
4927
+ return fn.call(_this, component);
4202
4928
  });
4203
4929
  },
4204
4930
  activeSection: function() {
4205
- return this.get("activeSection");
4931
+ return this.get("active_section");
4932
+ },
4933
+ pageControllers: function(deep) {
4934
+ if (deep == null) deep = false;
4935
+ return this.controllers.apply(this, arguments);
4206
4936
  },
4207
4937
  controllers: function(deep) {
4208
4938
  if (deep == null) deep = false;
4209
- return this.select('ctype', 'controller', deep);
4939
+ return this.select(function(component) {
4940
+ var type;
4941
+ type = component.type || component.ctype;
4942
+ return type === "controller" || type === "page_controller";
4943
+ });
4944
+ },
4945
+ availablePages: function() {
4946
+ return this.availableSections.apply(this, arguments);
4210
4947
  },
4211
4948
  availableSections: function() {
4212
4949
  var base,
@@ -4218,37 +4955,43 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4218
4955
  return memo;
4219
4956
  }, base);
4220
4957
  },
4958
+ pageNames: function() {
4959
+ return this.sectionNames();
4960
+ },
4221
4961
  sectionNames: function(deep) {
4222
4962
  if (deep == null) deep = false;
4223
4963
  return this.pluck('name');
4224
- },
4225
- "default": function(callback) {
4226
- return this.navigate_to(this.defaultCard, callback);
4227
- },
4228
- navigate_to: function(section, callback) {
4229
- var _this = this;
4230
- section || (section = this.defaultCard);
4231
- this.activate(section, false, function(activator, previous, current) {
4232
- _this.state.set({
4233
- active_section: current.name
4234
- });
4235
- if (_.isFunction(callback)) return callback.apply(current);
4236
- });
4237
- return this.find(section);
4238
4964
  }
4239
4965
  });
4240
4966
 
4241
4967
  }).call(this);
4242
4968
  (function() {
4969
+ var buttonField;
4970
+
4971
+ buttonField = Luca.register("Luca.fields.ButtonField");
4243
4972
 
4244
- _.def('Luca.fields.ButtonField')["extends"]('Luca.core.Field')["with"]({
4973
+ buttonField["extends"]("Luca.core.Field");
4974
+
4975
+ buttonField.triggers("button:click");
4976
+
4977
+ buttonField.publicConfiguration({
4245
4978
  readOnly: true,
4979
+ input_value: void 0,
4980
+ input_type: "button",
4981
+ icon_class: void 0,
4982
+ input_name: void 0,
4983
+ white: void 0
4984
+ });
4985
+
4986
+ buttonField.privateConfiguration({
4987
+ isButton: true,
4988
+ template: "fields/button_field",
4246
4989
  events: {
4247
4990
  "click input": "click_handler"
4248
- },
4249
- hooks: ["button:click"],
4250
- className: 'luca-ui-field luca-ui-button-field',
4251
- template: 'fields/button_field',
4991
+ }
4992
+ });
4993
+
4994
+ buttonField.privateInterface({
4252
4995
  click_handler: function(e) {
4253
4996
  var me, my;
4254
4997
  me = my = $(e.currentTarget);
@@ -4268,7 +5011,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4268
5011
  this.input_id || (this.input_id = _.uniqueId('button'));
4269
5012
  this.input_name || (this.input_name = this.name || (this.name = this.input_id));
4270
5013
  this.input_value || (this.input_value = this.label || (this.label = this.text));
4271
- this.input_type || (this.input_type = "button");
4272
5014
  this.input_class || (this.input_class = this["class"]);
4273
5015
  this.icon_class || (this.icon_class = "");
4274
5016
  if (this.icon_class.length && !this.icon_class.match(/^icon-/)) {
@@ -4281,13 +5023,21 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4281
5023
  }
4282
5024
  });
4283
5025
 
5026
+ buttonField.defines({
5027
+ version: 1
5028
+ });
5029
+
4284
5030
  }).call(this);
4285
5031
  (function() {
4286
- var make;
5032
+ var checkboxArray, make;
4287
5033
 
4288
5034
  make = Luca.View.prototype.make;
4289
5035
 
4290
- _.def('Luca.fields.CheckboxArray')["extends"]('Luca.core.Field')["with"]({
5036
+ checkboxArray = Luca.register("Luca.fields.CheckboxArray");
5037
+
5038
+ checkboxArray["extends"]("Luca.core.Field");
5039
+
5040
+ checkboxArray.defines({
4291
5041
  version: 2,
4292
5042
  template: "fields/checkbox_array",
4293
5043
  className: "luca-ui-checkbox-array",
@@ -4298,7 +5048,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4298
5048
  initialize: function(options) {
4299
5049
  this.options = options != null ? options : {};
4300
5050
  _.extend(this, this.options);
4301
- _.extend(this, Luca.modules.Deferrable);
5051
+ _.extend(this, Luca.concerns.Deferrable);
4302
5052
  _.bindAll(this, "renderCheckboxes", "clickHandler", "checkSelected");
4303
5053
  Luca.core.Field.prototype.initialize.apply(this, arguments);
4304
5054
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4316,6 +5066,9 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4316
5066
  console.log("Error Configuring Collection", this, e.message);
4317
5067
  }
4318
5068
  cbArray = this;
5069
+ if (!Luca.isBackboneCollection(this.collection)) {
5070
+ throw "Checkbox Array Fields must specify a @collection property";
5071
+ }
4319
5072
  if (this.collection.length > 0) {
4320
5073
  return this.renderCheckboxes();
4321
5074
  } else {
@@ -4411,15 +5164,27 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4411
5164
 
4412
5165
  }).call(this);
4413
5166
  (function() {
5167
+ var checkboxField;
5168
+
5169
+ checkboxField = Luca.register("Luca.fields.CheckboxField");
4414
5170
 
4415
- _.def('Luca.fields.CheckboxField')["extends"]('Luca.core.Field')["with"]({
5171
+ checkboxField["extends"]("Luca.core.Field");
5172
+
5173
+ checkboxField.triggers("checked", "unchecked");
5174
+
5175
+ checkboxField.publicConfiguration({
5176
+ send_blanks: true,
5177
+ input_value: 1
5178
+ });
5179
+
5180
+ checkboxField.privateConfiguration({
5181
+ template: 'fields/checkbox_field',
4416
5182
  events: {
4417
5183
  "change input": "change_handler"
4418
- },
4419
- className: 'luca-ui-checkbox-field luca-ui-field',
4420
- template: 'fields/checkbox_field',
4421
- hooks: ["checked", "unchecked"],
4422
- send_blanks: true,
5184
+ }
5185
+ });
5186
+
5187
+ checkboxField.privateInterface({
4423
5188
  change_handler: function(e) {
4424
5189
  var me, my;
4425
5190
  me = my = $(e.target);
@@ -4434,14 +5199,14 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4434
5199
  this.options = options != null ? options : {};
4435
5200
  _.extend(this, this.options);
4436
5201
  _.bindAll(this, "change_handler");
4437
- return Luca.core.Field.prototype.initialize.apply(this, arguments);
4438
- },
4439
- afterInitialize: function() {
5202
+ Luca.core.Field.prototype.initialize.apply(this, arguments);
4440
5203
  this.input_id || (this.input_id = _.uniqueId('field'));
4441
5204
  this.input_name || (this.input_name = this.name);
4442
- this.input_value || (this.input_value = 1);
4443
5205
  return this.label || (this.label = this.name);
4444
- },
5206
+ }
5207
+ });
5208
+
5209
+ checkboxField.publicInterface({
4445
5210
  setValue: function(checked) {
4446
5211
  return this.getInputElement().attr('checked', checked);
4447
5212
  },
@@ -4450,10 +5215,20 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4450
5215
  }
4451
5216
  });
4452
5217
 
5218
+ checkboxField.defines({
5219
+ version: 1
5220
+ });
5221
+
4453
5222
  }).call(this);
4454
5223
  (function() {
5224
+ var fileUpload;
5225
+
5226
+ fileUpload = Luca.register("Luca.fields.FileUploadField");
5227
+
5228
+ fileUpload["extends"]("Luca.core.Field");
4455
5229
 
4456
- _.def('Luca.fields.FileUploadField')["extends"]('Luca.core.Field')["with"]({
5230
+ fileUpload.defines({
5231
+ version: 1,
4457
5232
  template: 'fields/file_upload_field',
4458
5233
  afterInitialize: function() {
4459
5234
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4465,8 +5240,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4465
5240
 
4466
5241
  }).call(this);
4467
5242
  (function() {
5243
+ var hiddenField;
5244
+
5245
+ hiddenField = Luca.register("Luca.fields.HiddenField");
4468
5246
 
4469
- _.def('Luca.fields.HiddenField')["extends"]('Luca.core.Field')["with"]({
5247
+ hiddenField["extends"]("Luca.core.Field");
5248
+
5249
+ hiddenField.defines({
4470
5250
  template: 'fields/hidden_field',
4471
5251
  afterInitialize: function() {
4472
5252
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4478,9 +5258,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4478
5258
 
4479
5259
  }).call(this);
4480
5260
  (function() {
5261
+ var labelField;
5262
+
5263
+ labelField = Luca.register("Luca.components.LabelField");
4481
5264
 
4482
- _.def("Luca.components.LabelField")["extends"]("Luca.core.Field")["with"]({
4483
- className: "luca-ui-field luca-ui-label-field",
5265
+ labelField["extends"]("Luca.core.Field");
5266
+
5267
+ labelField.defines({
4484
5268
  formatter: function(value) {
4485
5269
  value || (value = this.getValue());
4486
5270
  return _.str.titleize(value);
@@ -4494,13 +5278,18 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4494
5278
 
4495
5279
  }).call(this);
4496
5280
  (function() {
5281
+ var selectField;
5282
+
5283
+ selectField = Luca.register("Luca.fields.SelectField");
5284
+
5285
+ selectField["extends"]("Luca.core.Field");
5286
+
5287
+ selectField.triggers("after:select");
4497
5288
 
4498
- _.def('Luca.fields.SelectField')["extends"]('Luca.core.Field')["with"]({
5289
+ selectField.defines({
4499
5290
  events: {
4500
5291
  "change select": "change_handler"
4501
5292
  },
4502
- hooks: ["after:select"],
4503
- className: 'luca-ui-select-field luca-ui-field',
4504
5293
  template: "fields/select_field",
4505
5294
  includeBlank: true,
4506
5295
  blankValue: '',
@@ -4508,7 +5297,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4508
5297
  initialize: function(options) {
4509
5298
  this.options = options != null ? options : {};
4510
5299
  _.extend(this, this.options);
4511
- _.extend(this, Luca.modules.Deferrable);
5300
+ _.extend(this, Luca.concerns.Deferrable);
4512
5301
  _.bindAll(this, "change_handler", "populateOptions", "beforeFetch");
4513
5302
  Luca.core.Field.prototype.initialize.apply(this, arguments);
4514
5303
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4603,13 +5392,14 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4603
5392
  initialize: function(options) {
4604
5393
  this.options = options != null ? options : {};
4605
5394
  _.bindAll(this, "keydown_handler");
4606
- Luca.core.Field.prototype.initialize.apply(this, arguments);
4607
5395
  this.input_id || (this.input_id = _.uniqueId('field'));
4608
5396
  this.input_name || (this.input_name = this.name);
4609
5397
  this.label || (this.label = this.name);
4610
5398
  this.input_class || (this.input_class = this["class"]);
4611
5399
  this.input_value || (this.input_value = "");
4612
- return this.inputStyles || (this.inputStyles = "height:" + this.height + ";width:" + this.width);
5400
+ this.inputStyles || (this.inputStyles = "height:" + this.height + ";width:" + this.width);
5401
+ this.placeHolder || (this.placeHolder = "");
5402
+ return Luca.core.Field.prototype.initialize.apply(this, arguments);
4613
5403
  },
4614
5404
  setValue: function(value) {
4615
5405
  return $(this.field()).val(value);
@@ -4636,8 +5426,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4636
5426
 
4637
5427
  }).call(this);
4638
5428
  (function() {
5429
+ var textField;
5430
+
5431
+ textField = Luca.register('Luca.fields.TextField');
4639
5432
 
4640
- _.def('Luca.fields.TextField')["extends"]('Luca.core.Field')["with"]({
5433
+ textField["extends"]('Luca.core.Field');
5434
+
5435
+ textField.defines({
4641
5436
  events: {
4642
5437
  "blur input": "blur_handler",
4643
5438
  "focus input": "focus_handler",
@@ -4663,6 +5458,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4663
5458
  this.$el.addClass('input-append');
4664
5459
  this.addOn = this.append;
4665
5460
  }
5461
+ this.placeHolder || (this.placeHolder = "");
4666
5462
  return Luca.core.Field.prototype.initialize.apply(this, arguments);
4667
5463
  },
4668
5464
  keyup_handler: function(e) {
@@ -4681,9 +5477,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4681
5477
 
4682
5478
  }).call(this);
4683
5479
  (function() {
5480
+ var typeAheadField;
5481
+
5482
+ typeAheadField = Luca.register("Luca.fields.TypeAheadField");
5483
+
5484
+ typeAheadField["extends"]("Luca.fields.TextField");
4684
5485
 
4685
- _.def('Luca.fields.TypeAheadField')["extends"]('Luca.fields.TextField')["with"]({
4686
- className: 'luca-ui-field',
5486
+ typeAheadField.defines({
4687
5487
  getSource: function() {
4688
5488
  return Luca.util.read(this.source) || [];
4689
5489
  },
@@ -4705,13 +5505,19 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4705
5505
 
4706
5506
  }).call(this);
4707
5507
  (function() {
5508
+ var toolbar;
4708
5509
 
4709
- _.def('Luca.components.FormButtonToolbar')["extends"]('Luca.components.Toolbar')["with"]({
5510
+ toolbar = Luca.register("Luca.components.FormButtonToolbar");
5511
+
5512
+ toolbar["extends"]("Luca.components.Toolbar");
5513
+
5514
+ toolbar.defines({
4710
5515
  className: 'luca-ui-form-toolbar form-actions',
4711
5516
  position: 'bottom',
4712
5517
  includeReset: false,
4713
5518
  render: function() {
4714
- return $(this.container).append(this.el);
5519
+ $(this.container).append(this.el);
5520
+ return this;
4715
5521
  },
4716
5522
  initialize: function(options) {
4717
5523
  this.options = options != null ? options : {};
@@ -4735,11 +5541,17 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4735
5541
 
4736
5542
  }).call(this);
4737
5543
  (function() {
5544
+ var formView;
5545
+
5546
+ formView = Luca.register("Luca.components.FormView");
4738
5547
 
4739
- _.def("Luca.components.FormView")["extends"]('Luca.core.Container')["with"]({
5548
+ formView["extends"]("Luca.core.Container");
5549
+
5550
+ formView.triggers("before:submit", "before:reset", "before:load", "before:load:new", "before:load:existing", "after:submit", "after:reset", "after:load", "after:load:new", "after:load:existing", "after:submit:success", "after:submit:fatal_error", "after:submit:error");
5551
+
5552
+ formView.defines({
4740
5553
  tagName: 'form',
4741
5554
  className: 'luca-ui-form-view',
4742
- hooks: ["before:submit", "before:reset", "before:load", "before:load:new", "before:load:existing", "after:submit", "after:reset", "after:load", "after:load:new", "after:load:existing", "after:submit:success", "after:submit:fatal_error", "after:submit:error"],
4743
5555
  events: {
4744
5556
  "click .submit-button": "submitHandler",
4745
5557
  "click .reset-button": "resetHandler"
@@ -4747,13 +5559,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4747
5559
  toolbar: true,
4748
5560
  legend: "",
4749
5561
  bodyClassName: "form-view-body",
4750
- version: "0.9.33333333",
5562
+ version: 1,
4751
5563
  initialize: function(options) {
4752
5564
  this.options = options != null ? options : {};
4753
- if (this.loadMask == null) this.loadMask = Luca.enableBootstrap;
5565
+ if (this.loadMask == null) this.loadMask = Luca.config.enableBoostrap;
4754
5566
  Luca.core.Container.prototype.initialize.apply(this, arguments);
4755
5567
  this.components || (this.components = this.fields);
4756
- _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars", "applyLoadMask");
5568
+ _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars");
4757
5569
  this.state || (this.state = new Backbone.Model);
4758
5570
  this.setupHooks(this.hooks);
4759
5571
  this.applyStyleClasses();
@@ -4770,7 +5582,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4770
5582
  return Luca.components.FormView.defaultFormViewToolbar;
4771
5583
  },
4772
5584
  applyStyleClasses: function() {
4773
- if (Luca.enableBootstrap) this.applyBootstrapStyleClasses();
5585
+ if (Luca.config.enableBoostrap) this.applyBootstrapStyleClasses();
4774
5586
  if (this.labelAlign) this.$el.addClass("label-align-" + this.labelAlign);
4775
5587
  if (this.fieldLayoutClass) return this.$el.addClass(this.fieldLayoutClass);
4776
5588
  },
@@ -4900,7 +5712,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4900
5712
  if (options.debug) {
4901
5713
  console.log("" + key + " Options", options, "Value", value, "Value Is Blank?", valueIsBlank, "Allow Blanks?", allowBlankValues);
4902
5714
  }
4903
- if (options.skip_buttons && field.ctype === "button_field") {
5715
+ if (options.skip_buttons && field.isButton) {
4904
5716
  skip = true;
4905
5717
  } else {
4906
5718
  if (valueIsBlank && allowBlankValues === false) skip = true;
@@ -5027,8 +5839,8 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5027
5839
  var _this = this;
5028
5840
  this.options = options != null ? options : {};
5029
5841
  _.extend(this, this.options);
5030
- _.extend(this, Luca.modules.Deferrable);
5031
- if (this.loadMask == null) this.loadMask = Luca.enableBootstrap;
5842
+ _.extend(this, Luca.concerns.Deferrable);
5843
+ if (this.loadMask == null) this.loadMask = Luca.config.enableBoostrap;
5032
5844
  if (this.loadMask === true) {
5033
5845
  this.loadMaskEl || (this.loadMaskEl = ".luca-ui-g-view-body");
5034
5846
  }
@@ -5090,7 +5902,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5090
5902
  var _ref;
5091
5903
  return (_ref = _this.wrapper) != null ? _ref.addClass(containerClass) : void 0;
5092
5904
  });
5093
- if (Luca.enableBootstrap) this.table.addClass('table');
5905
+ if (Luca.config.enableBoostrap) this.table.addClass('table');
5094
5906
  return _((_ref = this.tableStyle) != null ? _ref.split(" ") : void 0).each(function(style) {
5095
5907
  return _this.table.addClass("table-" + style);
5096
5908
  });
@@ -5255,15 +6067,15 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5255
6067
  (function() {
5256
6068
  var multiView, propagateCollectionComponents, validateComponent;
5257
6069
 
5258
- multiView = Luca.define("Luca.components.MultiCollectionView");
6070
+ multiView = Luca.register("Luca.components.MultiCollectionView");
5259
6071
 
5260
6072
  multiView["extends"]("Luca.containers.CardView");
5261
6073
 
5262
- multiView.behavesAs("LoadMaskable", "Filterable", "Paginatable");
6074
+ multiView.mixesIn("QueryCollectionBindings", "LoadMaskable", "Filterable", "Paginatable");
5263
6075
 
5264
6076
  multiView.triggers("before:refresh", "after:refresh", "refresh", "empty:results");
5265
6077
 
5266
- multiView.defaultsTo({
6078
+ multiView.defines({
5267
6079
  version: 1,
5268
6080
  stateful: true,
5269
6081
  defaultState: {
@@ -5279,11 +6091,10 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5279
6091
  view = _ref[_i];
5280
6092
  validateComponent(view);
5281
6093
  }
6094
+ Luca.containers.CardView.prototype.initialize.apply(this, arguments);
5282
6095
  this.on("refresh", this.refresh, this);
5283
6096
  this.on("after:card:switch", this.refresh, this);
5284
- this.on("after:components", propagateCollectionComponents, this);
5285
- this.debug("multi collection , proto initialize");
5286
- return Luca.containers.CardView.prototype.initialize.apply(this, arguments);
6097
+ return this.on("after:components", propagateCollectionComponents, this);
5287
6098
  },
5288
6099
  relayAfterRefresh: function(models, query, options) {
5289
6100
  return this.trigger("after:refresh", models, query, options);
@@ -5291,38 +6102,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5291
6102
  refresh: function() {
5292
6103
  var _ref;
5293
6104
  return (_ref = this.activeComponent()) != null ? _ref.trigger("refresh") : void 0;
5294
- },
5295
- getCollection: function() {
5296
- return this.collection;
5297
- },
5298
- applyQuery: function(query, queryOptions) {
5299
- if (query == null) query = {};
5300
- if (queryOptions == null) queryOptions = {};
5301
- this.query = query;
5302
- this.queryOptions = queryOptions;
5303
- return this;
5304
- },
5305
- getQuery: function() {
5306
- var query, querySource, _i, _len, _ref;
5307
- this.debug("Get Query");
5308
- query = this.query || (this.query = {});
5309
- _ref = this.querySources;
5310
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5311
- querySource = _ref[_i];
5312
- query = _.extend(query, querySource() || {});
5313
- }
5314
- return query;
5315
- },
5316
- getQueryOptions: function() {
5317
- var optionSource, options, _i, _len, _ref;
5318
- this.debug("Get Query Options");
5319
- options = this.queryOptions || (this.queryOptions = {});
5320
- _ref = this.optionsSources;
5321
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5322
- optionSource = _ref[_i];
5323
- options = _.extend(options, optionSource() || {});
5324
- }
5325
- return options;
5326
6105
  }
5327
6106
  });
5328
6107
 
@@ -5412,11 +6191,12 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5412
6191
  "click a.prev": "previousPage"
5413
6192
  },
5414
6193
  afterInitialize: function() {
5415
- var _this = this;
6194
+ var _ref,
6195
+ _this = this;
5416
6196
  _.bindAll(this, "updateWithPageCount");
5417
- return this.state.on("change", function(state, numberOfPages) {
6197
+ return (_ref = this.state) != null ? _ref.on("change", function(state, numberOfPages) {
5418
6198
  return _this.updateWithPageCount(state.get('numberOfPages'));
5419
- });
6199
+ }) : void 0;
5420
6200
  },
5421
6201
  limit: function() {
5422
6202
  var _ref;
@@ -5475,7 +6255,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5475
6255
  this.pageCount = pageCount;
5476
6256
  if (models == null) models = [];
5477
6257
  modelCount = models.length;
5478
- console.log("Update With Page Count", this.pageCount, modelCount);
5479
6258
  this.pageButtonContainer().empty();
5480
6259
  _(this.pageCount).times(function(index) {
5481
6260
  var button, page;
@@ -5732,15 +6511,17 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5732
6511
  "": "default"
5733
6512
  },
5734
6513
  initialize: function(options) {
5735
- var _this = this;
6514
+ var _ref,
6515
+ _this = this;
5736
6516
  this.options = options;
5737
6517
  _.extend(this, this.options);
5738
6518
  this.routeHandlers = _(this.routes).values();
5739
- return _(this.routeHandlers).each(function(route_id) {
6519
+ _(this.routeHandlers).each(function(route_id) {
5740
6520
  return _this.bind("route:" + route_id, function() {
5741
6521
  return _this.trigger.apply(_this, ["change:navigation", route_id].concat(_(arguments).flatten()));
5742
6522
  });
5743
6523
  });
6524
+ return (_ref = Backbone.Router.initialize) != null ? _ref.apply(this, arguments) : void 0;
5744
6525
  },
5745
6526
  navigate: function(route, triggerRoute) {
5746
6527
  if (triggerRoute == null) triggerRoute = false;
@@ -5773,22 +6554,25 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5773
6554
  itemTagName: "tr",
5774
6555
  stateful: true,
5775
6556
  observeChanges: true,
6557
+ widths: [],
5776
6558
  columns: [],
5777
6559
  emptyText: "There are no results to display",
5778
6560
  itemRenderer: function(item, model) {
5779
6561
  return Luca.components.TableView.rowRenderer.call(this, item, model);
5780
6562
  },
5781
6563
  initialize: function(options) {
5782
- var column,
6564
+ var column, index, width,
5783
6565
  _this = this;
5784
6566
  this.options = options != null ? options : {};
5785
6567
  Luca.components.CollectionView.prototype.initialize.apply(this, arguments);
6568
+ index = 0;
5786
6569
  this.columns = (function() {
5787
6570
  var _i, _len, _ref, _results;
5788
6571
  _ref = this.columns;
5789
6572
  _results = [];
5790
6573
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5791
6574
  column = _ref[_i];
6575
+ if (width = this.widths[index]) column.width = width;
5792
6576
  if (_.isString(column)) {
5793
6577
  column = {
5794
6578
  reader: column
@@ -5797,6 +6581,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5797
6581
  if (!(column.header != null)) {
5798
6582
  column.header = _.str.titleize(_.str.humanize(column.reader));
5799
6583
  }
6584
+ index++;
5800
6585
  _results.push(column);
5801
6586
  }
5802
6587
  return _results;