luca 0.9.42 → 0.9.65

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. data/CHANGELOG +50 -9
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +2 -0
  4. data/README.md +5 -0
  5. data/assets/javascripts/dependencies/underscore-min.js +5 -31
  6. data/lib/generators/luca/application/application_generator.rb +71 -0
  7. data/lib/generators/luca/application/templates/controller.rb +6 -0
  8. data/lib/generators/luca/application/templates/index.html.erb +7 -0
  9. data/lib/generators/luca/application/templates/index.html.haml +6 -0
  10. data/lib/generators/luca/application/templates/javascripts/application.js +28 -0
  11. data/lib/generators/luca/application/templates/javascripts/application.js.coffee +20 -0
  12. data/lib/generators/luca/application/templates/javascripts/config.js +15 -0
  13. data/lib/generators/luca/application/templates/javascripts/config.js.coffee +9 -0
  14. data/lib/generators/luca/application/templates/javascripts/dependencies.js +5 -0
  15. data/lib/generators/luca/application/templates/javascripts/dependencies.js.coffee +5 -0
  16. data/lib/generators/luca/application/templates/javascripts/index.js +9 -0
  17. data/lib/generators/luca/application/templates/javascripts/index.js.coffee +9 -0
  18. data/lib/generators/luca/application/templates/javascripts/main.js +8 -0
  19. data/lib/generators/luca/application/templates/javascripts/main.js.coffee +3 -0
  20. data/lib/generators/luca/application/templates/javascripts/main.jst.ejs +1 -0
  21. data/lib/generators/luca/application/templates/javascripts/router.js +12 -0
  22. data/lib/generators/luca/application/templates/javascripts/router.js.coffee +7 -0
  23. data/lib/luca/rails/version.rb +1 -1
  24. data/spec/components/collection_view_spec.coffee +59 -0
  25. data/spec/components/multi_collection_view_spec.coffee +5 -0
  26. data/{src/templates/components/form_alert → spec/components/pagination_control_spec.coffee} +0 -0
  27. data/spec/components/table_view_spec.coffee +17 -0
  28. data/spec/core/container_spec.coffee +127 -5
  29. data/spec/core/model_spec.coffee +21 -3
  30. data/spec/define_spec.coffee +19 -0
  31. data/spec/mixin_spec.coffee +49 -0
  32. data/spec/modules/filterable_spec.coffee +25 -0
  33. data/spec/modules/paginatable_spec.coffee +0 -0
  34. data/spec/modules/state_model_spec.coffee +0 -0
  35. data/src/components/application.coffee +52 -38
  36. data/src/components/collection_view.coffee +118 -45
  37. data/src/components/fields/checkbox_field.coffee +2 -2
  38. data/src/components/fields/file_upload_field.coffee +0 -3
  39. data/src/components/fields/hidden_field.coffee +0 -3
  40. data/src/components/fields/label_field.coffee +1 -4
  41. data/src/components/fields/select_field.coffee +6 -6
  42. data/src/components/fields/text_area_field.coffee +1 -0
  43. data/src/components/fields/text_field.coffee +4 -0
  44. data/src/components/fields/type_ahead_field.coffee +5 -9
  45. data/src/components/form_view.coffee +28 -23
  46. data/src/components/multi_collection_view.coffee +121 -0
  47. data/src/components/pagination_control.coffee +106 -0
  48. data/src/components/table_view.coffee +22 -13
  49. data/src/containers/card_view.coffee +44 -11
  50. data/src/containers/panel_toolbar.coffee +88 -82
  51. data/src/containers/tab_view.coffee +3 -3
  52. data/src/core/collection.coffee +11 -4
  53. data/src/core/container.coffee +206 -122
  54. data/src/core/field.coffee +13 -10
  55. data/src/core/model.coffee +23 -27
  56. data/src/core/registry.coffee +42 -29
  57. data/src/core/view.coffee +63 -149
  58. data/src/define.coffee +91 -19
  59. data/src/framework.coffee +11 -9
  60. data/src/managers/collection_manager.coffee +24 -8
  61. data/src/modules/application_event_bindings.coffee +19 -0
  62. data/src/modules/collection_event_bindings.coffee +26 -0
  63. data/src/modules/deferrable.coffee +3 -1
  64. data/src/modules/dom_helpers.coffee +49 -0
  65. data/src/modules/enhanced_properties.coffee +23 -0
  66. data/src/modules/filterable.coffee +82 -0
  67. data/src/modules/grid_layout.coffee +13 -1
  68. data/src/modules/{load_mask.coffee → loadmaskable.coffee} +10 -4
  69. data/src/modules/modal_view.coffee +38 -0
  70. data/src/modules/paginatable.coffee +87 -0
  71. data/src/modules/state_model.coffee +16 -0
  72. data/src/modules/templating.coffee +8 -0
  73. data/src/plugins/events.coffee +30 -2
  74. data/src/templates/components/bootstrap_form_controls.jst.ejs +10 -0
  75. data/src/templates/components/collection_loader_view.jst.ejs +6 -0
  76. data/src/templates/components/form_alert.jst.ejs +4 -0
  77. data/src/templates/components/grid_view.jst.ejs +11 -0
  78. data/src/templates/components/grid_view_empty_text.jst.ejs +3 -0
  79. data/src/templates/components/load_mask.jst.ejs +5 -0
  80. data/src/templates/components/nav_bar.jst.ejs +4 -0
  81. data/src/templates/components/pagination.jst.ejs +10 -0
  82. data/src/templates/containers/basic.jst.ejs +1 -0
  83. data/src/templates/containers/tab_selector_container.jst.ejs +12 -0
  84. data/src/templates/containers/tab_view.jst.ejs +2 -0
  85. data/src/templates/containers/toolbar_wrapper.jst.ejs +1 -0
  86. data/src/templates/fields/button_field.jst.ejs +2 -0
  87. data/src/templates/fields/button_field_link.jst.ejs +6 -0
  88. data/src/templates/fields/checkbox_array.jst.ejs +4 -0
  89. data/src/templates/fields/checkbox_array_item.jst.ejs +3 -0
  90. data/src/templates/fields/checkbox_field.jst.ejs +10 -0
  91. data/src/templates/fields/file_upload_field.jst.ejs +10 -0
  92. data/src/templates/fields/hidden_field.jst.ejs +1 -0
  93. data/src/templates/fields/select_field.jst.ejs +11 -0
  94. data/src/templates/fields/text_area_field.jst.ejs +11 -0
  95. data/src/templates/fields/text_field.jst.ejs +16 -0
  96. data/src/templates/table_view.jst.ejs +4 -0
  97. data/src/tools/console.coffee +51 -21
  98. data/src/util.coffee +17 -4
  99. data/vendor/assets/javascripts/luca-ui-base.js +5304 -0
  100. data/vendor/assets/javascripts/luca-ui-bootstrap.js +9 -0
  101. data/vendor/assets/javascripts/luca-ui-development-tools.js +52 -24
  102. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
  103. data/vendor/assets/javascripts/luca-ui-full.js +1700 -595
  104. data/vendor/assets/javascripts/luca-ui-full.min.js +7 -6
  105. data/vendor/assets/javascripts/luca-ui-spec.js +6815 -0
  106. data/vendor/assets/javascripts/luca-ui-templates.js +92 -24
  107. data/vendor/assets/javascripts/luca-ui.js +1695 -564
  108. data/vendor/assets/javascripts/luca-ui.min.js +4 -4
  109. metadata +69 -28
  110. data/src/templates/components/bootstrap_form_controls.luca +0 -7
  111. data/src/templates/components/collection_loader_view.luca +0 -5
  112. data/src/templates/components/form_alert.luca +0 -3
  113. data/src/templates/components/grid_view.luca +0 -7
  114. data/src/templates/components/grid_view_empty_text.luca +0 -3
  115. data/src/templates/components/load_mask.luca +0 -3
  116. data/src/templates/components/nav_bar.luca +0 -2
  117. data/src/templates/containers/basic.luca +0 -1
  118. data/src/templates/containers/tab_selector_container.luca +0 -8
  119. data/src/templates/containers/tab_view.luca +0 -2
  120. data/src/templates/containers/toolbar_wrapper.luca +0 -1
  121. data/src/templates/fields/button_field.luca +0 -2
  122. data/src/templates/fields/button_field_link.luca +0 -5
  123. data/src/templates/fields/checkbox_array.luca +0 -4
  124. data/src/templates/fields/checkbox_array_item.luca +0 -4
  125. data/src/templates/fields/checkbox_field.luca +0 -9
  126. data/src/templates/fields/file_upload_field.luca +0 -8
  127. data/src/templates/fields/hidden_field.luca +0 -1
  128. data/src/templates/fields/select_field.luca +0 -8
  129. data/src/templates/fields/text_area_field.luca +0 -8
  130. data/src/templates/fields/text_field.luca +0 -17
  131. data/src/templates/sample/contents.luca +0 -1
  132. data/src/templates/sample/welcome.luca +0 -1
  133. data/src/templates/table_view.luca +0 -4
@@ -18,7 +18,7 @@
18
18
  };
19
19
 
20
20
  _.extend(Luca, {
21
- VERSION: "0.9.42",
21
+ VERSION: "0.9.65",
22
22
  core: {},
23
23
  containers: {},
24
24
  components: {},
@@ -26,18 +26,21 @@
26
26
  util: {},
27
27
  fields: {},
28
28
  registry: {},
29
- options: {}
29
+ options: {},
30
+ config: {}
30
31
  });
31
32
 
32
33
  _.extend(Luca, Backbone.Events);
33
34
 
34
- Luca.autoRegister = true;
35
+ Luca.autoRegister = Luca.config.autoRegister = true;
35
36
 
36
- Luca.developmentMode = false;
37
+ Luca.developmentMode = Luca.config.developmentMode = false;
37
38
 
38
- Luca.enableGlobalObserver = false;
39
+ Luca.enableGlobalObserver = Luca.config.enableGlobalObserver = false;
39
40
 
40
- Luca.enableBootstrap = true;
41
+ Luca.enableBootstrap = Luca.config.enableBootstrap = true;
42
+
43
+ Luca.config.enhancedViewProperties = true;
41
44
 
42
45
  Luca.keys = {
43
46
  ENTER: 13,
@@ -55,8 +58,8 @@
55
58
  return memo;
56
59
  }, {});
57
60
 
58
- Luca.find = function() {
59
- return;
61
+ Luca.find = function(el) {
62
+ return Luca($(el).data('luca-id'));
60
63
  };
61
64
 
62
65
  Luca.supportsEvents = Luca.supportsBackboneEvents = function(obj) {
@@ -227,42 +230,134 @@
227
230
  _.mixin(UnderscoreExtensions);
228
231
 
229
232
  }).call(this);
230
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["components/bootstrap_form_controls"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'form-actions\'>\n <a class=\'btn btn-primary submit-button\'>\n <i class=\'icon-ok icon-white\'></i>\n Save Changes\n </a>\n <a class=\'btn reset-button cancel-button\'>\n <i class=\'icon-remove\'></i>\n Cancel\n </a>\n</div>\n');}return __p.join('');}; }).call(this);
231
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["components/collection_loader_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'modal\' id=\'progress-model\' style=\'display: none;\'>\n <div class=\'progress progress-info progress-striped active\'>\n <div class=\'bar\' style=\'width: 0%;\'></div>\n </div>\n <div class=\'message\'>\n Initializing...\n </div>\n</div>\n');}return __p.join('');}; }).call(this);
232
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["components/form_alert"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'', className ,'\'>\n <a class=\'close\' data-dismiss=\'alert\' href=\'#\'>x</a>\n ', message ,'\n</div>\n');}return __p.join('');}; }).call(this);
233
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["components/grid_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'luca-ui-g-view-wrapper\'>\n <div class=\'g-view-header\'></div>\n <div class=\'luca-ui-g-view-body\'>\n <table cellpadding=\'0\' cellspacing=\'0\' class=\'luca-ui-g-view scrollable-table\' width=\'100%\'>\n <thead class=\'fixed\'></thead>\n <tbody class=\'scrollable\'></tbody>\n </table>\n </div>\n <div class=\'luca-ui-g-view-footer\'></div>\n</div>\n');}return __p.join('');}; }).call(this);
234
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["components/grid_view_empty_text"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'empty-text-wrapper\'>\n <p>\n ', text ,'\n </p>\n</div>\n');}return __p.join('');}; }).call(this);
235
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["components/load_mask"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'load-mask\'>\n <div class=\'progress progress-striped active\'>\n <div class=\'bar\' style=\'width:1%\'></div>\n </div>\n</div>\n');}return __p.join('');}; }).call(this);
236
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["components/nav_bar"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'navbar-inner\'>\n <div class=\'luca-ui-navbar-body container\'></div>\n</div>\n');}return __p.join('');}; }).call(this);
237
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["containers/basic"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'', classes ,'\' id=\'', id ,'\' style=\'', style ,'\'></div>\n');}return __p.join('');}; }).call(this);
238
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["containers/tab_selector_container"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'tab-selector-container\' id=\'', cid ,'-tab-selector\'>\n <ul class=\'nav nav-tabs\' id=\'', cid ,'-tabs-nav\'>\n '); for(var i = 0; i < components.length; i++ ) { __p.push('\n '); var component = components[i];__p.push('\n <li class=\'tab-selector\' data-target=\'', i ,'\'>\n <a data-target=\'', i ,'\'>\n ', component.title ,'\n </a>\n </li>\n '); } __p.push('\n </ul>\n</div>\n');}return __p.join('');}; }).call(this);
239
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["containers/tab_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<ul class=\'nav ', navClass ,'\' id=\'', cid ,'-tabs-selector\'></ul>\n<div class=\'tab-content\' id=\'', cid ,'-tab-view-content\'></div>\n');}return __p.join('');}; }).call(this);
240
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["containers/toolbar_wrapper"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'luca-ui-toolbar-wrapper\' id=\'', id ,'\'></div>\n');}return __p.join('');}; }).call(this);
241
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["fields/button_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label>&nbsp</label>\n<input class=\'btn ', input_class ,'\' id=\'', input_id ,'\' style=\'', inputStyles ,'\' type=\'', input_type ,'\' value=\'', input_value ,'\' />\n');}return __p.join('');}; }).call(this);
242
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["fields/button_field_link"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<a class=\'btn ', input_class ,'\'>\n '); if(icon_class.length) { __p.push('\n <i class=\'', icon_class ,'\'></i>\n '); } __p.push('\n ', input_value ,'\n</a>\n');}return __p.join('');}; }).call(this);
243
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["fields/checkbox_array"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'control-group\'>\n <label for=\'', input_id ,'\'>\n ', label ,'\n </label>\n <div class=\'controls\'></div>\n</div>\n');}return __p.join('');}; }).call(this);
244
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["fields/checkbox_array_item"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label for=\'', input_id ,'\'>\n <input id=\'', input_id ,'\' name=\'', input_name ,'\' type=\'checkbox\' value=\'', value ,'\' />\n ', label ,'\n</label>\n');}return __p.join('');}; }).call(this);
245
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["fields/checkbox_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label for=\'', input_id ,'\'>\n ', label ,'\n <input name=\'', input_name ,'\' style=\'', inputStyles ,'\' type=\'checkbox\' value=\'', input_value ,'\' />\n</label>\n'); if(helperText) { __p.push('\n<p class=\'helper-text help-block\'>\n ', helperText ,'\n</p>\n'); } __p.push('\n');}return __p.join('');}; }).call(this);
246
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["fields/file_upload_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<input id=\'', input_id ,'\' name=\'', input_name ,'\' style=\'', inputStyles ,'\' type=\'file\' />\n'); if(helperText) { __p.push('\n<p class=\'helper-text help-block\'>\n ', helperText ,'\n</p>\n'); } __p.push('\n');}return __p.join('');}; }).call(this);
247
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["fields/hidden_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<input id=\'', input_id ,'\' name=\'', input_name ,'\' type=\'hidden\' value=\'', input_value ,'\' />\n');}return __p.join('');}; }).call(this);
248
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["fields/select_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 <select id=\'', input_id ,'\' name=\'', input_name ,'\' style=\'', inputStyles ,'\'></select>\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('');}; }).call(this);
249
- (function() {Luca.templates || (Luca.templates = {}); Luca.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<textarea class=\'', input_class ,'\' id=\'', input_id ,'\' name=\'', input_name ,'\' style=\'', inputStyles ,'\'></textarea>\n'); if(helperText) { __p.push('\n<p class=\'helper-text help-block\'>\n ', helperText ,'\n</p>\n'); } __p.push('\n');}return __p.join('');}; }).call(this);
250
- (function() {Luca.templates || (Luca.templates = {}); Luca.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 ,'\'>\n ', label ,'\n</label>\n'); } __p.push('\n<div class=\'controls\'>\n '); if( typeof(addOn) !== "undefined" ) { __p.push('\n <span class=\'add-on\'>\n ', addOn ,'\n </span>\n '); } __p.push('\n <input class=\'', input_class ,'\' id=\'', input_id ,'\' name=\'', input_name ,'\' placeholder=\'', placeHolder ,'\' style=\'', inputStyles ,'\' type=\'text\' />\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('');}; }).call(this);
251
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["sample/contents"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<p>Sample Contents</p>\n');}return __p.join('');}; }).call(this);
252
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["sample/welcome"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('welcome.luca\n');}return __p.join('');}; }).call(this);
253
- (function() {Luca.templates || (Luca.templates = {}); Luca.templates["table_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<thead></thead>\n<tbody class=\'table-body\'></tbody>\n<tfoot></tfoot>\n<caption></caption>\n');}return __p.join('');}; }).call(this);
254
233
  (function() {
255
- var currentNamespace;
234
+ this.JST || (this.JST = {});
235
+ this.JST["luca-src/templates/components/bootstrap_form_controls"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class="btn-group form-actions">\n <a class="btn btn-primary submit-button">\n <i class="icon icon-ok icon-white"></i>\n Save Changes\n </a>\n <a class="btn reset-button cancel-button">\n <i class="icon icon-remove"></i>\n Cancel\n </a>\n</div>\n');}return __p.join('');};
236
+ }).call(this);
237
+ (function() {
238
+ this.JST || (this.JST = {});
239
+ this.JST["luca-src/templates/components/collection_loader_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div id="progress-modal" class="modal" style="display: none">\n <div class="progress progress-info progress-striped active">\n <div class="bar" style="width:0%;"></div>\n </div>\n <div class="message">Initializing...</div>\n</div>\n');}return __p.join('');};
240
+ }).call(this);
241
+ (function() {
242
+ this.JST || (this.JST = {});
243
+ this.JST["luca-src/templates/components/form_alert"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class="', className ,'">\n <a class="close" href="#" data-dismiss="alert">x</a>\n ', message ,'\n</div>\n');}return __p.join('');};
244
+ }).call(this);
245
+ (function() {
246
+ this.JST || (this.JST = {});
247
+ this.JST["luca-src/templates/components/grid_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class="luca-ui-g-view-wrapper">\n <div class="g-view-header"></div>\n <div class="luca-ui-g-view-body">\n <table class="luca-ui-g-view scrollable-table" width="100%" cellpadding=0 cellspacing=0>\n <thead class="fixed"></thead>\n <tbody class="scrollable"></tbody>\n <tfoot></tfoot>\n </table>\n </div>\n <div class="luca-ui-g-view-header"></div>\n</div>\n');}return __p.join('');};
248
+ }).call(this);
249
+ (function() {
250
+ this.JST || (this.JST = {});
251
+ this.JST["luca-src/templates/components/grid_view_empty_text"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class="empty-text empty-text-wrapper">\n <p>', text ,'</p>\n</div>\n');}return __p.join('');};
252
+ }).call(this);
253
+ (function() {
254
+ this.JST || (this.JST = {});
255
+ this.JST["luca-src/templates/components/load_mask"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class="load-mask">\n <div class="progress progress-striped active">\n <div class="bar" style="width:0%"></div>\n </div>\n</div>\n');}return __p.join('');};
256
+ }).call(this);
257
+ (function() {
258
+ this.JST || (this.JST = {});
259
+ this.JST["luca-src/templates/components/nav_bar"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class="navbar-inner">\n <div class="luca-ui-navbar-body container">\n </div>\n</div>\n');}return __p.join('');};
260
+ }).call(this);
261
+ (function() {
262
+ this.JST || (this.JST = {});
263
+ this.JST["luca-src/templates/components/pagination"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class="pagination">\n <a class="btn previous">\n <i class="icon icon-chevron-left"></i>\n </a>\n <div class="pagination-group">\n </div>\n <a class="btn next">\n <i class="icon icon-chevron-right"></i>\n </a>\n</div>\n');}return __p.join('');};
264
+ }).call(this);
265
+ (function() {
266
+ this.JST || (this.JST = {});
267
+ this.JST["luca-src/templates/containers/basic"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div id="', id ,'" class="', classes ,'" style="', style ,'"></div>\n');}return __p.join('');};
268
+ }).call(this);
269
+ (function() {
270
+ this.JST || (this.JST = {});
271
+ this.JST["luca-src/templates/containers/tab_selector_container"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div id="', cid ,'-tab-selector" class="tab-selector-container">\n <ul id="', cid ,'-tabs-nav" class="nav nav-tabs">\n '); for(var i = 0; i < components.length; i++ ) { __p.push('\n '); var component = components[i];__p.push('\n <li class="tab-selector" data-target="', i ,'">\n <a data-target="', i ,'">\n ', component.title ,'\n </a>\n </li>\n '); } __p.push('\n </ul>\n</div>\n');}return __p.join('');};
272
+ }).call(this);
273
+ (function() {
274
+ this.JST || (this.JST = {});
275
+ this.JST["luca-src/templates/containers/tab_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<ul id="', cid ,'-tabs-selector" class="nav ', navClass ,'"></ul>\n<div id="', cid ,'-tab-view-content" class="tab-content"></div>\n');}return __p.join('');};
276
+ }).call(this);
277
+ (function() {
278
+ this.JST || (this.JST = {});
279
+ this.JST["luca-src/templates/containers/toolbar_wrapper"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class="luca-ui-toolbar-wrapper" id="', id ,'"></div>\n');}return __p.join('');};
280
+ }).call(this);
281
+ (function() {
282
+ this.JST || (this.JST = {});
283
+ this.JST["luca-src/templates/fields/button_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label>&nbsp;</label>\n<input style="', inputStyles ,'" class="btn ', input_class ,'" value="', input_value ,'" type="', input_type ,'" id="<%= input_id" />\n');}return __p.join('');};
284
+ }).call(this);
285
+ (function() {
286
+ this.JST || (this.JST = {});
287
+ this.JST["luca-src/templates/fields/button_field_link"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<a class="btn ', input_class ,'">\n '); if(icon_class.length) { __p.push('\n <i class="', icon_class ,'"></i>\n ', input_value ,'\n '); } __p.push('\n</a>\n');}return __p.join('');};
288
+ }).call(this);
289
+ (function() {
290
+ this.JST || (this.JST = {});
291
+ this.JST["luca-src/templates/fields/checkbox_array"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class="control-group">\n <label for="', input_id ,'"><%= label =>\n <div class="controls"><div>\n</div>\n');}return __p.join('');};
292
+ }).call(this);
293
+ (function() {
294
+ this.JST || (this.JST = {});
295
+ this.JST["luca-src/templates/fields/checkbox_array_item"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label for="', input_id ,'">\n <input id="', input_id ,'" type="checkbox" name="', input_name ,'" value="', value ,'" />\n</label>\n');}return __p.join('');};
296
+ }).call(this);
297
+ (function() {
298
+ this.JST || (this.JST = {});
299
+ this.JST["luca-src/templates/fields/checkbox_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label for="', input_id ,'">\n ', label ,'\n <input type="checkbox" name="', input_name ,'" value="', input_value ,'" style="', inputStyles ,'" />\n</label>\n\n'); if(helperText) { __p.push('\n<p class="helper-text help-block">\n ', helperText ,'\n</p>\n'); } __p.push('\n');}return __p.join('');};
300
+ }).call(this);
301
+ (function() {
302
+ this.JST || (this.JST = {});
303
+ this.JST["luca-src/templates/fields/file_upload_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label for="', input_id ,'">\n ', label ,'\n <input type="file" name="', input_name ,'" value="', input_value ,'" style="', inputStyles ,'" />\n</label>\n\n'); if(helperText) { __p.push('\n<p class="helper-text help-block">\n ', helperText ,'\n</p>\n'); } __p.push('\n');}return __p.join('');};
304
+ }).call(this);
305
+ (function() {
306
+ this.JST || (this.JST = {});
307
+ this.JST["luca-src/templates/fields/hidden_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push(' <input type="hidden" name="', input_name ,'" value="', input_value ,'" style="', inputStyles ,'" />\n');}return __p.join('');};
308
+ }).call(this);
309
+ (function() {
310
+ this.JST || (this.JST = {});
311
+ this.JST["luca-src/templates/fields/select_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 <select name="', input_name ,'" value="', input_value ,'" style="', inputStyles ,'" ></select>\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('');};
312
+ }).call(this);
313
+ (function() {
314
+ this.JST || (this.JST = {});
315
+ 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('');};
316
+ }).call(this);
317
+ (function() {
318
+ this.JST || (this.JST = {});
319
+ 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('');};
320
+ }).call(this);
321
+ (function() {
322
+ this.JST || (this.JST = {});
323
+ this.JST["luca-src/templates/table_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<thead></thead>\n<tbody class="table-body"></tbody>\n<tfoot></tfoot>\n<caption></caption>\n');}return __p.join('');};
324
+ }).call(this);
325
+ (function() {
326
+ var currentNamespace,
327
+ __slice = Array.prototype.slice;
256
328
 
257
329
  Luca.util.resolve = function(accessor, source_object) {
258
- source_object || (source_object = window || global);
259
- return _(accessor.split(/\./)).inject(function(obj, key) {
260
- return obj = obj != null ? obj[key] : void 0;
261
- }, source_object);
330
+ var resolved;
331
+ try {
332
+ source_object || (source_object = window || global);
333
+ resolved = _(accessor.split(/\./)).inject(function(obj, key) {
334
+ return obj = obj != null ? obj[key] : void 0;
335
+ }, source_object);
336
+ } catch (e) {
337
+ console.log("Error resolving", accessor, source_object);
338
+ throw e;
339
+ }
340
+ return resolved;
262
341
  };
263
342
 
264
343
  Luca.util.nestedValue = Luca.util.resolve;
265
344
 
345
+ Luca.util.argumentsLogger = function(prompt) {
346
+ return function() {
347
+ return console.log(prompt, arguments);
348
+ };
349
+ };
350
+
351
+ Luca.util.read = function() {
352
+ var args, property;
353
+ property = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
354
+ if (_.isFunction(property)) {
355
+ return property.apply(this, args);
356
+ } else {
357
+ return property;
358
+ }
359
+ };
360
+
266
361
  Luca.util.classify = function(string) {
267
362
  if (string == null) string = "";
268
363
  return _.string.camelize(_.string.capitalize(string));
@@ -409,13 +504,13 @@
409
504
 
410
505
  }).call(this);
411
506
  (function() {
412
- var DeferredBindingProxy;
507
+ var DeferredBindingProxy,
508
+ __slice = Array.prototype.slice;
413
509
 
414
510
  DeferredBindingProxy = (function() {
415
511
 
416
512
  function DeferredBindingProxy(object, operation, wrapWithUnderscore) {
417
- var fn,
418
- _this = this;
513
+ var fn;
419
514
  this.object = object;
420
515
  if (wrapWithUnderscore == null) wrapWithUnderscore = true;
421
516
  if (_.isFunction(operation)) {
@@ -427,11 +522,11 @@
427
522
  throw "Must pass a function or a string representing one";
428
523
  }
429
524
  if (wrapWithUnderscore === true) {
430
- this.fn = function() {
525
+ this.fn = _.bind(function() {
431
526
  return _.defer(fn);
432
- };
527
+ }, this.object);
433
528
  } else {
434
- this.fn = fn;
529
+ this.fn = _.bind(fn, this.object);
435
530
  }
436
531
  this;
437
532
  }
@@ -465,15 +560,80 @@
465
560
  }
466
561
  };
467
562
 
563
+ Luca.EventsExt = {
564
+ waitUntil: function(trigger, context) {
565
+ return this.waitFor.call(this, trigger, context);
566
+ },
567
+ waitFor: function(trigger, context) {
568
+ var proxy, self;
569
+ self = this;
570
+ return proxy = {
571
+ on: function(target) {
572
+ return target.waitFor.call(target, trigger, context);
573
+ },
574
+ and: function() {
575
+ var fn, runList, _i, _len, _results;
576
+ runList = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
577
+ _results = [];
578
+ for (_i = 0, _len = runList.length; _i < _len; _i++) {
579
+ fn = runList[_i];
580
+ fn = _.isFunction(fn) ? fn : self[fn];
581
+ _results.push(self.once(trigger, fn, context));
582
+ }
583
+ return _results;
584
+ },
585
+ andThen: function() {
586
+ return self.and.apply(self, arguments);
587
+ }
588
+ };
589
+ },
590
+ relayEvent: function(trigger) {
591
+ var _this = this;
592
+ return {
593
+ on: function() {
594
+ var components;
595
+ components = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
596
+ return {
597
+ to: function() {
598
+ var component, target, targets, _i, _len, _results;
599
+ targets = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
600
+ _results = [];
601
+ for (_i = 0, _len = targets.length; _i < _len; _i++) {
602
+ target = targets[_i];
603
+ _results.push((function() {
604
+ var _j, _len2, _results2,
605
+ _this = this;
606
+ _results2 = [];
607
+ for (_j = 0, _len2 = components.length; _j < _len2; _j++) {
608
+ component = components[_j];
609
+ _results2.push(component.on(trigger, function() {
610
+ var args;
611
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
612
+ args.unshift(trigger);
613
+ return target.trigger.apply(target, args);
614
+ }));
615
+ }
616
+ return _results2;
617
+ }).call(_this));
618
+ }
619
+ return _results;
620
+ }
621
+ };
622
+ }
623
+ };
624
+ }
625
+ };
626
+
468
627
  }).call(this);
469
628
  (function() {
470
- var DefineProxy;
471
-
472
- Luca.define = function(componentName) {
473
- return new DefineProxy(componentName);
474
- };
629
+ var DefineProxy,
630
+ __slice = Array.prototype.slice;
475
631
 
476
- Luca.component = Luca.define;
632
+ _.mixin({
633
+ def: Luca.component = Luca.define = Luca.register = function(componentName) {
634
+ return new DefineProxy(componentName);
635
+ }
636
+ });
477
637
 
478
638
  DefineProxy = (function() {
479
639
 
@@ -481,6 +641,7 @@
481
641
  var parts;
482
642
  this.namespace = Luca.util.namespace();
483
643
  this.componentId = this.componentName = componentName;
644
+ this.superClassName = 'Luca.View';
484
645
  if (componentName.match(/\./)) {
485
646
  this.namespaced = true;
486
647
  parts = componentName.split('.');
@@ -510,19 +671,58 @@
510
671
  return this;
511
672
  };
512
673
 
513
- DefineProxy.prototype.enhance = function(properties) {
514
- if (properties != null) return this["with"](properties);
674
+ DefineProxy.prototype.triggers = function() {
675
+ var hook, hooks, _i, _len;
676
+ hooks = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
677
+ _.defaults(this.properties || (this.properties = {}), {
678
+ hooks: []
679
+ });
680
+ for (_i = 0, _len = hooks.length; _i < _len; _i++) {
681
+ hook = hooks[_i];
682
+ this.properties.hooks.push(hook);
683
+ }
684
+ this.properties.hooks = _.uniq(this.properties.hooks);
685
+ return this;
686
+ };
687
+
688
+ DefineProxy.prototype.includes = function() {
689
+ var include, includes, _i, _len;
690
+ includes = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
691
+ _.defaults(this.properties || (this.properties = {}), {
692
+ include: []
693
+ });
694
+ for (_i = 0, _len = includes.length; _i < _len; _i++) {
695
+ include = includes[_i];
696
+ this.properties.include.push(include);
697
+ }
698
+ this.properties.include = _.uniq(this.properties.include);
699
+ return this;
700
+ };
701
+
702
+ DefineProxy.prototype.mixesIn = function() {
703
+ var mixin, mixins, _i, _len;
704
+ mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
705
+ _.defaults(this.properties || (this.properties = {}), {
706
+ mixins: []
707
+ });
708
+ for (_i = 0, _len = mixins.length; _i < _len; _i++) {
709
+ mixin = mixins[_i];
710
+ this.properties.mixins.push(mixin);
711
+ }
712
+ this.properties.mixins = _.uniq(this.properties.mixins);
515
713
  return this;
516
714
  };
517
715
 
518
- DefineProxy.prototype["with"] = function(properties) {
716
+ DefineProxy.prototype.defaultProperties = function(properties) {
519
717
  var at, componentType, _base;
718
+ if (properties == null) properties = {};
719
+ _.defaults((this.properties || (this.properties = {})), properties);
520
720
  at = this.namespaced ? Luca.util.resolve(this.namespace, window || global) : window || global;
521
721
  if (this.namespaced && !(at != null)) {
522
722
  eval("(window||global)." + this.namespace + " = {}");
523
723
  at = Luca.util.resolve(this.namespace, window || global);
524
724
  }
525
- at[this.componentId] = Luca.extend(this.superClassName, this.componentName, properties);
725
+ at[this.componentId] = Luca.extend(this.superClassName, this.componentName, this.properties);
526
726
  if (Luca.autoRegister === true) {
527
727
  if (Luca.isViewPrototype(at[this.componentId])) componentType = "view";
528
728
  if (Luca.isCollectionPrototype(at[this.componentId])) {
@@ -531,7 +731,7 @@
531
731
  componentType = "collection";
532
732
  }
533
733
  if (Luca.isModelPrototype(at[this.componentId])) componentType = "model";
534
- Luca.register(_.string.underscored(this.componentId), this.componentName, componentType);
734
+ Luca.registerComponent(_.string.underscored(this.componentId), this.componentName, componentType);
535
735
  }
536
736
  return at[this.componentId];
537
737
  };
@@ -540,12 +740,19 @@
540
740
 
541
741
  })();
542
742
 
743
+ DefineProxy.prototype.behavesAs = DefineProxy.prototype.uses = DefineProxy.prototype.mixesIn;
744
+
745
+ DefineProxy.prototype.defines = DefineProxy.prototype.defaults = DefineProxy.prototype.exports = DefineProxy.prototype.defaultProperties;
746
+
747
+ DefineProxy.prototype.defaultsTo = DefineProxy.prototype.enhance = DefineProxy.prototype["with"] = DefineProxy.prototype.defaultProperties;
748
+
543
749
  Luca.extend = function(superClassName, childName, properties) {
544
- var definition, mixin, superClass, _i, _len, _ref;
750
+ var definition, include, superClass, _i, _len, _ref;
545
751
  if (properties == null) properties = {};
546
752
  superClass = Luca.util.resolve(superClassName, window || global);
753
+ superClass.__initializers || (superClass.__initializers = []);
547
754
  if (!_.isFunction(superClass != null ? superClass.extend : void 0)) {
548
- throw "" + superClassName + " is not a valid component to extend from";
755
+ throw "Error defining " + childName + ". " + superClassName + " is not a valid component to extend from";
549
756
  }
550
757
  properties.displayName = childName;
551
758
  properties._superClass = function() {
@@ -554,23 +761,126 @@
554
761
  };
555
762
  properties._super = function(method, context, args) {
556
763
  var _ref;
764
+ if (context == null) context = this;
765
+ if (args == null) args = [];
557
766
  return (_ref = this._superClass().prototype[method]) != null ? _ref.apply(context, args) : void 0;
558
767
  };
559
768
  definition = superClass.extend(properties);
560
769
  if (_.isArray(properties != null ? properties.include : void 0)) {
561
770
  _ref = properties.include;
562
771
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
563
- mixin = _ref[_i];
564
- if (_.isString(mixin)) mixin = Luca.util.resolve(mixin);
565
- _.extend(definition.prototype, mixin);
772
+ include = _ref[_i];
773
+ if (_.isString(include)) include = Luca.util.resolve(include);
774
+ _.extend(definition.prototype, include);
566
775
  }
567
776
  }
568
777
  return definition;
569
778
  };
570
779
 
571
- _.mixin({
572
- def: Luca.define
573
- });
780
+ Luca.mixin = function(mixinName) {
781
+ var namespace, resolved;
782
+ namespace = _(Luca.mixin.namespaces).detect(function(space) {
783
+ var _ref;
784
+ return ((_ref = Luca.util.resolve(space)) != null ? _ref[mixinName] : void 0) != null;
785
+ });
786
+ namespace || (namespace = "Luca.modules");
787
+ resolved = Luca.util.resolve(namespace)[mixinName];
788
+ if (resolved == null) {
789
+ console.log("Could not find " + mixinName + " in ", Luca.mixin.namespaces);
790
+ }
791
+ return resolved;
792
+ };
793
+
794
+ Luca.mixin.namespaces = ["Luca.modules"];
795
+
796
+ Luca.mixin.namespace = function(namespace) {
797
+ Luca.mixin.namespaces.push(namespace);
798
+ return Luca.mixin.namespaces = _(Luca.mixin.namespaces).uniq();
799
+ };
800
+
801
+ Luca.decorate = function(componentPrototype) {
802
+ if (_.isString(componentPrototype)) {
803
+ componentPrototype = Luca.util.resolve(componentPrototype).prototype;
804
+ }
805
+ return {
806
+ "with": function(mixin) {
807
+ var mixinDefinition, mixinPrivates, sanitized, superclassMixins, _ref;
808
+ mixinDefinition = Luca.mixin(mixin);
809
+ mixinPrivates = _(mixinDefinition).chain().keys().select(function(key) {
810
+ return ("" + key).match(/^__/);
811
+ });
812
+ sanitized = _(mixinDefinition).omit(mixinPrivates.value());
813
+ _.extend(componentPrototype, sanitized);
814
+ if (mixinDefinition != null) {
815
+ if ((_ref = mixinDefinition.__included) != null) {
816
+ _ref.call(mixinDefinition, mixin);
817
+ }
818
+ }
819
+ superclassMixins = componentPrototype._superClass().prototype.mixins;
820
+ componentPrototype.mixins || (componentPrototype.mixins = []);
821
+ componentPrototype.mixins.push(mixin);
822
+ componentPrototype.mixins = componentPrototype.mixins.concat(superclassMixins);
823
+ componentPrototype.mixins = _(componentPrototype.mixins).chain().uniq().compact().value();
824
+ return componentPrototype;
825
+ }
826
+ };
827
+ };
828
+
829
+ }).call(this);
830
+ (function() {
831
+
832
+ Luca.modules.ApplicationEventBindings = {
833
+ __initializer: function() {
834
+ var app, eventTrigger, handler, _len, _ref, _ref2, _results;
835
+ if (_.isEmpty(this.applicationEvents)) return;
836
+ app = this.app;
837
+ if (_.isString(app) || _.isUndefined(app)) {
838
+ app = (_ref = Luca.Application) != null ? typeof _ref.get === "function" ? _ref.get(app) : void 0 : void 0;
839
+ }
840
+ if (!Luca.supportsEvents(app)) {
841
+ throw "Error binding to the application object on " + (this.name || this.cid);
842
+ }
843
+ _ref2 = this.applicationEvents;
844
+ _results = [];
845
+ for (handler = 0, _len = _ref2.length; handler < _len; handler++) {
846
+ eventTrigger = _ref2[handler];
847
+ if (_.isString(handler)) handler = this[handler];
848
+ if (!_.isFunction(handler)) {
849
+ throw "Error registering application event " + eventTrigger + " on " + (this.name || this.cid);
850
+ }
851
+ _results.push(app.on(eventTrigger, handler));
852
+ }
853
+ return _results;
854
+ }
855
+ };
856
+
857
+ }).call(this);
858
+ (function() {
859
+
860
+ Luca.modules.CollectionEventBindings = {
861
+ __initializer: function() {
862
+ var collection, eventTrigger, handler, key, manager, signature, _ref, _ref2, _results;
863
+ if (_.isEmpty(this.collectionEvents)) return;
864
+ manager = this.collectionManager || Luca.CollectionManager.get();
865
+ _ref = this.collectionEvents;
866
+ _results = [];
867
+ for (signature in _ref) {
868
+ handler = _ref[signature];
869
+ _ref2 = signature.split(" "), key = _ref2[0], eventTrigger = _ref2[1];
870
+ collection = manager.getOrCreate(key);
871
+ if (!collection) throw "Could not find collection specified by " + key;
872
+ if (_.isString(handler)) handler = this[handler];
873
+ if (!_.isFunction(handler)) throw "invalid collectionEvents configuration";
874
+ try {
875
+ _results.push(collection.on(eventTrigger, handler, collection));
876
+ } catch (e) {
877
+ console.log("Error Binding To Collection in registerCollectionEvents", this);
878
+ throw e;
879
+ }
880
+ }
881
+ return _results;
882
+ }
883
+ };
574
884
 
575
885
  }).call(this);
576
886
  (function() {
@@ -593,20 +903,219 @@
593
903
  }
594
904
  };
595
905
 
906
+ }).call(this);
907
+ (function() {
908
+
909
+ Luca.modules.DomHelpers = {
910
+ __initializer: function() {
911
+ var additional, additionalClasses, _i, _len, _results;
912
+ additionalClasses = _(this.additionalClassNames || []).clone();
913
+ if (this.wrapperClass != null) this.$wrap(this.wrapperClass);
914
+ if (_.isString(additionalClasses)) {
915
+ additionalClasses = additionalClasses.split(" ");
916
+ }
917
+ if (this.gridSpan) additionalClasses.push("span" + this.gridSpan);
918
+ if (this.gridOffset) additionalClasses.push("offset" + this.gridOffset);
919
+ if (this.gridRowFluid) additionalClasses.push("row-fluid");
920
+ if (this.gridRow) additionalClasses.push("row");
921
+ if (additionalClasses == null) return;
922
+ _results = [];
923
+ for (_i = 0, _len = additionalClasses.length; _i < _len; _i++) {
924
+ additional = additionalClasses[_i];
925
+ _results.push(this.$el.addClass(additional));
926
+ }
927
+ return _results;
928
+ },
929
+ $wrap: function(wrapper) {
930
+ if (_.isString(wrapper) && !wrapper.match(/[<>]/)) {
931
+ wrapper = this.make("div", {
932
+ "class": wrapper
933
+ });
934
+ }
935
+ return this.$el.wrap(wrapper);
936
+ },
937
+ $template: function(template, variables) {
938
+ if (variables == null) variables = {};
939
+ return this.$el.html(Luca.template(template, variables));
940
+ },
941
+ $html: function(content) {
942
+ return this.$el.html(content);
943
+ },
944
+ $append: function(content) {
945
+ return this.$el.append(content);
946
+ },
947
+ $attach: function() {
948
+ return this.$container().append(this.el);
949
+ },
950
+ $bodyEl: function() {
951
+ return this.$el;
952
+ },
953
+ $container: function() {
954
+ return $(this.container);
955
+ }
956
+ };
957
+
958
+ }).call(this);
959
+ (function() {
960
+
961
+ Luca.modules.EnhancedProperties = {
962
+ __initializer: function() {
963
+ if (Luca.config.enhancedViewProperties !== true) return;
964
+ if (_.isString(this.collection) && Luca.CollectionManager.get()) {
965
+ this.collection = Luca.CollectionManager.get().getOrCreate(this.collection);
966
+ }
967
+ if (this.template != null) this.$template(this.template, this);
968
+ if (_.isString(this.collectionManager)) {
969
+ return this.collectionManager = Luca.CollectionManager.get(this.collectionManager);
970
+ }
971
+ }
972
+ };
973
+
974
+ }).call(this);
975
+ (function() {
976
+ var FilterModel,
977
+ __hasProp = Object.prototype.hasOwnProperty,
978
+ __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; };
979
+
980
+ Luca.modules.Filterable = {
981
+ __included: function(component, module) {
982
+ return _.extend(Luca.Collection.prototype, {
983
+ __filters: {}
984
+ });
985
+ },
986
+ __initializer: function(component, module) {
987
+ var filter, _base, _ref,
988
+ _this = this;
989
+ if (this.filterable === false) return;
990
+ if (!Luca.isBackboneCollection(this.collection)) {
991
+ this.collection = typeof (_base = Luca.CollectionManager).get === "function" ? (_ref = _base.get()) != null ? _ref.getOrCreate(this.collection) : void 0 : void 0;
992
+ }
993
+ if (!Luca.isBackboneCollection(this.collection)) {
994
+ this.debug("Skipping Filterable due to no collection being present on " + (this.name || this.cid));
995
+ this.debug("Collection", this.collection);
996
+ return;
997
+ }
998
+ this.getCollection || (this.getCollection = function() {
999
+ return this.collection;
1000
+ });
1001
+ filter = this.getFilterState();
1002
+ this.querySources || (this.querySources = []);
1003
+ this.optionsSources || (this.optionsSources = []);
1004
+ this.query || (this.query = {});
1005
+ this.queryOptions || (this.queryOptions = {});
1006
+ this.querySources.push((function() {
1007
+ return filter.toQuery();
1008
+ }));
1009
+ this.optionsSources.push((function() {
1010
+ return filter.toOptions();
1011
+ }));
1012
+ if (this.debugMode === true) {
1013
+ console.log("Filterable");
1014
+ console.log(this.querySources);
1015
+ console.log(this.optionsSources);
1016
+ }
1017
+ filter.on("change", function() {
1018
+ var merged;
1019
+ if (_this.isRemote()) {
1020
+ merged = _.extend(_this.getQuery(), _this.getQueryOptions());
1021
+ return _this.collection.applyFilter(merged, _this.getQueryOptions());
1022
+ } else {
1023
+ return _this.trigger("refresh");
1024
+ }
1025
+ });
1026
+ return module;
1027
+ },
1028
+ isRemote: function() {
1029
+ return this.getQueryOptions().remote === true;
1030
+ },
1031
+ getFilterState: function() {
1032
+ var _base, _name;
1033
+ return (_base = this.collection.__filters)[_name = this.cid] || (_base[_name] = new FilterModel(this.filterable));
1034
+ },
1035
+ setSortBy: function(sortBy, options) {
1036
+ if (options == null) options = {};
1037
+ return this.getFilterState().setOption('sortBy', sortBy, options);
1038
+ },
1039
+ applyFilter: function(query, options) {
1040
+ if (query == null) query = {};
1041
+ if (options == null) options = {};
1042
+ options = _.defaults(options, this.getQueryOptions());
1043
+ query = _.defaults(query, this.getQuery());
1044
+ return this.getFilterState().set({
1045
+ query: query,
1046
+ options: options
1047
+ }, options);
1048
+ }
1049
+ };
1050
+
1051
+ FilterModel = (function(_super) {
1052
+
1053
+ __extends(FilterModel, _super);
1054
+
1055
+ function FilterModel() {
1056
+ FilterModel.__super__.constructor.apply(this, arguments);
1057
+ }
1058
+
1059
+ FilterModel.prototype.defaults = {
1060
+ options: {},
1061
+ query: {}
1062
+ };
1063
+
1064
+ FilterModel.prototype.setOption = function(option, value, options) {
1065
+ var payload;
1066
+ payload = {};
1067
+ payload[option] = value;
1068
+ return this.set('options', _.extend(this.toOptions(), payload), options);
1069
+ };
1070
+
1071
+ FilterModel.prototype.setQueryOption = function(option, value, options) {
1072
+ var payload;
1073
+ payload = {};
1074
+ payload[option] = value;
1075
+ return this.set('query', _.extend(this.toQuery(), payload), options);
1076
+ };
1077
+
1078
+ FilterModel.prototype.toOptions = function() {
1079
+ return this.toJSON().options;
1080
+ };
1081
+
1082
+ FilterModel.prototype.toQuery = function() {
1083
+ return this.toJSON().query;
1084
+ };
1085
+
1086
+ FilterModel.prototype.toRemote = function() {
1087
+ var options;
1088
+ options = this.toOptions();
1089
+ return _.extend(this.toQuery(), {
1090
+ limit: options.limit,
1091
+ page: options.page,
1092
+ sortBy: options.sortBy
1093
+ });
1094
+ };
1095
+
1096
+ return FilterModel;
1097
+
1098
+ })(Backbone.Model);
1099
+
596
1100
  }).call(this);
597
1101
  (function() {
598
1102
 
599
1103
  Luca.modules.GridLayout = {
600
- _included: function(view, module) {}
1104
+ _initializer: function() {
1105
+ if (this.gridSpan) this.$el.addClass("span" + this.gridSpan);
1106
+ if (this.gridOffset) this.$el.addClass("offset" + this.gridOffset);
1107
+ if (this.gridRowFluid) this.$el.addClass("row-fluid");
1108
+ if (this.gridRow) return this.$el.addClass("row");
1109
+ }
601
1110
  };
602
1111
 
603
1112
  }).call(this);
604
1113
  (function() {
605
1114
 
606
1115
  Luca.modules.LoadMaskable = {
607
- _included: function(self, module) {
1116
+ __initializer: function() {
608
1117
  var _this = this;
609
- _.bindAll(self, "applyLoadMask", "disableLoadMask");
1118
+ if (this.loadMask !== true) return;
610
1119
  if (this.loadMask === true) {
611
1120
  this.defer(function() {
612
1121
  _this.$el.addClass('with-mask');
@@ -615,10 +1124,16 @@
615
1124
  return _this.$('.load-mask').hide();
616
1125
  }
617
1126
  }).until("after:render");
618
- this.on(this.loadmaskEnableEvent || "enable:loadmask", this.applyLoadMask);
619
- return this.on(this.loadmaskDisableEvent || "disable:loadmask", this.applyLoadMask);
1127
+ this.on(this.loadmaskEnableEvent || "enable:loadmask", this.applyLoadMask, this);
1128
+ return this.on(this.loadmaskDisableEvent || "disable:loadmask", this.applyLoadMask, this);
620
1129
  }
621
1130
  },
1131
+ showLoadMask: function() {
1132
+ return this.trigger("enable:loadmask");
1133
+ },
1134
+ hideLoadMask: function() {
1135
+ return this.trigger("disable:loadmask");
1136
+ },
622
1137
  loadMaskTarget: function() {
623
1138
  if (this.loadMaskEl != null) {
624
1139
  return this.$(this.loadMaskEl);
@@ -742,7 +1257,197 @@
742
1257
 
743
1258
  }).call(this);
744
1259
  (function() {
745
- var component_cache, registry;
1260
+ var applyModalConfig;
1261
+
1262
+ Luca.modules.ModalView = {
1263
+ closeOnEscape: true,
1264
+ showOnInitialize: false,
1265
+ backdrop: false,
1266
+ __initializer: function() {
1267
+ this.$el.addClass("modal");
1268
+ this.on("before:render", applyModalConfig, this);
1269
+ return this;
1270
+ },
1271
+ container: function() {
1272
+ return $('body');
1273
+ },
1274
+ toggle: function() {
1275
+ return this.$el.modal('toggle');
1276
+ },
1277
+ show: function() {
1278
+ return this.$el.modal('show');
1279
+ },
1280
+ hide: function() {
1281
+ return this.$el.modal('hide');
1282
+ }
1283
+ };
1284
+
1285
+ applyModalConfig = function() {
1286
+ this.$el.addClass('modal');
1287
+ if (this.fade === true) this.$el.addClass('fade');
1288
+ $('body').append(this.$el);
1289
+ this.$el.modal({
1290
+ backdrop: this.backdrop === true,
1291
+ keyboard: this.closeOnEscape === true,
1292
+ show: this.showOnInitialize === true
1293
+ });
1294
+ return this;
1295
+ };
1296
+
1297
+ }).call(this);
1298
+ (function() {
1299
+
1300
+ Luca.modules.Paginatable = {
1301
+ paginatorViewClass: 'Luca.components.PaginationControl',
1302
+ paginationSelector: ".toolbar.bottom",
1303
+ __included: function() {
1304
+ return _.extend(Luca.Collection.prototype, {
1305
+ __paginators: {}
1306
+ });
1307
+ },
1308
+ __initializer: function() {
1309
+ var collection, paginationState, _base, _ref,
1310
+ _this = this;
1311
+ if (this.paginatable === false) return;
1312
+ if (!Luca.isBackboneCollection(this.collection)) {
1313
+ this.collection = typeof (_base = Luca.CollectionManager).get === "function" ? (_ref = _base.get()) != null ? _ref.getOrCreate(this.collection) : void 0 : void 0;
1314
+ }
1315
+ if (!Luca.isBackboneCollection(this.collection)) {
1316
+ this.debug("Skipping Paginatable due to no collection being present on " + (this.name || this.cid));
1317
+ this.debug("collection", this.collection);
1318
+ return;
1319
+ }
1320
+ _.bindAll(this, "paginationControl", "pager");
1321
+ this.getCollection || (this.getCollection = function() {
1322
+ return this.collection;
1323
+ });
1324
+ collection = this.getCollection();
1325
+ paginationState = this.getPaginationState();
1326
+ this.optionsSources || (this.optionsSources = []);
1327
+ this.queryOptions || (this.queryOptions = {});
1328
+ this.optionsSources.push(function() {
1329
+ var options;
1330
+ options = _(paginationState.toJSON()).pick('limit', 'page', 'sortBy');
1331
+ return _.extend(options, {
1332
+ pager: _this.pager
1333
+ });
1334
+ });
1335
+ paginationState.on("change:page", function(state) {
1336
+ var filter;
1337
+ if (_this.isRemote()) {
1338
+ filter = _.extend(_this.toQuery(), _this.toQueryOptions());
1339
+ return _this.collection.applyFilter(filter, {
1340
+ remote: true
1341
+ });
1342
+ } else {
1343
+ return _this.trigger("refresh");
1344
+ }
1345
+ });
1346
+ return this.on("before:render", this.renderPaginationControl, this);
1347
+ },
1348
+ pager: function(numberOfPages, models) {
1349
+ this.getPaginationState().set({
1350
+ numberOfPages: numberOfPages,
1351
+ itemCount: models.length
1352
+ });
1353
+ return this.paginationControl().updateWithPageCount(numberOfPages, models);
1354
+ },
1355
+ isRemote: function() {
1356
+ return this.getQueryOptions().remote === true;
1357
+ },
1358
+ getPaginationState: function() {
1359
+ var _base, _name;
1360
+ return (_base = this.collection.__paginators)[_name = this.cid] || (_base[_name] = this.paginationControl().state);
1361
+ },
1362
+ paginationContainer: function() {
1363
+ return this.$(">" + this.paginationSelector);
1364
+ },
1365
+ setCurrentPage: function(page, options) {
1366
+ if (page == null) page = 1;
1367
+ if (options == null) options = {};
1368
+ return this.getPaginationState().set('page', page, options);
1369
+ },
1370
+ setPage: function(page, options) {
1371
+ if (page == null) page = 1;
1372
+ if (options == null) options = {};
1373
+ return this.getPaginationState().set('page', page, options);
1374
+ },
1375
+ setLimit: function(limit, options) {
1376
+ if (limit == null) limit = 0;
1377
+ if (options == null) options = {};
1378
+ return this.getPaginationState().set('limit', limit, options);
1379
+ },
1380
+ paginationControl: function() {
1381
+ if (this.paginator != null) return this.paginator;
1382
+ _.defaults(this.paginatable || (this.paginatable = {}), {
1383
+ page: 1,
1384
+ limit: 20
1385
+ });
1386
+ this.paginator = Luca.util.lazyComponent({
1387
+ type: "pagination_control",
1388
+ collection: this.getCollection(),
1389
+ defaultState: this.paginatable,
1390
+ parent: this.name || this.cid,
1391
+ debugMode: this.debugMode
1392
+ });
1393
+ return this.paginator;
1394
+ },
1395
+ renderPaginationControl: function() {
1396
+ var control;
1397
+ control = this.paginationControl();
1398
+ this.paginationContainer().append(control.render().$el);
1399
+ return control;
1400
+ }
1401
+ };
1402
+
1403
+ }).call(this);
1404
+ (function() {
1405
+
1406
+ Luca.modules.StateModel = {
1407
+ __initializer: function() {
1408
+ var _this = this;
1409
+ if (this.stateful !== true) return;
1410
+ if ((this.state != null) && !Luca.isBackboneModel(this.state)) return;
1411
+ this.state = new Backbone.Model(this.defaultState || {});
1412
+ this.set || (this.set = function() {
1413
+ return _this.state.set.apply(_this.state, arguments);
1414
+ });
1415
+ this.get || (this.get = function() {
1416
+ return _this.state.get.apply(_this.state, arguments);
1417
+ });
1418
+ return this.state.on("change", function(state) {
1419
+ var changed, previousValues, value, _len, _ref, _results;
1420
+ _this.trigger("state:change", state);
1421
+ previousValues = state.previousAttributes();
1422
+ _ref = state.changedAttributes;
1423
+ _results = [];
1424
+ for (value = 0, _len = _ref.length; value < _len; value++) {
1425
+ changed = _ref[value];
1426
+ _results.push(_this.trigger("state:change:" + changed, value, state.previous(changed)));
1427
+ }
1428
+ return _results;
1429
+ });
1430
+ }
1431
+ };
1432
+
1433
+ }).call(this);
1434
+ (function() {
1435
+
1436
+ Luca.modules.Templating = {
1437
+ __initializer: function() {
1438
+ var template, templateContent, templateVars;
1439
+ templateVars = Luca.util.read.call(this, this.bodyTemplateVars) || {};
1440
+ if (template = this.bodyTemplate) {
1441
+ this.$el.empty();
1442
+ templateContent = Luca.template(template, templateVars);
1443
+ return Luca.View.prototype.$html.call(this, templateContent);
1444
+ }
1445
+ }
1446
+ };
1447
+
1448
+ }).call(this);
1449
+ (function() {
1450
+ var componentCacheStore, registry;
746
1451
 
747
1452
  registry = {
748
1453
  classes: {},
@@ -751,12 +1456,14 @@
751
1456
  namespaces: ['Luca.containers', 'Luca.components']
752
1457
  };
753
1458
 
754
- component_cache = {
1459
+ componentCacheStore = {
755
1460
  cid_index: {},
756
1461
  name_index: {}
757
1462
  };
758
1463
 
759
- Luca.defaultComponentType = 'view';
1464
+ Luca.config.defaultComponentClass = Luca.defaultComponentClass = 'Luca.View';
1465
+
1466
+ Luca.config.defaultComponentType = Luca.defaultComponentType = 'view';
760
1467
 
761
1468
  Luca.registry.aliases = {
762
1469
  grid: "grid_view",
@@ -767,10 +1474,13 @@
767
1474
  card: "card_view",
768
1475
  paged: "card_view",
769
1476
  wizard: "card_view",
770
- collection: "collection_view"
1477
+ collection: "collection_view",
1478
+ list: "collection_view",
1479
+ multi: "collection_multi_view",
1480
+ table: "table_view"
771
1481
  };
772
1482
 
773
- Luca.register = function(component, prototypeName, componentType) {
1483
+ Luca.registerComponent = function(component, prototypeName, componentType) {
774
1484
  if (componentType == null) componentType = "view";
775
1485
  Luca.trigger("component:registered", component, prototypeName);
776
1486
  switch (componentType) {
@@ -794,10 +1504,10 @@
794
1504
  return instance != null ? (_ref = instance.refreshCode) != null ? _ref.call(instance, prototypeDefinition) : void 0 : void 0;
795
1505
  });
796
1506
  }
797
- return Luca.register(component, prototypeName);
1507
+ return Luca.registerComponent(component, prototypeName);
798
1508
  };
799
1509
 
800
- Luca.registry.addNamespace = function(identifier) {
1510
+ Luca.registry.addNamespace = Luca.registry.namespace = function(identifier) {
801
1511
  registry.namespaces.push(identifier);
802
1512
  return registry.namespaces = _(registry.namespaces).uniq();
803
1513
  };
@@ -826,14 +1536,20 @@
826
1536
  };
827
1537
 
828
1538
  Luca.registry.instances = function() {
829
- return _(component_cache.cid_index).values();
1539
+ return _(componentCacheStore.cid_index).values();
1540
+ };
1541
+
1542
+ Luca.registry.findInstancesByClass = function(componentClass) {
1543
+ return Luca.registry.findInstancesByClassName(componentClass.displayName);
830
1544
  };
831
1545
 
832
1546
  Luca.registry.findInstancesByClassName = function(className) {
833
1547
  var instances;
1548
+ if (!_.isString(className)) className = className.displayName;
834
1549
  instances = Luca.registry.instances();
835
1550
  return _(instances).select(function(instance) {
836
- var _ref;
1551
+ var isClass, _ref;
1552
+ isClass = instance.displayName === className;
837
1553
  return instance.displayName === className || (typeof instance._superClass === "function" ? (_ref = instance._superClass()) != null ? _ref.displayName : void 0 : void 0) === className;
838
1554
  });
839
1555
  };
@@ -852,18 +1568,20 @@
852
1568
  });
853
1569
  };
854
1570
 
855
- Luca.cache = function(needle, component) {
1571
+ Luca.cache = Luca.cacheInstance = function(cacheKey, object) {
856
1572
  var lookup_id;
857
- if (component != null) component_cache.cid_index[needle] = component;
858
- component = component_cache.cid_index[needle];
859
- if ((component != null ? component.component_name : void 0) != null) {
860
- component_cache.name_index[component.component_name] = component.cid;
861
- } else if ((component != null ? component.name : void 0) != null) {
862
- component_cache.name_index[component.name] = component.cid;
1573
+ if (cacheKey == null) return;
1574
+ if ((object != null ? object.doNotCache : void 0) === true) return object;
1575
+ if (object != null) componentCacheStore.cid_index[cacheKey] = object;
1576
+ object = componentCacheStore.cid_index[cacheKey];
1577
+ if ((object != null ? object.component_name : void 0) != null) {
1578
+ componentCacheStore.name_index[object.component_name] = object.cid;
1579
+ } else if ((object != null ? object.name : void 0) != null) {
1580
+ componentCacheStore.name_index[object.name] = object.cid;
863
1581
  }
864
- if (component != null) return component;
865
- lookup_id = component_cache.name_index[needle];
866
- return component_cache.cid_index[lookup_id];
1582
+ if (object != null) return object;
1583
+ lookup_id = componentCacheStore.name_index[cacheKey];
1584
+ return componentCacheStore.cid_index[lookup_id];
867
1585
  };
868
1586
 
869
1587
  }).call(this);
@@ -909,95 +1627,46 @@
909
1627
 
910
1628
  }).call(this);
911
1629
  (function() {
912
- var bindAllEventHandlers, customizeRender, originalExtend, registerApplicationEvents, registerCollectionEvents, setupBodyTemplate;
1630
+ var bindAllEventHandlers, bindEventHandlers, view,
1631
+ __slice = Array.prototype.slice;
1632
+
1633
+ view = Luca.register("Luca.View");
1634
+
1635
+ view["extends"]("Backbone.View");
1636
+
1637
+ view.includes("Luca.Events", "Luca.modules.DomHelpers");
1638
+
1639
+ view.mixesIn("DomHelpers", "Templating", "EnhancedProperties", "CollectionEventBindings", "ApplicationEventBindings", "StateModel");
913
1640
 
914
- _.def("Luca.View")["extends"]("Backbone.View")["with"]({
915
- include: ['Luca.Events'],
916
- additionalClassNames: [],
917
- hooks: ["before:initialize", "after:initialize", "before:render", "after:render", "first:activation", "activation", "deactivation"],
1641
+ view.triggers("before:initialize", "after:initialize", "before:render", "after:render", "first:activation", "activation", "deactivation");
1642
+
1643
+ view.defines({
918
1644
  initialize: function(options) {
919
- var additional, module, _i, _j, _len, _len2, _ref, _ref2, _ref3, _ref4,
920
- _this = this;
921
1645
  this.options = options != null ? options : {};
922
1646
  this.trigger("before:initialize", this, this.options);
923
1647
  _.extend(this, this.options);
924
1648
  if (this.autoBindEventHandlers === true || this.bindAllEvents === true) {
925
1649
  bindAllEventHandlers.call(this);
926
1650
  }
927
- setupBodyTemplate.call(this);
928
1651
  if (this.name != null) this.cid = _.uniqueId(this.name);
929
- Luca.cache(this.cid, this);
1652
+ this.$el.attr("data-luca-id", this.name || this.cid);
1653
+ Luca.cacheInstance(this.cid, this);
930
1654
  this.setupHooks(_(Luca.View.prototype.hooks.concat(this.hooks)).uniq());
931
- if (this.additionalClassNames) {
932
- if (_.isString(this.additionalClassNames)) {
933
- this.additionalClassNames = this.additionalClassNames.split(" ");
934
- }
935
- }
936
- if (this.gridSpan) this.additionalClassNames.push("span" + this.gridSpan);
937
- if (this.gridOffset) {
938
- this.additionalClassNames.push("offset" + this.gridOffset);
939
- }
940
- if (this.gridRowFluid) this.additionalClassNames.push("row-fluid");
941
- if (this.gridRow) this.additionalClassNames.push("row");
942
- if (((_ref = this.additionalClassNames) != null ? _ref.length : void 0) > 0) {
943
- _ref2 = this.additionalClassNames;
944
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
945
- additional = _ref2[_i];
946
- this.$el.addClass(additional);
947
- }
948
- }
949
- if (this.wrapperClass != null) this.$wrap(this.wrapperClass);
950
- registerCollectionEvents.call(this);
951
- registerApplicationEvents.call(this);
1655
+ this.setupMixins();
952
1656
  this.delegateEvents();
953
- if (this.stateful === true && !(this.state != null)) {
954
- this.state = new Backbone.Model(this.defaultState || {});
955
- if (this.set == null) {
956
- this.set = function() {
957
- return _this.state.set.apply(_this.state, argumuments);
958
- };
959
- }
960
- if (this.get == null) {
961
- this.get = function() {
962
- return _this.state.get.apply(_this.state, argumuments);
963
- };
964
- }
965
- }
966
- if (((_ref3 = this.mixins) != null ? _ref3.length : void 0) > 0) {
967
- _ref4 = this.mixins;
968
- for (_j = 0, _len2 = _ref4.length; _j < _len2; _j++) {
969
- module = _ref4[_j];
970
- Luca.modules[module]._included.call(this, this, module);
971
- }
972
- }
973
1657
  return this.trigger("after:initialize", this);
974
1658
  },
975
- $wrap: function(wrapper) {
976
- if (_.isString(wrapper) && !wrapper.match(/[<>]/)) {
977
- wrapper = this.make("div", {
978
- "class": wrapper
979
- });
1659
+ setupMixins: function() {
1660
+ var module, _i, _len, _ref, _ref2, _ref3, _ref4, _results;
1661
+ if (((_ref = this.mixins) != null ? _ref.length : void 0) > 0) {
1662
+ _ref2 = this.mixins;
1663
+ _results = [];
1664
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1665
+ module = _ref2[_i];
1666
+ _results.push((_ref3 = Luca.mixin(module)) != null ? (_ref4 = _ref3.__initializer) != null ? _ref4.call(this, this, module) : void 0 : void 0);
1667
+ }
1668
+ return _results;
980
1669
  }
981
- return this.$el.wrap(wrapper);
982
- },
983
- $template: function(template, variables) {
984
- if (variables == null) variables = {};
985
- return this.$el.html(Luca.template(template, variables));
986
- },
987
- $html: function(content) {
988
- return this.$el.html(content);
989
- },
990
- $append: function(content) {
991
- return this.$el.append(content);
992
- },
993
- $attach: function() {
994
- return this.$container().append(this.el);
995
- },
996
- $bodyEl: function() {
997
- return this.$el;
998
- },
999
- $container: function() {
1000
- return $(this.container);
1001
1670
  },
1002
1671
  setupHooks: function(set) {
1003
1672
  var _this = this;
@@ -1007,12 +1676,12 @@
1007
1676
  fn = Luca.util.hook(eventId);
1008
1677
  callback = function() {
1009
1678
  var _ref;
1010
- return (_ref = _this[fn]) != null ? _ref.apply(_this, arguments) : void 0;
1679
+ return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
1011
1680
  };
1012
1681
  if (eventId != null ? eventId.match(/once:/) : void 0) {
1013
1682
  callback = _.once(callback);
1014
1683
  }
1015
- return _this.bind(eventId, callback);
1684
+ return _this.on(eventId, callback, _this);
1016
1685
  });
1017
1686
  },
1018
1687
  registerEvent: function(selector, handler) {
@@ -1034,14 +1703,10 @@
1034
1703
  return Luca.util.selectProperties(Luca.isBackboneView, this);
1035
1704
  },
1036
1705
  debug: function() {
1037
- var message, _i, _len, _results;
1706
+ var args;
1707
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
1038
1708
  if (!(this.debugMode || (window.LucaDebugMode != null))) return;
1039
- _results = [];
1040
- for (_i = 0, _len = arguments.length; _i < _len; _i++) {
1041
- message = arguments[_i];
1042
- _results.push(console.log([this.name || this.cid, message]));
1043
- }
1044
- return _results;
1709
+ return console.log([this.name || this.cid].concat(__slice.call(args)));
1045
1710
  },
1046
1711
  trigger: function() {
1047
1712
  if (Luca.enableGlobalObserver) {
@@ -1056,14 +1721,14 @@
1056
1721
  }
1057
1722
  });
1058
1723
 
1059
- originalExtend = Backbone.View.extend;
1724
+ Luca.View._originalExtend = Backbone.View.extend;
1060
1725
 
1061
- customizeRender = function(definition) {
1726
+ Luca.View.renderWrapper = function(definition) {
1062
1727
  var _base;
1063
1728
  _base = definition.render;
1064
1729
  _base || (_base = Luca.View.prototype.$attach);
1065
1730
  definition.render = function() {
1066
- var autoTrigger, deferred, fn, target, trigger, view,
1731
+ var autoTrigger, deferred, fn, target, trigger,
1067
1732
  _this = this;
1068
1733
  view = this;
1069
1734
  if (this.deferrable) {
@@ -1072,7 +1737,7 @@
1072
1737
  this.deferrable = this.collection;
1073
1738
  }
1074
1739
  target || (target = this.deferrable);
1075
- trigger = this.deferrable_event ? this.deferrable_event : "reset";
1740
+ trigger = this.deferrable_event ? this.deferrable_event : Luca.View.deferrableEvent;
1076
1741
  deferred = function() {
1077
1742
  _base.call(view);
1078
1743
  return view.trigger("after:render", view);
@@ -1100,88 +1765,78 @@
1100
1765
  return definition;
1101
1766
  };
1102
1767
 
1103
- bindAllEventHandlers = function() {
1104
- var _this = this;
1105
- return _(this.events).each(function(handler, event) {
1106
- if (_.isString(handler)) return _.bindAll(_this, handler);
1107
- });
1108
- };
1109
-
1110
- registerApplicationEvents = function() {
1111
- var app, eventTrigger, handler, _len, _ref, _ref2, _results;
1112
- if (_.isEmpty(this.applicationEvents)) return;
1113
- app = this.app;
1114
- if (_.isString(app) || _.isUndefined(app)) {
1115
- app = (_ref = Luca.Application) != null ? typeof _ref.get === "function" ? _ref.get(app) : void 0 : void 0;
1116
- }
1117
- if (!Luca.supportsEvents(app)) {
1118
- throw "Error binding to the application object on " + (this.name || this.cid);
1119
- }
1120
- _ref2 = this.applicationEvents;
1121
- _results = [];
1122
- for (handler = 0, _len = _ref2.length; handler < _len; handler++) {
1123
- eventTrigger = _ref2[handler];
1124
- if (_.isString(handler)) handler = this[handler];
1125
- if (!_.isFunction(handler)) {
1126
- throw "Error registering application event " + eventTrigger + " on " + (this.name || this.cid);
1127
- }
1128
- _results.push(app.on(eventTrigger, handler));
1129
- }
1130
- return _results;
1131
- };
1132
-
1133
- registerCollectionEvents = function() {
1134
- var collection, eventTrigger, handler, key, manager, signature, _ref, _ref2, _results;
1135
- if (_.isEmpty(this.collectionEvents)) return;
1136
- manager = this.collectionManager;
1137
- if (_.isString(manager) || _.isUndefined(manager)) {
1138
- manager = Luca.CollectionManager.get(manager);
1139
- }
1140
- _ref = this.collectionEvents;
1141
- _results = [];
1142
- for (signature in _ref) {
1143
- handler = _ref[signature];
1144
- console.log("Sig", signature, "Handler", handler);
1145
- _ref2 = signature.split(" "), key = _ref2[0], eventTrigger = _ref2[1];
1146
- collection = manager.getOrCreate(key);
1147
- if (!collection) throw "Could not find collection specified by " + key;
1148
- if (_.isString(handler)) handler = this[handler];
1149
- if (!_.isFunction(handler)) throw "invalid collectionEvents configuration";
1150
- try {
1151
- _results.push(collection.bind(eventTrigger, handler));
1152
- } catch (e) {
1153
- console.log("Error Binding To Collection in registerCollectionEvents", this);
1154
- throw e;
1155
- }
1768
+ bindAllEventHandlers = function() {
1769
+ var config, _i, _len, _ref, _results;
1770
+ _ref = [this.events, this.componentEvents, this.collectionEvents, this.applicationEvents];
1771
+ _results = [];
1772
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1773
+ config = _ref[_i];
1774
+ if (!_.isEmpty(config)) _results.push(bindEventHandlers.call(this, config));
1156
1775
  }
1157
1776
  return _results;
1158
1777
  };
1159
1778
 
1160
- setupBodyTemplate = function() {
1161
- var template, templateVars;
1162
- templateVars = this.bodyTemplateVars ? this.bodyTemplateVars.call(this) : this;
1163
- if (template = this.bodyTemplate) {
1164
- this.$el.empty();
1165
- return Luca.View.prototype.$html.call(this, Luca.template(template, templateVars));
1779
+ bindEventHandlers = function(events) {
1780
+ var eventSignature, handler, _results;
1781
+ if (events == null) events = {};
1782
+ _results = [];
1783
+ for (eventSignature in events) {
1784
+ handler = events[eventSignature];
1785
+ if (_.isString(handler)) {
1786
+ _results.push(_.bindAll(this, handler));
1787
+ } else {
1788
+ _results.push(void 0);
1789
+ }
1166
1790
  }
1791
+ return _results;
1167
1792
  };
1168
1793
 
1169
1794
  Luca.View.extend = function(definition) {
1170
1795
  var module, _i, _len, _ref;
1171
- definition = customizeRender(definition);
1796
+ definition = Luca.View.renderWrapper(definition);
1172
1797
  if ((definition.mixins != null) && _.isArray(definition.mixins)) {
1173
1798
  _ref = definition.mixins;
1174
1799
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1175
1800
  module = _ref[_i];
1176
- _.extend(definition, Luca.modules[module]);
1801
+ Luca.decorate(definition)["with"](module);
1177
1802
  }
1178
1803
  }
1179
- return originalExtend.call(this, definition);
1804
+ return Luca.View._originalExtend.call(this, definition);
1180
1805
  };
1181
1806
 
1807
+ Luca.View.deferrableEvent = "reset";
1808
+
1182
1809
  }).call(this);
1183
1810
  (function() {
1184
- var setupComputedProperties;
1811
+ var model, setupComputedProperties;
1812
+
1813
+ model = Luca.define('Luca.Model');
1814
+
1815
+ model["extends"]('Backbone.Model');
1816
+
1817
+ model.includes('Luca.Events');
1818
+
1819
+ model.defines({
1820
+ initialize: function() {
1821
+ Backbone.Model.prototype.initialize(this, arguments);
1822
+ return setupComputedProperties.call(this);
1823
+ },
1824
+ read: function(attr) {
1825
+ if (_.isFunction(this[attr])) {
1826
+ return this[attr].call(this);
1827
+ } else {
1828
+ return this.get(attr);
1829
+ }
1830
+ },
1831
+ get: function(attr) {
1832
+ var _ref;
1833
+ if ((_ref = this.computed) != null ? _ref.hasOwnProperty(attr) : void 0) {
1834
+ return this._computed[attr];
1835
+ } else {
1836
+ return Backbone.Model.prototype.get.call(this, attr);
1837
+ }
1838
+ }
1839
+ });
1185
1840
 
1186
1841
  setupComputedProperties = function() {
1187
1842
  var attr, dependencies, _ref, _results,
@@ -1206,32 +1861,22 @@
1206
1861
  return _results;
1207
1862
  };
1208
1863
 
1209
- _.def('Luca.Model')["extends"]('Backbone.Model')["with"]({
1210
- include: ['Luca.Events'],
1211
- initialize: function() {
1212
- Backbone.Model.prototype.initialize(this, arguments);
1213
- return setupComputedProperties.call(this);
1214
- },
1215
- get: function(attr) {
1216
- var _ref;
1217
- if ((_ref = this.computed) != null ? _ref.hasOwnProperty(attr) : void 0) {
1218
- return this._computed[attr];
1219
- } else {
1220
- return Backbone.Model.prototype.get.call(this, attr);
1221
- }
1222
- }
1223
- });
1224
-
1225
1864
  }).call(this);
1226
1865
  (function() {
1227
- var source;
1866
+ var collection;
1867
+
1868
+ collection = Luca.define('Luca.Collection');
1228
1869
 
1229
- source = 'Backbone.Collection';
1870
+ if (Backbone.QueryCollection != null) {
1871
+ collection["extends"]('Backbone.QueryCollection');
1872
+ } else {
1873
+ collection["extends"]('Backbone.Collection');
1874
+ }
1230
1875
 
1231
- if (Backbone.QueryCollection != null) source = 'Backbone.QueryCollection';
1876
+ collection.includes('Luca.Events');
1232
1877
 
1233
- _.def("Luca.Collection")["extends"](source)["with"]({
1234
- include: ['Luca.Events'],
1878
+ collection.defines({
1879
+ model: Luca.Model,
1235
1880
  cachedMethods: [],
1236
1881
  remoteFilter: false,
1237
1882
  initialize: function(models, options) {
@@ -1464,7 +2109,7 @@
1464
2109
  return _results;
1465
2110
  },
1466
2111
  setupMethodCaching: function() {
1467
- var cache, collection, membershipEvents;
2112
+ var cache, membershipEvents;
1468
2113
  collection = this;
1469
2114
  membershipEvents = ["reset", "add", "remove"];
1470
2115
  cache = this._methodCache = {};
@@ -1687,11 +2332,13 @@
1687
2332
  this.input_id || (this.input_id = _.uniqueId('field'));
1688
2333
  this.input_name || (this.input_name = this.name);
1689
2334
  this.input_class || (this.input_class = "");
2335
+ this.input_type || (this.input_type = "");
1690
2336
  this.helperText || (this.helperText = "");
1691
2337
  if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) {
1692
2338
  this.label || (this.label = "*" + this.label);
1693
2339
  }
1694
2340
  this.inputStyles || (this.inputStyles = "");
2341
+ this.input_value || (this.input_value = this.value || "");
1695
2342
  if (this.disabled) this.disable();
1696
2343
  this.updateState(this.state);
1697
2344
  this.placeHolder || (this.placeHolder = "");
@@ -1699,22 +2346,20 @@
1699
2346
  },
1700
2347
  beforeRender: function() {
1701
2348
  if (Luca.enableBootstrap) this.$el.addClass('control-group');
1702
- if (this.required) this.$el.addClass('required');
1703
- this.$el.html(Luca.template(this.template, this));
1704
- return this.input = $('input', this.el);
2349
+ if (this.required) return this.$el.addClass('required');
1705
2350
  },
1706
2351
  change_handler: function(e) {
1707
2352
  return this.trigger("on:change", this, e);
1708
2353
  },
1709
2354
  disable: function() {
1710
- return $("input", this.el).attr('disabled', true);
2355
+ return this.getInputElement().attr('disabled', true);
1711
2356
  },
1712
2357
  enable: function() {
1713
- return $("input", this.el).attr('disabled', false);
2358
+ return this.getInputElement().attr('disabled', false);
1714
2359
  },
1715
2360
  getValue: function() {
1716
- var raw;
1717
- raw = this.input.attr('value');
2361
+ var raw, _ref;
2362
+ raw = (_ref = this.getInputElement()) != null ? _ref.attr('value') : void 0;
1718
2363
  if (_.str.isBlank(raw)) return raw;
1719
2364
  switch (this.valueType) {
1720
2365
  case "integer":
@@ -1727,11 +2372,12 @@
1727
2372
  return raw;
1728
2373
  }
1729
2374
  },
1730
- render: function() {
1731
- return $(this.container).append(this.$el);
1732
- },
1733
2375
  setValue: function(value) {
1734
- return this.input.attr('value', value);
2376
+ var _ref;
2377
+ return (_ref = this.getInputElement()) != null ? _ref.attr('value', value) : void 0;
2378
+ },
2379
+ getInputElement: function() {
2380
+ return this.input || (this.input = this.$('input').eq(0));
1735
2381
  },
1736
2382
  updateState: function(state) {
1737
2383
  var _this = this;
@@ -1744,57 +2390,28 @@
1744
2390
 
1745
2391
  }).call(this);
1746
2392
  (function() {
1747
- var applyDOMConfig, doComponents, doLayout;
2393
+ var applyDOMConfig, container, createGetterMethods, createMethodsToGetComponentsByRole, doComponents, doLayout, indexComponent, validateContainerConfiguration;
1748
2394
 
1749
- doLayout = function() {
1750
- this.trigger("before:layout", this);
1751
- this.prepareLayout();
1752
- return this.trigger("after:layout", this);
1753
- };
2395
+ container = Luca.register("Luca.core.Container");
1754
2396
 
1755
- applyDOMConfig = function(panel, panelIndex) {
1756
- var config, style_declarations;
1757
- style_declarations = [];
1758
- if (panel.height != null) {
1759
- style_declarations.push("height: " + (_.isNumber(panel.height) ? panel.height + 'px' : panel.height));
1760
- }
1761
- if (panel.width != null) {
1762
- style_declarations.push("width: " + (_.isNumber(panel.width) ? panel.width + 'px' : panel.width));
1763
- }
1764
- if (panel.float) style_declarations.push("float: " + panel.float);
1765
- config = {
1766
- "class": (panel != null ? panel.classes : void 0) || this.componentClass,
1767
- id: "" + this.cid + "-" + panelIndex,
1768
- style: style_declarations.join(';'),
1769
- "data-luca-owner": this.name || this.cid
1770
- };
1771
- if (this.customizeContainerEl != null) {
1772
- config = this.customizeContainerEl(config, panel, panelIndex);
1773
- }
1774
- return config;
1775
- };
2397
+ container["extends"]("Luca.components.Panel");
1776
2398
 
1777
- doComponents = function() {
1778
- this.trigger("before:components", this, this.components);
1779
- this.prepareComponents();
1780
- this.createComponents();
1781
- this.trigger("before:render:components", this, this.components);
1782
- this.renderComponents();
1783
- return this.trigger("after:components", this, this.components);
1784
- };
2399
+ container.triggers("before:components", "before:render:components", "before:layout", "after:components", "after:layout", "first:activation");
1785
2400
 
1786
- _.def('Luca.core.Container')["extends"]('Luca.components.Panel')["with"]({
2401
+ container.defines({
1787
2402
  className: 'luca-ui-container',
1788
2403
  componentTag: 'div',
1789
2404
  componentClass: 'luca-ui-panel',
1790
2405
  isContainer: true,
1791
- hooks: ["before:components", "before:render:components", "before:layout", "after:components", "after:layout", "first:activation"],
1792
2406
  rendered: false,
1793
2407
  components: [],
2408
+ componentEvents: {},
1794
2409
  initialize: function(options) {
1795
2410
  this.options = options != null ? options : {};
1796
2411
  _.extend(this, this.options);
1797
- this.setupHooks(["before:components", "before:render:components", "before:layout", "after:components", "after:layout", "first:activation"]);
2412
+ this.setupHooks(Luca.core.Container.prototype.hooks);
2413
+ this.components || (this.components = this.fields || (this.fields = this.pages || (this.pages = this.cards || (this.cards = this.views))));
2414
+ validateContainerConfiguration(this);
1798
2415
  return Luca.View.prototype.initialize.apply(this, arguments);
1799
2416
  },
1800
2417
  beforeRender: function() {
@@ -1807,7 +2424,6 @@
1807
2424
  return containerEl;
1808
2425
  },
1809
2426
  prepareLayout: function() {
1810
- var container;
1811
2427
  container = this;
1812
2428
  return this.componentContainers = _(this.components).map(function(component, index) {
1813
2429
  return applyDOMConfig.call(container, component, index);
@@ -1847,31 +2463,27 @@
1847
2463
  if (this.componentsCreated === true) return;
1848
2464
  map = this.componentIndex = {
1849
2465
  name_index: {},
1850
- cid_index: {}
2466
+ cid_index: {},
2467
+ role_index: {}
1851
2468
  };
2469
+ container = this;
1852
2470
  this.components = _(this.components).map(function(object, index) {
1853
- var component;
1854
- component = Luca.isBackboneView(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, Luca.util.lazyComponent(object));
1855
- if (_.isString(component.getter)) {
1856
- _this[component.getter] = (function() {
1857
- return component;
1858
- });
1859
- }
1860
- if (!component.container && component.options.container) {
2471
+ var component, created, _ref;
2472
+ 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));
2473
+ if (!component.container && ((_ref = component.options) != null ? _ref.container : void 0)) {
1861
2474
  component.container = component.options.container;
1862
2475
  }
1863
- if (map && (component.cid != null)) map.cid_index[component.cid] = index;
1864
- if (map && (component.name != null)) {
1865
- map.name_index[component.name] = index;
2476
+ if (!(component.container != null)) {
2477
+ console.log(component, index, _this);
2478
+ console.error("could not assign container property to component on container " + (_this.name || _this.cid));
1866
2479
  }
2480
+ indexComponent(component).at(index)["in"](_this.componentIndex);
1867
2481
  return component;
1868
2482
  });
1869
2483
  this.componentsCreated = true;
1870
- if (!_.isEmpty(this.componentEvents)) this.registerComponentEvents();
1871
2484
  return map;
1872
2485
  },
1873
2486
  renderComponents: function(debugMode) {
1874
- var container;
1875
2487
  this.debugMode = debugMode != null ? debugMode : "";
1876
2488
  this.debug("container render components");
1877
2489
  container = this;
@@ -1880,7 +2492,7 @@
1880
2492
  return container;
1881
2493
  };
1882
2494
  try {
1883
- $(component.container).append(component.el);
2495
+ this.$(component.container).eq(0).append(component.el);
1884
2496
  return component.render();
1885
2497
  } catch (e) {
1886
2498
  console.log("Error Rendering Component " + (component.name || component.cid), component);
@@ -1907,43 +2519,102 @@
1907
2519
  }
1908
2520
  });
1909
2521
  },
2522
+ _: function() {
2523
+ return _(this.components);
2524
+ },
1910
2525
  pluck: function(attribute) {
1911
- return _(this.components).pluck(attribute);
2526
+ return this._().pluck(attribute);
1912
2527
  },
1913
2528
  invoke: function(method) {
1914
- return _(this.components).invoke(method);
2529
+ return this._().invoke(method);
2530
+ },
2531
+ select: function(fn) {
2532
+ return this._().select(fn);
2533
+ },
2534
+ detect: function(fn) {
2535
+ return this._().detect(attribute);
2536
+ },
2537
+ reject: function(fn) {
2538
+ return this._().reject(fn);
1915
2539
  },
1916
2540
  map: function(fn) {
1917
- return _(this.components).map(fn);
2541
+ return this._().map(fn);
1918
2542
  },
1919
- componentEvents: {},
1920
- registerComponentEvents: function() {
1921
- var component, componentName, handler, listener, trigger, _ref, _ref2, _results;
1922
- _ref = this.componentEvents;
2543
+ registerComponentEvents: function(eventList) {
2544
+ var component, componentNameOrRole, eventId, handler, listener, _ref, _ref2, _results,
2545
+ _this = this;
2546
+ container = this;
2547
+ _ref = eventList || this.componentEvents || {};
1923
2548
  _results = [];
1924
2549
  for (listener in _ref) {
1925
2550
  handler = _ref[listener];
1926
- _ref2 = listener.split(' '), componentName = _ref2[0], trigger = _ref2[1];
1927
- component = this.findComponentByName(componentName);
1928
- _results.push(component != null ? component.bind(trigger, this[handler]) : void 0);
2551
+ _ref2 = listener.split(' '), componentNameOrRole = _ref2[0], eventId = _ref2[1];
2552
+ if (!_.isFunction(this[handler])) {
2553
+ console.log("Error registering component event", listener, componentNameOrRole, eventId);
2554
+ throw "Invalid component event definition " + listener + ". Specified handler is not a method on the container";
2555
+ }
2556
+ if (componentNameOrRole === "*") {
2557
+ _results.push(this.eachComponent(function(component) {
2558
+ return component.on(eventId, _this[handler], container);
2559
+ }));
2560
+ } else {
2561
+ component = this.findComponentForEventBinding(componentNameOrRole);
2562
+ if (!((component != null) && Luca.isComponent(component))) {
2563
+ console.log("Error registering component event", listener, componentNameOrRole, eventId);
2564
+ throw "Invalid component event definition: " + componentNameOrRole;
2565
+ }
2566
+ _results.push(component != null ? component.bind(eventId, this[handler], container) : void 0);
2567
+ }
1929
2568
  }
1930
2569
  return _results;
1931
2570
  },
2571
+ subContainers: function() {
2572
+ return this.select(function(component) {
2573
+ return component.isContainer === true;
2574
+ });
2575
+ },
2576
+ roles: function() {
2577
+ return _(this.allChildren()).pluck('role');
2578
+ },
2579
+ allChildren: function() {
2580
+ var children, grandchildren;
2581
+ children = this.components;
2582
+ grandchildren = _(this.subContainers()).invoke('allChildren');
2583
+ return _([children, grandchildren]).chain().compact().flatten().value();
2584
+ },
2585
+ findComponentForEventBinding: function(nameRoleOrGetter, deep) {
2586
+ if (deep == null) deep = true;
2587
+ return this.findComponentByName(nameRoleOrGetter, deep) || this.findComponentByGetter(nameRoleOrGetter, deep) || this.findComponentByRole(nameRoleOrGetter, deep);
2588
+ },
2589
+ findComponentByGetter: function(getter, deep) {
2590
+ if (deep == null) deep = false;
2591
+ return _(this.allChildren()).detect(function(component) {
2592
+ return component.getter === getter;
2593
+ });
2594
+ },
2595
+ findComponentByRole: function(role, deep) {
2596
+ if (deep == null) deep = false;
2597
+ return _(this.allChildren()).detect(function(component) {
2598
+ return component.role === role || component.type === role || component.ctype === role;
2599
+ });
2600
+ },
1932
2601
  findComponentByName: function(name, deep) {
1933
2602
  if (deep == null) deep = false;
1934
- return this.findComponent(name, "name_index", deep);
2603
+ return _(this.allChildren()).detect(function(component) {
2604
+ return component.name === name;
2605
+ });
1935
2606
  },
1936
2607
  findComponentById: function(id, deep) {
1937
2608
  if (deep == null) deep = false;
1938
2609
  return this.findComponent(id, "cid_index", deep);
1939
2610
  },
1940
2611
  findComponent: function(needle, haystack, deep) {
1941
- var component, position, sub_container, _ref, _ref2;
2612
+ var component, position, sub_container, _ref;
1942
2613
  if (haystack == null) haystack = "name";
1943
2614
  if (deep == null) deep = false;
1944
2615
  if (this.componentsCreated !== true) this.createComponents();
1945
2616
  position = (_ref = this.componentIndex) != null ? _ref[haystack][needle] : void 0;
1946
- component = (_ref2 = this.components) != null ? _ref2[position] : void 0;
2617
+ component = this.components[position];
1947
2618
  if (component) return component;
1948
2619
  if (deep === true) {
1949
2620
  sub_container = _(this.components).detect(function(component) {
@@ -1976,20 +2647,16 @@
1976
2647
  return this.components[this.activeItem];
1977
2648
  },
1978
2649
  componentElements: function() {
1979
- return this.$(">." + this.componentClass, this.$bodyEl());
2650
+ return this.$("[data-luca-parent='" + (this.name || this.cid) + "']");
1980
2651
  },
1981
2652
  getComponent: function(needle) {
1982
2653
  return this.components[needle];
1983
2654
  },
1984
- rootComponent: function() {
1985
- console.log("Calling rootComponent will be deprecated. use isRootComponent instead");
1986
- return !(this.getParent != null);
1987
- },
1988
2655
  isRootComponent: function() {
1989
2656
  return !(this.getParent != null);
1990
2657
  },
1991
2658
  getRootComponent: function() {
1992
- if (this.rootComponent()) {
2659
+ if (this.isRootComponent()) {
1993
2660
  return this;
1994
2661
  } else {
1995
2662
  return this.getParent().getRootComponent();
@@ -1997,23 +2664,21 @@
1997
2664
  },
1998
2665
  selectByAttribute: function(attribute, value, deep) {
1999
2666
  var components;
2667
+ if (value == null) value = void 0;
2000
2668
  if (deep == null) deep = false;
2001
2669
  components = _(this.components).map(function(component) {
2002
2670
  var matches, test;
2003
2671
  matches = [];
2004
2672
  test = component[attribute];
2005
- if (test === value) matches.push(component);
2673
+ if (test === value || (!(value != null) && (test != null))) {
2674
+ matches.push(component);
2675
+ }
2006
2676
  if (deep === true) {
2007
2677
  matches.push(typeof component.selectByAttribute === "function" ? component.selectByAttribute(attribute, value, true) : void 0);
2008
2678
  }
2009
2679
  return _.compact(matches);
2010
2680
  });
2011
2681
  return _.flatten(components);
2012
- },
2013
- select: function(attribute, value, deep) {
2014
- if (deep == null) deep = false;
2015
- console.log("Container.select will be replaced by selectByAttribute in 1.0");
2016
- return Luca.core.Container.prototype.selectByAttribute.apply(this, arguments);
2017
2682
  }
2018
2683
  });
2019
2684
 
@@ -2023,6 +2688,98 @@
2023
2688
  return attachMethod(component.render().el);
2024
2689
  };
2025
2690
 
2691
+ doLayout = function() {
2692
+ this.trigger("before:layout", this);
2693
+ this.prepareLayout();
2694
+ return this.trigger("after:layout", this);
2695
+ };
2696
+
2697
+ applyDOMConfig = function(panel, panelIndex) {
2698
+ var config, style_declarations;
2699
+ style_declarations = [];
2700
+ if (panel.height != null) {
2701
+ style_declarations.push("height: " + (_.isNumber(panel.height) ? panel.height + 'px' : panel.height));
2702
+ }
2703
+ if (panel.width != null) {
2704
+ style_declarations.push("width: " + (_.isNumber(panel.width) ? panel.width + 'px' : panel.width));
2705
+ }
2706
+ if (panel.float) style_declarations.push("float: " + panel.float);
2707
+ config = {
2708
+ "class": (panel != null ? panel.classes : void 0) || this.componentClass,
2709
+ id: "" + this.cid + "-" + panelIndex,
2710
+ style: style_declarations.join(';'),
2711
+ "data-luca-parent": this.name || this.cid
2712
+ };
2713
+ if (this.customizeContainerEl != null) {
2714
+ config = this.customizeContainerEl(config, panel, panelIndex);
2715
+ }
2716
+ return config;
2717
+ };
2718
+
2719
+ createGetterMethods = function() {
2720
+ var childrenWithGetter;
2721
+ container = this;
2722
+ childrenWithGetter = _(this.allChildren()).select(function(component) {
2723
+ return component.getter != null;
2724
+ });
2725
+ return _(childrenWithGetter).each(function(component) {
2726
+ var _name;
2727
+ return container[_name = component.getter] || (container[_name] = function() {
2728
+ console.log(component.getter, component, container);
2729
+ return component;
2730
+ });
2731
+ });
2732
+ };
2733
+
2734
+ createMethodsToGetComponentsByRole = function() {
2735
+ var childrenWithRole;
2736
+ container = this;
2737
+ childrenWithRole = _(this.allChildren()).select(function(component) {
2738
+ return component.role != null;
2739
+ });
2740
+ return _(childrenWithRole).each(function(component) {
2741
+ var getter;
2742
+ getter = _.str.camelize("get_" + component.role);
2743
+ return container[getter] || (container[getter] = function() {
2744
+ return component;
2745
+ });
2746
+ });
2747
+ };
2748
+
2749
+ doComponents = function() {
2750
+ this.trigger("before:components", this, this.components);
2751
+ this.prepareComponents();
2752
+ this.createComponents();
2753
+ this.trigger("before:render:components", this, this.components);
2754
+ this.renderComponents();
2755
+ this.trigger("after:components", this, this.components);
2756
+ if (this.skipGetterMethods !== true) {
2757
+ createGetterMethods.call(this);
2758
+ createMethodsToGetComponentsByRole.call(this);
2759
+ }
2760
+ return this.registerComponentEvents();
2761
+ };
2762
+
2763
+ validateContainerConfiguration = function() {
2764
+ return true;
2765
+ };
2766
+
2767
+ indexComponent = function(component) {
2768
+ return {
2769
+ at: function(index) {
2770
+ return {
2771
+ "in": function(map) {
2772
+ if (component.cid != null) map.cid_index[component.cid] = index;
2773
+ if (component.role != null) map.role_index[component.role] = index;
2774
+ if (component.name != null) {
2775
+ return map.name_index[component.name] = index;
2776
+ }
2777
+ }
2778
+ };
2779
+ }
2780
+ };
2781
+ };
2782
+
2026
2783
  }).call(this);
2027
2784
  (function() {
2028
2785
  var guessCollectionClass, handleInitialCollections, loadInitialCollections;
@@ -2073,7 +2830,12 @@
2073
2830
  CollectionClass = collectionOptions.base;
2074
2831
  CollectionClass || (CollectionClass = guessCollectionClass.call(this, key));
2075
2832
  if (collectionOptions.private) collectionOptions.name = "";
2076
- collection = new CollectionClass(initialModels, collectionOptions);
2833
+ try {
2834
+ collection = new CollectionClass(initialModels, collectionOptions);
2835
+ } catch (e) {
2836
+ console.log("Error creating collection", CollectionClass, collectionOptions, key);
2837
+ throw e;
2838
+ }
2077
2839
  this.add(key, collection);
2078
2840
  collectionManager = this;
2079
2841
  if (this.relayEvents === true) {
@@ -2147,10 +2909,28 @@
2147
2909
 
2148
2910
  })();
2149
2911
 
2912
+ Luca.CollectionManager.isRunning = function() {
2913
+ return _.isEmpty(Luca.CollectionManager.instances) !== true;
2914
+ };
2915
+
2150
2916
  Luca.CollectionManager.destroyAll = function() {
2151
2917
  return Luca.CollectionManager.instances = {};
2152
2918
  };
2153
2919
 
2920
+ Luca.CollectionManager.loadCollectionsByName = function(set, callback) {
2921
+ var collection, name, _i, _len, _results;
2922
+ _results = [];
2923
+ for (_i = 0, _len = set.length; _i < _len; _i++) {
2924
+ name = set[_i];
2925
+ collection = this.getOrCreate(name);
2926
+ collection.once("reset", function() {
2927
+ return callback(collection);
2928
+ });
2929
+ _results.push(collection.fetch());
2930
+ }
2931
+ return _results;
2932
+ };
2933
+
2154
2934
  guessCollectionClass = function(key) {
2155
2935
  var classified, guess, guesses, _ref;
2156
2936
  classified = Luca.util.classify(key);
@@ -2167,7 +2947,7 @@
2167
2947
  };
2168
2948
 
2169
2949
  loadInitialCollections = function() {
2170
- var collectionDidLoad,
2950
+ var collectionDidLoad, set,
2171
2951
  _this = this;
2172
2952
  collectionDidLoad = function(collection) {
2173
2953
  var current;
@@ -2176,14 +2956,8 @@
2176
2956
  _this.trigger("collection_loaded", collection.name);
2177
2957
  return collection.unbind("reset");
2178
2958
  };
2179
- return _(this.initialCollections).each(function(name) {
2180
- var collection;
2181
- collection = _this.getOrCreate(name);
2182
- collection.once("reset", function() {
2183
- return collectionDidLoad(collection);
2184
- });
2185
- return collection.fetch();
2186
- });
2959
+ set = this.initialCollections;
2960
+ return Luca.CollectionManager.loadCollectionsByName.call(this, set, collectionDidLoad);
2187
2961
  };
2188
2962
 
2189
2963
  handleInitialCollections = function() {
@@ -2202,6 +2976,7 @@
2202
2976
  }));
2203
2977
  }
2204
2978
  loadInitialCollections.call(this);
2979
+ this.initialCollectionsLoadedu;
2205
2980
  return this;
2206
2981
  };
2207
2982
 
@@ -2314,9 +3089,13 @@
2314
3089
 
2315
3090
  }).call(this);
2316
3091
  (function() {
3092
+ var component;
3093
+
3094
+ component = Luca.define("Luca.containers.CardView");
2317
3095
 
2318
- _.def("Luca.containers.CardView")["extends"]("Luca.core.Container")["with"]({
2319
- componentType: 'card_view',
3096
+ component["extends"]("Luca.core.Container");
3097
+
3098
+ component.defaults({
2320
3099
  className: 'luca-ui-card-view-wrapper',
2321
3100
  activeCard: 0,
2322
3101
  components: [],
@@ -2326,21 +3105,16 @@
2326
3105
  initialize: function(options) {
2327
3106
  this.options = options;
2328
3107
  Luca.core.Container.prototype.initialize.apply(this, arguments);
2329
- return this.setupHooks(this.hooks);
3108
+ this.setupHooks(this.hooks);
3109
+ return this.components || (this.components = this.pages || (this.pages = this.cards));
2330
3110
  },
2331
3111
  prepareComponents: function() {
2332
- var _ref,
2333
- _this = this;
3112
+ var _ref;
2334
3113
  if ((_ref = Luca.core.Container.prototype.prepareComponents) != null) {
2335
3114
  _ref.apply(this, arguments);
2336
3115
  }
2337
- return _(this.components).each(function(component, index) {
2338
- if (index === _this.activeCard) {
2339
- return $(component.container).show();
2340
- } else {
2341
- return $(component.container).hide();
2342
- }
2343
- });
3116
+ this.componentElements().hide();
3117
+ return this.activeComponentElement().show();
2344
3118
  },
2345
3119
  activeComponentElement: function() {
2346
3120
  return this.componentElements().eq(this.activeCard);
@@ -2352,13 +3126,27 @@
2352
3126
  containerEl.style += panelIndex === this.activeCard ? "display:block;" : "display:none;";
2353
3127
  return containerEl;
2354
3128
  },
3129
+ atFirst: function() {
3130
+ return this.activeCard === 0;
3131
+ },
3132
+ atLast: function() {
3133
+ return this.activeCard === this.components.length - 1;
3134
+ },
3135
+ next: function() {
3136
+ if (this.atLast()) return;
3137
+ return this.activate(this.activeCard + 1);
3138
+ },
3139
+ previous: function() {
3140
+ if (this.atFirst()) return;
3141
+ return this.activate(this.activeCard - 1);
3142
+ },
2355
3143
  cycle: function() {
2356
3144
  var nextIndex;
2357
- nextIndex = this.activeCard < this.components.length - 1 ? this.activeCard + 1 : 0;
3145
+ nextIndex = this.atLast() ? 0 : this.activeCard + 1;
2358
3146
  return this.activate(nextIndex);
2359
3147
  },
2360
3148
  find: function(name) {
2361
- return this.findComponentByName(name, true);
3149
+ return Luca(name);
2362
3150
  },
2363
3151
  firstActivation: function() {
2364
3152
  return this.activeComponent().trigger("first:activation", this, this.activeComponent());
@@ -2450,33 +3238,93 @@
2450
3238
  }
2451
3239
  });
2452
3240
 
2453
- _.def("Luca.containers.ModalView")["extends"]("Luca.ModalView")["with"]();
2454
-
2455
- }).call(this);
2456
- (function() {
2457
-
2458
- _.def("Luca.PageView")["extends"]("Luca.containers.CardView")["with"]({
2459
- version: 2
2460
- });
2461
-
2462
- }).call(this);
2463
- (function() {
2464
- var buildButton, make, prepareButtons;
2465
-
3241
+ _.def("Luca.containers.ModalView")["extends"]("Luca.ModalView")["with"]();
3242
+
3243
+ }).call(this);
3244
+ (function() {
3245
+
3246
+ _.def("Luca.PageView")["extends"]("Luca.containers.CardView")["with"]({
3247
+ version: 2
3248
+ });
3249
+
3250
+ }).call(this);
3251
+ (function() {
3252
+ var buildButton, make, panelToolbar, prepareButtons;
3253
+
3254
+ panelToolbar = Luca.register("Luca.components.PanelToolbar");
3255
+
3256
+ panelToolbar["extends"]("Luca.View");
3257
+
3258
+ panelToolbar.defines({
3259
+ buttons: [],
3260
+ className: "luca-ui-toolbar btn-toolbar",
3261
+ well: true,
3262
+ orientation: 'top',
3263
+ autoBindEventHandlers: true,
3264
+ events: {
3265
+ "click a.btn, click .dropdown-menu li": "clickHandler"
3266
+ },
3267
+ initialize: function(options) {
3268
+ var _ref;
3269
+ this.options = options != null ? options : {};
3270
+ this._super("initialize", this, arguments);
3271
+ if (this.group === true && ((_ref = this.buttons) != null ? _ref.length : void 0) >= 0) {
3272
+ return this.buttons = [
3273
+ {
3274
+ group: true,
3275
+ buttons: this.buttons
3276
+ }
3277
+ ];
3278
+ }
3279
+ },
3280
+ clickHandler: function(e) {
3281
+ var eventId, hook, me, my, source;
3282
+ me = my = $(e.target);
3283
+ if (me.is('i')) me = my = $(e.target).parent();
3284
+ if (this.selectable === true) {
3285
+ my.siblings().removeClass("is-selected");
3286
+ me.addClass('is-selected');
3287
+ }
3288
+ if (!(eventId = my.data('eventid'))) return;
3289
+ hook = Luca.util.hook(eventId);
3290
+ source = this.parent || this;
3291
+ if (_.isFunction(source[hook])) {
3292
+ return source[hook].call(this, me, e);
3293
+ } else {
3294
+ return source.trigger(eventId, me, e);
3295
+ }
3296
+ },
3297
+ beforeRender: function() {
3298
+ this._super("beforeRender", this, arguments);
3299
+ if (this.well === true) this.$el.addClass('well');
3300
+ if (this.selectable === true) this.$el.addClass('btn-selectable');
3301
+ this.$el.addClass("toolbar-" + this.orientation);
3302
+ if (this.align === "right") this.$el.addClass("pull-right");
3303
+ if (this.align === "left") return this.$el.addClass("pull-left");
3304
+ },
3305
+ render: function() {
3306
+ var element, _i, _len, _ref;
3307
+ this.$el.empty();
3308
+ _ref = prepareButtons(this.buttons);
3309
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3310
+ element = _ref[_i];
3311
+ this.$el.append(element);
3312
+ }
3313
+ return this;
3314
+ }
3315
+ });
3316
+
2466
3317
  make = Backbone.View.prototype.make;
2467
3318
 
2468
3319
  buildButton = function(config, wrap) {
2469
3320
  var autoWrapClass, buttonAttributes, buttonEl, buttons, dropdownEl, dropdownItems, label, object, white, wrapper,
2470
3321
  _this = this;
2471
3322
  if (wrap == null) wrap = true;
2472
- if (config.ctype != null) {
3323
+ if ((config.ctype != null) || (config.type != null)) {
2473
3324
  config.className || (config.className = "");
2474
3325
  config.className += 'toolbar-component';
2475
3326
  object = Luca(config).render();
2476
- if (Luca.isBackboneView(object)) {
2477
- console.log("Adding toolbar component", object);
2478
- return object.el;
2479
- }
3327
+ if (Luca.isBackboneView(object)) return object.$el;
2480
3328
  }
2481
3329
  if (config.spacer) {
2482
3330
  return make("div", {
@@ -2489,8 +3337,11 @@
2489
3337
  }, config.text);
2490
3338
  }
2491
3339
  wrapper = 'btn-group';
2492
- if (config.wrapper != null) wrapper += " " + config.wrapper;
2493
- if (config.align != null) wrapper += " align-" + config.align;
3340
+ if (config.wrapper != null) wrapper += "" + config.wrapper;
3341
+ if (config.align != null) {
3342
+ wrapper += "pull-" + config.align + " align-" + config.align;
3343
+ }
3344
+ if (config.selectable === true) wrapper += 'btn-selectable';
2494
3345
  if ((config.group != null) && (config.buttons != null)) {
2495
3346
  buttons = prepareButtons(config.buttons, false);
2496
3347
  return make("div", {
@@ -2512,6 +3363,7 @@
2512
3363
  if (config.color != null) {
2513
3364
  buttonAttributes["class"] += " btn-" + config.color;
2514
3365
  }
3366
+ if (config.selected != null) buttonAttributes["class"] += " is-selected";
2515
3367
  if (config.dropdown) {
2516
3368
  label = "" + label + " <span class='caret'></span>";
2517
3369
  buttonAttributes["class"] += " dropdown-toggle";
@@ -2541,51 +3393,16 @@
2541
3393
  };
2542
3394
 
2543
3395
  prepareButtons = function(buttons, wrap) {
3396
+ var button, _i, _len, _results;
3397
+ if (buttons == null) buttons = [];
2544
3398
  if (wrap == null) wrap = true;
2545
- return _(buttons).map(function(button) {
2546
- return buildButton(button, wrap);
2547
- });
2548
- };
2549
-
2550
- _.def("Luca.containers.PanelToolbar")["extends"]("Luca.View")["with"]({
2551
- className: "luca-ui-toolbar btn-toolbar",
2552
- buttons: [],
2553
- well: true,
2554
- orientation: 'top',
2555
- autoBindEventHandlers: true,
2556
- events: {
2557
- "click a.btn, click .dropdown-menu li": "clickHandler"
2558
- },
2559
- clickHandler: function(e) {
2560
- var eventId, hook, me, my, source;
2561
- me = my = $(e.target);
2562
- if (me.is('i')) me = my = $(e.target).parent();
2563
- eventId = my.data('eventid');
2564
- if (eventId == null) return;
2565
- hook = Luca.util.hook(eventId);
2566
- source = this.parent || this;
2567
- if (_.isFunction(source[hook])) {
2568
- return source[hook].call(this, me, e);
2569
- } else {
2570
- return source.trigger(eventId, me, e);
2571
- }
2572
- },
2573
- beforeRender: function() {
2574
- this._super("beforeRender", this, arguments);
2575
- if (this.well === true) this.$el.addClass('well');
2576
- this.$el.addClass("toolbar-" + this.orientation);
2577
- if (this.styles != null) return this.applyStyles(this.styles);
2578
- },
2579
- render: function() {
2580
- var elements,
2581
- _this = this;
2582
- this.$el.empty();
2583
- elements = prepareButtons(this.buttons);
2584
- return _(elements).each(function(element) {
2585
- return _this.$el.append(element);
2586
- });
3399
+ _results = [];
3400
+ for (_i = 0, _len = buttons.length; _i < _len; _i++) {
3401
+ button = buttons[_i];
3402
+ _results.push(buildButton(button, wrap));
2587
3403
  }
2588
- });
3404
+ return _results;
3405
+ };
2589
3406
 
2590
3407
  }).call(this);
2591
3408
  (function() {
@@ -2651,11 +3468,12 @@
2651
3468
  return (_ref = Luca.containers.CardView.prototype.beforeLayout) != null ? _ref.apply(this, arguments) : void 0;
2652
3469
  },
2653
3470
  afterRender: function() {
2654
- var _ref;
3471
+ var tabContainerId, _ref;
2655
3472
  if ((_ref = Luca.containers.CardView.prototype.afterRender) != null) {
2656
3473
  _ref.apply(this, arguments);
2657
3474
  }
2658
- this.registerEvent("click #" + this.cid + "-tabs-selector li a", "select");
3475
+ tabContainerId = this.tabContainer().attr("id");
3476
+ this.registerEvent("click #" + tabContainerId + " li a", "select");
2659
3477
  if (Luca.enableBootstrap && (this.tab_position === "left" || this.tab_position === "right")) {
2660
3478
  this.tabContainerWrapper().addClass("span2");
2661
3479
  return this.tabContentWrapper().addClass("span9");
@@ -2666,7 +3484,9 @@
2666
3484
  tabView = this;
2667
3485
  return this.each(function(component, index) {
2668
3486
  var icon, link, selector, _ref;
2669
- if (component.tabIcon) icon = "<i class='icon-" + component.tabIcon;
3487
+ if (component.tabIcon) {
3488
+ icon = "<i class='icon-" + component.tabIcon + "'></i>";
3489
+ }
2670
3490
  link = "<a href='#'>" + (icon || '') + " " + component.title + "</a>";
2671
3491
  selector = tabView.make("li", {
2672
3492
  "class": "tab-selector",
@@ -2810,9 +3630,8 @@
2810
3630
 
2811
3631
  }).call(this);
2812
3632
  (function() {
2813
- var startHistory;
2814
3633
 
2815
- startHistory = function() {
3634
+ Luca.util.startHistory = function() {
2816
3635
  return Backbone.history.start();
2817
3636
  };
2818
3637
 
@@ -2847,7 +3666,7 @@
2847
3666
  Luca.Application.instances[appName] = app;
2848
3667
  Luca.containers.Viewport.prototype.initialize.apply(this, arguments);
2849
3668
  this.state = new Luca.Model(this.defaultState);
2850
- this.setupMainController();
3669
+ if (this.useController === true) this.setupMainController();
2851
3670
  this.setupCollectionManager();
2852
3671
  this.defer(function() {
2853
3672
  return app.render();
@@ -2951,7 +3770,9 @@
2951
3770
  });
2952
3771
  }
2953
3772
  return (_ref2 = this.getMainController()) != null ? _ref2.each(function(component) {
2954
- if (component.ctype.match(/controller$/)) {
3773
+ var type;
3774
+ type = component.type || component.type;
3775
+ if (type.match(/controller$/)) {
2955
3776
  return component.bind("after:card:switch", function(previous, current) {
2956
3777
  _this.state.set({
2957
3778
  active_sub_section: current.name
@@ -2967,7 +3788,7 @@
2967
3788
  definedComponents = this.components || [];
2968
3789
  this.components = [
2969
3790
  {
2970
- ctype: 'controller',
3791
+ type: 'controller',
2971
3792
  name: "main_controller",
2972
3793
  components: definedComponents
2973
3794
  }
@@ -2976,25 +3797,27 @@
2976
3797
  }
2977
3798
  },
2978
3799
  setupCollectionManager: function() {
2979
- var collectionManagerOptions, _base, _ref, _ref2;
2980
- if (this.useCollectionManager === true) {
2981
- if (_.isString(this.collectionManagerClass)) {
2982
- this.collectionManagerClass = Luca.util.resolve(this.collectionManagerClass);
2983
- }
2984
- collectionManagerOptions = this.collectionManagerOptions;
2985
- if (_.isObject(this.collectionManager) && !_.isFunction((_ref = this.collectionManager) != null ? _ref.get : void 0)) {
2986
- collectionManagerOptions = this.collectionManager;
2987
- this.collectionManager = void 0;
2988
- }
2989
- if (_.isString(this.collectionManager)) {
2990
- collectionManagerOptions = {
2991
- name: this.collectionManager
2992
- };
2993
- }
2994
- this.collectionManager = typeof (_base = Luca.CollectionManager).get === "function" ? _base.get(collectionManagerOptions.name) : void 0;
2995
- if (!_.isFunction((_ref2 = this.collectionManager) != null ? _ref2.get : void 0)) {
2996
- return this.collectionManager = new this.collectionManagerClass(collectionManagerOptions);
2997
- }
3800
+ var collectionManagerOptions, _base, _ref, _ref2, _ref3;
3801
+ if (this.useCollectionManager !== true) return;
3802
+ if ((this.collectionManager != null) && (((_ref = this.collectionManager) != null ? _ref.get : void 0) != null)) {
3803
+ return;
3804
+ }
3805
+ if (_.isString(this.collectionManagerClass)) {
3806
+ this.collectionManagerClass = Luca.util.resolve(this.collectionManagerClass);
3807
+ }
3808
+ collectionManagerOptions = this.collectionManagerOptions || {};
3809
+ if (_.isObject(this.collectionManager) && !_.isFunction((_ref2 = this.collectionManager) != null ? _ref2.get : void 0)) {
3810
+ collectionManagerOptions = this.collectionManager;
3811
+ this.collectionManager = void 0;
3812
+ }
3813
+ if (_.isString(this.collectionManager)) {
3814
+ collectionManagerOptions = {
3815
+ name: this.collectionManager
3816
+ };
3817
+ }
3818
+ this.collectionManager = typeof (_base = Luca.CollectionManager).get === "function" ? _base.get(collectionManagerOptions.name) : void 0;
3819
+ if (!_.isFunction((_ref3 = this.collectionManager) != null ? _ref3.get : void 0)) {
3820
+ return this.collectionManager = new this.collectionManagerClass(collectionManagerOptions);
2998
3821
  }
2999
3822
  },
3000
3823
  setupRouter: function() {
@@ -3010,7 +3833,7 @@
3010
3833
  if (this.autoStartHistory === true) {
3011
3834
  this.autoStartHistory = "before:render";
3012
3835
  }
3013
- return this.defer(startHistory, false).until(this, this.autoStartHistory);
3836
+ return this.defer(Luca.util.startHistory, false).until(this, this.autoStartHistory);
3014
3837
  }
3015
3838
  },
3016
3839
  setupKeyHandler: function() {
@@ -3090,47 +3913,70 @@
3090
3913
 
3091
3914
  }).call(this);
3092
3915
  (function() {
3093
- var make, setupChangeObserver;
3916
+ var collectionView, make;
3917
+
3918
+ collectionView = Luca.define("Luca.components.CollectionView");
3094
3919
 
3095
- _.def("Luca.components.CollectionView")["extends"]("Luca.components.Panel")["with"]({
3096
- tagName: "div",
3920
+ collectionView["extends"]("Luca.components.Panel");
3921
+
3922
+ collectionView.behavesAs("LoadMaskable", "Filterable", "Paginatable");
3923
+
3924
+ collectionView.triggers("before:refresh", "after:refresh", "refresh", "empty:results");
3925
+
3926
+ collectionView.defaults({
3927
+ tagName: "ol",
3097
3928
  className: "luca-ui-collection-view",
3098
3929
  bodyClassName: "collection-ui-panel",
3099
3930
  itemTemplate: void 0,
3100
3931
  itemRenderer: void 0,
3101
3932
  itemTagName: 'li',
3102
3933
  itemClassName: 'collection-item',
3103
- hooks: ["empty:results"],
3104
3934
  initialize: function(options) {
3105
3935
  var _this = this;
3106
3936
  this.options = options != null ? options : {};
3107
3937
  _.extend(this, this.options);
3108
3938
  _.bindAll(this, "refresh");
3109
3939
  if (!((this.collection != null) || this.options.collection)) {
3940
+ console.log("Error on initialize of collection view", this);
3110
3941
  throw "Collection Views must specify a collection";
3111
3942
  }
3112
3943
  if (!((this.itemTemplate != null) || (this.itemRenderer != null) || (this.itemProperty != null))) {
3113
3944
  throw "Collection Views must specify an item template or item renderer function";
3114
3945
  }
3115
- Luca.components.Panel.prototype.initialize.apply(this, arguments);
3116
- if (_.isString(this.collection) && Luca.CollectionManager.get()) {
3117
- this.collection = Luca.CollectionManager.get().getOrCreate(this.collection);
3946
+ if (_.isString(this.collection)) {
3947
+ if (Luca.CollectionManager.get()) {
3948
+ this.collection = Luca.CollectionManager.get().getOrCreate(this.collection);
3949
+ } else {
3950
+ console.log("String Collection but no collection manager");
3951
+ }
3118
3952
  }
3119
- if (Luca.isBackboneCollection(this.collection)) {
3953
+ if (!Luca.isBackboneCollection(this.collection)) {
3954
+ console.log("Missing Collection on " + (this.name || this.cid), this, this.collection);
3955
+ throw "Collection Views must have a valid backbone collection";
3120
3956
  this.collection.on("before:fetch", function() {
3121
- if (_this.loadMask === true) return _this.trigger("enable:loadmask");
3957
+ return _this.trigger("enable:loadmask");
3122
3958
  });
3123
3959
  this.collection.bind("reset", function() {
3124
- if (_this.loadMask === true) _this.trigger("disable:loadmask");
3960
+ _this.refresh();
3961
+ return _this.trigger("disable:loadmask");
3962
+ });
3963
+ this.collection.bind("remove", function() {
3125
3964
  return _this.refresh();
3126
3965
  });
3127
- this.collection.bind("add", this.refresh);
3128
- this.collection.bind("remove", this.refresh);
3129
- if (this.observeChanges === true) setupChangeObserver.call(this);
3130
- } else {
3131
- throw "Collection Views must have a valid backbone collection";
3966
+ this.collection.bind("add", function() {
3967
+ return _this.refresh();
3968
+ });
3969
+ if (this.observeChanges === true) {
3970
+ this.collection.on("change", this.refreshModel, this);
3971
+ }
3972
+ }
3973
+ Luca.components.Panel.prototype.initialize.apply(this, arguments);
3974
+ if (this.autoRefreshOnModelsPresent !== false) {
3975
+ this.defer(function() {
3976
+ if (_this.collection.length > 0) return _this.refresh();
3977
+ }).until("after:render");
3132
3978
  }
3133
- if (this.collection.length > 0) return this.refresh();
3979
+ return this.on("refresh", this.refresh, this);
3134
3980
  },
3135
3981
  attributesForItem: function(item, model) {
3136
3982
  return _.extend({}, {
@@ -3143,29 +3989,67 @@
3143
3989
  var content, templateFn;
3144
3990
  if (item == null) item = {};
3145
3991
  if ((this.itemTemplate != null) && (templateFn = Luca.template(this.itemTemplate))) {
3146
- content = templateFn.call(this, item);
3992
+ return content = templateFn.call(this, item);
3147
3993
  }
3148
3994
  if ((this.itemRenderer != null) && _.isFunction(this.itemRenderer)) {
3149
- content = this.itemRenderer.call(this, item, item.model, item.index);
3995
+ return content = this.itemRenderer.call(this, item, item.model, item.index);
3150
3996
  }
3151
- if (this.itemProperty) {
3152
- content = item.model.get(this.itemProperty) || item.model[this.itemProperty];
3153
- if (_.isFunction(content)) content = content();
3997
+ if (this.itemProperty && (item.model != null)) {
3998
+ return content = item.model.read(this.itemProperty);
3154
3999
  }
3155
- return content;
4000
+ return "";
3156
4001
  },
3157
4002
  makeItem: function(model, index) {
3158
- var item;
4003
+ var attributes, content, item;
3159
4004
  item = this.prepareItem != null ? this.prepareItem.call(this, model, index) : {
3160
4005
  model: model,
3161
4006
  index: index
3162
4007
  };
3163
- return make(this.itemTagName, this.attributesForItem(item, model), this.contentForItem(item));
4008
+ attributes = this.attributesForItem(item, model);
4009
+ content = this.contentForItem(item);
4010
+ try {
4011
+ return make(this.itemTagName, attributes, content);
4012
+ } catch (e) {
4013
+ return console.log("Error generating DOM element for CollectionView", this, model, index);
4014
+ }
4015
+ },
4016
+ getCollection: function() {
4017
+ return this.collection;
4018
+ },
4019
+ applyQuery: function(query, queryOptions) {
4020
+ if (query == null) query = {};
4021
+ if (queryOptions == null) queryOptions = {};
4022
+ this.query = query;
4023
+ this.queryOptions = queryOptions;
4024
+ this.refresh();
4025
+ return this;
4026
+ },
4027
+ getQuery: function() {
4028
+ var query, querySource, _i, _len, _ref;
4029
+ query = this.query || (this.query = {});
4030
+ _ref = _(this.querySources || []).compact();
4031
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4032
+ querySource = _ref[_i];
4033
+ query = _.extend(query, querySource() || {});
4034
+ }
4035
+ return query;
4036
+ },
4037
+ getQueryOptions: function() {
4038
+ var optionSource, options, _i, _len, _ref;
4039
+ options = this.queryOptions || (this.queryOptions = {});
4040
+ _ref = _(this.optionsSources || []).compact();
4041
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4042
+ optionSource = _ref[_i];
4043
+ options = _.extend(options, optionSource() || {});
4044
+ }
4045
+ return options;
3164
4046
  },
3165
- getModels: function() {
4047
+ getModels: function(query, options) {
3166
4048
  var _ref;
3167
- if (((_ref = this.collection) != null ? _ref.query : void 0) && (this.filter || this.filterOptions)) {
3168
- return this.collection.query(this.filter, this.filterOptions);
4049
+ if ((_ref = this.collection) != null ? _ref.query : void 0) {
4050
+ query || (query = this.getQuery());
4051
+ options || (options = this.getQueryOptions());
4052
+ return this.collection.query(query, options);
3169
4053
  } else {
3170
4054
  return this.collection.models;
3171
4055
  }
@@ -3176,18 +4060,27 @@
3176
4060
  refreshModel: function(model) {
3177
4061
  var index;
3178
4062
  index = this.collection.indexOf(model);
3179
- return this.locateItemElement(model.get('id')).empty().append(this.contentForItem({
4063
+ this.locateItemElement(model.get('id')).empty().append(this.contentForItem({
3180
4064
  model: model,
3181
4065
  index: index
3182
4066
  }, model));
4067
+ return this.trigger("model:refreshed", index, model);
3183
4068
  },
3184
- refresh: function() {
3185
- var _this = this;
4069
+ refresh: function(query, options, models) {
4070
+ var index, model, _i, _len;
4071
+ query || (query = this.getQuery());
4072
+ options || (options = this.getQueryOptions());
4073
+ models || (models = this.getModels(query, options));
3186
4074
  this.$bodyEl().empty();
3187
- if (this.getModels().length === 0) this.trigger("empty:results");
3188
- return _(this.getModels()).each(function(model, index) {
3189
- return _this.$append(_this.makeItem(model, index));
3190
- });
4075
+ this.trigger("before:refresh", models, query, options);
4076
+ if (models.length === 0) this.trigger("empty:results");
4077
+ index = 0;
4078
+ for (_i = 0, _len = models.length; _i < _len; _i++) {
4079
+ model = models[_i];
4080
+ this.$append(this.makeItem(model, index++));
4081
+ }
4082
+ this.trigger("after:refresh", models, query, options);
4083
+ return this;
3191
4084
  },
3192
4085
  registerEvent: function(domEvent, selector, handler) {
3193
4086
  var eventTrigger;
@@ -3207,13 +4100,6 @@
3207
4100
 
3208
4101
  make = Luca.View.prototype.make;
3209
4102
 
3210
- setupChangeObserver = function() {
3211
- var _this = this;
3212
- return this.collection.on("change", function(model) {
3213
- return _this.refreshModel(model);
3214
- });
3215
- };
3216
-
3217
4103
  }).call(this);
3218
4104
  (function() {
3219
4105
 
@@ -3480,10 +4366,10 @@
3480
4366
  return this.label || (this.label = this.name);
3481
4367
  },
3482
4368
  setValue: function(checked) {
3483
- return this.input.attr('checked', checked);
4369
+ return this.getInputElement().attr('checked', checked);
3484
4370
  },
3485
4371
  getValue: function() {
3486
- return this.input.is(":checked");
4372
+ return this.getInputElement().is(":checked");
3487
4373
  }
3488
4374
  });
3489
4375
 
@@ -3492,10 +4378,6 @@
3492
4378
 
3493
4379
  _.def('Luca.fields.FileUploadField')["extends"]('Luca.core.Field')["with"]({
3494
4380
  template: 'fields/file_upload_field',
3495
- initialize: function(options) {
3496
- this.options = options != null ? options : {};
3497
- return Luca.core.Field.prototype.initialize.apply(this, arguments);
3498
- },
3499
4381
  afterInitialize: function() {
3500
4382
  this.input_id || (this.input_id = _.uniqueId('field'));
3501
4383
  this.input_name || (this.input_name = this.name);
@@ -3509,10 +4391,6 @@
3509
4391
 
3510
4392
  _.def('Luca.fields.HiddenField')["extends"]('Luca.core.Field')["with"]({
3511
4393
  template: 'fields/hidden_field',
3512
- initialize: function(options) {
3513
- this.options = options != null ? options : {};
3514
- return Luca.core.Field.prototype.initialize.apply(this, arguments);
3515
- },
3516
4394
  afterInitialize: function() {
3517
4395
  this.input_id || (this.input_id = _.uniqueId('field'));
3518
4396
  this.input_name || (this.input_name = this.name);
@@ -3526,16 +4404,13 @@
3526
4404
 
3527
4405
  _.def("Luca.components.LabelField")["extends"]("Luca.core.Field")["with"]({
3528
4406
  className: "luca-ui-field luca-ui-label-field",
3529
- getValue: function() {
3530
- return this.$('input').attr('value');
3531
- },
3532
4407
  formatter: function(value) {
3533
4408
  value || (value = this.getValue());
3534
4409
  return _.str.titleize(value);
3535
4410
  },
3536
4411
  setValue: function(value) {
3537
4412
  this.trigger("change", value, this.getValue());
3538
- this.$('input').attr('value', value);
4413
+ this.getInputElement().attr('value', value);
3539
4414
  return this.$('.value').html(this.formatter(value));
3540
4415
  }
3541
4416
  });
@@ -3590,9 +4465,11 @@
3590
4465
  return hash;
3591
4466
  });
3592
4467
  },
4468
+ getInputElement: function() {
4469
+ return this.input || (this.input = this.$('select').eq(0));
4470
+ },
3593
4471
  afterRender: function() {
3594
4472
  var _ref, _ref2;
3595
- this.input = $('select', this.el);
3596
4473
  if (((_ref = this.collection) != null ? (_ref2 = _ref.models) != null ? _ref2.length : void 0 : void 0) > 0) {
3597
4474
  return this.populateOptions();
3598
4475
  } else {
@@ -3610,9 +4487,9 @@
3610
4487
  return this.trigger("on:change", this, e);
3611
4488
  },
3612
4489
  resetOptions: function() {
3613
- this.input.html('');
4490
+ this.getInputElement().html('');
3614
4491
  if (this.includeBlank) {
3615
- return this.input.append("<option value='" + this.blankValue + "'>" + this.blankText + "</option>");
4492
+ return this.getInputElement().append("<option value='" + this.blankValue + "'>" + this.blankText + "</option>");
3616
4493
  }
3617
4494
  },
3618
4495
  populateOptions: function() {
@@ -3626,7 +4503,7 @@
3626
4503
  display = model.get(_this.displayField);
3627
4504
  if (_this.selected && value === _this.selected) selected = "selected";
3628
4505
  option = "<option " + selected + " value='" + value + "'>" + display + "</option>";
3629
- return _this.input.append(option);
4506
+ return _this.getInputElement().append(option);
3630
4507
  });
3631
4508
  }
3632
4509
  this.trigger("after:populate:options", this);
@@ -3654,6 +4531,7 @@
3654
4531
  this.input_name || (this.input_name = this.name);
3655
4532
  this.label || (this.label = this.name);
3656
4533
  this.input_class || (this.input_class = this["class"]);
4534
+ this.input_value || (this.input_value = "");
3657
4535
  return this.inputStyles || (this.inputStyles = "height:" + this.height + ";width:" + this.width);
3658
4536
  },
3659
4537
  setValue: function(value) {
@@ -3699,6 +4577,7 @@
3699
4577
  this.input_name || (this.input_name = this.name);
3700
4578
  this.label || (this.label = this.name);
3701
4579
  this.input_class || (this.input_class = this["class"]);
4580
+ this.input_value || (this.input_value = this.value || "");
3702
4581
  if (this.prepend) {
3703
4582
  this.$el.addClass('input-prepend');
3704
4583
  this.addOn = this.prepend;
@@ -3729,19 +4608,18 @@
3729
4608
  _.def('Luca.fields.TypeAheadField')["extends"]('Luca.fields.TextField')["with"]({
3730
4609
  className: 'luca-ui-field',
3731
4610
  getSource: function() {
3732
- if (_.isFunction(this.source)) return this.source.call(this);
3733
- return this.source || [];
4611
+ return Luca.util.read(this.source) || [];
3734
4612
  },
3735
4613
  matcher: function(item) {
3736
4614
  return true;
3737
4615
  },
3738
4616
  beforeRender: function() {
3739
- this._super("beforeRender", this, arguments);
3740
- return this.$('input').attr('data-provide', 'typeahead');
4617
+ Luca.fields.TextField.prototype.beforeRender.apply(this, arguments);
4618
+ return this.getInputElement().attr('data-provide', 'typeahead');
3741
4619
  },
3742
4620
  afterRender: function() {
3743
- this._super("afterRender", this, arguments);
3744
- return this.$('input').typeahead({
4621
+ Luca.fields.TextField.prototype.afterRender.apply(this, arguments);
4622
+ return this.getInputElement().typeahead({
3745
4623
  matcher: this.matcher,
3746
4624
  source: this.getSource()
3747
4625
  });
@@ -3780,27 +4658,6 @@
3780
4658
 
3781
4659
  }).call(this);
3782
4660
  (function() {
3783
- var defaultToolbar;
3784
-
3785
- defaultToolbar = {
3786
- buttons: [
3787
- {
3788
- icon: "remove-sign",
3789
- label: "Reset",
3790
- eventId: "click:reset",
3791
- className: "reset-button",
3792
- align: 'right'
3793
- }, {
3794
- icon: "ok-sign",
3795
- white: true,
3796
- label: "Save Changes",
3797
- eventId: "click:submit",
3798
- color: "success",
3799
- className: 'submit-button',
3800
- align: 'right'
3801
- }
3802
- ]
3803
- };
3804
4661
 
3805
4662
  _.def("Luca.components.FormView")["extends"]('Luca.core.Container')["with"]({
3806
4663
  tagName: 'form',
@@ -3818,6 +4675,7 @@
3818
4675
  this.options = options != null ? options : {};
3819
4676
  if (this.loadMask == null) this.loadMask = Luca.enableBootstrap;
3820
4677
  Luca.core.Container.prototype.initialize.apply(this, arguments);
4678
+ this.components || (this.components = this.fields);
3821
4679
  _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars", "applyLoadMask");
3822
4680
  this.state || (this.state = new Backbone.Model);
3823
4681
  this.setupHooks(this.hooks);
@@ -3832,7 +4690,7 @@
3832
4690
  }
3833
4691
  },
3834
4692
  getDefaultToolbar: function() {
3835
- return defaultToolbar;
4693
+ return Luca.components.FormView.defaultFormViewToolbar;
3836
4694
  },
3837
4695
  applyStyleClasses: function() {
3838
4696
  if (Luca.enableBootstrap) this.applyBootstrapStyleClasses();
@@ -4046,6 +4904,26 @@
4046
4904
  }
4047
4905
  });
4048
4906
 
4907
+ Luca.components.FormView.defaultFormViewToolbar = {
4908
+ buttons: [
4909
+ {
4910
+ icon: "remove-sign",
4911
+ label: "Reset",
4912
+ eventId: "click:reset",
4913
+ className: "reset-button",
4914
+ align: 'right'
4915
+ }, {
4916
+ icon: "ok-sign",
4917
+ white: true,
4918
+ label: "Save Changes",
4919
+ eventId: "click:submit",
4920
+ color: "success",
4921
+ className: 'submit-button',
4922
+ align: 'right'
4923
+ }
4924
+ ]
4925
+ };
4926
+
4049
4927
  }).call(this);
4050
4928
  (function() {
4051
4929
 
@@ -4296,6 +5174,115 @@
4296
5174
  bodyTemplate: "components/load_mask"
4297
5175
  });
4298
5176
 
5177
+ }).call(this);
5178
+ (function() {
5179
+ var multiView, propagateCollectionComponents, validateComponent;
5180
+
5181
+ multiView = Luca.define("Luca.components.MultiCollectionView");
5182
+
5183
+ multiView["extends"]("Luca.containers.CardView");
5184
+
5185
+ multiView.behavesAs("LoadMaskable", "Filterable", "Paginatable");
5186
+
5187
+ multiView.triggers("before:refresh", "after:refresh", "refresh", "empty:results");
5188
+
5189
+ multiView.defaultsTo({
5190
+ version: 1,
5191
+ stateful: true,
5192
+ defaultState: {
5193
+ activeView: 0
5194
+ },
5195
+ viewContainerClass: "luca-ui-multi-view-container",
5196
+ initialize: function(options) {
5197
+ var view, _i, _len, _ref;
5198
+ this.options = options != null ? options : {};
5199
+ this.components || (this.components = this.views);
5200
+ _ref = this.components;
5201
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5202
+ view = _ref[_i];
5203
+ validateComponent(view);
5204
+ }
5205
+ this.on("refresh", this.refresh, this);
5206
+ this.on("after:card:switch", this.refresh, this);
5207
+ this.on("after:components", propagateCollectionComponents, this);
5208
+ this.debug("multi collection , proto initialize");
5209
+ return Luca.containers.CardView.prototype.initialize.apply(this, arguments);
5210
+ },
5211
+ relayAfterRefresh: function(models, query, options) {
5212
+ return this.trigger("after:refresh", models, query, options);
5213
+ },
5214
+ refresh: function() {
5215
+ var _ref;
5216
+ return (_ref = this.activeComponent()) != null ? _ref.trigger("refresh") : void 0;
5217
+ },
5218
+ getCollection: function() {
5219
+ return this.collection;
5220
+ },
5221
+ applyQuery: function(query, queryOptions) {
5222
+ if (query == null) query = {};
5223
+ if (queryOptions == null) queryOptions = {};
5224
+ this.query = query;
5225
+ this.queryOptions = queryOptions;
5226
+ return this;
5227
+ },
5228
+ getQuery: function() {
5229
+ var query, querySource, _i, _len, _ref;
5230
+ this.debug("Get Query");
5231
+ query = this.query || (this.query = {});
5232
+ _ref = this.querySources;
5233
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5234
+ querySource = _ref[_i];
5235
+ query = _.extend(query, querySource() || {});
5236
+ }
5237
+ return query;
5238
+ },
5239
+ getQueryOptions: function() {
5240
+ var optionSource, options, _i, _len, _ref;
5241
+ this.debug("Get Query Options");
5242
+ options = this.queryOptions || (this.queryOptions = {});
5243
+ _ref = this.optionsSources;
5244
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5245
+ optionSource = _ref[_i];
5246
+ options = _.extend(options, optionSource() || {});
5247
+ }
5248
+ return options;
5249
+ }
5250
+ });
5251
+
5252
+ propagateCollectionComponents = function() {
5253
+ var component, container, _i, _len, _ref, _results,
5254
+ _this = this;
5255
+ container = this;
5256
+ _ref = this.components;
5257
+ _results = [];
5258
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5259
+ component = _ref[_i];
5260
+ component.on("after:refresh", function(models, query, options) {
5261
+ _this.debug("collection member after refresh");
5262
+ return _this.trigger("after:refresh", models, query, options);
5263
+ });
5264
+ _results.push(_.extend(component, {
5265
+ collection: container.getCollection(),
5266
+ getQuery: function() {
5267
+ return container.getQuery.call(container);
5268
+ },
5269
+ getQueryOptions: function() {
5270
+ return container.getQueryOptions.call(container);
5271
+ }
5272
+ }));
5273
+ }
5274
+ return _results;
5275
+ };
5276
+
5277
+ validateComponent = function(component) {
5278
+ var type;
5279
+ type = component.type || component.ctype;
5280
+ if (type === "collection" || type === "collection_view" || type === "table" || type === "table_view") {
5281
+ return;
5282
+ }
5283
+ throw "The MultiCollectionView expects to contain multiple collection views";
5284
+ };
5285
+
4299
5286
  }).call(this);
4300
5287
  (function() {
4301
5288
 
@@ -4330,6 +5317,129 @@
4330
5317
  version: 2
4331
5318
  });
4332
5319
 
5320
+ }).call(this);
5321
+ (function() {
5322
+ var paginationControl;
5323
+
5324
+ paginationControl = Luca.register("Luca.components.PaginationControl");
5325
+
5326
+ paginationControl["extends"]("Luca.View");
5327
+
5328
+ paginationControl.defines({
5329
+ template: "components/pagination",
5330
+ stateful: true,
5331
+ autoBindEventHandlers: true,
5332
+ events: {
5333
+ "click a[data-page-number]": "selectPage",
5334
+ "click a.next": "nextPage",
5335
+ "click a.prev": "previousPage"
5336
+ },
5337
+ afterInitialize: function() {
5338
+ var _this = this;
5339
+ _.bindAll(this, "updateWithPageCount");
5340
+ return this.state.on("change", function(state, numberOfPages) {
5341
+ return _this.updateWithPageCount(state.get('numberOfPages'));
5342
+ });
5343
+ },
5344
+ limit: function() {
5345
+ var _ref;
5346
+ return parseInt(this.state.get('limit') || ((_ref = this.collection) != null ? _ref.length : void 0));
5347
+ },
5348
+ page: function() {
5349
+ return parseInt(this.state.get('page') || 1);
5350
+ },
5351
+ nextPage: function() {
5352
+ if (!this.nextEnabled()) return;
5353
+ return this.state.set('page', this.page() + 1);
5354
+ },
5355
+ previousPage: function() {
5356
+ if (!this.previousEnabled()) return;
5357
+ return this.state.set('page', this.page() - 1);
5358
+ },
5359
+ selectPage: function(e) {
5360
+ var me, my;
5361
+ me = my = this.$(e.target);
5362
+ if (!me.is('a.page')) me = my = my.closest('a.page');
5363
+ my.siblings().removeClass('is-selected');
5364
+ me.addClass('is-selected');
5365
+ return this.setPage(my.data('page-number'));
5366
+ },
5367
+ setPage: function(page, options) {
5368
+ if (page == null) page = 1;
5369
+ if (options == null) options = {};
5370
+ return this.state.set('page', page, options);
5371
+ },
5372
+ setLimit: function(limit, options) {
5373
+ if (limit == null) limit = 1;
5374
+ if (options == null) options = {};
5375
+ return this.state.set('limit', limit, options);
5376
+ },
5377
+ pageButtonContainer: function() {
5378
+ return this.$('.group');
5379
+ },
5380
+ previousEnabled: function() {
5381
+ return this.page() > 1;
5382
+ },
5383
+ nextEnabled: function() {
5384
+ return this.page() < this.totalPages();
5385
+ },
5386
+ previousButton: function() {
5387
+ return this.$('a.page.prev');
5388
+ },
5389
+ nextButton: function() {
5390
+ return this.$('a.page.next');
5391
+ },
5392
+ pageButtons: function() {
5393
+ return this.$('a[data-page-number]', this.pageButtonContainer());
5394
+ },
5395
+ updateWithPageCount: function(pageCount, models) {
5396
+ var modelCount,
5397
+ _this = this;
5398
+ this.pageCount = pageCount;
5399
+ if (models == null) models = [];
5400
+ modelCount = models.length;
5401
+ console.log("Update With Page Count", this.pageCount, modelCount);
5402
+ this.pageButtonContainer().empty();
5403
+ _(this.pageCount).times(function(index) {
5404
+ var button, page;
5405
+ page = index + 1;
5406
+ button = _this.make("a", {
5407
+ "data-page-number": page,
5408
+ "class": "page"
5409
+ }, page);
5410
+ return _this.pageButtonContainer().append(button);
5411
+ });
5412
+ this.toggleNavigationButtons();
5413
+ this.selectActivePageButton();
5414
+ return this;
5415
+ },
5416
+ toggleNavigationButtons: function() {
5417
+ this.$('a.next, a.prev').addClass('disabled');
5418
+ if (this.nextEnabled()) this.nextButton().removeClass('disabled');
5419
+ if (this.previousEnabled()) {
5420
+ return this.previousButton().removeClass('disabled');
5421
+ }
5422
+ },
5423
+ selectActivePageButton: function() {
5424
+ return this.activePageButton().addClass('is-selected');
5425
+ },
5426
+ activePageButton: function() {
5427
+ return this.pageButtons().filter("[data-page-number='" + (this.page()) + "']");
5428
+ },
5429
+ totalPages: function() {
5430
+ return this.pageCount;
5431
+ },
5432
+ totalItems: function() {
5433
+ var _ref;
5434
+ return parseInt(((_ref = this.collection) != null ? _ref.length : void 0) || 0);
5435
+ },
5436
+ itemsPerPage: function(value, options) {
5437
+ if (options == null) options = {};
5438
+ if (value != null) this.state.set("limit", value, options);
5439
+ return parseInt(this.state.get("limit"));
5440
+ }
5441
+ });
5442
+
4333
5443
  }).call(this);
4334
5444
  (function() {
4335
5445
 
@@ -4591,17 +5701,32 @@
4591
5701
  itemRenderer: function(item, model) {
4592
5702
  return Luca.components.TableView.rowRenderer.call(this, item, model);
4593
5703
  },
4594
- emptyResults: function() {
4595
- return this.$('tbody').append("<tr><td colspan=" + this.columns.length + ">" + this.emptyText + "</td></tr>");
4596
- },
4597
5704
  initialize: function(options) {
4598
- var _this = this;
5705
+ var column,
5706
+ _this = this;
4599
5707
  this.options = options != null ? options : {};
4600
5708
  Luca.components.CollectionView.prototype.initialize.apply(this, arguments);
5709
+ this.columns = (function() {
5710
+ var _i, _len, _ref, _results;
5711
+ _ref = this.columns;
5712
+ _results = [];
5713
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5714
+ column = _ref[_i];
5715
+ if (_.isString(column)) {
5716
+ column = {
5717
+ reader: column
5718
+ };
5719
+ }
5720
+ if (!(column.header != null)) {
5721
+ column.header = _.str.titleize(_.str.humanize(column.reader));
5722
+ }
5723
+ _results.push(column);
5724
+ }
5725
+ return _results;
5726
+ }).call(this);
4601
5727
  return this.defer(function() {
4602
- Luca.components.TableView.renderHeader.call(_this, _this.columns, _this.$('thead'));
4603
- return _this.$el.removeClass('row-fluid');
4604
- }).until("before:render");
5728
+ return Luca.components.TableView.renderHeader.call(_this, _this.columns, _this.$('thead'));
5729
+ }).until("after:render");
4605
5730
  }
4606
5731
  });
4607
5732
 
@@ -4615,29 +5740,30 @@
4615
5740
  _results = [];
4616
5741
  for (_i = 0, _len = columns.length; _i < _len; _i++) {
4617
5742
  column = columns[_i];
4618
- _results.push("<th data-col-index='" + index + "'>" + column.header + "</th>");
5743
+ _results.push("<th data-col-index='" + (index++) + "'>" + column.header + "</th>");
4619
5744
  }
4620
5745
  return _results;
4621
5746
  })();
4622
- $(targetElement).append(make("tr", {}, content));
5747
+ this.$(targetElement).append("<tr>" + (content.join('')) + "</tr>");
4623
5748
  index = 0;
4624
5749
  _results = [];
4625
5750
  for (_i = 0, _len = columns.length; _i < _len; _i++) {
4626
5751
  column = columns[_i];
4627
5752
  if (column.width != null) {
4628
- _results.push(this.$("th[data-col-index='" + index + "']", targetElement).css('width', column.width));
5753
+ _results.push(this.$("th[data-col-index='" + (index++) + "']", targetElement).css('width', column.width));
4629
5754
  }
4630
5755
  }
4631
5756
  return _results;
4632
5757
  };
4633
5758
 
4634
5759
  Luca.components.TableView.rowRenderer = function(item, model, index) {
4635
- var columnConfig, _i, _len, _ref, _results;
5760
+ var colIndex, columnConfig, _i, _len, _ref, _results;
5761
+ colIndex = 0;
4636
5762
  _ref = this.columns;
4637
5763
  _results = [];
4638
5764
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4639
5765
  columnConfig = _ref[_i];
4640
- _results.push(Luca.components.TableView.renderColumn.call(this, columnConfig, item, model, index));
5766
+ _results.push(Luca.components.TableView.renderColumn.call(this, columnConfig, item, model, colIndex++));
4641
5767
  }
4642
5768
  return _results;
4643
5769
  };
@@ -4645,7 +5771,12 @@
4645
5771
  Luca.components.TableView.renderColumn = function(column, item, model, index) {
4646
5772
  var cellValue;
4647
5773
  cellValue = model.read(column.reader);
4648
- return make("td", {}, cellValue);
5774
+ if (_.isFunction(column.renderer)) {
5775
+ cellValue = column.renderer.call(this, cellValue, model, column);
5776
+ }
5777
+ return make("td", {
5778
+ "data-col-index": index
5779
+ }, cellValue);
4649
5780
  };
4650
5781
 
4651
5782
  }).call(this);