luca 0.9.2 → 0.9.4

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 (129) hide show
  1. data/.gitignore +1 -0
  2. data/.rvmrc +1 -1
  3. data/CHANGELOG +46 -2
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +2 -2
  6. data/Guardfile +1 -1
  7. data/README.md +64 -27
  8. data/ROADMAP +17 -2
  9. data/Rakefile +49 -1
  10. data/app.rb +38 -2
  11. data/assets/javascripts/luca-ui-base.coffee +1 -20
  12. data/assets/javascripts/luca-ui-full.js +3 -0
  13. data/assets/javascripts/luca-ui.coffee +0 -5
  14. data/assets/javascripts/sandbox/application.coffee +24 -18
  15. data/assets/javascripts/sandbox/router.coffee +16 -6
  16. data/assets/javascripts/sandbox/templates/builder/component_list.luca +1 -0
  17. data/assets/javascripts/sandbox/templates/builder.luca +2 -0
  18. data/assets/javascripts/sandbox/templates/main.luca +4 -3
  19. data/assets/javascripts/sandbox/templates/sandbox/docs_index.luca +1 -0
  20. data/assets/javascripts/sandbox/templates/sandbox/navigation.luca +6 -1
  21. data/assets/javascripts/sandbox/templates/sandbox/readme.luca +30 -0
  22. data/assets/javascripts/sandbox/views/builder/builder_canvas.coffee +3 -0
  23. data/assets/javascripts/sandbox/views/builder/builder_editor.coffee +6 -0
  24. data/assets/javascripts/sandbox/views/builder/component_list.coffee +38 -0
  25. data/assets/javascripts/sandbox/views/builder/project_browser.coffee +14 -0
  26. data/assets/javascripts/sandbox/views/builder.coffee +133 -0
  27. data/assets/javascripts/sandbox/views/docs_controller.coffee +7 -0
  28. data/assets/javascripts/sandbox/views/inspector/instance_filter.coffee +18 -0
  29. data/assets/javascripts/sandbox/{collections/sample.coffee → views/inspector/instance_list.coffee} +0 -0
  30. data/assets/javascripts/sandbox/views/inspector.coffee +11 -0
  31. data/assets/javascripts/sandbox.coffee +2 -0
  32. data/assets/stylesheets/luca-ui-full.css +3 -0
  33. data/assets/stylesheets/sandbox/builder.scss +79 -0
  34. data/assets/stylesheets/sandbox/sandbox.scss +2 -1
  35. data/docs/application.md +41 -0
  36. data/docs/collection.md +79 -0
  37. data/docs/collection_manager.md +76 -0
  38. data/docs/container_philosophy.md +122 -0
  39. data/docs/event_binding_helpers.md +164 -0
  40. data/docs/method_caching_and_computed_properties.md +77 -0
  41. data/docs/view.md +119 -0
  42. data/lib/luca/rails/version.rb +1 -1
  43. data/lib/luca/template.rb +9 -9
  44. data/site/assets/bootstrap.min.js +7 -0
  45. data/site/assets/luca-ui-bootstrap.css +19 -1
  46. data/site/assets/luca-ui-development-tools.css +10 -0
  47. data/site/assets/luca-ui-development-tools.min.js +15 -0
  48. data/site/assets/luca-ui-full.min.js +8 -0
  49. data/site/assets/luca-ui.min.js +4 -0
  50. data/site/assets/sandbox.css +52 -4
  51. data/site/assets/sandbox.js +368 -30
  52. data/site/docs/application.html +41 -0
  53. data/site/docs/caching.html +43 -0
  54. data/site/docs/collection.html +75 -0
  55. data/site/docs/collection_manager.html +71 -0
  56. data/site/docs/containers.html +118 -0
  57. data/site/docs/events.html +153 -0
  58. data/site/docs/view.html +128 -0
  59. data/site/img/glyphicons-halflings-white.png +0 -0
  60. data/site/img/glyphicons-halflings.png +0 -0
  61. data/site/source-map.js +1 -0
  62. data/spec/core/view_spec.coffee +5 -17
  63. data/spec/managers/collection_manager_spec.coffee +4 -7
  64. data/src/components/application.coffee +202 -77
  65. data/src/components/base_toolbar.coffee +1 -1
  66. data/src/components/collection_view.coffee +38 -10
  67. data/src/components/controller.coffee +24 -1
  68. data/src/components/fields/checkbox_field.coffee +9 -12
  69. data/src/components/fields/label_field.coffee +14 -0
  70. data/src/components/fields/select_field.coffee +2 -2
  71. data/src/components/fields/text_field.coffee +12 -7
  72. data/src/components/fields/type_ahead_field.coffee +1 -0
  73. data/src/components/form_view.coffee +44 -25
  74. data/src/components/page_controller.coffee +2 -0
  75. data/src/containers/card_view.coffee +4 -1
  76. data/src/containers/column_view.coffee +2 -1
  77. data/src/containers/modal_view.coffee +6 -2
  78. data/src/containers/page_view.coffee +2 -0
  79. data/src/containers/panel_toolbar.coffee +0 -5
  80. data/src/containers/viewport.coffee +28 -10
  81. data/src/core/collection.coffee +7 -1
  82. data/src/core/container.coffee +57 -30
  83. data/src/core/core.coffee +0 -186
  84. data/src/core/field.coffee +11 -3
  85. data/src/core/model.coffee +31 -16
  86. data/src/core/panel.coffee +6 -46
  87. data/src/core/registry.coffee +19 -2
  88. data/src/core/script_loader.coffee +32 -0
  89. data/src/core/view.coffee +112 -139
  90. data/src/define.coffee +110 -0
  91. data/src/framework.coffee +8 -2
  92. data/src/luca.coffee +22 -0
  93. data/src/managers/collection_manager.coffee +65 -31
  94. data/src/modules/load_mask.coffee +47 -0
  95. data/src/plugins/development_tool_helpers.coffee +21 -0
  96. data/src/plugins/events.coffee +54 -0
  97. data/src/stylesheets/components/viewport.scss +15 -0
  98. data/src/stylesheets/containers/container.scss +1 -4
  99. data/src/stylesheets/tools/component_tester.scss +18 -0
  100. data/src/templates/fields/select_field.luca +6 -5
  101. data/src/templates/fields/text_field.luca +10 -9
  102. data/src/tools/application_inspector.coffee +2 -0
  103. data/src/tools/coffee_script_editor.coffee +28 -6
  104. data/src/tools/collections/components.coffee +59 -0
  105. data/src/tools/collections/instances.coffee +15 -0
  106. data/src/tools/component_tester.coffee +12 -22
  107. data/src/tools/console.coffee +22 -4
  108. data/src/tools/models/components.coffee +16 -54
  109. data/src/tools/models/instance.coffee +2 -0
  110. data/src/{core/util.coffee → util.coffee} +10 -1
  111. data/vendor/assets/javascripts/luca-ui-base.js +132 -137
  112. data/vendor/assets/javascripts/luca-ui-development-tools.js +191 -219
  113. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +2 -2
  114. data/vendor/assets/javascripts/luca-ui-full.js +4680 -0
  115. data/vendor/assets/javascripts/luca-ui-full.min.js +8 -0
  116. data/vendor/assets/javascripts/luca-ui-spec.js +291 -225
  117. data/vendor/assets/javascripts/luca-ui.js +1001 -724
  118. data/vendor/assets/javascripts/luca-ui.min.js +4 -4
  119. data/vendor/assets/stylesheets/luca-ui-bootstrap.css +19 -1
  120. data/vendor/assets/stylesheets/luca-ui-development-tools.css +10 -0
  121. data/vendor/assets/stylesheets/luca-ui-full.css +1334 -0
  122. data/vendor/assets/stylesheets/luca-ui-spec.css +19 -1
  123. data/vendor/assets/stylesheets/luca-ui.css +19 -1
  124. data/views/index.erb +2 -5
  125. metadata +58 -9
  126. data/lib/sprockets/luca_template.rb +0 -49
  127. data/src/tools/class_browser.coffee +0 -39
  128. data/src/tools/components/class_browser_detail.coffee +0 -10
  129. data/src/tools/components/class_browser_list.coffee +0 -74
@@ -25,7 +25,8 @@
25
25
  modules: {},
26
26
  util: {},
27
27
  fields: {},
28
- registry: {}
28
+ registry: {},
29
+ options: {}
29
30
  });
30
31
 
31
32
  _.extend(Luca, Backbone.Events);
@@ -71,26 +72,32 @@
71
72
  };
72
73
 
73
74
  Luca.isBackboneModel = function(obj) {
75
+ if (_.isString(obj)) obj = Luca.util.resolve(obj);
74
76
  return _.isFunction(obj != null ? obj.set : void 0) && _.isFunction(obj != null ? obj.get : void 0) && _.isObject(obj != null ? obj.attributes : void 0);
75
77
  };
76
78
 
77
79
  Luca.isBackboneView = function(obj) {
80
+ if (_.isString(obj)) obj = Luca.util.resolve(obj);
78
81
  return _.isFunction(obj != null ? obj.render : void 0) && !_.isUndefined(obj != null ? obj.el : void 0);
79
82
  };
80
83
 
81
84
  Luca.isBackboneCollection = function(obj) {
85
+ if (_.isString(obj)) obj = Luca.util.resolve(obj);
82
86
  return _.isFunction(obj != null ? obj.fetch : void 0) && _.isFunction(obj != null ? obj.reset : void 0);
83
87
  };
84
88
 
85
89
  Luca.isViewPrototype = function(obj) {
90
+ if (_.isString(obj)) obj = Luca.util.resolve(obj);
86
91
  return (obj != null) && (obj.prototype != null) && (obj.prototype.make != null) && (obj.prototype.$ != null) && (obj.prototype.render != null);
87
92
  };
88
93
 
89
94
  Luca.isModelPrototype = function(obj) {
95
+ if (_.isString(obj)) obj = Luca.util.resolve(obj);
90
96
  return (obj != null) && (typeof obj.prototype === "function" ? obj.prototype((obj.prototype.save != null) && (obj.prototype.changedAttributes != null)) : void 0);
91
97
  };
92
98
 
93
99
  Luca.isCollectionPrototype = function(obj) {
100
+ if (_.isString(obj)) obj = Luca.util.resolve(obj);
94
101
  return (obj != null) && (obj.prototype != null) && !Luca.isModelPrototype(obj) && (obj.prototype.reset != null) && (obj.prototype.select != null) && (obj.prototype.reject != null);
95
102
  };
96
103
 
@@ -219,6 +226,64 @@
219
226
 
220
227
  _.mixin(UnderscoreExtensions);
221
228
 
229
+ }).call(this);
230
+ (function() {
231
+ var DeferredBindingProxy;
232
+
233
+ DeferredBindingProxy = (function() {
234
+
235
+ function DeferredBindingProxy(object, operation, wrapWithUnderscore) {
236
+ var fn,
237
+ _this = this;
238
+ this.object = object;
239
+ if (wrapWithUnderscore == null) wrapWithUnderscore = true;
240
+ if (_.isFunction(operation)) {
241
+ fn = operation;
242
+ } else if (_.isString(operation) && _.isFunction(this.object[operation])) {
243
+ fn = this.object[operation];
244
+ }
245
+ if (!_.isFunction(fn)) {
246
+ throw "Must pass a function or a string representing one";
247
+ }
248
+ if (wrapWithUnderscore === true) {
249
+ this.fn = function() {
250
+ return _.defer(fn);
251
+ };
252
+ } else {
253
+ this.fn = fn;
254
+ }
255
+ this;
256
+ }
257
+
258
+ DeferredBindingProxy.prototype.until = function(watch, trigger) {
259
+ if ((watch != null) && !(trigger != null)) {
260
+ trigger = watch;
261
+ watch = this.object;
262
+ }
263
+ watch.once(trigger, this.fn);
264
+ return this.object;
265
+ };
266
+
267
+ return DeferredBindingProxy;
268
+
269
+ })();
270
+
271
+ Luca.Events = {
272
+ defer: function(operation, wrapWithUnderscore) {
273
+ if (wrapWithUnderscore == null) wrapWithUnderscore = true;
274
+ return new DeferredBindingProxy(this, operation, wrapWithUnderscore);
275
+ },
276
+ once: function(trigger, callback, context) {
277
+ var onceFn;
278
+ context || (context = this);
279
+ onceFn = function() {
280
+ callback.apply(context, arguments);
281
+ return this.unbind(trigger, onceFn);
282
+ };
283
+ return this.bind(trigger, onceFn);
284
+ }
285
+ };
286
+
222
287
  }).call(this);
223
288
  (function() {
224
289
  var currentNamespace;
@@ -330,7 +395,7 @@
330
395
 
331
396
  }).call(this);
332
397
  (function() {
333
- var DeferredBindingProxy, DefineProxy;
398
+ var DefineProxy;
334
399
 
335
400
  Luca.define = function(componentName) {
336
401
  return new DefineProxy(componentName);
@@ -379,7 +444,7 @@
379
444
  };
380
445
 
381
446
  DefineProxy.prototype["with"] = function(properties) {
382
- var at, componentType;
447
+ var at, componentType, _base;
383
448
  at = this.namespaced ? Luca.util.resolve(this.namespace, window || global) : window || global;
384
449
  if (this.namespaced && !(at != null)) {
385
450
  eval("(window||global)." + this.namespace + " = {}");
@@ -389,6 +454,8 @@
389
454
  if (Luca.autoRegister === true) {
390
455
  if (Luca.isViewPrototype(at[this.componentId])) componentType = "view";
391
456
  if (Luca.isCollectionPrototype(at[this.componentId])) {
457
+ (_base = Luca.Collection).namespaces || (_base.namespaces = []);
458
+ Luca.Collection.namespaces.push(this.namespace);
392
459
  componentType = "collection";
393
460
  }
394
461
  if (Luca.isModelPrototype(at[this.componentId])) componentType = "model";
@@ -424,107 +491,6 @@
424
491
  def: Luca.define
425
492
  });
426
493
 
427
- DeferredBindingProxy = (function() {
428
-
429
- function DeferredBindingProxy(object, operation, wrapWithUnderscore) {
430
- var fn,
431
- _this = this;
432
- this.object = object;
433
- if (wrapWithUnderscore == null) wrapWithUnderscore = true;
434
- if (_.isFunction(operation)) {
435
- fn = operation;
436
- } else if (_.isString(operation) && _.isFunction(this.object[operation])) {
437
- fn = this.object[operation];
438
- }
439
- if (!_.isFunction(fn)) {
440
- throw "Must pass a function or a string representing one";
441
- }
442
- if (wrapWithUnderscore === true) {
443
- this.fn = function() {
444
- return _.defer(fn);
445
- };
446
- } else {
447
- this.fn = fn;
448
- }
449
- this;
450
- }
451
-
452
- DeferredBindingProxy.prototype.until = function(watch, trigger) {
453
- if ((watch != null) && !(trigger != null)) {
454
- trigger = watch;
455
- watch = this.object;
456
- }
457
- watch.once(trigger, this.fn);
458
- return this.object;
459
- };
460
-
461
- return DeferredBindingProxy;
462
-
463
- })();
464
-
465
- Luca.Events = {
466
- defer: function(operation, wrapWithUnderscore) {
467
- if (wrapWithUnderscore == null) wrapWithUnderscore = true;
468
- return new DeferredBindingProxy(this, operation, wrapWithUnderscore);
469
- },
470
- once: function(trigger, callback, context) {
471
- var onceFn;
472
- context || (context = this);
473
- onceFn = function() {
474
- callback.apply(context, arguments);
475
- return this.unbind(trigger, onceFn);
476
- };
477
- return this.bind(trigger, onceFn);
478
- }
479
- };
480
-
481
- Luca.ScriptLoader = (function() {
482
-
483
- ScriptLoader.loaded = {};
484
-
485
- function ScriptLoader(options) {
486
- var ready;
487
- if (options == null) options = {};
488
- _.extend(this, Backbone.Events, Luca.Events);
489
- this.autoStart = options.autoStart === true;
490
- this.scripts = options.scripts;
491
- ready = function() {
492
- return this.trigger("ready");
493
- };
494
- this.ready = _.after(this.scripts.length, ready);
495
- _.bindAll(this, "load", "ready");
496
- this.defer("load").until(this, "start");
497
- if (this.autoStart === true) this.trigger("start");
498
- this.bind("ready", this.onReady);
499
- }
500
-
501
- ScriptLoader.prototype.applyPrefix = function(script) {
502
- return script;
503
- };
504
-
505
- ScriptLoader.prototype.onReady = function() {
506
- return console.log("All dependencies loaded");
507
- };
508
-
509
- ScriptLoader.prototype.start = function() {
510
- return this.trigger("start");
511
- };
512
-
513
- ScriptLoader.prototype.load = function() {
514
- var script, _i, _len, _ref, _results;
515
- _ref = this.scripts;
516
- _results = [];
517
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
518
- script = _ref[_i];
519
- _results.push(Luca.util.loadScript(this.applyPrefix(script), this.ready));
520
- }
521
- return _results;
522
- };
523
-
524
- return ScriptLoader;
525
-
526
- })();
527
-
528
494
  }).call(this);
529
495
  (function() {
530
496
  var component_cache, registry;
@@ -608,7 +574,7 @@
608
574
 
609
575
  Luca.registry.classes = function(toString) {
610
576
  if (toString == null) toString = false;
611
- return _(registry.classes).map(function(className, ctype) {
577
+ return _(_.extend({}, registry.classes, registry.model_classes, registry.collection_classes)).map(function(className, ctype) {
612
578
  if (toString) {
613
579
  return className;
614
580
  } else {
@@ -641,7 +607,9 @@
641
607
  var customizeRender, originalExtend;
642
608
 
643
609
  _.def("Luca.View")["extends"]("Backbone.View")["with"]({
610
+ include: ['Luca.Events'],
644
611
  additionalClassNames: [],
612
+ hooks: ["after:initialize", "before:render", "after:render", "first:activation", "activation", "deactivation"],
645
613
  debug: function() {
646
614
  var message, _i, _len, _results;
647
615
  if (!(this.debugMode || (window.LucaDebugMode != null))) return;
@@ -663,7 +631,6 @@
663
631
  }
664
632
  return Backbone.View.prototype.trigger.apply(this, arguments);
665
633
  },
666
- hooks: ["after:initialize", "before:render", "after:render", "first:activation", "activation", "deactivation"],
667
634
  initialize: function(options) {
668
635
  var additional, template, unique, _i, _len, _ref;
669
636
  this.options = options != null ? options : {};
@@ -687,6 +654,7 @@
687
654
  this.$el.addClass(additional);
688
655
  }
689
656
  }
657
+ if (this.wrapperClass != null) this.$wrap(this.wrapperClass);
690
658
  this.trigger("after:initialize", this);
691
659
  this.registerCollectionEvents();
692
660
  return this.delegateEvents();
@@ -859,29 +827,35 @@
859
827
 
860
828
  }).call(this);
861
829
  (function() {
830
+ var setupComputedProperties;
831
+
832
+ setupComputedProperties = function() {
833
+ var attr, dependencies, _ref, _results,
834
+ _this = this;
835
+ if (_.isUndefined(this.computed)) return;
836
+ this._computed = {};
837
+ _ref = this.computed;
838
+ _results = [];
839
+ for (attr in _ref) {
840
+ dependencies = _ref[attr];
841
+ this.on("change:" + attr, function() {
842
+ return _this._computed[attr] = _this[attr].call(_this);
843
+ });
844
+ _results.push(_(dependencies).each(function(dep) {
845
+ _this.on("change:" + dep, function() {
846
+ return _this.trigger("change:" + attr);
847
+ });
848
+ if (_this.has(dep)) return _this.trigger("change:" + attr);
849
+ }));
850
+ }
851
+ return _results;
852
+ };
862
853
 
863
854
  _.def('Luca.Model')["extends"]('Backbone.Model')["with"]({
855
+ include: ['Luca.Events'],
864
856
  initialize: function() {
865
- var attr, dependencies, _ref, _results,
866
- _this = this;
867
857
  Backbone.Model.prototype.initialize(this, arguments);
868
- if (_.isUndefined(this.computed)) return;
869
- this._computed = {};
870
- _ref = this.computed;
871
- _results = [];
872
- for (attr in _ref) {
873
- dependencies = _ref[attr];
874
- this.on("change:" + attr, function() {
875
- return _this._computed[attr] = _this[attr].call(_this);
876
- });
877
- _results.push(_(dependencies).each(function(dep) {
878
- _this.on("change:" + dep, function() {
879
- return _this.trigger("change:" + attr);
880
- });
881
- if (_this.has(dep)) return _this.trigger("change:" + attr);
882
- }));
883
- }
884
- return _results;
858
+ return setupComputedProperties.call(this);
885
859
  },
886
860
  get: function(attr) {
887
861
  var _ref;
@@ -902,6 +876,7 @@
902
876
  if (Backbone.QueryCollection != null) source = 'Backbone.QueryCollection';
903
877
 
904
878
  _.def("Luca.Collection")["extends"](source)["with"]({
879
+ include: ['Luca.Events'],
905
880
  cachedMethods: [],
906
881
  remoteFilter: false,
907
882
  initialize: function(models, options) {
@@ -1839,6 +1814,12 @@
1839
1814
  }
1840
1815
  });
1841
1816
  },
1817
+ pluck: function(attribute) {
1818
+ return _(this.components).pluck(attribute);
1819
+ },
1820
+ invoke: function(method) {
1821
+ return _(this.components).invoke(method);
1822
+ },
1842
1823
  select: function(attribute, value, deep) {
1843
1824
  var components;
1844
1825
  if (deep == null) deep = false;
@@ -1847,8 +1828,8 @@
1847
1828
  matches = [];
1848
1829
  test = component[attribute];
1849
1830
  if (test === value) matches.push(component);
1850
- if (deep === true && component.isContainer === true) {
1851
- matches.push(component.select(attribute, value, true));
1831
+ if (deep === true) {
1832
+ matches.push(typeof component.select === "function" ? component.select(attribute, value, true) : void 0);
1852
1833
  }
1853
1834
  return _.compact(matches);
1854
1835
  });
@@ -2025,10 +2006,17 @@
2025
2006
  };
2026
2007
 
2027
2008
  CollectionManager.prototype.guessCollectionClass = function(key) {
2028
- var classified, guess;
2009
+ var classified, guess, guesses, _ref;
2029
2010
  classified = Luca.util.classify(key);
2030
2011
  guess = (this.collectionNamespace || (window || global))[classified];
2031
2012
  guess || (guess = (this.collectionNamespace || (window || global))["" + classified + "Collection"]);
2013
+ if (!(guess != null) && ((_ref = Luca.Collection.namespaces) != null ? _ref.length : void 0) > 0) {
2014
+ guesses = _(Luca.Collection.namespaces.reverse()).map(function(namespace) {
2015
+ return Luca.util.resolve("" + namespace + "." + classified) || Luca.util.resolve("" + namespace + "." + classified + "Collection");
2016
+ });
2017
+ guesses = _(guesses).compact();
2018
+ if (guesses.length > 0) guess = guesses[0];
2019
+ }
2032
2020
  return guess;
2033
2021
  };
2034
2022
 
@@ -2235,7 +2223,8 @@
2235
2223
  return this.activeComponent().trigger("first:activation", this, this.activeComponent());
2236
2224
  },
2237
2225
  activate: function(index, silent, callback) {
2238
- var current, previous, _ref, _ref2, _ref3, _ref4;
2226
+ var current, previous, _ref, _ref2, _ref3, _ref4,
2227
+ _this = this;
2239
2228
  if (silent == null) silent = false;
2240
2229
  if (_.isFunction(silent)) {
2241
2230
  silent = false;
@@ -2261,6 +2250,9 @@
2261
2250
  _ref2.apply(previous, ["before:activation", this, previous, current]);
2262
2251
  }
2263
2252
  }
2253
+ _.defer(function() {
2254
+ return _this.$el.data(_this.activeAttribute || "active-card", current.name);
2255
+ });
2264
2256
  }
2265
2257
  this.componentElements().hide();
2266
2258
  if (!current.previously_activated) {
@@ -2442,9 +2434,6 @@
2442
2434
  return _(elements).each(function(element) {
2443
2435
  return _this.$el.append(element);
2444
2436
  });
2445
- },
2446
- afterRender: function() {
2447
- return this._super("afterRender", this, arguments);
2448
2437
  }
2449
2438
  });
2450
2439
 
@@ -2577,7 +2566,7 @@
2577
2566
 
2578
2567
  _.def('Luca.containers.Viewport').extend('Luca.containers.CardView')["with"]({
2579
2568
  activeItem: 0,
2580
- className: 'luca-ui-viewport',
2569
+ additionalClassNames: 'luca-ui-viewport',
2581
2570
  fullscreen: true,
2582
2571
  fluid: false,
2583
2572
  wrapperClass: 'row',
@@ -2585,8 +2574,9 @@
2585
2574
  this.options = options != null ? options : {};
2586
2575
  _.extend(this, this.options);
2587
2576
  if (Luca.enableBootstrap === true) {
2588
- if (this.fluid === true) this.wrapperClass = "row-fluid";
2589
- this.$wrap(this.wrapperClass);
2577
+ if (this.fluid === true) {
2578
+ this.wrapperClass = "row-fluid fluid-viewport-wrapper";
2579
+ }
2590
2580
  }
2591
2581
  Luca.core.Container.prototype.initialize.apply(this, arguments);
2592
2582
  if (this.fullscreen) return $('html,body').addClass('luca-ui-fullscreen');
@@ -2604,8 +2594,8 @@
2604
2594
  if ((_ref = Luca.containers.CardView.prototype.after) != null) {
2605
2595
  _ref.apply(this, arguments);
2606
2596
  }
2607
- if (Luca.enableBootstrap === true) {
2608
- return this.$el.children().wrap('<div class="container" />');
2597
+ if (Luca.enableBootstrap === true && this.containerClassName) {
2598
+ return this.$el.children().wrap('<div class="#{ containerClassName }" />');
2609
2599
  }
2610
2600
  },
2611
2601
  renderTopNavigation: function() {
@@ -2631,6 +2621,11 @@
2631
2621
 
2632
2622
 
2633
2623
 
2624
+ }).call(this);
2625
+ (function() {
2626
+
2627
+
2628
+
2634
2629
  }).call(this);
2635
2630
  (function() {
2636
2631
 
@@ -2644,13 +2639,24 @@
2644
2639
 
2645
2640
  }).call(this);
2646
2641
  (function() {
2642
+ var startHistory;
2643
+
2644
+ startHistory = function() {
2645
+ return Backbone.history.start();
2646
+ };
2647
2647
 
2648
2648
  _.def('Luca.Application')["extends"]('Luca.containers.Viewport')["with"]({
2649
- autoStartHistory: true,
2649
+ name: "MyApp",
2650
+ defaultState: {},
2651
+ autoBoot: false,
2652
+ autoStartHistory: "before:render",
2650
2653
  useCollectionManager: true,
2654
+ collectionManager: {},
2651
2655
  collectionManagerClass: "Luca.CollectionManager",
2652
2656
  plugin: false,
2653
2657
  useController: true,
2658
+ useKeyHandler: false,
2659
+ keyEvents: {},
2654
2660
  components: [
2655
2661
  {
2656
2662
  ctype: 'template',
@@ -2660,37 +2666,41 @@
2660
2666
  }
2661
2667
  ],
2662
2668
  initialize: function(options) {
2663
- var definedComponents, _base,
2669
+ var alreadyRunning, app, appName, _base,
2664
2670
  _this = this;
2665
2671
  this.options = options != null ? options : {};
2672
+ app = this;
2673
+ appName = this.name;
2674
+ alreadyRunning = typeof Luca.getApplication === "function" ? Luca.getApplication() : void 0;
2675
+ (_base = Luca.Application).instances || (_base.instances = {});
2676
+ Luca.Application.instances[appName] = app;
2666
2677
  Luca.containers.Viewport.prototype.initialize.apply(this, arguments);
2667
- if (this.useController === true) definedComponents = this.components || [];
2668
- this.components = [
2669
- {
2670
- ctype: 'controller',
2671
- name: "main_controller",
2672
- components: definedComponents
2673
- }
2674
- ];
2675
- if (this.useCollectionManager === true) {
2676
- if (_.isString(this.collectionManagerClass)) {
2677
- this.collectionManagerClass = Luca.util.resolve(this.collectionManagerClass);
2678
- }
2679
- this.collectionManager || (this.collectionManager = typeof (_base = Luca.CollectionManager).get === "function" ? _base.get() : void 0);
2680
- this.collectionManager || (this.collectionManager = new this.collectionManagerClass(this.collectionManagerOptions || (this.collectionManagerOptions = {})));
2681
- }
2682
2678
  this.state = new Luca.Model(this.defaultState);
2679
+ this.setupMainController();
2680
+ this.setupCollectionManager();
2683
2681
  this.defer(function() {
2684
- return _this.render();
2685
- }).until("ready");
2686
- if (this.useKeyRouter === true && (this.keyEvents != null)) {
2687
- this.setupKeyRouter();
2688
- }
2689
- if (this.plugin !== true) {
2690
- return Luca.getApplication = function() {
2691
- return _this;
2682
+ return app.render();
2683
+ }).until(this, "ready");
2684
+ this.setupRouter();
2685
+ console.log("The useKeyRouter property is being deprecated. switch to useKeyHandler instead");
2686
+ if ((this.useKeyHandler === true || this.useKeyRouter === true) && (this.keyEvents != null)) {
2687
+ this.setupKeyHandler();
2688
+ }
2689
+ if (!(this.plugin === true || alreadyRunning)) {
2690
+ Luca.getApplication = function(name) {
2691
+ if (name == null) return app;
2692
+ return Luca.Application.instances[name];
2692
2693
  };
2693
2694
  }
2695
+ if (this.autoBoot) {
2696
+ if (Luca.util.resolve(this.name)) {
2697
+ throw "Attempting to override window." + this.name + " when it already exists";
2698
+ }
2699
+ return $(function() {
2700
+ window[appName] = app;
2701
+ return app.boot();
2702
+ });
2703
+ }
2694
2704
  },
2695
2705
  activeView: function() {
2696
2706
  var active;
@@ -2700,50 +2710,17 @@
2700
2710
  return this.view(this.activeSection());
2701
2711
  }
2702
2712
  },
2703
- activeSubSection: function() {
2704
- return this.get("active_sub_section");
2705
- },
2706
2713
  activeSection: function() {
2707
2714
  return this.get("active_section");
2708
2715
  },
2709
- beforeRender: function() {
2710
- var routerStartEvent, _ref;
2711
- if ((_ref = Luca.containers.Viewport.prototype.beforeRender) != null) {
2712
- _ref.apply(this, arguments);
2713
- }
2714
- if ((this.router != null) && this.autoStartHistory === true) {
2715
- routerStartEvent = this.startRouterOn || "after:render";
2716
- if (routerStartEvent === "before:render") {
2717
- return Backbone.history.start();
2718
- } else {
2719
- return this.bind(routerStartEvent, function() {
2720
- return Backbone.history.start();
2721
- });
2722
- }
2723
- }
2716
+ activeSubSection: function() {
2717
+ return this.get("active_sub_section");
2724
2718
  },
2725
- afterComponents: function() {
2726
- var _ref, _ref2, _ref3,
2727
- _this = this;
2728
- if ((_ref = Luca.containers.Viewport.prototype.afterComponents) != null) {
2729
- _ref.apply(this, arguments);
2730
- }
2731
- if ((_ref2 = this.getMainController()) != null) {
2732
- _ref2.bind("after:card:switch", function(previous, current) {
2733
- return _this.state.set({
2734
- active_section: current.name
2735
- });
2736
- });
2737
- }
2738
- return (_ref3 = this.getMainController()) != null ? _ref3.each(function(component) {
2739
- if (component.ctype.match(/controller$/)) {
2740
- return component.bind("after:card:switch", function(previous, current) {
2741
- return _this.state.set({
2742
- active_sub_section: current.name
2743
- });
2744
- });
2745
- }
2746
- }) : void 0;
2719
+ activePages: function() {
2720
+ var _this = this;
2721
+ return this.$('.luca-ui-controller').map(function(index, element) {
2722
+ return $(element).data('active-section');
2723
+ });
2747
2724
  },
2748
2725
  boot: function() {
2749
2726
  return this.trigger("ready");
@@ -2754,12 +2731,8 @@
2754
2731
  get: function(attribute) {
2755
2732
  return this.state.get(attribute);
2756
2733
  },
2757
- getMainController: function() {
2758
- if (this.useController === true) return this.components[0];
2759
- return Luca.cache('main_controller');
2760
- },
2761
- set: function(attributes) {
2762
- return this.state.set(attributes);
2734
+ set: function(attribute, value, options) {
2735
+ return this.state.set.apply(this.state, arguments);
2763
2736
  },
2764
2737
  view: function(name) {
2765
2738
  return Luca.cache(name);
@@ -2767,17 +2740,11 @@
2767
2740
  navigate_to: function(component_name, callback) {
2768
2741
  return this.getMainController().navigate_to(component_name, callback);
2769
2742
  },
2770
- setupKeyRouter: function() {
2771
- var router, _base;
2772
- if (!this.keyEvents) return;
2773
- (_base = this.keyEvents).control_meta || (_base.control_meta = {});
2774
- if (this.keyEvents.meta_control) {
2775
- _.extend(this.keyEvents.control_meta, this.keyEvents.meta_control);
2776
- }
2777
- router = _.bind(this.keyRouter, this);
2778
- return $(document).keydown(router);
2743
+ getMainController: function() {
2744
+ if (this.useController === true) return this.components[0];
2745
+ return Luca.cache('main_controller');
2779
2746
  },
2780
- keyRouter: function(e) {
2747
+ keyHandler: function(e) {
2781
2748
  var control, isInputEvent, keyEvent, keyname, meta, source, _ref;
2782
2749
  if (!(e && this.keyEvents)) return;
2783
2750
  isInputEvent = $(e.target).is('input') || $(e.target).is('textarea');
@@ -2797,6 +2764,88 @@
2797
2764
  return this.trigger(keyEvent);
2798
2765
  }
2799
2766
  }
2767
+ },
2768
+ setupControllerBindings: function() {
2769
+ var _ref, _ref2,
2770
+ _this = this;
2771
+ if ((_ref = this.getMainController()) != null) {
2772
+ _ref.bind("after:card:switch", function(previous, current) {
2773
+ return _this.state.set({
2774
+ active_section: current.name
2775
+ });
2776
+ });
2777
+ }
2778
+ return (_ref2 = this.getMainController()) != null ? _ref2.each(function(component) {
2779
+ if (component.ctype.match(/controller$/)) {
2780
+ return component.bind("after:card:switch", function(previous, current) {
2781
+ return _this.state.set({
2782
+ active_sub_section: current.name
2783
+ });
2784
+ });
2785
+ }
2786
+ }) : void 0;
2787
+ },
2788
+ setupMainController: function() {
2789
+ var definedComponents;
2790
+ if (this.useController === true) {
2791
+ definedComponents = this.components || [];
2792
+ this.components = [
2793
+ {
2794
+ ctype: 'controller',
2795
+ name: "main_controller",
2796
+ components: definedComponents
2797
+ }
2798
+ ];
2799
+ return this.defer(this.setupControllerBindings, false).until("after:components");
2800
+ }
2801
+ },
2802
+ setupCollectionManager: function() {
2803
+ var collectionManagerOptions, _base, _ref, _ref2;
2804
+ if (this.useCollectionManager === true) {
2805
+ if (_.isString(this.collectionManagerClass)) {
2806
+ this.collectionManagerClass = Luca.util.resolve(this.collectionManagerClass);
2807
+ }
2808
+ collectionManagerOptions = this.collectionManagerOptions;
2809
+ if (_.isObject(this.collectionManager) && !_.isFunction((_ref = this.collectionManager) != null ? _ref.get : void 0)) {
2810
+ collectionManagerOptions = this.collectionManager;
2811
+ this.collectionManager = void 0;
2812
+ }
2813
+ if (_.isString(this.collectionManager)) {
2814
+ collectionManagerOptions = {
2815
+ name: this.collectionManager
2816
+ };
2817
+ }
2818
+ this.collectionManager = typeof (_base = Luca.CollectionManager).get === "function" ? _base.get(collectionManagerOptions.name) : void 0;
2819
+ if (!_.isFunction((_ref2 = this.collectionManager) != null ? _ref2.get : void 0)) {
2820
+ return this.collectionManager = new this.collectionManagerClass(collectionManagerOptions);
2821
+ }
2822
+ }
2823
+ },
2824
+ setupRouter: function() {
2825
+ var app, routerClass;
2826
+ app = this;
2827
+ if (_.isString(this.router)) {
2828
+ routerClass = Luca.util.resolve(this.router);
2829
+ this.router = new routerClass({
2830
+ app: app
2831
+ });
2832
+ }
2833
+ if (this.router && this.autoStartHistory) {
2834
+ if (this.autoStartHistory === true) {
2835
+ this.autoStartHistory = "before:render";
2836
+ }
2837
+ return this.defer(startHistory, false).until(this, this.autoStartHistory);
2838
+ }
2839
+ },
2840
+ setupKeyHandler: function() {
2841
+ var handler, _base;
2842
+ if (!this.keyEvents) return;
2843
+ (_base = this.keyEvents).control_meta || (_base.control_meta = {});
2844
+ if (this.keyEvents.meta_control) {
2845
+ _.extend(this.keyEvents.control_meta, this.keyEvents.meta_control);
2846
+ }
2847
+ handler = _.bind(this.keyHandler, this);
2848
+ return $(document).keydown(handler);
2800
2849
  }
2801
2850
  });
2802
2851
 
@@ -2904,7 +2953,7 @@
2904
2953
  content = templateFn.call(this, item);
2905
2954
  }
2906
2955
  if ((this.itemRenderer != null) && _.isFunction(this.itemRenderer)) {
2907
- content = this.itemRenderer.call(this, item);
2956
+ content = this.itemRenderer.call(this, item, item.model, item.index);
2908
2957
  }
2909
2958
  if (this.itemProperty) {
2910
2959
  content = item.model.get(this.itemProperty) || item.model[this.itemProperty];
@@ -2957,6 +3006,8 @@
2957
3006
  (function() {
2958
3007
 
2959
3008
  _.def('Luca.components.Controller')["extends"]('Luca.containers.CardView')["with"]({
3009
+ additionalClassNames: ['luca-ui-controller'],
3010
+ activeAttribute: "active-section",
2960
3011
  initialize: function(options) {
2961
3012
  var _ref;
2962
3013
  this.options = options;
@@ -2975,6 +3026,27 @@
2975
3026
  return fn.apply(_this, [component]);
2976
3027
  });
2977
3028
  },
3029
+ activeSection: function() {
3030
+ return this.get("activeSection");
3031
+ },
3032
+ controllers: function(deep) {
3033
+ if (deep == null) deep = false;
3034
+ return this.select('ctype', 'controller', deep);
3035
+ },
3036
+ availableSections: function() {
3037
+ var base,
3038
+ _this = this;
3039
+ base = {};
3040
+ base[this.name] = this.sectionNames();
3041
+ return _(this.controllers()).reduce(function(memo, controller) {
3042
+ memo[controller.name] = controller.sectionNames();
3043
+ return memo;
3044
+ }, base);
3045
+ },
3046
+ sectionNames: function(deep) {
3047
+ if (deep == null) deep = false;
3048
+ return this.pluck('name');
3049
+ },
2978
3050
  "default": function(callback) {
2979
3051
  return this.navigate_to(this.defaultCard, callback);
2980
3052
  },
@@ -4286,13 +4358,7 @@
4286
4358
  }).call(this);
4287
4359
  (function() {
4288
4360
 
4289
- _.extend(Luca, Luca.Events);
4290
-
4291
- _.extend(Luca.View.prototype, Luca.Events);
4292
-
4293
- _.extend(Luca.Collection.prototype, Luca.Events);
4294
4361
 
4295
- _.extend(Luca.Model.prototype, Luca.Events);
4296
4362
 
4297
4363
  }).call(this);
4298
4364
  (function() {