luca 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +17 -0
  3. data/Gemfile.lock +77 -0
  4. data/Guardfile +22 -0
  5. data/README.md +291 -0
  6. data/Rakefile +28 -0
  7. data/app.rb +46 -0
  8. data/assets/images/glyphicons-halflings-white.png +0 -0
  9. data/assets/images/glyphicons-halflings.png +0 -0
  10. data/assets/javascripts/dependencies/backbone-min.js +37 -0
  11. data/assets/javascripts/dependencies/backbone-query.min.js +1 -0
  12. data/assets/javascripts/dependencies/bootstrap.min.js +1 -0
  13. data/assets/javascripts/dependencies/jasmine-html.js +190 -0
  14. data/assets/javascripts/dependencies/jasmine.js +2476 -0
  15. data/assets/javascripts/dependencies/jquery.js +4 -0
  16. data/assets/javascripts/dependencies/modal.js +698 -0
  17. data/assets/javascripts/dependencies/modernizr.min.js +30 -0
  18. data/assets/javascripts/dependencies/prettify.js +28 -0
  19. data/assets/javascripts/dependencies/sinon.js +3469 -0
  20. data/assets/javascripts/dependencies/spin-min.js +2 -0
  21. data/assets/javascripts/dependencies/underscore-min.js +31 -0
  22. data/assets/javascripts/dependencies/underscore-string.min.js +14 -0
  23. data/assets/javascripts/dependencies.coffee +7 -0
  24. data/assets/javascripts/luca-ui-base.coffee +12 -0
  25. data/assets/javascripts/luca-ui-spec.coffee +2 -0
  26. data/assets/javascripts/luca-ui.coffee +3 -0
  27. data/assets/javascripts/sandbox/collections/sample.coffee +0 -0
  28. data/assets/javascripts/sandbox/config.coffee +7 -0
  29. data/assets/javascripts/sandbox/sandbox.coffee +16 -0
  30. data/assets/javascripts/sandbox/templates/features/collection_helpers.luca +33 -0
  31. data/assets/javascripts/sandbox/templates/features/form_demo_code.luca +48 -0
  32. data/assets/javascripts/sandbox/templates/features/grid_demo_code.luca +24 -0
  33. data/assets/javascripts/sandbox/templates/features/introduction.luca +11 -0
  34. data/assets/javascripts/sandbox/templates/features/view_helpers.luca +43 -0
  35. data/assets/javascripts/sandbox/templates/navigation.luca +8 -0
  36. data/assets/javascripts/sandbox/views/form_demo.coffee +47 -0
  37. data/assets/javascripts/sandbox/views/grid_demo.coffee +23 -0
  38. data/assets/javascripts/sandbox/views/pages/collection_events_sample.coffee +1 -0
  39. data/assets/javascripts/sandbox/views/pages/pages_controller.coffee +28 -0
  40. data/assets/javascripts/sandbox.coffee +4 -0
  41. data/assets/javascripts/spec-dependencies.coffee +4 -0
  42. data/assets/stylesheets/bootstrap-responsive.min.css +3 -0
  43. data/assets/stylesheets/bootstrap.min.css +610 -0
  44. data/assets/stylesheets/jasmine.css +166 -0
  45. data/assets/stylesheets/luca-ui-bootstrap.css +5 -0
  46. data/assets/stylesheets/luca-ui-spec.css +3 -0
  47. data/assets/stylesheets/luca-ui.css +3 -0
  48. data/assets/stylesheets/prettify.css +40 -0
  49. data/assets/stylesheets/sandbox/sandbox.scss +4 -0
  50. data/assets/stylesheets/sandbox.css +3 -0
  51. data/config.ru +11 -0
  52. data/lib/luca/command_line.rb +69 -0
  53. data/lib/luca/rails/engine.rb +12 -0
  54. data/lib/luca/rails/version.rb +6 -0
  55. data/lib/luca/rails.rb +9 -0
  56. data/lib/luca/template.rb +51 -0
  57. data/lib/luca/test_harness.rb +106 -0
  58. data/lib/luca.rb +1 -0
  59. data/lib/sprockets/luca_template.rb +49 -0
  60. data/lib/templates/spec_manifest_javascripts.erb +7 -0
  61. data/lib/templates/spec_manifest_stylesheets.erb +11 -0
  62. data/luca.gemspec +26 -0
  63. data/public/jasmine/index.html +26 -0
  64. data/public/sandbox/api.js +1 -0
  65. data/spec/components/application_spec.coffee +0 -0
  66. data/spec/components/collection_loader_view_spec.coffee +0 -0
  67. data/spec/components/controller_spec.coffee +0 -0
  68. data/spec/components/form_view_spec.coffee +13 -0
  69. data/spec/components/grid_view_spec.coffee +0 -0
  70. data/spec/components/record_manager_spec.coffee +0 -0
  71. data/spec/components/template_spec.coffee +0 -0
  72. data/spec/containers/card_view_spec.coffee +1 -0
  73. data/spec/containers/column_view_spec.coffee +0 -0
  74. data/spec/containers/modal_view_spec.coffee +0 -0
  75. data/spec/containers/panel_view_spec.coffee +0 -0
  76. data/spec/containers/split_view_spec.coffee +0 -0
  77. data/spec/containers/tab_view_spec.coffee +0 -0
  78. data/spec/containers/viewport_spec.coffee +0 -0
  79. data/spec/core/collection_spec.coffee +215 -0
  80. data/spec/core/container_spec.coffee +0 -0
  81. data/spec/core/field_spec.coffee +0 -0
  82. data/spec/core/observer_spec.coffee +0 -0
  83. data/spec/core/view_spec.coffee +87 -0
  84. data/spec/framework_spec.coffee +48 -0
  85. data/spec/helper.coffee +120 -0
  86. data/spec/managers/collection_manager_spec.coffee +95 -0
  87. data/spec/managers/socket_manager_spec.coffee +0 -0
  88. data/src/components/application.coffee +83 -0
  89. data/src/components/base_toolbar.coffee +16 -0
  90. data/src/components/collection_loader_view.coffee +37 -0
  91. data/src/components/controller.coffee +41 -0
  92. data/src/components/fields/button_field.coffee +40 -0
  93. data/src/components/fields/checkbox_field.coffee +41 -0
  94. data/src/components/fields/file_upload_field.coffee +15 -0
  95. data/src/components/fields/hidden_field.coffee +18 -0
  96. data/src/components/fields/select_field.coffee +100 -0
  97. data/src/components/fields/text_area_field.coffee +43 -0
  98. data/src/components/fields/text_field.coffee +42 -0
  99. data/src/components/fields/type_ahead_field.coffee +10 -0
  100. data/src/components/form_button_toolbar.coffee +26 -0
  101. data/src/components/form_view.coffee +205 -0
  102. data/src/components/grid_view.coffee +208 -0
  103. data/src/components/record_manager.coffee +215 -0
  104. data/src/components/router.coffee +34 -0
  105. data/src/components/template.coffee +19 -0
  106. data/src/containers/card_view.coffee +89 -0
  107. data/src/containers/column_view.coffee +48 -0
  108. data/src/containers/modal_view.coffee +85 -0
  109. data/src/containers/panel_view.coffee +24 -0
  110. data/src/containers/split_view.coffee +12 -0
  111. data/src/containers/tab_view.coffee +77 -0
  112. data/src/containers/viewport.coffee +16 -0
  113. data/src/core/collection.coffee +319 -0
  114. data/src/core/container.coffee +256 -0
  115. data/src/core/field.coffee +68 -0
  116. data/src/core/observer.coffee +17 -0
  117. data/src/core/view.coffee +190 -0
  118. data/src/framework.coffee +110 -0
  119. data/src/index.coffee +255 -0
  120. data/src/managers/collection_manager.coffee +168 -0
  121. data/src/managers/socket_manager.coffee +54 -0
  122. data/src/modules/deferrable.coffee +18 -0
  123. data/src/modules/local_storage.coffee +50 -0
  124. data/src/stylesheets/base.scss +78 -0
  125. data/src/stylesheets/components/form_view.scss +54 -0
  126. data/src/stylesheets/components/grid_view.scss +111 -0
  127. data/src/stylesheets/components/toolbar.scss +15 -0
  128. data/src/stylesheets/containers/container.scss +7 -0
  129. data/src/stylesheets/containers/modal_view.scss +0 -0
  130. data/src/stylesheets/containers/tab_view.scss +33 -0
  131. data/src/stylesheets/normalize.scss +430 -0
  132. data/src/templates/components/bootstrap_form_controls.luca +7 -0
  133. data/src/templates/components/collection_loader_view.luca +5 -0
  134. data/src/templates/components/form_view.luca +15 -0
  135. data/src/templates/components/grid_view.luca +9 -0
  136. data/src/templates/components/grid_view_empty_text.luca +3 -0
  137. data/src/templates/containers/basic.luca +1 -0
  138. data/src/templates/containers/tab_selector_container.luca +8 -0
  139. data/src/templates/containers/tab_view.luca +1 -0
  140. data/src/templates/containers/toolbar_wrapper.luca +1 -0
  141. data/src/templates/fields/button_field.luca +2 -0
  142. data/src/templates/fields/button_field_link.luca +5 -0
  143. data/src/templates/fields/checkbox_field.luca +9 -0
  144. data/src/templates/fields/file_upload_field.luca +8 -0
  145. data/src/templates/fields/hidden_field.luca +1 -0
  146. data/src/templates/fields/select_field.luca +7 -0
  147. data/src/templates/fields/text_area_field.luca +8 -0
  148. data/src/templates/fields/text_field.luca +13 -0
  149. data/src/templates/sample/contents.luca +1 -0
  150. data/src/templates/sample/welcome.luca +1 -0
  151. data/vendor/assets/images/glyphicons-halflings-white.png +0 -0
  152. data/vendor/assets/images/glyphicons-halflings.png +0 -0
  153. data/vendor/assets/javascripts/luca-spec-dependencies.js +6135 -0
  154. data/vendor/assets/javascripts/luca-ui-base.js +1527 -0
  155. data/vendor/assets/javascripts/luca-ui-spec.js +3654 -0
  156. data/vendor/assets/javascripts/luca-ui.js +2763 -0
  157. data/vendor/assets/luca-ui/base.css +85 -0
  158. data/vendor/assets/luca-ui/components/application.js +91 -0
  159. data/vendor/assets/luca-ui/components/base_toolbar.js +23 -0
  160. data/vendor/assets/luca-ui/components/controller.js +38 -0
  161. data/vendor/assets/luca-ui/components/fields/button_field.js +45 -0
  162. data/vendor/assets/luca-ui/components/fields/checkbox_field.js +43 -0
  163. data/vendor/assets/luca-ui/components/fields/file_upload_field.js +20 -0
  164. data/vendor/assets/luca-ui/components/fields/hidden_field.js +20 -0
  165. data/vendor/assets/luca-ui/components/fields/select_field.js +97 -0
  166. data/vendor/assets/luca-ui/components/fields/text_area_field.js +48 -0
  167. data/vendor/assets/luca-ui/components/fields/text_field.js +46 -0
  168. data/vendor/assets/luca-ui/components/fields/type_ahead_field.js +13 -0
  169. data/vendor/assets/luca-ui/components/form_button_toolbar.js +32 -0
  170. data/vendor/assets/luca-ui/components/form_view.css +32 -0
  171. data/vendor/assets/luca-ui/components/form_view.js +207 -0
  172. data/vendor/assets/luca-ui/components/grid_view.css +76 -0
  173. data/vendor/assets/luca-ui/components/grid_view.js +202 -0
  174. data/vendor/assets/luca-ui/components/record_manager.js +207 -0
  175. data/vendor/assets/luca-ui/components/router.js +36 -0
  176. data/vendor/assets/luca-ui/components/template.js +26 -0
  177. data/vendor/assets/luca-ui/components/toolbar.css +11 -0
  178. data/vendor/assets/luca-ui/containers/card_view.js +98 -0
  179. data/vendor/assets/luca-ui/containers/column_view.js +52 -0
  180. data/vendor/assets/luca-ui/containers/container.css +3 -0
  181. data/vendor/assets/luca-ui/containers/modal_view.css +0 -0
  182. data/vendor/assets/luca-ui/containers/modal_view.js +87 -0
  183. data/vendor/assets/luca-ui/containers/panel_view.js +34 -0
  184. data/vendor/assets/luca-ui/containers/split_view.js +13 -0
  185. data/vendor/assets/luca-ui/containers/tab_view.css +16 -0
  186. data/vendor/assets/luca-ui/containers/tab_view.js +80 -0
  187. data/vendor/assets/luca-ui/containers/viewport.js +18 -0
  188. data/vendor/assets/luca-ui/core/collection.js +221 -0
  189. data/vendor/assets/luca-ui/core/container.js +205 -0
  190. data/vendor/assets/luca-ui/core/field.js +59 -0
  191. data/vendor/assets/luca-ui/core/observer.js +42 -0
  192. data/vendor/assets/luca-ui/core/view.js +127 -0
  193. data/vendor/assets/luca-ui/framework.js +110 -0
  194. data/vendor/assets/luca-ui/index.js +5 -0
  195. data/vendor/assets/luca-ui/managers/collection_manager.js +98 -0
  196. data/vendor/assets/luca-ui/managers/socket_manager.js +52 -0
  197. data/vendor/assets/luca-ui/modules/deferrable.js +21 -0
  198. data/vendor/assets/luca-ui/modules/local_storage.js +81 -0
  199. data/vendor/assets/luca-ui/normalize.css +359 -0
  200. data/vendor/assets/luca-ui/stylesheets/base.css +85 -0
  201. data/vendor/assets/luca-ui/stylesheets/components/form_view.css +32 -0
  202. data/vendor/assets/luca-ui/stylesheets/components/grid_view.css +76 -0
  203. data/vendor/assets/luca-ui/stylesheets/components/toolbar.css +11 -0
  204. data/vendor/assets/luca-ui/stylesheets/containers/container.css +3 -0
  205. data/vendor/assets/luca-ui/stylesheets/containers/modal_view.css +0 -0
  206. data/vendor/assets/luca-ui/stylesheets/containers/tab_view.css +16 -0
  207. data/vendor/assets/luca-ui/stylesheets/normalize.css +359 -0
  208. data/vendor/assets/luca-ui/templates/components/bootstrap_form_controls.js +4 -0
  209. data/vendor/assets/luca-ui/templates/components/form_view.js +4 -0
  210. data/vendor/assets/luca-ui/templates/components/grid_view.js +4 -0
  211. data/vendor/assets/luca-ui/templates/components/grid_view_empty_text.js +4 -0
  212. data/vendor/assets/luca-ui/templates/containers/basic.js +4 -0
  213. data/vendor/assets/luca-ui/templates/containers/tab_selector_container.js +4 -0
  214. data/vendor/assets/luca-ui/templates/containers/tab_view.js +4 -0
  215. data/vendor/assets/luca-ui/templates/containers/toolbar_wrapper.js +4 -0
  216. data/vendor/assets/luca-ui/templates/fields/button_field.js +4 -0
  217. data/vendor/assets/luca-ui/templates/fields/button_field_link.js +4 -0
  218. data/vendor/assets/luca-ui/templates/fields/checkbox_field.js +4 -0
  219. data/vendor/assets/luca-ui/templates/fields/file_upload_field.js +4 -0
  220. data/vendor/assets/luca-ui/templates/fields/hidden_field.js +4 -0
  221. data/vendor/assets/luca-ui/templates/fields/select_field.js +4 -0
  222. data/vendor/assets/luca-ui/templates/fields/text_area_field.js +4 -0
  223. data/vendor/assets/luca-ui/templates/fields/text_field.js +4 -0
  224. data/vendor/assets/luca-ui/templates/sample/contents.js +4 -0
  225. data/vendor/assets/luca-ui/templates/sample/welcome.js +4 -0
  226. data/vendor/assets/stylesheets/luca-spec-dependencies.css +166 -0
  227. data/vendor/assets/stylesheets/luca-ui-bootstrap.css +1201 -0
  228. data/vendor/assets/stylesheets/luca-ui-spec.css +586 -0
  229. data/vendor/assets/stylesheets/luca-ui.css +586 -0
  230. data/views/index.erb +20 -0
  231. data/views/jasmine.erb +22 -0
  232. data/views/spec_harness.erb +29 -0
  233. metadata +361 -0
@@ -0,0 +1,3654 @@
1
+ (function() {
2
+
3
+ _.mixin(_.string);
4
+
5
+ window.Luca = {
6
+ VERSION: "0.6.6",
7
+ core: {},
8
+ containers: {},
9
+ components: {},
10
+ modules: {},
11
+ fields: {},
12
+ util: {},
13
+ registry: {
14
+ classes: {},
15
+ namespaces: ["Luca.containers", "Luca.components"]
16
+ },
17
+ component_cache: {
18
+ cid_index: {},
19
+ name_index: {}
20
+ }
21
+ };
22
+
23
+ Luca.enableBootstrap = true;
24
+
25
+ Luca.registry.addNamespace = function(identifier) {
26
+ Luca.registry.namespaces.push(identifier);
27
+ return Luca.registry.namespaces = _(Luca.registry.namespaces).uniq();
28
+ };
29
+
30
+ Luca.cache = function(needle, component) {
31
+ var lookup_id;
32
+ if (component != null) Luca.component_cache.cid_index[needle] = component;
33
+ component = Luca.component_cache.cid_index[needle];
34
+ if ((component != null ? component.component_name : void 0) != null) {
35
+ Luca.component_cache.name_index[component.component_name] = component.cid;
36
+ } else if ((component != null ? component.name : void 0) != null) {
37
+ Luca.component_cache.name_index[component.name] = component.cid;
38
+ }
39
+ if (component != null) return component;
40
+ lookup_id = Luca.component_cache.name_index[needle];
41
+ return Luca.component_cache.cid_index[lookup_id];
42
+ };
43
+
44
+ Luca.util.nestedValue = function(accessor, source_object) {
45
+ return _(accessor.split(/\./)).inject(function(obj, key) {
46
+ return obj = obj != null ? obj[key] : void 0;
47
+ }, source_object);
48
+ };
49
+
50
+ Luca.registry.lookup = function(ctype) {
51
+ var c, className, parents;
52
+ c = Luca.registry.classes[ctype];
53
+ if (c != null) return c;
54
+ className = _.camelize(_.capitalize(ctype));
55
+ parents = _(Luca.registry.namespaces).map(function(namespace) {
56
+ return Luca.util.nestedValue(namespace, window || global);
57
+ });
58
+ return _.first(_.compact(_(parents).map(function(parent) {
59
+ return parent[className];
60
+ })));
61
+ };
62
+
63
+ Luca.util.lazyComponent = function(config) {
64
+ var componentClass, constructor, ctype;
65
+ ctype = config.ctype;
66
+ componentClass = Luca.registry.lookup(ctype);
67
+ if (!componentClass) {
68
+ throw "Invalid Component Type: " + ctype + ". Did you forget to register it?";
69
+ }
70
+ constructor = eval(componentClass);
71
+ return new constructor(config);
72
+ };
73
+
74
+ Luca.register = function(component, constructor_class) {
75
+ var exists;
76
+ exists = Luca.registry.classes[component];
77
+ if (exists != null) {
78
+ throw "Can not register component with the signature " + component + ". Already exists";
79
+ } else {
80
+ return Luca.registry.classes[component] = constructor_class;
81
+ }
82
+ };
83
+
84
+ Luca.available_templates = function(filter) {
85
+ var available;
86
+ if (filter == null) filter = "";
87
+ available = _(Luca.templates).keys();
88
+ if (filter.length > 0) {
89
+ return _(available).select(function(tmpl) {
90
+ return tmpl.match(filter);
91
+ });
92
+ } else {
93
+ return available;
94
+ }
95
+ };
96
+
97
+ Luca.util.isIE = function() {
98
+ try {
99
+ Object.defineProperty({}, '', {});
100
+ return false;
101
+ } catch (e) {
102
+ return true;
103
+ }
104
+ };
105
+
106
+ $((function() {
107
+ return $('body').addClass('luca-ui-enabled');
108
+ })());
109
+
110
+ }).call(this);
111
+ (function() {
112
+
113
+ Luca.modules.Deferrable = {
114
+ configure_collection: function(setAsDeferrable) {
115
+ var collectionManager, _ref, _ref2;
116
+ if (setAsDeferrable == null) setAsDeferrable = true;
117
+ if (!this.collection) return;
118
+ if (_.isString(this.collection) && (collectionManager = (_ref = Luca.CollectionManager) != null ? _ref.get() : void 0)) {
119
+ this.collection = collectionManager.getOrCreate(this.collection);
120
+ }
121
+ if (!(this.collection && _.isFunction(this.collection.fetch) && _.isFunction(this.collection.reset))) {
122
+ this.collection = new Luca.Collection(this.collection.initial_set, this.collection);
123
+ }
124
+ if ((_ref2 = this.collection) != null ? _ref2.deferrable_trigger : void 0) {
125
+ this.deferrable_trigger = this.collection.deferrable_trigger;
126
+ }
127
+ if (setAsDeferrable) return this.deferrable = this.collection;
128
+ }
129
+ };
130
+
131
+ }).call(this);
132
+ (function() {
133
+
134
+ Luca.LocalStore = (function() {
135
+
136
+ function LocalStore(name) {
137
+ var store;
138
+ this.name = name;
139
+ store = localStorage.getItem(this.name);
140
+ this.data = (store && JSON.parse(store)) || {};
141
+ }
142
+
143
+ LocalStore.prototype.guid = function() {
144
+ var S4;
145
+ S4 = function() {
146
+ return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
147
+ };
148
+ return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4();
149
+ };
150
+
151
+ LocalStore.prototype.save = function() {
152
+ return localStorage.setItem(this.name, JSON.stringify(this.data));
153
+ };
154
+
155
+ LocalStore.prototype.create = function(model) {
156
+ if (!model.id) model.id = model.attribtues.id = this.guid();
157
+ this.data[model.id] = model;
158
+ this.save();
159
+ return model;
160
+ };
161
+
162
+ LocalStore.prototype.update = function(model) {
163
+ this.data[model.id] = model;
164
+ this.save();
165
+ return model;
166
+ };
167
+
168
+ LocalStore.prototype.find = function(model) {
169
+ return this.data[model.id];
170
+ };
171
+
172
+ LocalStore.prototype.findAll = function() {
173
+ return _.values(this.data);
174
+ };
175
+
176
+ LocalStore.prototype.destroy = function(model) {
177
+ delete this.data[model.id];
178
+ this.save();
179
+ return model;
180
+ };
181
+
182
+ return LocalStore;
183
+
184
+ })();
185
+
186
+ Backbone.LocalSync = function(method, model, options) {
187
+ var resp, store;
188
+ store = model.localStorage || model.collection.localStorage;
189
+ resp = (function() {
190
+ switch (method) {
191
+ case "read":
192
+ if (model.id) {
193
+ return store.find(model);
194
+ } else {
195
+ return store.findAll();
196
+ }
197
+ case "create":
198
+ return store.create(model);
199
+ case "update":
200
+ return store.update(model);
201
+ case "delete":
202
+ return store.destroy(model);
203
+ }
204
+ })();
205
+ if (resp) {
206
+ return options.success(resp);
207
+ } else {
208
+ return options.error("Record not found");
209
+ }
210
+ };
211
+
212
+ }).call(this);
213
+ (function() {
214
+ Luca.templates || (Luca.templates = {});
215
+ 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('');};
216
+ }).call(this);
217
+ (function() {
218
+ Luca.templates || (Luca.templates = {});
219
+ 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\' stype=\'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('');};
220
+ }).call(this);
221
+ (function() {
222
+ Luca.templates || (Luca.templates = {});
223
+ Luca.templates["components/form_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'luca-ui-form-view-wrapper\' id=\'', cid ,'-wrapper\'>\n <div class=\'form-view-header\'>\n <div class=\'toolbar-container top\' id=\'', cid ,'-top-toolbar-container\'></div>\n </div>\n '); if(legend){ __p.push('\n <fieldset>\n <legend>\n ', legend ,'\n </legend>\n <div class=\'form-view-flash-container\'></div>\n <div class=\'form-view-body\'></div>\n </fieldset>\n '); } else { __p.push('\n <ul class=\'form-view-flash-container\'></ul>\n <div class=\'form-view-body\'></div>\n '); } __p.push('\n <div class=\'form-view-footer\'>\n <div class=\'toolbar-container bottom\' id=\'', cid ,'-bottom-toolbar-container\'></div>\n </div>\n</div>\n');}return __p.join('');};
224
+ }).call(this);
225
+ (function() {
226
+ Luca.templates || (Luca.templates = {});
227
+ Luca.templates["components/grid_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'luca-ui-grid-view-wrapper\'>\n <div class=\'grid-view-header\'>\n <div class=\'toolbar-container top\'></div>\n </div>\n <div class=\'grid-view-body\'>\n <table cellpadding=\'0\' cellspacing=\'0\' class=\'luca-ui-grid-view scrollable-table\' width=\'100%\'>\n <thead class=\'fixed\'></thead>\n <tbody class=\'scrollable\'></tbody>\n </table>\n </div>\n <div class=\'grid-view-footer\'>\n <div class=\'toolbar-container bottom\'></div>\n </div>\n</div>\n');}return __p.join('');};
228
+ }).call(this);
229
+ (function() {
230
+ Luca.templates || (Luca.templates = {});
231
+ 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('');};
232
+ }).call(this);
233
+ (function() {
234
+ Luca.templates || (Luca.templates = {});
235
+ 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('');};
236
+ }).call(this);
237
+ (function() {
238
+ Luca.templates || (Luca.templates = {});
239
+ 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('');};
240
+ }).call(this);
241
+ (function() {
242
+ Luca.templates || (Luca.templates = {});
243
+ Luca.templates["containers/tab_view"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<div class=\'tab-content\' id=\'', cid ,'-tab-view-content\'></div>\n');}return __p.join('');};
244
+ }).call(this);
245
+ (function() {
246
+ Luca.templates || (Luca.templates = {});
247
+ 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('');};
248
+ }).call(this);
249
+ (function() {
250
+ Luca.templates || (Luca.templates = {});
251
+ 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('');};
252
+ }).call(this);
253
+ (function() {
254
+ Luca.templates || (Luca.templates = {});
255
+ 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('');};
256
+ }).call(this);
257
+ (function() {
258
+ Luca.templates || (Luca.templates = {});
259
+ 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('');};
260
+ }).call(this);
261
+ (function() {
262
+ Luca.templates || (Luca.templates = {});
263
+ 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('');};
264
+ }).call(this);
265
+ (function() {
266
+ Luca.templates || (Luca.templates = {});
267
+ 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('');};
268
+ }).call(this);
269
+ (function() {
270
+ Luca.templates || (Luca.templates = {});
271
+ 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<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');}return __p.join('');};
272
+ }).call(this);
273
+ (function() {
274
+ Luca.templates || (Luca.templates = {});
275
+ 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('');};
276
+ }).call(this);
277
+ (function() {
278
+ Luca.templates || (Luca.templates = {});
279
+ Luca.templates["fields/text_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label class=\'control-label\' for=\'', input_id ,'\'>\n ', label ,'\n</label>\n'); if( typeof(addOn) !== "undefined" ) { __p.push('\n<span class=\'add-on\'>\n ', addOn ,'\n</span>\n'); } __p.push('\n<input 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');}return __p.join('');};
280
+ }).call(this);
281
+ (function() {
282
+ Luca.templates || (Luca.templates = {});
283
+ 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('');};
284
+ }).call(this);
285
+ (function() {
286
+ Luca.templates || (Luca.templates = {});
287
+ 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('');};
288
+ }).call(this);
289
+ (function() {
290
+ var __slice = Array.prototype.slice;
291
+
292
+ Luca.Observer = (function() {
293
+
294
+ function Observer(options) {
295
+ var _this = this;
296
+ this.options = options != null ? options : {};
297
+ _.extend(this, Backbone.Events);
298
+ this.type = this.options.type;
299
+ if (this.options.debugAll) {
300
+ this.bind("event", function() {
301
+ var args, t;
302
+ t = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
303
+ return console.log("Observed " + _this.type + " " + (t.name || t.id || t.cid), t, _(args).flatten());
304
+ });
305
+ }
306
+ }
307
+
308
+ Observer.prototype.relay = function() {
309
+ var args, triggerer;
310
+ triggerer = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
311
+ this.trigger("event", triggerer, args);
312
+ return this.trigger("event:" + args[0], triggerer, args.slice(1));
313
+ };
314
+
315
+ return Observer;
316
+
317
+ })();
318
+
319
+ Luca.Observer.enableObservers = function(options) {
320
+ if (options == null) options = {};
321
+ Luca.enableGlobalObserver = true;
322
+ Luca.ViewObserver = new Luca.Observer(_.extend(options, {
323
+ type: "view"
324
+ }));
325
+ return Luca.CollectionObserver = new Luca.Observer(_.extend(options, {
326
+ type: "collection"
327
+ }));
328
+ };
329
+
330
+ }).call(this);
331
+ (function() {
332
+
333
+ Luca.View = Backbone.View.extend({
334
+ base: 'Luca.View'
335
+ });
336
+
337
+ Luca.View.originalExtend = Backbone.View.extend;
338
+
339
+ Luca.View.extend = function(definition) {
340
+ var _base;
341
+ _base = definition.render;
342
+ _base || (_base = function() {
343
+ var container;
344
+ container = _.isFunction(this.container) ? this.container() : this.container;
345
+ if (!($(container) && this.$el)) return this;
346
+ $(container).append(this.$el);
347
+ return this;
348
+ });
349
+ definition.render = function() {
350
+ var _this = this;
351
+ if (this.deferrable) {
352
+ this.trigger("before:render", this);
353
+ this.deferrable.bind(this.deferrable_event, _.once(function() {
354
+ _base.apply(_this, arguments);
355
+ return _this.trigger("after:render", _this);
356
+ }));
357
+ if (!this.deferrable_trigger) this.immediate_trigger = true;
358
+ if (this.immediate_trigger === true) {
359
+ return this.deferrable.fetch();
360
+ } else {
361
+ return this.bind(this.deferrable_trigger, _.once(function() {
362
+ return _this.deferrable.fetch();
363
+ }));
364
+ }
365
+ } else {
366
+ this.trigger("before:render", this);
367
+ _base.apply(this, arguments);
368
+ return this.trigger("after:render", this);
369
+ }
370
+ };
371
+ return Luca.View.originalExtend.apply(this, [definition]);
372
+ };
373
+
374
+ _.extend(Luca.View.prototype, {
375
+ debug: function() {
376
+ var message, _i, _len, _results;
377
+ if (!(this.debugMode || (window.LucaDebugMode != null))) return;
378
+ _results = [];
379
+ for (_i = 0, _len = arguments.length; _i < _len; _i++) {
380
+ message = arguments[_i];
381
+ _results.push(console.log([this.name || this.cid, message]));
382
+ }
383
+ return _results;
384
+ },
385
+ trigger: function() {
386
+ if (Luca.enableGlobalObserver) {
387
+ Luca.ViewObserver || (Luca.ViewObserver = new Luca.Observer({
388
+ type: "view"
389
+ }));
390
+ Luca.ViewObserver.relay(this, arguments);
391
+ }
392
+ return Backbone.View.prototype.trigger.apply(this, arguments);
393
+ },
394
+ hooks: ["after:initialize", "before:render", "after:render", "first:activation", "activation", "deactivation"],
395
+ deferrable_event: "reset",
396
+ initialize: function(options) {
397
+ var unique,
398
+ _this = this;
399
+ this.options = options != null ? options : {};
400
+ _.extend(this, this.options);
401
+ if (this.name != null) this.cid = _.uniqueId(this.name);
402
+ Luca.cache(this.cid, this);
403
+ unique = _(Luca.View.prototype.hooks.concat(this.hooks)).uniq();
404
+ this.setupHooks(unique);
405
+ if (this.autoBindEventHandlers === true) {
406
+ _(this.events).each(function(handler, event) {
407
+ if (_.isString(handler)) return _.bindAll(_this, handler);
408
+ });
409
+ }
410
+ this.trigger("after:initialize", this);
411
+ return this.registerCollectionEvents();
412
+ },
413
+ $container: function() {
414
+ return $(this.container);
415
+ },
416
+ setupHooks: function(set) {
417
+ var _this = this;
418
+ set || (set = this.hooks);
419
+ return _(set).each(function(event) {
420
+ var fn, parts, prefix;
421
+ parts = event.split(':');
422
+ prefix = parts.shift();
423
+ parts = _(parts).map(function(p) {
424
+ return _.capitalize(p);
425
+ });
426
+ fn = prefix + parts.join('');
427
+ return _this.bind(event, function() {
428
+ if (_this[fn]) return _this[fn].apply(_this, arguments);
429
+ });
430
+ });
431
+ },
432
+ getCollectionManager: function() {
433
+ var _ref;
434
+ return this.collectionManager || ((_ref = Luca.CollectionManager.get) != null ? _ref.call() : void 0);
435
+ },
436
+ registerCollectionEvents: function() {
437
+ var manager,
438
+ _this = this;
439
+ manager = this.getCollectionManager();
440
+ return _(this.collectionEvents).each(function(handler, signature) {
441
+ var collection, event, key, _ref;
442
+ _ref = signature.split(" "), key = _ref[0], event = _ref[1];
443
+ collection = _this["" + key + "Collection"] = manager.getOrCreate(key);
444
+ if (!collection) throw "Could not find collection specified by " + key;
445
+ if (_.isString(handler)) handler = _this[handler];
446
+ if (!_.isFunction(handler)) throw "invalid collectionEvents configuration";
447
+ try {
448
+ return collection.bind(event, handler);
449
+ } catch (e) {
450
+ console.log("Error Binding To Collection in registerCollectionEvents", _this);
451
+ throw e;
452
+ }
453
+ });
454
+ }
455
+ });
456
+
457
+ }).call(this);
458
+ (function() {
459
+
460
+ Luca.Collection = (Backbone.QueryCollection || Backbone.Collection).extend({
461
+ initialize: function(models, options) {
462
+ var table,
463
+ _this = this;
464
+ if (models == null) models = [];
465
+ this.options = options;
466
+ _.extend(this, this.options);
467
+ if (this.cached) {
468
+ this.bootstrap_cache_key = _.isFunction(this.cached) ? this.cached() : this.cached;
469
+ }
470
+ if (this.registerAs || this.registerWith) {
471
+ console.log("This configuration API is deprecated. use @name and @manager properties instead");
472
+ }
473
+ this.name || (this.name = this.registerAs);
474
+ this.manager || (this.manager = this.registerWith);
475
+ if (this.name && !this.manager) this.manager = Luca.CollectionManager.get();
476
+ if (this.manager) {
477
+ this.name || (this.name = this.cached());
478
+ this.name = _.isFunction(this.name) ? this.name() : this.name;
479
+ if (!(this.private || this.anonymous)) {
480
+ this.bind("after:initialize", function() {
481
+ return _this.register(_this.manager, _this.name, _this);
482
+ });
483
+ }
484
+ }
485
+ if (this.useLocalStorage === true && (window.localStorage != null)) {
486
+ table = this.bootstrap_cache_key || this.name;
487
+ throw "Must specify either a cached or registerAs property to use localStorage";
488
+ this.localStorage = new Luca.LocalStore(table);
489
+ }
490
+ if (_.isArray(this.data) && this.data.length > 0) {
491
+ this.memoryCollection = true;
492
+ }
493
+ if (this.useNormalUrl !== true) this.__wrapUrl();
494
+ Backbone.Collection.prototype.initialize.apply(this, [models, this.options]);
495
+ return this.trigger("after:initialize");
496
+ },
497
+ __wrapUrl: function() {
498
+ var params, url,
499
+ _this = this;
500
+ if (_.isFunction(this.url)) {
501
+ return this.url = _.wrap(this.url, function(fn) {
502
+ var existing_params, new_val, parts, queryString, val;
503
+ val = fn.apply(_this);
504
+ parts = val.split('?');
505
+ if (parts.length > 1) existing_params = _.last(parts);
506
+ queryString = _this.queryString();
507
+ if (existing_params && val.match(existing_params)) {
508
+ queryString = queryString.replace(existing_params, '');
509
+ }
510
+ new_val = "" + val + "?" + queryString;
511
+ if (new_val.match(/\?$/)) new_val = new_val.replace(/\?$/, '');
512
+ return new_val;
513
+ });
514
+ } else {
515
+ url = this.url;
516
+ params = this.queryString();
517
+ return this.url = _([url, params]).compact().join("?");
518
+ }
519
+ },
520
+ queryString: function() {
521
+ var parts,
522
+ _this = this;
523
+ parts = _(this.base_params || (this.base_params = Luca.Collection.baseParams())).inject(function(memo, value, key) {
524
+ var str;
525
+ str = "" + key + "=" + value;
526
+ memo.push(str);
527
+ return memo;
528
+ }, []);
529
+ return _.uniq(parts).join("&");
530
+ },
531
+ resetFilter: function() {
532
+ this.base_params = Luca.Collection.baseParams();
533
+ return this;
534
+ },
535
+ applyFilter: function(filter, options) {
536
+ if (filter == null) filter = {};
537
+ if (options == null) options = {};
538
+ this.applyParams(filter);
539
+ return this.fetch(_.extend(options, {
540
+ refresh: true
541
+ }));
542
+ },
543
+ applyParams: function(params) {
544
+ this.base_params || (this.base_params = Luca.Collection.baseParams());
545
+ return _.extend(this.base_params, params);
546
+ },
547
+ register: function(collectionManager, key, collection) {
548
+ if (collectionManager == null) {
549
+ collectionManager = Luca.CollectionManager.get();
550
+ }
551
+ if (key == null) key = "";
552
+ if (!(key.length >= 1)) {
553
+ throw "Can not register with a collection manager without a key";
554
+ }
555
+ if (collectionManager == null) {
556
+ throw "Can not register with a collection manager without a valid collection manager";
557
+ }
558
+ if (_.isString(collectionManager)) {
559
+ collectionManager = Luca.util.nestedValue(collectionManager, window || global);
560
+ }
561
+ if (!collectionManager) throw "Could not register with collection manager";
562
+ if (_.isFunction(collectionManager.add)) {
563
+ return collectionManager.add(key, collection);
564
+ }
565
+ if (_.isObject(collectionManager)) {
566
+ return collectionManager[key] = collection;
567
+ }
568
+ },
569
+ loadFromBootstrap: function() {
570
+ if (!this.bootstrap_cache_key) return;
571
+ this.reset(this.cached_models());
572
+ return this.trigger("bootstrapped", this);
573
+ },
574
+ bootstrap: function() {
575
+ return this.loadFromBootstrap();
576
+ },
577
+ cached_models: function() {
578
+ return Luca.Collection.cache(this.bootstrap_cache_key);
579
+ },
580
+ fetch: function(options) {
581
+ var url;
582
+ if (options == null) options = {};
583
+ this.trigger("before:fetch", this);
584
+ if (this.memoryCollection === true) return this.reset(this.data);
585
+ if (this.cached_models().length && !options.refresh) return this.bootstrap();
586
+ url = _.isFunction(this.url) ? this.url() : this.url;
587
+ if (!((url && url.length > 1) || this.localStorage)) return true;
588
+ this.fetching = true;
589
+ try {
590
+ return Backbone.Collection.prototype.fetch.apply(this, arguments);
591
+ } catch (e) {
592
+ console.log("Error in Collection.fetch", e);
593
+ throw e;
594
+ }
595
+ },
596
+ onceLoaded: function(fn, options) {
597
+ var wrapped,
598
+ _this = this;
599
+ if (options == null) {
600
+ options = {
601
+ autoFetch: true
602
+ };
603
+ }
604
+ if (this.length > 0 && !this.fetching) {
605
+ fn.apply(this, [this]);
606
+ return;
607
+ }
608
+ wrapped = function() {
609
+ return fn.apply(_this, [_this]);
610
+ };
611
+ this.bind("reset", function() {
612
+ wrapped();
613
+ return this.unbind("reset", this);
614
+ });
615
+ if (!(this.fetching || !options.autoFetch)) return this.fetch();
616
+ },
617
+ ifLoaded: function(fn, options) {
618
+ var scope,
619
+ _this = this;
620
+ if (options == null) {
621
+ options = {
622
+ scope: this,
623
+ autoFetch: true
624
+ };
625
+ }
626
+ scope = options.scope || this;
627
+ if (this.length > 0 && !this.fetching) fn.apply(scope, [this]);
628
+ this.bind("reset", function(collection) {
629
+ return fn.apply(scope, [collection]);
630
+ });
631
+ if (!(this.fetching === true || !options.autoFetch || this.length > 0)) {
632
+ return this.fetch();
633
+ }
634
+ },
635
+ parse: function(response) {
636
+ var models;
637
+ this.fetching = false;
638
+ this.trigger("after:response", response);
639
+ models = this.root != null ? response[this.root] : response;
640
+ if (this.bootstrap_cache_key) {
641
+ Luca.Collection.cache(this.bootstrap_cache_key, models);
642
+ }
643
+ return models;
644
+ }
645
+ });
646
+
647
+ _.extend(Luca.Collection.prototype, {
648
+ trigger: function() {
649
+ if (Luca.enableGlobalObserver) {
650
+ Luca.CollectionObserver || (Luca.CollectionObserver = new Luca.Observer({
651
+ type: "collection"
652
+ }));
653
+ Luca.CollectionObserver.relay(this, arguments);
654
+ }
655
+ return Backbone.View.prototype.trigger.apply(this, arguments);
656
+ }
657
+ });
658
+
659
+ Luca.Collection.baseParams = function(obj) {
660
+ if (obj) return Luca.Collection._baseParams = obj;
661
+ if (_.isFunction(Luca.Collection._baseParams)) {
662
+ return Luca.Collection._baseParams.call();
663
+ }
664
+ if (_.isObject(Luca.Collection._baseParams)) {
665
+ return Luca.Collection._baseParams;
666
+ }
667
+ };
668
+
669
+ Luca.Collection._bootstrapped_models = {};
670
+
671
+ Luca.Collection.bootstrap = function(obj) {
672
+ return _.extend(Luca.Collection._bootstrapped_models, obj);
673
+ };
674
+
675
+ Luca.Collection.cache = function(key, models) {
676
+ if (models) return Luca.Collection._bootstrapped_models[key] = models;
677
+ return Luca.Collection._bootstrapped_models[key] || [];
678
+ };
679
+
680
+ }).call(this);
681
+ (function() {
682
+
683
+ Luca.core.Field = Luca.View.extend({
684
+ className: 'luca-ui-text-field luca-ui-field',
685
+ isField: true,
686
+ template: 'fields/text_field',
687
+ labelAlign: 'top',
688
+ hooks: ["before:validation", "after:validation", "on:change"],
689
+ statuses: ["warning", "error", "success"],
690
+ initialize: function(options) {
691
+ var _ref;
692
+ this.options = options != null ? options : {};
693
+ _.extend(this, this.options);
694
+ Luca.View.prototype.initialize.apply(this, arguments);
695
+ this.input_id || (this.input_id = _.uniqueId('field'));
696
+ this.input_name || (this.input_name = this.name);
697
+ this.helperText || (this.helperText = "");
698
+ if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) {
699
+ this.label || (this.label = "*" + this.label);
700
+ }
701
+ this.inputStyles || (this.inputStyles = "");
702
+ if (this.disabled) this.disable();
703
+ this.updateState(this.state);
704
+ return this.placeHolder || (this.placeHolder = "");
705
+ },
706
+ beforeRender: function() {
707
+ if (Luca.enableBootstrap) this.$el.addClass('control-group');
708
+ if (this.required) this.$el.addClass('required');
709
+ this.$el.html(Luca.templates[this.template](this));
710
+ return this.input = $('input', this.el);
711
+ },
712
+ change_handler: function(e) {
713
+ return this.trigger("on:change", this, e);
714
+ },
715
+ disable: function() {
716
+ return $("input", this.el).attr('disabled', true);
717
+ },
718
+ enable: function() {
719
+ return $("input", this.el).attr('disabled', false);
720
+ },
721
+ getValue: function() {
722
+ return this.input.attr('value');
723
+ },
724
+ render: function() {
725
+ return $(this.container).append(this.$el);
726
+ },
727
+ setValue: function(value) {
728
+ return this.input.attr('value', value);
729
+ },
730
+ updateState: function(state) {
731
+ var _this = this;
732
+ return _(this.statuses).each(function(cls) {
733
+ _this.$el.removeClass(cls);
734
+ return _this.$el.addClass(state);
735
+ });
736
+ }
737
+ });
738
+
739
+ }).call(this);
740
+ (function() {
741
+
742
+ Luca.core.Container = Luca.View.extend({
743
+ className: 'luca-ui-container',
744
+ componentClass: 'luca-ui-panel',
745
+ isContainer: true,
746
+ hooks: ["before:components", "before:layout", "after:components", "after:layout", "first:activation"],
747
+ rendered: false,
748
+ components: [],
749
+ initialize: function(options) {
750
+ this.options = options != null ? options : {};
751
+ _.extend(this, this.options);
752
+ this.setupHooks(Luca.core.Container.prototype.hooks);
753
+ return Luca.View.prototype.initialize.apply(this, arguments);
754
+ },
755
+ beforeRender: function() {
756
+ this.debug("container before render");
757
+ this.doLayout();
758
+ return this.doComponents();
759
+ },
760
+ doLayout: function() {
761
+ this.debug("container do layout");
762
+ this.trigger("before:layout", this);
763
+ this.prepareLayout();
764
+ return this.trigger("after:layout", this);
765
+ },
766
+ doComponents: function() {
767
+ this.debug("container do components");
768
+ this.trigger("before:components", this, this.components);
769
+ this.prepareComponents();
770
+ this.createComponents();
771
+ this.renderComponents();
772
+ return this.trigger("after:components", this, this.components);
773
+ },
774
+ applyPanelConfig: function(panel, panelIndex) {
775
+ var config, style_declarations;
776
+ style_declarations = [];
777
+ if (panel.height) {
778
+ style_declarations.push("height: " + (_.isNumber(panel.height) ? panel.height + 'px' : panel.height));
779
+ }
780
+ if (panel.width) {
781
+ style_declarations.push("width: " + (_.isNumber(panel.width) ? panel.width + 'px' : panel.width));
782
+ }
783
+ if (panel.float) style_declarations.push("float: " + panel.float);
784
+ return config = {
785
+ classes: (panel != null ? panel.classes : void 0) || this.componentClass,
786
+ id: "" + this.cid + "-" + panelIndex,
787
+ style: style_declarations.join(';')
788
+ };
789
+ },
790
+ prepareLayout: function() {
791
+ var _this = this;
792
+ this.debug("container prepare layout");
793
+ this.componentContainers = _(this.components).map(function(component, index) {
794
+ return _this.applyPanelConfig.apply(_this, [component, index]);
795
+ });
796
+ if (this.appendContainers) {
797
+ return _(this.componentContainers).each(function(container) {
798
+ return _this.$el.append(Luca.templates["containers/basic"](container));
799
+ });
800
+ }
801
+ },
802
+ prepareComponents: function() {
803
+ var _this = this;
804
+ this.debug("container prepare components");
805
+ return this.components = _(this.components).map(function(object, index) {
806
+ var panel;
807
+ panel = _this.componentContainers[index];
808
+ object.container = _this.appendContainers ? "#" + panel.id : _this.el;
809
+ return object;
810
+ });
811
+ },
812
+ createComponents: function() {
813
+ var map,
814
+ _this = this;
815
+ this.debug("container create components");
816
+ map = this.componentIndex = {
817
+ name_index: {},
818
+ cid_index: {}
819
+ };
820
+ this.components = _(this.components).map(function(object, index) {
821
+ var component;
822
+ component = _.isObject(object) && object.render && object.trigger ? object : (object.ctype || (object.ctype = Luca.defaultComponentType || "template"), Luca.util.lazyComponent(object));
823
+ if (!component.container && component.options.container) {
824
+ component.container = component.options.container;
825
+ }
826
+ if (map && (component.cid != null)) map.cid_index[component.cid] = index;
827
+ if (map && (component.name != null)) {
828
+ map.name_index[component.name] = index;
829
+ }
830
+ return component;
831
+ });
832
+ return this.debug("components created", this.components);
833
+ },
834
+ renderComponents: function(debugMode) {
835
+ var _this = this;
836
+ this.debugMode = debugMode != null ? debugMode : "";
837
+ this.debug("container render components");
838
+ return _(this.components).each(function(component) {
839
+ component.getParent = function() {
840
+ return _this;
841
+ };
842
+ $(component.container).append($(component.el));
843
+ try {
844
+ return component.render();
845
+ } catch (e) {
846
+ console.log("Error Rendering Component " + (component.name || component.cid), component);
847
+ console.log(e.message);
848
+ return console.log(e.stack);
849
+ }
850
+ });
851
+ },
852
+ firstActivation: function() {
853
+ var _this = this;
854
+ return _(this.components).each(function(component) {
855
+ var activator, _ref;
856
+ activator = _this;
857
+ if ((component != null ? component.previously_activated : void 0) !== true) {
858
+ if (component != null) {
859
+ if ((_ref = component.trigger) != null) {
860
+ _ref.apply(component, ["first:activation", [component, activator]]);
861
+ }
862
+ }
863
+ return component.previously_activated = true;
864
+ }
865
+ });
866
+ },
867
+ select: function(attribute, value, deep) {
868
+ var components;
869
+ if (deep == null) deep = false;
870
+ components = _(this.components).map(function(component) {
871
+ var matches, test;
872
+ matches = [];
873
+ test = component[attribute];
874
+ if (test === value) matches.push(component);
875
+ if (deep === true && component.isContainer === true) {
876
+ matches.push(component.select(attribute, value, true));
877
+ }
878
+ return _.compact(matches);
879
+ });
880
+ return _.flatten(components);
881
+ },
882
+ findComponentByName: function(name, deep) {
883
+ if (deep == null) deep = false;
884
+ return this.findComponent(name, "name_index", deep);
885
+ },
886
+ findComponentById: function(id, deep) {
887
+ if (deep == null) deep = false;
888
+ return this.findComponent(id, "cid_index", deep);
889
+ },
890
+ findComponent: function(needle, haystack, deep) {
891
+ var component, position, sub_container, _ref, _ref2;
892
+ if (haystack == null) haystack = "name";
893
+ if (deep == null) deep = false;
894
+ position = (_ref = this.componentIndex) != null ? _ref[haystack][needle] : void 0;
895
+ component = (_ref2 = this.components) != null ? _ref2[position] : void 0;
896
+ if (component) return component;
897
+ if (deep === true) {
898
+ sub_container = _(this.components).detect(function(component) {
899
+ return component != null ? typeof component.findComponent === "function" ? component.findComponent(needle, haystack, true) : void 0 : void 0;
900
+ });
901
+ return sub_container != null ? typeof sub_container.findComponent === "function" ? sub_container.findComponent(needle, haystack, true) : void 0 : void 0;
902
+ }
903
+ },
904
+ eachComponent: function(fn, deep) {
905
+ var _this = this;
906
+ if (deep == null) deep = true;
907
+ return _(this.components).each(function(component) {
908
+ var _ref;
909
+ fn.apply(component, [component]);
910
+ if (deep) {
911
+ return component != null ? (_ref = component.eachComponent) != null ? _ref.apply(component, [fn, deep]) : void 0 : void 0;
912
+ }
913
+ });
914
+ },
915
+ indexOf: function(name) {
916
+ var names;
917
+ names = _(this.components).pluck('name');
918
+ return _(names).indexOf(name);
919
+ },
920
+ activeComponent: function() {
921
+ if (!this.activeItem) return this;
922
+ return this.components[this.activeItem];
923
+ },
924
+ componentElements: function() {
925
+ return $("." + this.componentClass, this.el);
926
+ },
927
+ getComponent: function(needle) {
928
+ return this.components[needle];
929
+ },
930
+ rootComponent: function() {
931
+ return !(this.getParent != null);
932
+ },
933
+ getRootComponent: function() {
934
+ if (this.rootComponent()) {
935
+ return this;
936
+ } else {
937
+ return this.getParent().getRootComponent();
938
+ }
939
+ }
940
+ });
941
+
942
+ Luca.register("container", "Luca.core.Container");
943
+
944
+ }).call(this);
945
+ (function() {
946
+ var instances;
947
+
948
+ instances = [];
949
+
950
+ Luca.CollectionManager = (function() {
951
+
952
+ CollectionManager.prototype.__collections = {};
953
+
954
+ function CollectionManager(options) {
955
+ this.options = options != null ? options : {};
956
+ _.extend(this, this.options);
957
+ _.extend(this, Backbone.Events);
958
+ instances.push(this);
959
+ this.state = new Backbone.Model;
960
+ if (this.collectionNames) {
961
+ this.state.set({
962
+ loaded_collections_count: 0,
963
+ collections_count: this.collectionNames.length
964
+ });
965
+ this.state.bind("change:loaded_collections_count", this.collectionCountDidChange);
966
+ if (this.useProgressLoader) {
967
+ this.loader = new Luca.components.CollectionLoaderView({
968
+ manager: this,
969
+ name: "collection_loader_view"
970
+ });
971
+ }
972
+ this.loadInitialCollections();
973
+ }
974
+ this;
975
+ }
976
+
977
+ CollectionManager.prototype.add = function(key, collection) {
978
+ var _base;
979
+ return (_base = this.currentScope())[key] || (_base[key] = collection);
980
+ };
981
+
982
+ CollectionManager.prototype.allCollections = function() {
983
+ return _(this.currentScope()).values();
984
+ };
985
+
986
+ CollectionManager.prototype.create = function(key, collectionOptions, initialModels) {
987
+ var CollectionClass, collection;
988
+ if (collectionOptions == null) collectionOptions = {};
989
+ if (initialModels == null) initialModels = [];
990
+ CollectionClass = collectionOptions.base;
991
+ CollectionClass || (CollectionClass = this.guessCollectionClass(key));
992
+ if (collectionOptions.private) collectionOptions.name = "";
993
+ collection = new CollectionClass(initialModels, collectionOptions);
994
+ this.add(key, collection);
995
+ return collection;
996
+ };
997
+
998
+ CollectionManager.prototype.collectionNamespace = Luca.Collection.namespace;
999
+
1000
+ CollectionManager.prototype.currentScope = function() {
1001
+ var current_scope, _base;
1002
+ if (current_scope = this.getScope()) {
1003
+ return (_base = this.__collections)[current_scope] || (_base[current_scope] = {});
1004
+ } else {
1005
+ return this.__collections;
1006
+ }
1007
+ };
1008
+
1009
+ CollectionManager.prototype.each = function(fn) {
1010
+ return _(this.all()).each(fn);
1011
+ };
1012
+
1013
+ CollectionManager.prototype.get = function(key) {
1014
+ return this.currentScope()[key];
1015
+ };
1016
+
1017
+ CollectionManager.prototype.getScope = function() {
1018
+ return;
1019
+ };
1020
+
1021
+ CollectionManager.prototype.getOrCreate = function(key, collectionOptions, initialModels) {
1022
+ if (collectionOptions == null) collectionOptions = {};
1023
+ if (initialModels == null) initialModels = [];
1024
+ return this.get(key) || this.create(key, collectionOptions, initialModels, false);
1025
+ };
1026
+
1027
+ CollectionManager.prototype.guessCollectionClass = function(key) {
1028
+ var classified, guess;
1029
+ classified = _(key).chain().capitalize().camelize().value();
1030
+ guess = (this.collectionNamespace || (window || global))[classified];
1031
+ guess || (guess = (this.collectionNamespace || (window || global))["" + classified + "Collection"]);
1032
+ return guess;
1033
+ };
1034
+
1035
+ CollectionManager.prototype.loadInitialCollections = function() {
1036
+ var collectionDidLoad,
1037
+ _this = this;
1038
+ collectionDidLoad = function(collection) {
1039
+ collection.unbind("reset");
1040
+ return _this.trigger("collection_loaded", collection.name);
1041
+ };
1042
+ return _(this.collectionNames).each(function(name) {
1043
+ var collection;
1044
+ collection = _this.getOrCreate(name);
1045
+ collection.bind("reset", function() {
1046
+ return collectionDidLoad(collection);
1047
+ });
1048
+ return collection.fetch();
1049
+ });
1050
+ };
1051
+
1052
+ CollectionManager.prototype.collectionCountDidChange = function() {
1053
+ if (this.totalCollectionsCount() === this.loadedCollectionsCount()) {
1054
+ return this.trigger("all_collections_loaded");
1055
+ }
1056
+ };
1057
+
1058
+ CollectionManager.prototype.totalCollectionsCount = function() {
1059
+ return this.state.get("collections_count");
1060
+ };
1061
+
1062
+ CollectionManager.prototype.loadedCollectionsCount = function() {
1063
+ return this.state.get("loaded_collections_count");
1064
+ };
1065
+
1066
+ CollectionManager.prototype.private = function(key, collectionOptions, initialModels) {
1067
+ if (collectionOptions == null) collectionOptions = {};
1068
+ if (initialModels == null) initialModels = [];
1069
+ return this.create(key, collectionOptions, initialModels, true);
1070
+ };
1071
+
1072
+ return CollectionManager;
1073
+
1074
+ })();
1075
+
1076
+ Luca.CollectionManager.destroyAll = function() {
1077
+ return instances = [];
1078
+ };
1079
+
1080
+ Luca.CollectionManager.instances = function() {
1081
+ return instances;
1082
+ };
1083
+
1084
+ Luca.CollectionManager.get = function() {
1085
+ return _(instances).last();
1086
+ };
1087
+
1088
+ }).call(this);
1089
+ (function() {
1090
+
1091
+ Luca.SocketManager = (function() {
1092
+
1093
+ function SocketManager(options) {
1094
+ this.options = options != null ? options : {};
1095
+ _.extend(Backbone.Events);
1096
+ this.loadTransport();
1097
+ }
1098
+
1099
+ SocketManager.prototype.connect = function() {
1100
+ switch (this.options.provider) {
1101
+ case "socket.io":
1102
+ return this.socket = io.connect(this.options.socket_host);
1103
+ case "faye.js":
1104
+ return this.socket = new Faye.Client(this.options.socket_host);
1105
+ }
1106
+ };
1107
+
1108
+ SocketManager.prototype.transportLoaded = function() {
1109
+ return this.connect();
1110
+ };
1111
+
1112
+ SocketManager.prototype.transport_script = function() {
1113
+ switch (this.options.provider) {
1114
+ case "socket.io":
1115
+ return "" + this.options.transport_host + "/socket.io/socket.io.js";
1116
+ case "faye.js":
1117
+ return "" + this.options.transport_host + "/faye.js";
1118
+ }
1119
+ };
1120
+
1121
+ SocketManager.prototype.loadTransport = function() {
1122
+ var script,
1123
+ _this = this;
1124
+ script = document.createElement('script');
1125
+ script.setAttribute("type", "text/javascript");
1126
+ script.setAttribute("src", this.transport_script());
1127
+ script.onload = this.transportLoaded;
1128
+ if (Luca.util.isIE()) {
1129
+ script.onreadystatechange = function() {
1130
+ if (script.readyState === "loaded") return _this.transportLoaded();
1131
+ };
1132
+ }
1133
+ return document.getElementsByTagName('head')[0].appendChild(script);
1134
+ };
1135
+
1136
+ return SocketManager;
1137
+
1138
+ })();
1139
+
1140
+ }).call(this);
1141
+ (function() {
1142
+
1143
+ Luca.containers.SplitView = Luca.core.Container.extend({
1144
+ layout: '100',
1145
+ componentType: 'split_view',
1146
+ containerTemplate: 'containers/basic',
1147
+ className: 'luca-ui-split-view',
1148
+ componentClass: 'luca-ui-panel'
1149
+ });
1150
+
1151
+ Luca.register('split_view', "Luca.containers.SplitView");
1152
+
1153
+ }).call(this);
1154
+ (function() {
1155
+
1156
+ Luca.containers.ColumnView = Luca.core.Container.extend({
1157
+ componentType: 'column_view',
1158
+ className: 'luca-ui-column-view',
1159
+ components: [],
1160
+ initialize: function(options) {
1161
+ this.options = options != null ? options : {};
1162
+ Luca.core.Container.prototype.initialize.apply(this, arguments);
1163
+ return this.setColumnWidths();
1164
+ },
1165
+ componentClass: 'luca-ui-column',
1166
+ containerTemplate: "containers/basic",
1167
+ appendContainers: true,
1168
+ autoColumnWidths: function() {
1169
+ var widths,
1170
+ _this = this;
1171
+ widths = [];
1172
+ _(this.components.length).times(function() {
1173
+ return widths.push(parseInt(100 / _this.components.length));
1174
+ });
1175
+ return widths;
1176
+ },
1177
+ setColumnWidths: function() {
1178
+ this.columnWidths = this.layout != null ? _(this.layout.split('/')).map(function(v) {
1179
+ return parseInt(v);
1180
+ }) : this.autoColumnWidths();
1181
+ return this.columnWidths = _(this.columnWidths).map(function(val) {
1182
+ return "" + val + "%";
1183
+ });
1184
+ },
1185
+ beforeComponents: function() {
1186
+ this.debug("column_view before components");
1187
+ return _(this.components).each(function(component) {
1188
+ return component.ctype || (component.ctype = "panel_view");
1189
+ });
1190
+ },
1191
+ beforeLayout: function() {
1192
+ var _ref,
1193
+ _this = this;
1194
+ this.debug("column_view before layout");
1195
+ _(this.columnWidths).each(function(width, index) {
1196
+ _this.components[index].float = "left";
1197
+ return _this.components[index].width = width;
1198
+ });
1199
+ return (_ref = Luca.core.Container.prototype.beforeLayout) != null ? _ref.apply(this, arguments) : void 0;
1200
+ }
1201
+ });
1202
+
1203
+ Luca.register('column_view', "Luca.containers.ColumnView");
1204
+
1205
+ }).call(this);
1206
+ (function() {
1207
+
1208
+ Luca.containers.CardView = Luca.core.Container.extend({
1209
+ componentType: 'card_view',
1210
+ className: 'luca-ui-card-view-wrapper',
1211
+ activeCard: 0,
1212
+ components: [],
1213
+ hooks: ['before:card:switch', 'after:card:switch'],
1214
+ initialize: function(options) {
1215
+ this.options = options;
1216
+ Luca.core.Container.prototype.initialize.apply(this, arguments);
1217
+ return this.setupHooks(this.hooks);
1218
+ },
1219
+ componentClass: 'luca-ui-card',
1220
+ beforeLayout: function() {
1221
+ var _this = this;
1222
+ return this.cards = _(this.components).map(function(card, cardIndex) {
1223
+ return {
1224
+ classes: _this.componentClass,
1225
+ style: "display:" + (cardIndex === _this.activeCard ? 'block' : 'none'),
1226
+ id: "" + _this.cid + "-" + cardIndex
1227
+ };
1228
+ });
1229
+ },
1230
+ prepareLayout: function() {
1231
+ var _this = this;
1232
+ return this.card_containers = _(this.cards).map(function(card, index) {
1233
+ _this.$el.append(Luca.templates["containers/basic"](card));
1234
+ return $("#" + card.id);
1235
+ });
1236
+ },
1237
+ prepareComponents: function() {
1238
+ var _this = this;
1239
+ return this.components = _(this.components).map(function(object, index) {
1240
+ var card;
1241
+ card = _this.cards[index];
1242
+ object.container = "#" + card.id;
1243
+ return object;
1244
+ });
1245
+ },
1246
+ activeComponent: function() {
1247
+ return this.getComponent(this.activeCard);
1248
+ },
1249
+ cycle: function() {
1250
+ var nextIndex;
1251
+ nextIndex = this.activeCard < this.components.length - 1 ? this.activeCard + 1 : 0;
1252
+ return this.activate(nextIndex);
1253
+ },
1254
+ find: function(name) {
1255
+ return this.findComponentByName(name, true);
1256
+ },
1257
+ firstActivation: function() {
1258
+ return this.activeComponent().trigger("first:activation", this, this.activeComponent());
1259
+ },
1260
+ activate: function(index, silent, callback) {
1261
+ var current, previous, _ref;
1262
+ if (silent == null) silent = false;
1263
+ if (_.isFunction(silent)) {
1264
+ silent = false;
1265
+ callback = silent;
1266
+ }
1267
+ if (index === this.activeCard) return;
1268
+ previous = this.activeComponent();
1269
+ current = this.getComponent(index);
1270
+ if (!current) {
1271
+ index = this.indexOf(index);
1272
+ current = this.getComponent(index);
1273
+ }
1274
+ if (!current) return;
1275
+ if (!silent) this.trigger("before:card:switch", previous, current);
1276
+ _(this.card_containers).each(function(container) {
1277
+ var _ref;
1278
+ if ((_ref = container.trigger) != null) {
1279
+ _ref.apply(container, ["deactivation", this, previous, current]);
1280
+ }
1281
+ return container.hide();
1282
+ });
1283
+ if (!current.previously_activated) {
1284
+ current.trigger("first:activation");
1285
+ current.previously_activated = true;
1286
+ }
1287
+ $(current.container).show();
1288
+ this.activeCard = index;
1289
+ if (!silent) {
1290
+ this.trigger("after:card:switch", previous, current);
1291
+ if ((_ref = current.trigger) != null) {
1292
+ _ref.apply(current, ["activation", this, previous, current]);
1293
+ }
1294
+ }
1295
+ if (_.isFunction(callback)) {
1296
+ return callback.apply(this, [this, previous, current]);
1297
+ }
1298
+ }
1299
+ });
1300
+
1301
+ Luca.register('card_view', "Luca.containers.CardView");
1302
+
1303
+ }).call(this);
1304
+ (function() {
1305
+
1306
+ Luca.containers.ModalView = Luca.core.Container.extend({
1307
+ componentType: 'modal_view',
1308
+ className: 'luca-ui-modal-view',
1309
+ components: [],
1310
+ renderOnInitialize: true,
1311
+ showOnRender: false,
1312
+ hooks: ['before:show', 'before:hide'],
1313
+ defaultModalOptions: {
1314
+ minWidth: 375,
1315
+ maxWidth: 375,
1316
+ minHeight: 550,
1317
+ maxHeight: 550,
1318
+ opacity: 80,
1319
+ onOpen: function(modal) {
1320
+ this.onOpen.apply(this);
1321
+ return this.onModalOpen.apply(modal, [modal, this]);
1322
+ },
1323
+ onClose: function(modal) {
1324
+ this.onClose.apply(this);
1325
+ return this.onModalClose.apply(modal, [modal, this]);
1326
+ }
1327
+ },
1328
+ modalOptions: {},
1329
+ initialize: function(options) {
1330
+ var _this = this;
1331
+ this.options = options != null ? options : {};
1332
+ Luca.core.Container.prototype.initialize.apply(this, arguments);
1333
+ this.setupHooks(this.hooks);
1334
+ _(this.defaultModalOptions).each(function(value, setting) {
1335
+ var _base;
1336
+ return (_base = _this.modalOptions)[setting] || (_base[setting] = value);
1337
+ });
1338
+ this.modalOptions.onOpen = _.bind(this.modalOptions.onOpen, this);
1339
+ return this.modalOptions.onClose = _.bind(this.modalOptions.onClose, this);
1340
+ },
1341
+ onOpen: function() {
1342
+ return true;
1343
+ },
1344
+ onClose: function() {
1345
+ return true;
1346
+ },
1347
+ getModal: function() {
1348
+ return this.modal;
1349
+ },
1350
+ onModalOpen: function(modal, view) {
1351
+ view.modal = modal;
1352
+ modal.overlay.show();
1353
+ modal.container.show();
1354
+ return modal.data.show();
1355
+ },
1356
+ onModalClose: function(modal, view) {
1357
+ return $.modal.close();
1358
+ },
1359
+ prepareLayout: function() {
1360
+ return $('body').append(this.$el);
1361
+ },
1362
+ prepareComponents: function() {
1363
+ var _this = this;
1364
+ return this.components = _(this.components).map(function(object, index) {
1365
+ object.container = _this.el;
1366
+ return object;
1367
+ });
1368
+ },
1369
+ afterInitialize: function() {
1370
+ this.$el.hide();
1371
+ if (this.renderOnInitialize) return this.render();
1372
+ },
1373
+ afterRender: function() {
1374
+ if (this.showOnRender) return this.show();
1375
+ },
1376
+ wrapper: function() {
1377
+ return $(this.$el.parent());
1378
+ },
1379
+ show: function() {
1380
+ this.trigger("before:show", this);
1381
+ return this.$el.modal(this.modalOptions);
1382
+ },
1383
+ hide: function() {
1384
+ return this.trigger("before:hide", this);
1385
+ }
1386
+ });
1387
+
1388
+ Luca.register("modal_view", "Luca.containers.ModalView");
1389
+
1390
+ }).call(this);
1391
+ (function() {
1392
+
1393
+ Luca.containers.PanelView = Luca.core.Container.extend({
1394
+ className: 'luca-ui-panel',
1395
+ initialize: function(options) {
1396
+ this.options = options != null ? options : {};
1397
+ return Luca.core.Container.prototype.initialize.apply(this, arguments);
1398
+ },
1399
+ afterLayout: function() {
1400
+ var contents;
1401
+ if (this.template) {
1402
+ contents = (Luca.templates || JST)[this.template](this);
1403
+ return this.$el.html(contents);
1404
+ }
1405
+ },
1406
+ render: function() {
1407
+ return $(this.container).append(this.$el);
1408
+ },
1409
+ afterRender: function() {
1410
+ var _ref,
1411
+ _this = this;
1412
+ if ((_ref = Luca.core.Container.prototype.afterRender) != null) {
1413
+ _ref.apply(this, arguments);
1414
+ }
1415
+ if (this.css) {
1416
+ console.log("Yes Yes Yall", this.css, this.$el);
1417
+ return _(this.css).each(function(value, property) {
1418
+ return _this.$el.css(property, value);
1419
+ });
1420
+ }
1421
+ }
1422
+ });
1423
+
1424
+ }).call(this);
1425
+ (function() {
1426
+
1427
+ Luca.containers.TabView = Luca.containers.CardView.extend({
1428
+ events: {
1429
+ "click ul.nav-tabs li": "select"
1430
+ },
1431
+ hooks: ["before:select", "after:select"],
1432
+ componentType: 'tab_view',
1433
+ className: 'luca-ui-tab-view tabbable',
1434
+ tab_position: 'top',
1435
+ tabVerticalOffset: '50px',
1436
+ initialize: function(options) {
1437
+ this.options = options != null ? options : {};
1438
+ Luca.containers.CardView.prototype.initialize.apply(this, arguments);
1439
+ _.bindAll(this, "select", "highlightSelectedTab");
1440
+ this.setupHooks(this.hooks);
1441
+ return this.bind("after:card:switch", this.highlightSelectedTab);
1442
+ },
1443
+ activeTabSelector: function() {
1444
+ return this.tabSelectors().eq(this.activeCard);
1445
+ },
1446
+ prepareLayout: function() {
1447
+ var _this = this;
1448
+ return this.card_containers = _(this.cards).map(function(card, index) {
1449
+ _this.$('.tab-content').append(Luca.templates["containers/basic"](card));
1450
+ return $("#" + card.id);
1451
+ });
1452
+ },
1453
+ beforeLayout: function() {
1454
+ this.$el.addClass("tabs-" + this.tab_position);
1455
+ if (this.tab_position === "below") {
1456
+ this.$el.append(Luca.templates["containers/tab_view"](this));
1457
+ this.$el.append(Luca.templates["containers/tab_selector_container"](this));
1458
+ } else {
1459
+ this.$el.append(Luca.templates["containers/tab_selector_container"](this));
1460
+ this.$el.append(Luca.templates["containers/tab_view"](this));
1461
+ }
1462
+ return Luca.containers.CardView.prototype.beforeLayout.apply(this, arguments);
1463
+ },
1464
+ beforeRender: function() {
1465
+ var _ref;
1466
+ if ((_ref = Luca.containers.CardView.prototype.beforeRender) != null) {
1467
+ _ref.apply(this, arguments);
1468
+ }
1469
+ this.activeTabSelector().addClass('active');
1470
+ if (Luca.enableBootstrap && this.tab_position === "left" || this.tab_position === "right") {
1471
+ this.$el.addClass('grid-12');
1472
+ this.tabContainerWrapper().addClass('grid-3');
1473
+ this.tabContentWrapper().addClass('grid-9');
1474
+ if (this.tabVerticalOffset) {
1475
+ return this.tabContainerWrapper().css('padding-top', this.tabVerticalOffset);
1476
+ }
1477
+ }
1478
+ },
1479
+ highlightSelectedTab: function() {
1480
+ this.tabSelectors().removeClass('active');
1481
+ return this.activeTabSelector().addClass('active');
1482
+ },
1483
+ select: function(e) {
1484
+ var me, my;
1485
+ me = my = $(e.currentTarget);
1486
+ this.trigger("before:select", this);
1487
+ this.activate(my.data('target'));
1488
+ return this.trigger("after:select", this);
1489
+ },
1490
+ tabContentWrapper: function() {
1491
+ return $("#" + this.cid + "-tab-view-content");
1492
+ },
1493
+ tabContainerWrapper: function() {
1494
+ return $("#" + this.cid + "-tabs-selector");
1495
+ },
1496
+ tabContainer: function() {
1497
+ return $("ul#" + this.cid + "-tabs-nav");
1498
+ },
1499
+ tabSelectors: function() {
1500
+ return $('li.tab-selector', this.tabContainer());
1501
+ }
1502
+ });
1503
+
1504
+ }).call(this);
1505
+ (function() {
1506
+
1507
+ Luca.containers.Viewport = Luca.containers.CardView.extend({
1508
+ activeItem: 0,
1509
+ className: 'luca-ui-viewport',
1510
+ fullscreen: true,
1511
+ initialize: function(options) {
1512
+ this.options = options != null ? options : {};
1513
+ Luca.core.Container.prototype.initialize.apply(this, arguments);
1514
+ if (this.fullscreen) return $('html,body').addClass('luca-ui-fullscreen');
1515
+ },
1516
+ render: function() {
1517
+ console.log("Rendering Viewport");
1518
+ return this.$el.addClass('luca-ui-viewport');
1519
+ }
1520
+ });
1521
+
1522
+ }).call(this);
1523
+ (function() {
1524
+
1525
+
1526
+
1527
+ }).call(this);
1528
+ (function() {
1529
+
1530
+ Luca.components.Template = Luca.View.extend({
1531
+ initialize: function(options) {
1532
+ this.options = options != null ? options : {};
1533
+ Luca.View.prototype.initialize.apply(this, arguments);
1534
+ if (!(this.template || this.markup)) {
1535
+ throw "Templates must specify which template / markup to use";
1536
+ }
1537
+ if (_.isString(this.templateContainer)) {
1538
+ return this.templateContainer = eval("(window || global)." + this.templateContainer);
1539
+ }
1540
+ },
1541
+ templateContainer: "Luca.templates",
1542
+ beforeRender: function() {
1543
+ if (_.isUndefined(this.templateContainer)) this.templateContainer = JST;
1544
+ return this.$el.html(this.markup || this.templateContainer[this.template](this.options));
1545
+ },
1546
+ render: function() {
1547
+ return $(this.container).append(this.$el);
1548
+ }
1549
+ });
1550
+
1551
+ Luca.register("template", "Luca.components.Template");
1552
+
1553
+ }).call(this);
1554
+ (function() {
1555
+
1556
+ Luca.Application = Luca.containers.Viewport.extend({
1557
+ components: [
1558
+ {
1559
+ ctype: 'controller',
1560
+ name: 'main_controller',
1561
+ defaultCard: 'welcome',
1562
+ components: [
1563
+ {
1564
+ ctype: 'template',
1565
+ name: 'welcome',
1566
+ template: 'sample/welcome',
1567
+ templateContainer: "Luca.templates"
1568
+ }
1569
+ ]
1570
+ }
1571
+ ],
1572
+ initialize: function(options) {
1573
+ var _this = this;
1574
+ this.options = options != null ? options : {};
1575
+ Luca.containers.Viewport.prototype.initialize.apply(this, arguments);
1576
+ this.collectionManager = new Luca.CollectionManager();
1577
+ this.state = new Backbone.Model(this.defaultState);
1578
+ return this.bind("ready", function() {
1579
+ return _this.render();
1580
+ });
1581
+ },
1582
+ activeView: function() {
1583
+ var active;
1584
+ if (active = this.activeSubSection()) {
1585
+ return this.view(active);
1586
+ } else {
1587
+ return this.view(this.activeSection());
1588
+ }
1589
+ },
1590
+ activeSubSection: function() {
1591
+ return this.get("active_sub_section");
1592
+ },
1593
+ activeSection: function() {
1594
+ return this.get("active_section");
1595
+ },
1596
+ afterComponents: function() {
1597
+ var _ref, _ref2, _ref3,
1598
+ _this = this;
1599
+ if ((_ref = Luca.containers.Viewport.prototype.afterComponents) != null) {
1600
+ _ref.apply(this, arguments);
1601
+ }
1602
+ if ((_ref2 = this.getMainController()) != null) {
1603
+ _ref2.bind("after:card:switch", function(previous, current) {
1604
+ return _this.state.set({
1605
+ active_section: current.name
1606
+ });
1607
+ });
1608
+ }
1609
+ return (_ref3 = this.getMainController()) != null ? _ref3.each(function(component) {
1610
+ if (component.ctype.match(/controller$/)) {
1611
+ return component.bind("after:card:switch", function(previous, current) {
1612
+ return _this.state.set({
1613
+ active_sub_section: current.name
1614
+ });
1615
+ });
1616
+ }
1617
+ }) : void 0;
1618
+ },
1619
+ beforeRender: function() {
1620
+ var _ref;
1621
+ return (_ref = Luca.containers.Viewport.prototype.beforeRender) != null ? _ref.apply(this, arguments) : void 0;
1622
+ },
1623
+ boot: function() {
1624
+ console.log("Sup?");
1625
+ return this.trigger("ready");
1626
+ },
1627
+ collection: function() {
1628
+ return this.collectionManager.getOrCreate.apply(this.collectionManager, arguments);
1629
+ },
1630
+ get: function(attribute) {
1631
+ return this.state.get(attribute);
1632
+ },
1633
+ getMainController: function() {
1634
+ return this.view("main_controler");
1635
+ },
1636
+ set: function(attributes) {
1637
+ return this.state.set(attributes);
1638
+ },
1639
+ view: function(name) {
1640
+ return Luca.cache(name);
1641
+ }
1642
+ });
1643
+
1644
+ }).call(this);
1645
+ (function() {
1646
+
1647
+ Luca.components.Toolbar = Luca.core.Container.extend({
1648
+ className: 'luca-ui-toolbar',
1649
+ position: 'bottom',
1650
+ initialize: function(options) {
1651
+ this.options = options != null ? options : {};
1652
+ return Luca.core.Container.prototype.initialize.apply(this, arguments);
1653
+ },
1654
+ prepareComponents: function() {
1655
+ var _this = this;
1656
+ return _(this.components).each(function(component) {
1657
+ return component.container = _this.el;
1658
+ });
1659
+ },
1660
+ render: function() {
1661
+ return $(this.container).append(this.el);
1662
+ }
1663
+ });
1664
+
1665
+ Luca.register("toolbar", "Luca.components.Toolbar");
1666
+
1667
+ }).call(this);
1668
+ (function() {
1669
+
1670
+ Luca.components.CollectionLoaderView = Luca.components.Template.extend({
1671
+ className: 'luca-ui-collection-loader-view',
1672
+ template: "components/collection_loader_view",
1673
+ initialize: function(options) {
1674
+ this.options = options != null ? options : {};
1675
+ Luca.components.Template.prototype.initialize.apply(this, arguments);
1676
+ this.container || (this.container = $('body'));
1677
+ this.manager || (this.manager = Luca.CollectionManager.get());
1678
+ return this.setupBindings();
1679
+ },
1680
+ modalContainer: function() {
1681
+ return $("#progress-modal", this.el);
1682
+ },
1683
+ setupBindings: function() {
1684
+ var _this = this;
1685
+ this.manager.bind("collection_loaded", function(name) {
1686
+ var loaded, progress, total;
1687
+ loaded = _this.manager.loadedCollectionsCount();
1688
+ total = _this.manager.totalCollectionsCount();
1689
+ progress = parseInt((loaded / total) * 100);
1690
+ _this.modalContainer().find('.progress .bar').attr("style", "width: " + progress + "%;");
1691
+ return _this.modalContainer().find('.message').html("Loaded " + (_(name).chain().humanize().titleize().value()) + "...");
1692
+ });
1693
+ return this.manager.bind("all_collections_loaded", function() {
1694
+ _this.modalContainer().find('.message').html("All done!");
1695
+ return _.delay(function() {
1696
+ return _this.modalContainer().modal('hide');
1697
+ }, 400);
1698
+ });
1699
+ }
1700
+ });
1701
+
1702
+ Luca.register("collection_loader_view", "Luca.components.CollectionLoaderView");
1703
+
1704
+ }).call(this);
1705
+ (function() {
1706
+
1707
+ Luca.components.Controller = Luca.containers.CardView.extend({
1708
+ initialize: function(options) {
1709
+ var _ref;
1710
+ this.options = options;
1711
+ Luca.containers.CardView.prototype.initialize.apply(this, arguments);
1712
+ this.defaultCard || (this.defaultCard = (_ref = this.components[0]) != null ? _ref.name : void 0);
1713
+ if (!this.defaultCard) {
1714
+ throw "Controllers must specify a defaultCard property and/or the first component must have a name";
1715
+ }
1716
+ return this.state = new Backbone.Model({
1717
+ active_section: this.defaultCard
1718
+ });
1719
+ },
1720
+ each: function(fn) {
1721
+ var _this = this;
1722
+ return _(this.components).each(function(component) {
1723
+ return fn.apply(_this, [component]);
1724
+ });
1725
+ },
1726
+ "default": function(callback) {
1727
+ return this.navigate_to(this.defaultCard, callback);
1728
+ },
1729
+ navigate_to: function(section, callback) {
1730
+ var _this = this;
1731
+ section || (section = this.defaultCard);
1732
+ this.activate(section, false, function(activator, previous, current) {
1733
+ _this.state.set({
1734
+ active_section: current.name
1735
+ });
1736
+ if (_.isFunction(callback)) return callback.apply(current);
1737
+ });
1738
+ return this.find(section);
1739
+ }
1740
+ });
1741
+
1742
+ }).call(this);
1743
+ (function() {
1744
+
1745
+ Luca.fields.ButtonField = Luca.core.Field.extend({
1746
+ form_field: true,
1747
+ readOnly: true,
1748
+ events: {
1749
+ "click input": "click_handler"
1750
+ },
1751
+ hooks: ["button:click"],
1752
+ className: 'luca-ui-field luca-ui-button-field',
1753
+ template: 'fields/button_field',
1754
+ click_handler: function(e) {
1755
+ var me, my;
1756
+ me = my = $(e.currentTarget);
1757
+ return this.trigger("button:click");
1758
+ },
1759
+ initialize: function(options) {
1760
+ var _ref;
1761
+ this.options = options != null ? options : {};
1762
+ _.extend(this.options);
1763
+ _.bindAll(this, "click_handler");
1764
+ Luca.core.Field.prototype.initialize.apply(this, arguments);
1765
+ if ((_ref = this.icon_class) != null ? _ref.length : void 0) {
1766
+ return this.template = "fields/button_field_link";
1767
+ }
1768
+ },
1769
+ afterInitialize: function() {
1770
+ this.input_id || (this.input_id = _.uniqueId('button'));
1771
+ this.input_name || (this.input_name = this.name || (this.name = this.input_id));
1772
+ this.input_value || (this.input_value = this.label || (this.label = this.text));
1773
+ this.input_type || (this.input_type = "button");
1774
+ this.input_class || (this.input_class = this["class"]);
1775
+ this.icon_class || (this.icon_class = "");
1776
+ if (this.icon_class.length && !this.icon_class.match(/^icon-/)) {
1777
+ return this.icon_class = "icon-" + this.icon_class;
1778
+ }
1779
+ },
1780
+ setValue: function() {
1781
+ return true;
1782
+ }
1783
+ });
1784
+
1785
+ Luca.register("button_field", "Luca.fields.ButtonField");
1786
+
1787
+ }).call(this);
1788
+ (function() {
1789
+
1790
+ Luca.fields.CheckboxField = Luca.core.Field.extend({
1791
+ form_field: true,
1792
+ events: {
1793
+ "change input": "change_handler"
1794
+ },
1795
+ change_handler: function(e) {
1796
+ var me, my;
1797
+ me = my = $(e.currentTarget);
1798
+ this.trigger("on:change", this, e);
1799
+ if (me.checked === true) {
1800
+ return this.trigger("checked");
1801
+ } else {
1802
+ return this.trigger("unchecked");
1803
+ }
1804
+ },
1805
+ className: 'luca-ui-checkbox-field luca-ui-field',
1806
+ template: 'fields/checkbox_field',
1807
+ hooks: ["checked", "unchecked"],
1808
+ initialize: function(options) {
1809
+ this.options = options != null ? options : {};
1810
+ _.extend(this, this.options);
1811
+ _.bindAll(this, "change_handler");
1812
+ return Luca.core.Field.prototype.initialize.apply(this, arguments);
1813
+ },
1814
+ afterInitialize: function() {
1815
+ this.input_id || (this.input_id = _.uniqueId('field'));
1816
+ this.input_name || (this.input_name = this.name);
1817
+ this.input_value || (this.input_value = 1);
1818
+ return this.label || (this.label = this.name);
1819
+ },
1820
+ setValue: function(checked) {
1821
+ return this.input.attr('checked', checked);
1822
+ },
1823
+ getValue: function() {
1824
+ return this.input.attr('checked') === true;
1825
+ }
1826
+ });
1827
+
1828
+ Luca.register("checkbox_field", "Luca.fields.CheckboxField");
1829
+
1830
+ }).call(this);
1831
+ (function() {
1832
+
1833
+ Luca.fields.FileUploadField = Luca.core.Field.extend({
1834
+ form_field: true,
1835
+ template: 'fields/file_upload_field',
1836
+ initialize: function(options) {
1837
+ this.options = options != null ? options : {};
1838
+ return Luca.core.Field.prototype.initialize.apply(this, arguments);
1839
+ },
1840
+ afterInitialize: function() {
1841
+ this.input_id || (this.input_id = _.uniqueId('field'));
1842
+ this.input_name || (this.input_name = this.name);
1843
+ this.label || (this.label = this.name);
1844
+ return this.helperText || (this.helperText = "");
1845
+ }
1846
+ });
1847
+
1848
+ Luca.register("file_upload_field", "Luca.fields.FileUploadField");
1849
+
1850
+ }).call(this);
1851
+ (function() {
1852
+
1853
+ Luca.fields.HiddenField = Luca.core.Field.extend({
1854
+ form_field: true,
1855
+ template: 'fields/hidden_field',
1856
+ initialize: function(options) {
1857
+ this.options = options != null ? options : {};
1858
+ return Luca.core.Field.prototype.initialize.apply(this, arguments);
1859
+ },
1860
+ afterInitialize: function() {
1861
+ this.input_id || (this.input_id = _.uniqueId('field'));
1862
+ this.input_name || (this.input_name = this.name);
1863
+ this.input_value || (this.input_value = this.value);
1864
+ return this.label || (this.label = this.name);
1865
+ }
1866
+ });
1867
+
1868
+ Luca.register("hidden_field", "Luca.fields.HiddenField");
1869
+
1870
+ }).call(this);
1871
+ (function() {
1872
+
1873
+ Luca.fields.SelectField = Luca.core.Field.extend({
1874
+ form_field: true,
1875
+ events: {
1876
+ "change select": "change_handler"
1877
+ },
1878
+ hooks: ["after:select"],
1879
+ className: 'luca-ui-select-field luca-ui-field',
1880
+ template: "fields/select_field",
1881
+ includeBlank: true,
1882
+ blankValue: '',
1883
+ blankText: 'Select One',
1884
+ initialize: function(options) {
1885
+ this.options = options != null ? options : {};
1886
+ _.extend(this, this.options);
1887
+ _.extend(this, Luca.modules.Deferrable);
1888
+ _.bindAll(this, "change_handler", "populateOptions", "beforeFetch");
1889
+ Luca.core.Field.prototype.initialize.apply(this, arguments);
1890
+ this.input_id || (this.input_id = _.uniqueId('field'));
1891
+ this.input_name || (this.input_name = this.name);
1892
+ this.label || (this.label = this.name);
1893
+ if (_.isUndefined(this.retainValue)) return this.retainValue = true;
1894
+ },
1895
+ afterInitialize: function() {
1896
+ var _ref;
1897
+ if ((_ref = this.collection) != null ? _ref.data : void 0) {
1898
+ this.valueField || (this.valueField = "id");
1899
+ this.displayField || (this.displayField = "name");
1900
+ this.parseData();
1901
+ }
1902
+ try {
1903
+ this.configure_collection();
1904
+ } catch (e) {
1905
+ console.log("Error Configuring Collection", this, e.message);
1906
+ }
1907
+ this.collection.bind("before:fetch", this.beforeFetch);
1908
+ return this.collection.bind("reset", this.populateOptions);
1909
+ },
1910
+ parseData: function() {
1911
+ var _this = this;
1912
+ return this.collection.data = _(this.collection.data).map(function(record) {
1913
+ var hash;
1914
+ if (!_.isArray(record)) return record;
1915
+ hash = {};
1916
+ hash[_this.valueField] = record[0];
1917
+ hash[_this.displayField] = record[1];
1918
+ return hash;
1919
+ });
1920
+ },
1921
+ afterRender: function() {
1922
+ var _ref, _ref2;
1923
+ this.input = $('select', this.el);
1924
+ if (((_ref = this.collection) != null ? (_ref2 = _ref.models) != null ? _ref2.length : void 0 : void 0) > 0) {
1925
+ return this.populateOptions();
1926
+ } else {
1927
+ return this.collection.trigger("reset");
1928
+ }
1929
+ },
1930
+ setValue: function(value) {
1931
+ this.currentValue = value;
1932
+ return Luca.core.Field.prototype.setValue.apply(this, arguments);
1933
+ },
1934
+ beforeFetch: function() {
1935
+ return this.resetOptions();
1936
+ },
1937
+ change_handler: function(e) {
1938
+ return this.trigger("on:change", this, e);
1939
+ },
1940
+ resetOptions: function() {
1941
+ this.input.html('');
1942
+ if (this.includeBlank) {
1943
+ return this.input.append("<option value='" + this.blankValue + "'>" + this.blankText + "</option>");
1944
+ }
1945
+ },
1946
+ populateOptions: function() {
1947
+ var _ref,
1948
+ _this = this;
1949
+ this.resetOptions();
1950
+ if (((_ref = this.collection) != null ? _ref.each : void 0) != null) {
1951
+ this.collection.each(function(model) {
1952
+ var display, option, selected, value;
1953
+ value = model.get(_this.valueField);
1954
+ display = model.get(_this.displayField);
1955
+ if (_this.selected && value === _this.selected) selected = "selected";
1956
+ option = "<option " + selected + " value='" + value + "'>" + display + "</option>";
1957
+ return _this.input.append(option);
1958
+ });
1959
+ }
1960
+ this.trigger("after:populate:options", this);
1961
+ return this.setValue(this.currentValue);
1962
+ }
1963
+ });
1964
+
1965
+ Luca.register("select_field", "Luca.fields.SelectField");
1966
+
1967
+ }).call(this);
1968
+ (function() {
1969
+
1970
+ Luca.fields.TextAreaField = Luca.core.Field.extend({
1971
+ form_field: true,
1972
+ events: {
1973
+ "keydown input": "keydown_handler",
1974
+ "blur input": "blur_handler",
1975
+ "focus input": "focus_handler"
1976
+ },
1977
+ template: 'fields/text_area_field',
1978
+ height: "200px",
1979
+ width: "90%",
1980
+ initialize: function(options) {
1981
+ this.options = options != null ? options : {};
1982
+ _.bindAll(this, "keydown_handler");
1983
+ Luca.core.Field.prototype.initialize.apply(this, arguments);
1984
+ this.input_id || (this.input_id = _.uniqueId('field'));
1985
+ this.input_name || (this.input_name = this.name);
1986
+ this.label || (this.label = this.name);
1987
+ this.input_class || (this.input_class = this["class"]);
1988
+ return this.inputStyles || (this.inputStyles = "height:" + this.height + ";width:" + this.width);
1989
+ },
1990
+ setValue: function(value) {
1991
+ return $(this.field()).val(value);
1992
+ },
1993
+ getValue: function() {
1994
+ return $(this.field()).val();
1995
+ },
1996
+ field: function() {
1997
+ return this.input = $("textarea#" + this.input_id, this.el);
1998
+ },
1999
+ keydown_handler: function(e) {
2000
+ var me, my;
2001
+ return me = my = $(e.currentTarget);
2002
+ },
2003
+ blur_handler: function(e) {
2004
+ var me, my;
2005
+ return me = my = $(e.currentTarget);
2006
+ },
2007
+ focus_handler: function(e) {
2008
+ var me, my;
2009
+ return me = my = $(e.currentTarget);
2010
+ }
2011
+ });
2012
+
2013
+ Luca.register("text_area_field", "Luca.fields.TextAreaField");
2014
+
2015
+ }).call(this);
2016
+ (function() {
2017
+
2018
+ Luca.fields.TextField = Luca.core.Field.extend({
2019
+ form_field: true,
2020
+ events: {
2021
+ "keydown input": "keydown_handler",
2022
+ "blur input": "blur_handler",
2023
+ "focus input": "focus_handler",
2024
+ "change input": "change_handler"
2025
+ },
2026
+ template: 'fields/text_field',
2027
+ initialize: function(options) {
2028
+ this.options = options != null ? options : {};
2029
+ _.bindAll(this, "keydown_handler", "blur_handler", "focus_handler");
2030
+ Luca.core.Field.prototype.initialize.apply(this, arguments);
2031
+ this.input_id || (this.input_id = _.uniqueId('field'));
2032
+ this.input_name || (this.input_name = this.name);
2033
+ this.label || (this.label = this.name);
2034
+ if (this.prepend) {
2035
+ this.$el.addClass('input-prepend');
2036
+ this.addOn = this.prepend;
2037
+ }
2038
+ if (this.append) {
2039
+ this.$el.addClass('input-append');
2040
+ return this.addOn = this.append;
2041
+ }
2042
+ },
2043
+ keydown_handler: _.throttle((function(e) {
2044
+ return this.change_handler.apply(this, arguments);
2045
+ }), 300),
2046
+ blur_handler: function(e) {
2047
+ var me, my;
2048
+ return me = my = $(e.currentTarget);
2049
+ },
2050
+ focus_handler: function(e) {
2051
+ var me, my;
2052
+ return me = my = $(e.currentTarget);
2053
+ },
2054
+ change_handler: function(e) {
2055
+ return this.trigger("on:change", this, e);
2056
+ }
2057
+ });
2058
+
2059
+ Luca.register("text_field", "Luca.fields.TextField");
2060
+
2061
+ }).call(this);
2062
+ (function() {
2063
+
2064
+ Luca.fields.TypeAheadField = Luca.fields.TextField.extend({
2065
+ form_field: true,
2066
+ className: 'luca-ui-field',
2067
+ afterInitialize: function() {
2068
+ this.input_id || (this.input_id = _.uniqueId('field'));
2069
+ this.input_name || (this.input_name = this.name);
2070
+ return this.label || (this.label = this.name);
2071
+ }
2072
+ });
2073
+
2074
+ }).call(this);
2075
+ (function() {
2076
+
2077
+ Luca.components.FormButtonToolbar = Luca.components.Toolbar.extend({
2078
+ className: 'luca-ui-form-toolbar form-actions',
2079
+ position: 'bottom',
2080
+ includeReset: false,
2081
+ render: function() {
2082
+ return $(this.container).append(this.el);
2083
+ },
2084
+ initialize: function(options) {
2085
+ this.options = options != null ? options : {};
2086
+ Luca.components.Toolbar.prototype.initialize.apply(this, arguments);
2087
+ this.components = [
2088
+ {
2089
+ ctype: 'button_field',
2090
+ label: 'Submit',
2091
+ "class": 'btn submit-button'
2092
+ }
2093
+ ];
2094
+ if (this.includeReset) {
2095
+ return this.components.push({
2096
+ ctype: 'button_field',
2097
+ label: 'Reset',
2098
+ "class": 'btn reset-button'
2099
+ });
2100
+ }
2101
+ }
2102
+ });
2103
+
2104
+ Luca.register("form_button_toolbar", "Luca.components.FormButtonToolbar");
2105
+
2106
+ }).call(this);
2107
+ (function() {
2108
+
2109
+ Luca.components.FormView = Luca.core.Container.extend({
2110
+ tagName: 'form',
2111
+ className: 'luca-ui-form-view',
2112
+ hooks: ["before:submit", "before:reset", "before:load", "before:load:new", "before:load:existing", "after:submit", "after:reset", "after:load", "after:load:new", "after:load:existing", "after:submit:success", "after:submit:fatal_error", "after:submit:error"],
2113
+ events: {
2114
+ "click .submit-button": "submitHandler",
2115
+ "click .reset-button": "resetHandler"
2116
+ },
2117
+ toolbar: true,
2118
+ initialize: function(options) {
2119
+ this.options = options != null ? options : {};
2120
+ Luca.core.Container.prototype.initialize.apply(this, arguments);
2121
+ _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars");
2122
+ this.state || (this.state = new Backbone.Model);
2123
+ this.setupHooks(this.hooks);
2124
+ this.legend || (this.legend = "");
2125
+ this.configureToolbars();
2126
+ return this.applyStyles();
2127
+ },
2128
+ addBootstrapFormControls: function() {
2129
+ var _this = this;
2130
+ return this.bind("after:render", function() {
2131
+ var el;
2132
+ el = _this.$('.toolbar-container.bottom');
2133
+ el.addClass('form-controls');
2134
+ return el.html(_this.formControlsTemplate || Luca.templates["components/bootstrap_form_controls"](_this));
2135
+ });
2136
+ },
2137
+ applyStyles: function() {
2138
+ if (Luca.enableBootstrap) this.applyBootstrapStyles();
2139
+ if (this.labelAlign) this.$el.addClass("label-align-" + this.labelAlign);
2140
+ if (this.fieldLayoutClass) return this.$el.addClass(this.fieldLayoutClass);
2141
+ },
2142
+ applyBootstrapStyles: function() {
2143
+ if (this.labelAlign === "left") this.inlineForm = true;
2144
+ if (this.well) this.$el.addClass('well');
2145
+ if (this.searchForm) this.$el.addClass('form-search');
2146
+ if (this.horizontalForm) this.$el.addClass('form-horizontal');
2147
+ if (this.inlineForm) return this.$el.addClass('form-inline');
2148
+ },
2149
+ configureToolbars: function() {
2150
+ if (Luca.enableBootstrap && this.toolbar === true) {
2151
+ return this.addBootstrapFormControls();
2152
+ }
2153
+ if (this.toolbar === true) {
2154
+ this.toolbars = [
2155
+ {
2156
+ ctype: 'form_button_toolbar',
2157
+ includeReset: true,
2158
+ position: 'bottom'
2159
+ }
2160
+ ];
2161
+ }
2162
+ if (this.toolbars && this.toolbars.length) {
2163
+ return this.bind("after:render", _.once(this.renderToolbars));
2164
+ }
2165
+ },
2166
+ resetHandler: function(e) {
2167
+ var me, my;
2168
+ me = my = $(e.currentTarget);
2169
+ this.trigger("before:reset", this);
2170
+ this.reset();
2171
+ return this.trigger("after:reset", this);
2172
+ },
2173
+ submitHandler: function(e) {
2174
+ var me, my;
2175
+ me = my = $(e.currentTarget);
2176
+ this.trigger("before:submit", this);
2177
+ return this.submit();
2178
+ },
2179
+ beforeLayout: function() {
2180
+ var _ref;
2181
+ if ((_ref = Luca.core.Container.prototype.beforeLayout) != null) {
2182
+ _ref.apply(this, arguments);
2183
+ }
2184
+ return this.$el.html(Luca.templates["components/form_view"](this));
2185
+ },
2186
+ prepareComponents: function() {
2187
+ var container;
2188
+ container = $('.form-view-body', this.el);
2189
+ return _(this.components).each(function(component) {
2190
+ return component.container = container;
2191
+ });
2192
+ },
2193
+ render: function() {
2194
+ return $(this.container).append(this.$el);
2195
+ },
2196
+ wrapper: function() {
2197
+ return this.$el.parents('.luca-ui-form-view-wrapper');
2198
+ },
2199
+ toolbarContainers: function(position) {
2200
+ if (position == null) position = "bottom";
2201
+ return $(".toolbar-container." + position, this.wrapper()).first();
2202
+ },
2203
+ renderToolbars: function() {
2204
+ var _this = this;
2205
+ return _(this.toolbars).each(function(toolbar) {
2206
+ toolbar.container = $("#" + _this.cid + "-" + toolbar.position + "-toolbar-container");
2207
+ toolbar = Luca.util.lazyComponent(toolbar);
2208
+ return toolbar.render();
2209
+ });
2210
+ },
2211
+ getField: function(name) {
2212
+ return _(this.getFields('name', name)).first();
2213
+ },
2214
+ getFields: function(attr, value) {
2215
+ var fields;
2216
+ fields = this.select("isField", true, true);
2217
+ if (fields.length > 0 && attr && value) {
2218
+ fields = _(fields).select(function(field) {
2219
+ var property, propvalue;
2220
+ property = field[attr];
2221
+ if (property == null) return false;
2222
+ propvalue = _.isFunction(property) ? property() : property;
2223
+ return value === propvalue;
2224
+ });
2225
+ }
2226
+ return fields;
2227
+ },
2228
+ loadModel: function(current_model) {
2229
+ var event, fields, form,
2230
+ _this = this;
2231
+ this.current_model = current_model;
2232
+ form = this;
2233
+ fields = this.getFields();
2234
+ this.trigger("before:load", this, this.current_model);
2235
+ if (this.current_model) {
2236
+ event = "before:load:" + (this.current_model.isNew() ? "new" : "existing");
2237
+ this.trigger(event, this, this.current_model);
2238
+ }
2239
+ _(fields).each(function(field) {
2240
+ var field_name, value;
2241
+ field_name = field.input_name || field.name;
2242
+ value = _.isFunction(_this.current_model[field_name]) ? _this.current_model[field_name].apply(_this, form) : _this.current_model.get(field_name);
2243
+ if (field.readOnly !== true) {
2244
+ return field != null ? field.setValue(value) : void 0;
2245
+ }
2246
+ });
2247
+ this.trigger("after:load", this, this.current_model);
2248
+ if (this.current_model) {
2249
+ return this.trigger("after:load:" + (this.current_model.isNew() ? "new" : "existing"), this, this.current_model);
2250
+ }
2251
+ },
2252
+ reset: function() {
2253
+ return this.loadModel(this.current_model);
2254
+ },
2255
+ clear: function() {
2256
+ var _this = this;
2257
+ this.current_model = this.defaultModel != null ? this.defaultModel() : void 0;
2258
+ return _(this.getFields()).each(function(field) {
2259
+ try {
2260
+ return field.setValue('');
2261
+ } catch (e) {
2262
+ return console.log("Error Clearing", _this, field);
2263
+ }
2264
+ });
2265
+ },
2266
+ getValues: function(reject_blank, skip_buttons) {
2267
+ if (reject_blank == null) reject_blank = false;
2268
+ if (skip_buttons == null) skip_buttons = true;
2269
+ return _(this.getFields()).inject(function(memo, field) {
2270
+ var skip, value;
2271
+ value = field.getValue();
2272
+ skip = false;
2273
+ if (skip_buttons && field.ctype === "button_field") skip = true;
2274
+ if (reject_blank && _.isBlank(value)) skip = true;
2275
+ if (field.input_name === "id" && _.isBlank(value)) skip = true;
2276
+ if (!skip) memo[field.input_name || name] = value;
2277
+ return memo;
2278
+ }, {});
2279
+ },
2280
+ submit_success_handler: function(model, response, xhr) {
2281
+ this.trigger("after:submit", this, model, response);
2282
+ if (response && response.success) {
2283
+ return this.trigger("after:submit:success", this, model, response);
2284
+ } else {
2285
+ return this.trigger("after:submit:error", this, model, response);
2286
+ }
2287
+ },
2288
+ submit_fatal_error_handler: function() {
2289
+ this.trigger.apply(["after:submit", this].concat(arguments));
2290
+ return this.trigger.apply(["after:submit:fatal_error", this].concat(arguments));
2291
+ },
2292
+ submit: function(save, saveOptions) {
2293
+ if (save == null) save = true;
2294
+ if (saveOptions == null) saveOptions = {};
2295
+ _.bindAll(this, "submit_success_handler", "submit_fatal_error_handler");
2296
+ saveOptions.success || (saveOptions.success = this.submit_success_handler);
2297
+ saveOptions.error || (saveOptions.error = this.submit_fatal_error_handler);
2298
+ this.current_model.set(this.getValues());
2299
+ if (!save) return;
2300
+ return this.current_model.save(this.current_model.toJSON(), saveOptions);
2301
+ },
2302
+ currentModel: function() {
2303
+ return this.current_model;
2304
+ },
2305
+ setLegend: function(legend) {
2306
+ this.legend = legend;
2307
+ return $('fieldset legend', this.el).first().html(this.legend);
2308
+ }
2309
+ });
2310
+
2311
+ Luca.register('form_view', 'Luca.components.FormView');
2312
+
2313
+ }).call(this);
2314
+ (function() {
2315
+
2316
+ Luca.components.GridView = Luca.View.extend({
2317
+ events: {
2318
+ "dblclick .grid-view-row": "double_click_handler",
2319
+ "click .grid-view-row": "click_handler"
2320
+ },
2321
+ className: 'luca-ui-grid-view',
2322
+ scrollable: true,
2323
+ emptyText: 'No Results To display',
2324
+ tableStyle: 'striped',
2325
+ hooks: ["before:grid:render", "before:render:header", "before:render:row", "after:grid:render", "row:double:click", "row:click", "after:collection:load"],
2326
+ initialize: function(options) {
2327
+ var _this = this;
2328
+ this.options = options != null ? options : {};
2329
+ _.extend(this, this.options);
2330
+ _.extend(this, Luca.modules.Deferrable);
2331
+ Luca.View.prototype.initialize.apply(this, arguments);
2332
+ _.bindAll(this, "double_click_handler", "click_handler");
2333
+ this.configure_collection();
2334
+ return this.collection.bind("reset", function(collection) {
2335
+ _this.refresh();
2336
+ return _this.trigger("after:collection:load", collection);
2337
+ });
2338
+ },
2339
+ beforeRender: function() {
2340
+ var _ref,
2341
+ _this = this;
2342
+ this.trigger("before:grid:render", this);
2343
+ if (this.scrollable) this.$el.addClass('scrollable-grid-view');
2344
+ this.$el.html(Luca.templates["components/grid_view"]());
2345
+ this.table = $('table.luca-ui-grid-view', this.el);
2346
+ this.header = $("thead", this.table);
2347
+ this.body = $("tbody", this.table);
2348
+ this.footer = $("tfoot", this.table);
2349
+ if (Luca.enableBootstrap) this.table.addClass('table');
2350
+ _((_ref = this.tableStyle) != null ? _ref.split(" ") : void 0).each(function(style) {
2351
+ return _this.table.addClass("table-" + style);
2352
+ });
2353
+ if (this.scrollable) this.setDimensions();
2354
+ this.renderHeader();
2355
+ this.emptyMessage();
2356
+ this.renderToolbars();
2357
+ return $(this.container).append(this.$el);
2358
+ },
2359
+ toolbarContainers: function(position) {
2360
+ if (position == null) position = "bottom";
2361
+ return $(".toolbar-container." + position, this.el);
2362
+ },
2363
+ renderToolbars: function() {
2364
+ var _this = this;
2365
+ return _(this.toolbars).each(function(toolbar) {
2366
+ toolbar = Luca.util.lazyComponent(toolbar);
2367
+ toolbar.container = _this.toolbarContainers(toolbar.position);
2368
+ return toolbar.render();
2369
+ });
2370
+ },
2371
+ setDimensions: function(offset) {
2372
+ var _this = this;
2373
+ this.height || (this.height = 285);
2374
+ $('.grid-view-body', this.el).height(this.height);
2375
+ $('tbody.scrollable', this.el).height(this.height - 23);
2376
+ this.container_width = (function() {
2377
+ return $(_this.container).width();
2378
+ })();
2379
+ this.width = this.container_width > 0 ? this.container_width : 756;
2380
+ $('.grid-view-body', this.el).width(this.width);
2381
+ $('.grid-view-body table', this.el).width(this.width);
2382
+ return this.setDefaultColumnWidths();
2383
+ },
2384
+ resize: function(newWidth) {
2385
+ var difference, distribution,
2386
+ _this = this;
2387
+ difference = newWidth - this.width;
2388
+ this.width = newWidth;
2389
+ $('.grid-view-body', this.el).width(this.width);
2390
+ $('.grid-view-body table', this.el).width(this.width);
2391
+ if (this.columns.length > 0) {
2392
+ distribution = difference / this.columns.length;
2393
+ return _(this.columns).each(function(col, index) {
2394
+ var column;
2395
+ column = $(".column-" + index, _this.el);
2396
+ return column.width(col.width = col.width + distribution);
2397
+ });
2398
+ }
2399
+ },
2400
+ padLastColumn: function() {
2401
+ var configured_column_widths, unused_width;
2402
+ configured_column_widths = _(this.columns).inject(function(sum, column) {
2403
+ return sum = column.width + sum;
2404
+ }, 0);
2405
+ unused_width = this.width - configured_column_widths;
2406
+ if (unused_width > 0) return this.lastColumn().width += unused_width;
2407
+ },
2408
+ setDefaultColumnWidths: function() {
2409
+ var default_column_width;
2410
+ default_column_width = this.columns.length > 0 ? this.width / this.columns.length : 200;
2411
+ _(this.columns).each(function(column) {
2412
+ return parseInt(column.width || (column.width = default_column_width));
2413
+ });
2414
+ return this.padLastColumn();
2415
+ },
2416
+ lastColumn: function() {
2417
+ return this.columns[this.columns.length - 1];
2418
+ },
2419
+ afterRender: function() {
2420
+ this.refresh();
2421
+ return this.trigger("after:grid:render", this);
2422
+ },
2423
+ emptyMessage: function(text) {
2424
+ if (text == null) text = "";
2425
+ text || (text = this.emptyText);
2426
+ this.body.html('');
2427
+ return this.body.append(Luca.templates["components/grid_view_empty_text"]({
2428
+ colspan: this.columns.length,
2429
+ text: text
2430
+ }));
2431
+ },
2432
+ refresh: function() {
2433
+ var _this = this;
2434
+ this.body.html('');
2435
+ this.collection.each(function(model, index) {
2436
+ return _this.render_row.apply(_this, [model, index]);
2437
+ });
2438
+ if (this.collection.models.length === 0) return this.emptyMessage();
2439
+ },
2440
+ ifLoaded: function(fn, scope) {
2441
+ scope || (scope = this);
2442
+ fn || (fn = function() {
2443
+ return true;
2444
+ });
2445
+ return this.collection.ifLoaded(fn, scope);
2446
+ },
2447
+ applyFilter: function(values, options) {
2448
+ if (options == null) {
2449
+ options = {
2450
+ auto: true,
2451
+ refresh: true
2452
+ };
2453
+ }
2454
+ return this.collection.applyFilter(values, options);
2455
+ },
2456
+ renderHeader: function() {
2457
+ var headers,
2458
+ _this = this;
2459
+ this.trigger("before:render:header");
2460
+ headers = _(this.columns).map(function(column, column_index) {
2461
+ var style;
2462
+ style = column.width ? "width:" + column.width + "px;" : "";
2463
+ return "<th style='" + style + "' class='column-" + column_index + "'>" + column.header + "</th>";
2464
+ });
2465
+ return this.header.append("<tr>" + headers + "</tr>");
2466
+ },
2467
+ render_row: function(row, row_index) {
2468
+ var alt_class, cells, model_id, _ref,
2469
+ _this = this;
2470
+ model_id = (row != null ? row.get : void 0) && (row != null ? row.attributes : void 0) ? row.get('id') : '';
2471
+ this.trigger("before:render:row", row, row_index);
2472
+ cells = _(this.columns).map(function(column, col_index) {
2473
+ var display, style, value;
2474
+ value = _this.cell_renderer(row, column, col_index);
2475
+ style = column.width ? "width:" + column.width + "px;" : "";
2476
+ display = _.isUndefined(value) ? "" : value;
2477
+ return "<td style='" + style + "' class='column-" + col_index + "'>" + display + "</td>";
2478
+ });
2479
+ if (this.alternateRowClasses) {
2480
+ alt_class = row_index % 2 === 0 ? "even" : "odd";
2481
+ }
2482
+ return (_ref = this.body) != null ? _ref.append("<tr data-record-id='" + model_id + "' data-row-index='" + row_index + "' class='grid-view-row " + alt_class + "' id='row-" + row_index + "'>" + cells + "</tr>") : void 0;
2483
+ },
2484
+ cell_renderer: function(row, column, columnIndex) {
2485
+ var source;
2486
+ if (_.isFunction(column.renderer)) {
2487
+ return column.renderer.apply(this, [row, column, columnIndex]);
2488
+ } else if (column.data.match(/\w+\.\w+/)) {
2489
+ source = row.attributes || row;
2490
+ return Luca.util.nestedValue(column.data, source);
2491
+ } else {
2492
+ return (typeof row.get === "function" ? row.get(column.data) : void 0) || row[column.data];
2493
+ }
2494
+ },
2495
+ double_click_handler: function(e) {
2496
+ var me, my, record, rowIndex;
2497
+ me = my = $(e.currentTarget);
2498
+ rowIndex = my.data('row-index');
2499
+ record = this.collection.at(rowIndex);
2500
+ return this.trigger("row:double:click", this, record, rowIndex);
2501
+ },
2502
+ click_handler: function(e) {
2503
+ var me, my, record, rowIndex;
2504
+ me = my = $(e.currentTarget);
2505
+ rowIndex = my.data('row-index');
2506
+ record = this.collection.at(rowIndex);
2507
+ this.trigger("row:click", this, record, rowIndex);
2508
+ $('.grid-view-row', this.body).removeClass('selected-row');
2509
+ return me.addClass('selected-row');
2510
+ }
2511
+ });
2512
+
2513
+ Luca.register("grid_view", "Luca.components.GridView");
2514
+
2515
+ }).call(this);
2516
+ (function() {
2517
+
2518
+ Luca.components.RecordManager = Luca.containers.CardView.extend({
2519
+ events: {
2520
+ "click .record-manager-grid .edit-link": "edit_handler",
2521
+ "click .record-manager-filter .filter-button": "filter_handler",
2522
+ "click .record-manager-filter .reset-button": "reset_filter_handler",
2523
+ "click .add-button": "add_handler",
2524
+ "click .refresh-button": "filter_handler",
2525
+ "click .back-to-search-button": "back_to_search_handler"
2526
+ },
2527
+ record_manager: true,
2528
+ initialize: function(options) {
2529
+ var _this = this;
2530
+ this.options = options != null ? options : {};
2531
+ Luca.containers.CardView.prototype.initialize.apply(this, arguments);
2532
+ if (!this.name) throw "Record Managers must specify a name";
2533
+ _.bindAll(this, "add_handler", "edit_handler", "filter_handler", "reset_filter_handler");
2534
+ if (this.filterConfig) _.extend(this.components[0][0], this.filterConfig);
2535
+ if (this.gridConfig) _.extend(this.components[0][1], this.gridConfig);
2536
+ if (this.editorConfig) _.extend(this.components[1][0], this.editorConfig);
2537
+ return this.bind("after:card:switch", function() {
2538
+ if (_this.activeCard === 0) _this.trigger("activation:search", _this);
2539
+ if (_this.activeCard === 1) {
2540
+ return _this.trigger("activation:editor", _this);
2541
+ }
2542
+ });
2543
+ },
2544
+ components: [
2545
+ {
2546
+ ctype: 'split_view',
2547
+ relayFirstActivation: true,
2548
+ components: [
2549
+ {
2550
+ ctype: 'form_view'
2551
+ }, {
2552
+ ctype: 'grid_view'
2553
+ }
2554
+ ]
2555
+ }, {
2556
+ ctype: 'form_view'
2557
+ }
2558
+ ],
2559
+ getSearch: function(activate, reset) {
2560
+ if (activate == null) activate = false;
2561
+ if (reset == null) reset = true;
2562
+ if (activate === true) this.activate(0);
2563
+ if (reset === true) this.getEditor().clear();
2564
+ return _.first(this.components);
2565
+ },
2566
+ getFilter: function() {
2567
+ return _.first(this.getSearch().components);
2568
+ },
2569
+ getGrid: function() {
2570
+ return _.last(this.getSearch().components);
2571
+ },
2572
+ getCollection: function() {
2573
+ return this.getGrid().collection;
2574
+ },
2575
+ getEditor: function(activate, reset) {
2576
+ var _this = this;
2577
+ if (activate == null) activate = false;
2578
+ if (reset == null) reset = false;
2579
+ if (activate === true) {
2580
+ this.activate(1, function(activator, previous, current) {
2581
+ return current.reset();
2582
+ });
2583
+ }
2584
+ return _.last(this.components);
2585
+ },
2586
+ beforeRender: function() {
2587
+ var _ref;
2588
+ this.$el.addClass("" + this.resource + "-manager");
2589
+ if ((_ref = Luca.containers.CardView.prototype.beforeRender) != null) {
2590
+ _ref.apply(this, arguments);
2591
+ }
2592
+ this.$el.addClass("" + this.resource + " record-manager");
2593
+ this.$el.data('resource', this.resource);
2594
+ $(this.getGrid().el).addClass("" + this.resource + " record-manager-grid");
2595
+ $(this.getFilter().el).addClass("" + this.resource + " record-manager-filter");
2596
+ return $(this.getEditor().el).addClass("" + this.resource + " record-manager-editor");
2597
+ },
2598
+ afterRender: function() {
2599
+ var collection, editor, filter, grid, manager, _ref,
2600
+ _this = this;
2601
+ if ((_ref = Luca.containers.CardView.prototype.afterRender) != null) {
2602
+ _ref.apply(this, arguments);
2603
+ }
2604
+ manager = this;
2605
+ grid = this.getGrid();
2606
+ filter = this.getFilter();
2607
+ editor = this.getEditor();
2608
+ collection = this.getCollection();
2609
+ grid.bind("row:double:click", function(grid, model, index) {
2610
+ manager.getEditor(true);
2611
+ return editor.loadModel(model);
2612
+ });
2613
+ editor.bind("before:submit", function() {
2614
+ $('.form-view-flash-container', _this.el).html('');
2615
+ return $('.form-view-body', _this.el).spin("large");
2616
+ });
2617
+ editor.bind("after:submit", function() {
2618
+ return $('.form-view-body', _this.el).spin(false);
2619
+ });
2620
+ editor.bind("after:submit:fatal_error", function() {
2621
+ $('.form-view-flash-container', _this.el).append("<li class='error'>There was an internal server error saving this record. Please contact developers@benchprep.com to report this error.</li>");
2622
+ return $('.form-view-body', _this.el).spin(false);
2623
+ });
2624
+ editor.bind("after:submit:error", function(form, model, response) {
2625
+ return _(response.errors).each(function(error) {
2626
+ return $('.form-view-flash-container', _this.el).append("<li class='error'>" + error + "</li>");
2627
+ });
2628
+ });
2629
+ editor.bind("after:submit:success", function(form, model, response) {
2630
+ $('.form-view-flash-container', _this.el).append("<li class='success'>Successfully Saved Record</li>");
2631
+ model.set(response.result);
2632
+ form.loadModel(model);
2633
+ grid.refresh();
2634
+ return _.delay(function() {
2635
+ $('.form-view-flash-container li.success', _this.el).fadeOut(1000);
2636
+ return $('.form-view-flash-container', _this.el).html('');
2637
+ }, 4000);
2638
+ });
2639
+ return filter.eachComponent(function(component) {
2640
+ try {
2641
+ return component.bind("on:change", _this.filter_handler);
2642
+ } catch (e) {
2643
+ return;
2644
+ }
2645
+ });
2646
+ },
2647
+ firstActivation: function() {
2648
+ this.getGrid().trigger("first:activation", this, this.getGrid());
2649
+ return this.getFilter().trigger("first:activation", this, this.getGrid());
2650
+ },
2651
+ reload: function() {
2652
+ var editor, filter, grid, manager;
2653
+ manager = this;
2654
+ grid = this.getGrid();
2655
+ filter = this.getFilter();
2656
+ editor = this.getEditor();
2657
+ filter.clear();
2658
+ return grid.applyFilter();
2659
+ },
2660
+ manageRecord: function(record_id) {
2661
+ var model,
2662
+ _this = this;
2663
+ model = this.getCollection().get(record_id);
2664
+ if (model) return this.loadModel(model);
2665
+ console.log("Could Not Find Model, building and fetching");
2666
+ model = this.buildModel();
2667
+ model.set({
2668
+ id: record_id
2669
+ }, {
2670
+ silent: true
2671
+ });
2672
+ return model.fetch({
2673
+ success: function(model, response) {
2674
+ return _this.loadModel(model);
2675
+ }
2676
+ });
2677
+ },
2678
+ loadModel: function(current_model) {
2679
+ this.current_model = current_model;
2680
+ this.getEditor(true).loadModel(this.current_model);
2681
+ return this.trigger("model:loaded", this.current_model);
2682
+ },
2683
+ currentModel: function() {
2684
+ return this.getEditor(false).currentModel();
2685
+ },
2686
+ buildModel: function() {
2687
+ var collection, editor, model;
2688
+ editor = this.getEditor(false);
2689
+ collection = this.getCollection();
2690
+ collection.add([{}], {
2691
+ silent: true,
2692
+ at: 0
2693
+ });
2694
+ return model = collection.at(0);
2695
+ },
2696
+ createModel: function() {
2697
+ return this.loadModel(this.buildModel());
2698
+ },
2699
+ reset_filter_handler: function(e) {
2700
+ this.getFilter().clear();
2701
+ return this.getGrid().applyFilter(this.getFilter().getValues());
2702
+ },
2703
+ filter_handler: function(e) {
2704
+ return this.getGrid().applyFilter(this.getFilter().getValues());
2705
+ },
2706
+ edit_handler: function(e) {
2707
+ var me, model, my, record_id;
2708
+ me = my = $(e.currentTarget);
2709
+ record_id = my.parents('tr').data('record-id');
2710
+ if (record_id) model = this.getGrid().collection.get(record_id);
2711
+ return model || (model = this.getGrid().collection.at(row_index));
2712
+ },
2713
+ add_handler: function(e) {
2714
+ var me, my, resource;
2715
+ me = my = $(e.currentTarget);
2716
+ return resource = my.parents('.record-manager').eq(0).data('resource');
2717
+ },
2718
+ destroy_handler: function(e) {},
2719
+ back_to_search_handler: function() {}
2720
+ });
2721
+
2722
+ }).call(this);
2723
+ (function() {
2724
+
2725
+ Luca.Router = Backbone.Router.extend({
2726
+ routes: {
2727
+ "": "default"
2728
+ },
2729
+ initialize: function(options) {
2730
+ var _this = this;
2731
+ this.options = options;
2732
+ _.extend(this, this.options);
2733
+ this.routeHandlers = _(this.routes).values();
2734
+ return _(this.routeHandlers).each(function(route_id) {
2735
+ return _this.bind("route:" + route_id, function() {
2736
+ return _this.trigger.apply(_this, ["change:navigation", route_id].concat(_(arguments).flatten()));
2737
+ });
2738
+ });
2739
+ },
2740
+ navigate: function(route, triggerRoute) {
2741
+ if (triggerRoute == null) triggerRoute = false;
2742
+ Backbone.Router.prototype.navigate.apply(this, arguments);
2743
+ return this.buildPathFrom(Backbone.history.getFragment());
2744
+ },
2745
+ buildPathFrom: function(matchedRoute) {
2746
+ var _this = this;
2747
+ return _(this.routes).each(function(route_id, route) {
2748
+ var args, regex;
2749
+ regex = _this._routeToRegExp(route);
2750
+ if (regex.test(matchedRoute)) {
2751
+ args = _this._extractParameters(regex, matchedRoute);
2752
+ return _this.trigger.apply(_this, ["change:navigation", route_id].concat(args));
2753
+ }
2754
+ });
2755
+ }
2756
+ });
2757
+
2758
+ }).call(this);
2759
+ (function() {
2760
+
2761
+
2762
+
2763
+ }).call(this);
2764
+ (function() {
2765
+
2766
+
2767
+
2768
+ }).call(this);
2769
+ (function() {
2770
+
2771
+
2772
+
2773
+ }).call(this);
2774
+ (function() {
2775
+
2776
+
2777
+
2778
+ }).call(this);
2779
+ (function() {
2780
+
2781
+ describe('The Form View', function() {
2782
+ return describe('Generating a form from a model', function() {
2783
+ return beforeEach(function() {
2784
+ var Model;
2785
+ Model = Backbone.Model.extend({
2786
+ schema: {
2787
+ field0: "hidden",
2788
+ field1: "text",
2789
+ field3: "boolean",
2790
+ field4: "blob",
2791
+ field5: {
2792
+ collection: "sample"
2793
+ }
2794
+ }
2795
+ });
2796
+ return this.model = new Model({
2797
+ field0: 1,
2798
+ field1: "jonathan",
2799
+ field3: true,
2800
+ field4: "what up player?"
2801
+ });
2802
+ });
2803
+ });
2804
+ });
2805
+
2806
+ }).call(this);
2807
+ (function() {
2808
+
2809
+
2810
+
2811
+ }).call(this);
2812
+ (function() {
2813
+
2814
+
2815
+
2816
+ }).call(this);
2817
+ (function() {
2818
+
2819
+
2820
+
2821
+ }).call(this);
2822
+ (function() {
2823
+
2824
+ describe("The Card View", function() {});
2825
+
2826
+ }).call(this);
2827
+ (function() {
2828
+
2829
+
2830
+
2831
+ }).call(this);
2832
+ (function() {
2833
+
2834
+
2835
+
2836
+ }).call(this);
2837
+ (function() {
2838
+
2839
+
2840
+
2841
+ }).call(this);
2842
+ (function() {
2843
+
2844
+
2845
+
2846
+ }).call(this);
2847
+ (function() {
2848
+
2849
+
2850
+
2851
+ }).call(this);
2852
+ (function() {
2853
+
2854
+
2855
+
2856
+ }).call(this);
2857
+ (function() {
2858
+
2859
+ describe("Luca.Collection", function() {
2860
+ it("should accept a name and collection manager", function() {
2861
+ var collection, mgr;
2862
+ mgr = new Luca.CollectionManager();
2863
+ collection = new Luca.Collection([], {
2864
+ name: "booya",
2865
+ manager: mgr
2866
+ });
2867
+ expect(collection.name).toEqual("booya");
2868
+ return expect(collection.manager).toEqual(mgr);
2869
+ });
2870
+ it("should allow me to specify my own fetch method on a per collection basis", function() {
2871
+ var collection, spy;
2872
+ spy = sinon.spy();
2873
+ collection = new Luca.Collection([], {
2874
+ fetch: spy
2875
+ });
2876
+ collection.fetch();
2877
+ return expect(spy.called).toBeTruthy();
2878
+ });
2879
+ it("should trigger before:fetch", function() {
2880
+ var collection, spy;
2881
+ collection = new Luca.Collection([], {
2882
+ url: "/models"
2883
+ });
2884
+ spy = sinon.spy();
2885
+ collection.bind("before:fetch", spy);
2886
+ collection.fetch();
2887
+ return expect(spy.called).toBeTruthy();
2888
+ });
2889
+ it("should automatically parse a response with a root in it", function() {
2890
+ var collection;
2891
+ collection = new Luca.Collection([], {
2892
+ root: "root",
2893
+ url: "/rooted/models"
2894
+ });
2895
+ collection.fetch();
2896
+ this.server.respond();
2897
+ return expect(collection.length).toEqual(2);
2898
+ });
2899
+ return it("should attempt to register with a collection manager", function() {
2900
+ var collection, registerSpy;
2901
+ registerSpy = sinon.spy();
2902
+ collection = new Luca.Collection([], {
2903
+ name: "registered",
2904
+ register: registerSpy
2905
+ });
2906
+ return expect(registerSpy).toHaveBeenCalled();
2907
+ });
2908
+ });
2909
+
2910
+ describe("The ifLoaded helper", function() {
2911
+ it("should fire the passed callback automatically if there are models", function() {
2912
+ var collection, spy;
2913
+ spy = sinon.spy();
2914
+ collection = new Luca.Collection([
2915
+ {
2916
+ attr: "value"
2917
+ }
2918
+ ]);
2919
+ collection.ifLoaded(spy);
2920
+ return expect(spy.callCount).toEqual(1);
2921
+ });
2922
+ it("should fire the passed callback any time the collection resets", function() {
2923
+ var collection, spy;
2924
+ spy = sinon.spy();
2925
+ collection = new Luca.Collection([
2926
+ {
2927
+ attr: "value"
2928
+ }
2929
+ ], {
2930
+ url: "/models"
2931
+ });
2932
+ collection.ifLoaded(function() {
2933
+ return spy.call();
2934
+ });
2935
+ collection.fetch();
2936
+ this.server.respond();
2937
+ return expect(spy.callCount).toEqual(2);
2938
+ });
2939
+ it("should not fire the callback if there are no models", function() {
2940
+ var collection, spy;
2941
+ spy = sinon.spy();
2942
+ collection = new Luca.Collection();
2943
+ collection.ifLoaded(spy);
2944
+ return expect(spy.called).toBeFalsy();
2945
+ });
2946
+ it("should automatically call fetch on the collection", function() {
2947
+ var collection, spy;
2948
+ spy = sinon.spy();
2949
+ collection = new Luca.Collection([], {
2950
+ url: "/models",
2951
+ blah: true
2952
+ });
2953
+ collection.ifLoaded(spy);
2954
+ this.server.respond();
2955
+ return expect(spy.called).toBeTruthy();
2956
+ });
2957
+ return it("should allow me to not automatically call fetch on the collection", function() {
2958
+ var collection, fn, spy;
2959
+ collection = new Luca.Collection([], {
2960
+ url: "/models"
2961
+ });
2962
+ spy = sinon.spy(collection.fetch);
2963
+ fn = function() {
2964
+ return true;
2965
+ };
2966
+ collection.ifLoaded(fn, {
2967
+ autoFetch: false
2968
+ });
2969
+ return expect(spy.called).toBeFalsy();
2970
+ });
2971
+ });
2972
+
2973
+ describe("The onceLoaded helper", function() {
2974
+ it("should fire the passed callback once if there are models", function() {
2975
+ var collection, spy;
2976
+ spy = sinon.spy();
2977
+ collection = new Luca.Collection([
2978
+ {
2979
+ attr: "value"
2980
+ }
2981
+ ]);
2982
+ collection.onceLoaded(spy);
2983
+ return expect(spy.callCount).toEqual(1);
2984
+ });
2985
+ it("should fire the passed callback only once", function() {
2986
+ var collection, spy;
2987
+ spy = sinon.spy();
2988
+ collection = new Luca.Collection([
2989
+ {
2990
+ attr: "value"
2991
+ }
2992
+ ], {
2993
+ url: "/models"
2994
+ });
2995
+ collection.onceLoaded(spy);
2996
+ expect(spy.callCount).toEqual(1);
2997
+ collection.fetch();
2998
+ this.server.respond();
2999
+ return expect(spy.callCount).toEqual(1);
3000
+ });
3001
+ it("should not fire the callback if there are no models", function() {
3002
+ var collection, spy;
3003
+ spy = sinon.spy();
3004
+ collection = new Luca.Collection();
3005
+ collection.onceLoaded(spy);
3006
+ return expect(spy.called).toBeFalsy();
3007
+ });
3008
+ it("should automatically call fetch on the collection", function() {
3009
+ var collection, spy;
3010
+ spy = sinon.spy();
3011
+ collection = new Luca.Collection([], {
3012
+ url: "/models"
3013
+ });
3014
+ collection.onceLoaded(spy);
3015
+ this.server.respond();
3016
+ return expect(spy.called).toBeTruthy();
3017
+ });
3018
+ return it("should allow me to not automatically call fetch on the collection", function() {
3019
+ var collection, fn, spy;
3020
+ collection = new Luca.Collection([], {
3021
+ url: "/models"
3022
+ });
3023
+ spy = sinon.spy(collection.fetch);
3024
+ fn = function() {
3025
+ return true;
3026
+ };
3027
+ collection.onceLoaded(fn, {
3028
+ autoFetch: false
3029
+ });
3030
+ return expect(spy.called).toBeFalsy();
3031
+ });
3032
+ });
3033
+
3034
+ describe("Registering with the collection manager", function() {
3035
+ it("should be able to find a default collection manager", function() {
3036
+ var mgr;
3037
+ mgr = new Luca.CollectionManager();
3038
+ return expect(Luca.CollectionManager.get()).toEqual(mgr);
3039
+ });
3040
+ it("should automatically register with the manager if I specify a name", function() {
3041
+ var collection, mgr;
3042
+ mgr = new Luca.CollectionManager();
3043
+ collection = new Luca.Collection([], {
3044
+ name: "auto_register"
3045
+ });
3046
+ return expect(mgr.get("auto_register")).toEqual(collection);
3047
+ });
3048
+ it("should register with a specific manager", function() {
3049
+ var collection;
3050
+ window.other_manager = new Luca.CollectionManager();
3051
+ collection = new Luca.Collection([], {
3052
+ name: "other_collection",
3053
+ manager: window.other_manager
3054
+ });
3055
+ return expect(window.other_manager.get("other_collection")).toEqual(collection);
3056
+ });
3057
+ it("should find a collection manager by string", function() {
3058
+ var collection;
3059
+ window.find_mgr_by_string = new Luca.CollectionManager();
3060
+ collection = new Luca.Collection([], {
3061
+ name: "biggie",
3062
+ manager: "find_mgr_by_string"
3063
+ });
3064
+ return expect(collection.manager).toBeDefined();
3065
+ });
3066
+ return it("should not register with a collection manager if it is marked as private", function() {
3067
+ var manager, private, registerSpy;
3068
+ manager = new Luca.CollectionManager();
3069
+ registerSpy = sinon.spy();
3070
+ private = new Luca.Collection([], {
3071
+ name: "private",
3072
+ manager: manager,
3073
+ private: true,
3074
+ register: registerSpy
3075
+ });
3076
+ return expect(registerSpy).not.toHaveBeenCalled();
3077
+ });
3078
+ });
3079
+
3080
+ describe("The Model Bootstrap", function() {
3081
+ window.ModelBootstrap = {
3082
+ sample: []
3083
+ };
3084
+ _(5).times(function(n) {
3085
+ return window.ModelBootstrap.sample.push({
3086
+ id: n,
3087
+ key: "value"
3088
+ });
3089
+ });
3090
+ it("should add an object into the models cache", function() {
3091
+ Luca.Collection.bootstrap(window.ModelBootstrap);
3092
+ return expect(Luca.Collection.cache("sample").length).toEqual(5);
3093
+ });
3094
+ it("should fetch the cached models from the bootstrap", function() {
3095
+ var collection;
3096
+ collection = new Luca.Collection([], {
3097
+ cached: function() {
3098
+ return "sample";
3099
+ }
3100
+ });
3101
+ collection.fetch();
3102
+ expect(collection.length).toEqual(5);
3103
+ return expect(collection.pluck('id')).toEqual([0, 1, 2, 3, 4]);
3104
+ });
3105
+ it("should reference the cached models", function() {
3106
+ var collection;
3107
+ collection = new Luca.Collection([], {
3108
+ cached: function() {
3109
+ return "sample";
3110
+ }
3111
+ });
3112
+ return expect(collection.cached_models().length).toEqual(5);
3113
+ });
3114
+ it("should avoid making an API call", function() {
3115
+ var collection, spy;
3116
+ spy = sinon.spy(Backbone.Collection.prototype.fetch);
3117
+ collection = new Luca.Collection([], {
3118
+ cached: function() {
3119
+ return "sample";
3120
+ }
3121
+ });
3122
+ collection.fetch();
3123
+ return expect(spy.called).toBeFalsy();
3124
+ });
3125
+ return it("should make an API call if specifically asked", function() {
3126
+ var collection, spy;
3127
+ spy = sinon.spy();
3128
+ collection = new Luca.Collection([], {
3129
+ cached: function() {
3130
+ return "sample";
3131
+ },
3132
+ url: function() {
3133
+ return "/models";
3134
+ }
3135
+ });
3136
+ collection.bind("after:response", spy);
3137
+ collection.fetch({
3138
+ refresh: true
3139
+ });
3140
+ this.server.respond();
3141
+ return expect(spy.called).toBeTruthy();
3142
+ });
3143
+ });
3144
+
3145
+ }).call(this);
3146
+ (function() {
3147
+
3148
+
3149
+
3150
+ }).call(this);
3151
+ (function() {
3152
+
3153
+
3154
+
3155
+ }).call(this);
3156
+ (function() {
3157
+
3158
+
3159
+
3160
+ }).call(this);
3161
+ (function() {
3162
+ var __hasProp = Object.prototype.hasOwnProperty,
3163
+ __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; };
3164
+
3165
+ describe("Luca.View", function() {
3166
+ var Custom;
3167
+ Custom = Luca.View.extend({
3168
+ clickHandler: sinon.spy(),
3169
+ autoBindEventHandlers: true
3170
+ });
3171
+ it("should be defined", function() {
3172
+ return expect(Luca.View).toBeDefined();
3173
+ });
3174
+ it("should extend itself with the passed options", function() {
3175
+ var view;
3176
+ view = new Luca.View({
3177
+ name: "custom"
3178
+ });
3179
+ return expect(view.name).toEqual("custom");
3180
+ });
3181
+ it("should create a unique id based on the name", function() {
3182
+ var view;
3183
+ view = new Luca.View({
3184
+ name: "boom"
3185
+ });
3186
+ return expect(view.cid).toContain('boom');
3187
+ });
3188
+ it("should register the view in the cache", function() {
3189
+ var view;
3190
+ view = new Luca.View({
3191
+ name: "cached"
3192
+ });
3193
+ return expect(Luca.cache("cached")).toBeDefined();
3194
+ });
3195
+ it("should trigger after initialize", function() {
3196
+ var view;
3197
+ view = new Luca.View();
3198
+ return expect(view).toHaveTriggered("after:initialize");
3199
+ });
3200
+ return it("should auto-bind event handlers", function() {});
3201
+ });
3202
+
3203
+ describe("Hooks", function() {
3204
+ it("should have before and after render hooks", function() {
3205
+ var Custom, view;
3206
+ Custom = Luca.View.extend({
3207
+ beforeRender: sinon.spy(),
3208
+ afterRender: sinon.spy()
3209
+ });
3210
+ view = new Custom();
3211
+ view.render();
3212
+ expect(view.beforeRender).toHaveBeenCalled();
3213
+ return expect(view.afterRender).toHaveBeenCalled();
3214
+ });
3215
+ return it("should call custom hooks in addition to framework hooks", function() {
3216
+ var Custom, view;
3217
+ Custom = Luca.View.extend({
3218
+ hooks: ["custom:hook"],
3219
+ afterRender: function() {
3220
+ return this.trigger("custom:hook");
3221
+ },
3222
+ customHook: sinon.spy()
3223
+ });
3224
+ view = new Custom();
3225
+ view.render();
3226
+ return expect(view.customHook).toHaveBeenCalled();
3227
+ });
3228
+ });
3229
+
3230
+ describe("The Collection Events API", function() {
3231
+ var App, SampleManager, SampleView;
3232
+ App = {
3233
+ collections: {}
3234
+ };
3235
+ App.collections.Sample = Luca.Collection.extend({
3236
+ name: "sample"
3237
+ });
3238
+ SampleView = Luca.View.extend({
3239
+ resetHandler: sinon.spy(),
3240
+ collectionEvents: {
3241
+ "sample reset": "resetHandler"
3242
+ }
3243
+ });
3244
+ SampleManager = (function(_super) {
3245
+
3246
+ __extends(SampleManager, _super);
3247
+
3248
+ function SampleManager() {
3249
+ SampleManager.__super__.constructor.apply(this, arguments);
3250
+ }
3251
+
3252
+ SampleManager.prototype.collectionNamespace = App.collections;
3253
+
3254
+ SampleManager.prototype.name = "collectionEvents";
3255
+
3256
+ return SampleManager;
3257
+
3258
+ })(Luca.CollectionManager);
3259
+ beforeEach(function() {
3260
+ this.manager || (this.manager = new SampleManager());
3261
+ return this.collection = this.manager.getOrCreate("sample");
3262
+ });
3263
+ it("should know which collection manager to use", function() {
3264
+ var view;
3265
+ view = new SampleView();
3266
+ return expect(view.getCollectionManager().name).toEqual("collectionEvents");
3267
+ });
3268
+ it("should create a reference to the collection", function() {
3269
+ var view;
3270
+ view = new SampleView();
3271
+ return expect(view.sampleCollection).toBeDefined();
3272
+ });
3273
+ return it("should call the resetHandler callback on the view", function() {
3274
+ var collection, view;
3275
+ view = new SampleView();
3276
+ collection = this.manager.get("sample");
3277
+ collection.reset([]);
3278
+ return expect(view.resetHandler).toHaveBeenCalled();
3279
+ });
3280
+ });
3281
+
3282
+ }).call(this);
3283
+ (function() {
3284
+ var EventMatchers, ModelMatchers, createFakeServer, eventBucket, getMatcherFunction, i, j, json, matcherName, msg, sinonName, spyMatcherHash, spyMatchers, triggerSpy, unusualMatchers;
3285
+
3286
+ json = function(object) {
3287
+ return JSON.stringify(object);
3288
+ };
3289
+
3290
+ msg = function(list) {
3291
+ if (list.length !== 0) {
3292
+ return list.join(";");
3293
+ } else {
3294
+ return "";
3295
+ }
3296
+ };
3297
+
3298
+ eventBucket = function(model, eventName) {
3299
+ var bucket, spiedEvents;
3300
+ spiedEvents = model.spiedEvents;
3301
+ if (!spiedEvents) spiedEvents = model.spiedEvents = {};
3302
+ bucket = spiedEvents[eventName];
3303
+ if (!bucket) bucket = spiedEvents[eventName] = [];
3304
+ return bucket;
3305
+ };
3306
+
3307
+ triggerSpy = function(constructor) {
3308
+ var trigger;
3309
+ trigger = constructor.prototype.trigger;
3310
+ return constructor.prototype.trigger = function(eventName) {
3311
+ var bucket;
3312
+ bucket = eventBucket(this, eventName);
3313
+ bucket.push(Array.prototype.slice.call(arguments, 1));
3314
+ return trigger.apply(this, arguments);
3315
+ };
3316
+ };
3317
+
3318
+ triggerSpy(Backbone.Model);
3319
+
3320
+ triggerSpy(Backbone.Collection);
3321
+
3322
+ triggerSpy(Backbone.View);
3323
+
3324
+ EventMatchers = {
3325
+ toHaveTriggered: function(eventName) {
3326
+ var bucket, triggeredWith;
3327
+ bucket = eventBucket(this.actual, eventName);
3328
+ triggeredWith = Array.prototype.slice.call(arguments, 1);
3329
+ this.message = function() {
3330
+ return ["expected model or collection to have received '" + eventName + "' with " + json(triggeredWith), "expected model not to have received event '" + eventName + "', but it did"];
3331
+ };
3332
+ return _.detect(bucket, function(args) {
3333
+ if (triggeredWith.length === 0) {
3334
+ return true;
3335
+ } else {
3336
+ return jasmine.getEnv().equals_(triggeredWith, args);
3337
+ }
3338
+ });
3339
+ }
3340
+ };
3341
+
3342
+ ModelMatchers = {
3343
+ toHaveAttributes: function(attributes) {
3344
+ var i, keys, message, missing, values;
3345
+ keys = [];
3346
+ values = [];
3347
+ jasmine.getEnv().equals_(this.actual.attributes, attributes, keys, values);
3348
+ missing = [];
3349
+ i = 0;
3350
+ while (i < keys.length) {
3351
+ message = keys[i];
3352
+ if (message.match(/but missing from/)) missing.push(keys[i]);
3353
+ i++;
3354
+ }
3355
+ this.message = function() {
3356
+ return ["model should have at least these attributes(" + json(attributes) + ") " + msg(missing) + " " + msg(values), "model should have none of the following attributes(" + json(attributes) + ") " + msg(keys) + " " + msg(values)];
3357
+ };
3358
+ return missing.length === 0 && values.length === 0;
3359
+ },
3360
+ toHaveExactlyTheseAttributes: function(attributes) {
3361
+ var equal, keys, values;
3362
+ keys = [];
3363
+ values = [];
3364
+ equal = jasmine.getEnv().equals_(this.actual.attributes, attributes, keys, values);
3365
+ this.message = function() {
3366
+ return ["model should match exact attributes, but does not. " + msg(keys) + " " + msg(values), "model has exactly these attributes, but shouldn't :" + json(attributes)];
3367
+ };
3368
+ return equal;
3369
+ }
3370
+ };
3371
+
3372
+ createFakeServer = function() {
3373
+ var server;
3374
+ server = sinon.fakeServer.create();
3375
+ server.respondWith("GET", "/models", [
3376
+ 200, {
3377
+ "Content-Type": "application/json"
3378
+ }, '[{"id":1,"attr1":"value1","attr2":"value2"},{"id":2,"attr1":"value1","attr2":"value2"}]'
3379
+ ]);
3380
+ server.respondWith("GET", "/rooted/models", [
3381
+ 200, {
3382
+ "Content-Type": "application/json"
3383
+ }, '{"root":[{"id":1,"attr1":"value1","attr2":"value2"},{"id":2,"attr1":"value1","attr2":"value2"}]}'
3384
+ ]);
3385
+ server.respondWith("GET", "/empty", [
3386
+ 200, {
3387
+ "Content-Type": "application/json"
3388
+ }, '[]'
3389
+ ]);
3390
+ return server;
3391
+ };
3392
+
3393
+ spyMatchers = "called calledOnce calledTwice calledThrice calledBefore calledAfter calledOn alwaysCalledOn calledWith alwaysCalledWith calledWithExactly alwaysCalledWithExactly".split(" ");
3394
+
3395
+ i = spyMatchers.length;
3396
+
3397
+ spyMatcherHash = {};
3398
+
3399
+ unusualMatchers = {
3400
+ returned: "toHaveReturned",
3401
+ alwaysReturned: "toHaveAlwaysReturned",
3402
+ threw: "toHaveThrown",
3403
+ alwaysThrew: "toHaveAlwaysThrown"
3404
+ };
3405
+
3406
+ getMatcherFunction = function(sinonName) {
3407
+ return function() {
3408
+ var sinonProperty;
3409
+ sinonProperty = this.actual[sinonName];
3410
+ if (typeof sinonProperty === "function") {
3411
+ return sinonProperty.apply(this.actual, arguments);
3412
+ } else {
3413
+ return sinonProperty;
3414
+ }
3415
+ };
3416
+ };
3417
+
3418
+ while (i--) {
3419
+ sinonName = spyMatchers[i];
3420
+ matcherName = "toHaveBeen" + sinonName.charAt(0).toUpperCase() + sinonName.slice(1);
3421
+ spyMatcherHash[matcherName] = getMatcherFunction(sinonName);
3422
+ }
3423
+
3424
+ for (j in unusualMatchers) {
3425
+ spyMatcherHash[unusualMatchers[j]] = getMatcherFunction(j);
3426
+ }
3427
+
3428
+ window.sinonJasmine = {
3429
+ getMatchers: function() {
3430
+ return spyMatcherHash;
3431
+ }
3432
+ };
3433
+
3434
+ beforeEach(function() {
3435
+ this.server = createFakeServer();
3436
+ this.addMatchers(ModelMatchers);
3437
+ this.addMatchers(EventMatchers);
3438
+ return this.addMatchers(sinonJasmine.getMatchers());
3439
+ });
3440
+
3441
+ afterEach(function() {
3442
+ return this.server.restore();
3443
+ });
3444
+
3445
+ }).call(this);
3446
+ (function() {
3447
+
3448
+ describe("The Luca Framework", function() {
3449
+ it("should specify a version", function() {
3450
+ return expect(Luca.VERSION).toBeDefined();
3451
+ });
3452
+ it("should define Luca in the global space", function() {
3453
+ return expect(Luca).toBeDefined();
3454
+ });
3455
+ it("should enable bootstrap by default", function() {
3456
+ return expect(Luca.enableBootstrap).toBeTruthy();
3457
+ });
3458
+ it("should have classes in the registry", function() {
3459
+ return expect(Luca.registry.classes).toBeDefined();
3460
+ });
3461
+ it("should be able to lookup classes in the registry by ctype", function() {
3462
+ return expect(Luca.registry.lookup("form_view")).toBeTruthy();
3463
+ });
3464
+ it("should allow me to add view namespaces to the registry", function() {
3465
+ Luca.registry.addNamespace("Test.namespace");
3466
+ return expect(Luca.registry.namespaces).toContain("Test.namespace");
3467
+ });
3468
+ it("should resolve a value.string to the object", function() {
3469
+ var value;
3470
+ window.nested = {
3471
+ value: {
3472
+ string: "haha"
3473
+ }
3474
+ };
3475
+ value = Luca.util.nestedValue("nested.value.string", window);
3476
+ return expect(value).toEqual("haha");
3477
+ });
3478
+ it("should create an instance of a class by ctype", function() {
3479
+ var component, object;
3480
+ object = {
3481
+ ctype: "template",
3482
+ template: "components/form_view"
3483
+ };
3484
+ component = Luca.util.lazyComponent(object);
3485
+ return expect(_.isFunction(component.render)).toBeTruthy();
3486
+ });
3487
+ return it("should find a created view in the cache", function() {
3488
+ var template;
3489
+ template = new Luca.components.Template({
3490
+ template: "components/form_view",
3491
+ name: 'test_template'
3492
+ });
3493
+ return expect(Luca.cache("test_template")).toBeDefined();
3494
+ });
3495
+ });
3496
+
3497
+ describe;
3498
+
3499
+ }).call(this);
3500
+ (function() {
3501
+
3502
+ describe("The Collection Manager", function() {
3503
+ var App;
3504
+ App = {
3505
+ collections: {}
3506
+ };
3507
+ App.collections.SampleCollection = Luca.Collection.extend({
3508
+ url: "/models"
3509
+ });
3510
+ beforeEach(function() {
3511
+ return this.manager = new Luca.CollectionManager({
3512
+ name: "manager",
3513
+ collectionNamespace: App.collections
3514
+ });
3515
+ });
3516
+ it("should be defined", function() {
3517
+ return expect(Luca.CollectionManager).toBeDefined();
3518
+ });
3519
+ it("should make the latest instance accessible by class function", function() {
3520
+ return expect(Luca.CollectionManager.get().name).toEqual("manager");
3521
+ });
3522
+ it("should be able to guess a collection constructor class", function() {
3523
+ var base;
3524
+ base = this.manager.guessCollectionClass("sample_collection");
3525
+ return expect(base).toEqual(App.collections.SampleCollection);
3526
+ });
3527
+ return it("should create a collection on demand", function() {
3528
+ var collection;
3529
+ collection = this.manager.getOrCreate("sample_collection");
3530
+ return expect(collection.url).toEqual("/models");
3531
+ });
3532
+ });
3533
+
3534
+ describe("Adding Collections", function() {
3535
+ var first, manager, second;
3536
+ manager = new Luca.CollectionManager;
3537
+ first = new Luca.Collection([], {
3538
+ name: "added",
3539
+ prop: "val2"
3540
+ });
3541
+ second = new Luca.Collection([], {
3542
+ name: "added",
3543
+ prop: "val1"
3544
+ });
3545
+ manager.add("added", first);
3546
+ manager.add("added", second);
3547
+ return expect(manager.get("added")).toEqual(first);
3548
+ });
3549
+
3550
+ describe("The Scope Functionality", function() {
3551
+ var babyone, babytwo, manager, scope;
3552
+ scope = "one";
3553
+ manager = new Luca.CollectionManager({
3554
+ getScope: function() {
3555
+ return scope;
3556
+ }
3557
+ });
3558
+ babyone = new Luca.Collection([
3559
+ {
3560
+ id: 1
3561
+ }, {
3562
+ id: 2
3563
+ }
3564
+ ], {
3565
+ name: "baby"
3566
+ });
3567
+ manager.add("baby", babyone);
3568
+ expect(manager.get("baby").pluck('id')).toEqual([1, 2]);
3569
+ expect(manager.get("baby")).toBeDefined();
3570
+ expect(manager.get("baby")).toEqual(babyone);
3571
+ expect(manager.allCollections().length).toEqual(1);
3572
+ scope = "two";
3573
+ babytwo = new Luca.Collection([
3574
+ {
3575
+ id: 3
3576
+ }, {
3577
+ id: 4
3578
+ }
3579
+ ], {
3580
+ name: "baby"
3581
+ });
3582
+ expect(manager.get("baby").pluck('id')).toEqual([3, 4]);
3583
+ expect(manager.get("baby")).toBeDefined();
3584
+ expect(manager.get("baby")).toEqual(babytwo);
3585
+ expect(manager.allCollections().length).toEqual(1);
3586
+ scope = "one";
3587
+ return expect(manager.get("baby").pluck('id')).toEqual([1, 2]);
3588
+ });
3589
+
3590
+ describe("Loading collections", function() {
3591
+ var App, exampleSpy, manager, sampleSpy;
3592
+ App = {
3593
+ collections: {}
3594
+ };
3595
+ exampleSpy = sinon.spy();
3596
+ sampleSpy = sinon.spy();
3597
+ App.collections.ExampleCollection = Luca.Collection.extend({
3598
+ name: "example",
3599
+ url: "/example_models",
3600
+ fetch: function() {
3601
+ exampleSpy.call();
3602
+ return this.reset([
3603
+ {
3604
+ id: 1
3605
+ }
3606
+ ]);
3607
+ }
3608
+ });
3609
+ App.collections.SampleCollection = Luca.Collection.extend({
3610
+ name: "sample",
3611
+ url: "/sample_models",
3612
+ fetch: function() {
3613
+ sampleSpy.call();
3614
+ return this.reset([
3615
+ {
3616
+ id: 4
3617
+ }
3618
+ ]);
3619
+ }
3620
+ });
3621
+ manager = new Luca.CollectionManager({
3622
+ name: "manager",
3623
+ collectionNamespace: App.collections,
3624
+ collectionNames: ["example", "sample"]
3625
+ });
3626
+ it("should have example collection created", function() {
3627
+ var collection;
3628
+ collection = manager.get("example");
3629
+ return expect(collection.url).toEqual("/example_models");
3630
+ });
3631
+ it("should have example collection fetched", function() {
3632
+ return expect(exampleSpy).toHaveBeenCalled();
3633
+ });
3634
+ it("should have sample collection created", function() {
3635
+ var collection;
3636
+ collection = manager.get("sample");
3637
+ return expect(collection.url).toEqual("/sample_models");
3638
+ });
3639
+ return it("should have sample collection loaded", function() {
3640
+ return expect(sampleSpy).toHaveBeenCalled();
3641
+ });
3642
+ });
3643
+
3644
+ }).call(this);
3645
+ (function() {
3646
+
3647
+
3648
+
3649
+ }).call(this);
3650
+ (function() {
3651
+
3652
+
3653
+
3654
+ }).call(this);