luca 0.9.6 → 0.9.7

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 (76) hide show
  1. data/CHANGELOG +37 -14
  2. data/lib/luca/rails/version.rb +1 -1
  3. data/spec/components/collection_view_spec.coffee +24 -2
  4. data/spec/components/pagination_control_spec.coffee +0 -0
  5. data/spec/concerns/dom_helpers_spec.coffee +16 -0
  6. data/spec/concerns/filterable_spec.coffee +25 -0
  7. data/spec/concerns/model_presenter_spec.coffee +31 -0
  8. data/spec/concerns/paginatable_spec.coffee +0 -0
  9. data/spec/concerns/state_model_spec.coffee +0 -0
  10. data/spec/concerns_spec.coffee +88 -0
  11. data/spec/core/container_spec.coffee +74 -12
  12. data/spec/core/model_spec.coffee +6 -1
  13. data/spec/define_spec.coffee +0 -6
  14. data/spec/util_spec.coffee +24 -0
  15. data/src/components/application.coffee +32 -30
  16. data/src/components/base_toolbar.coffee +6 -4
  17. data/src/components/collection_loader_view.coffee +3 -1
  18. data/src/components/collection_view.coffee +42 -21
  19. data/src/components/controller.coffee +3 -1
  20. data/src/components/fields/button_field.coffee +19 -12
  21. data/src/components/fields/checkbox_array.coffee +8 -2
  22. data/src/components/fields/checkbox_field.coffee +18 -9
  23. data/src/components/fields/file_upload_field.coffee +5 -1
  24. data/src/components/fields/hidden_field.coffee +3 -1
  25. data/src/components/fields/label_field.coffee +4 -3
  26. data/src/components/fields/select_field.coffee +7 -8
  27. data/src/components/fields/text_field.coffee +3 -1
  28. data/src/components/fields/type_ahead_field.coffee +4 -2
  29. data/src/components/form_button_toolbar.coffee +4 -1
  30. data/src/components/form_view.coffee +49 -44
  31. data/src/components/grid_view.coffee +1 -1
  32. data/src/components/multi_collection_view.coffee +49 -22
  33. data/src/components/pagination_control.coffee +17 -13
  34. data/src/{modules → concerns}/application_event_bindings.coffee +1 -1
  35. data/src/{modules → concerns}/collection_event_bindings.coffee +1 -1
  36. data/src/{modules → concerns}/deferrable.coffee +1 -1
  37. data/src/{modules → concerns}/dom_helpers.coffee +11 -2
  38. data/src/{modules → concerns}/enhanced_properties.coffee +1 -1
  39. data/src/concerns/filterable.coffee +82 -0
  40. data/src/{modules → concerns}/grid_layout.coffee +1 -1
  41. data/src/{modules → concerns}/loadmaskable.coffee +1 -1
  42. data/src/{modules → concerns}/local_storage.coffee +0 -0
  43. data/src/{modules → concerns}/modal_view.coffee +1 -1
  44. data/src/concerns/model_presenter.coffee +23 -0
  45. data/src/concerns/paginatable.coffee +87 -0
  46. data/src/{modules → concerns}/state_model.coffee +1 -1
  47. data/src/{modules → concerns}/templating.coffee +1 -1
  48. data/src/concerns.coffee +70 -0
  49. data/src/containers/tab_view.coffee +7 -10
  50. data/src/core/collection.coffee +17 -1
  51. data/src/core/container.coffee +56 -31
  52. data/src/core/field.coffee +39 -38
  53. data/src/core/meta_data.coffee +37 -0
  54. data/src/core/model.coffee +18 -1
  55. data/src/core/view.coffee +25 -29
  56. data/src/define.coffee +54 -66
  57. data/src/framework.coffee +23 -18
  58. data/src/index.coffee +3 -1
  59. data/src/stylesheets/components/checkbox_array.scss +1 -1
  60. data/src/stylesheets/components/form_view.scss +5 -5
  61. data/src/stylesheets/components/viewport.scss +2 -1
  62. data/src/stylesheets/containers/container.scss +0 -5
  63. data/src/stylesheets/containers/tab_view.scss +5 -5
  64. data/src/tools/console.coffee +5 -5
  65. data/src/util.coffee +47 -0
  66. data/vendor/assets/javascripts/luca-ui-development-tools.js +5 -5
  67. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
  68. data/vendor/assets/javascripts/luca-ui-full.js +905 -416
  69. data/vendor/assets/javascripts/luca-ui-full.min.js +5 -5
  70. data/vendor/assets/javascripts/luca-ui.js +905 -416
  71. data/vendor/assets/javascripts/luca-ui.min.js +5 -4
  72. data/vendor/assets/stylesheets/luca-ui.css +15 -15
  73. metadata +27 -17
  74. data/spec/mixin_spec.coffee +0 -49
  75. data/src/modules/filterable.coffee +0 -60
  76. data/src/modules/paginatable.coffee +0 -79
@@ -95,11 +95,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
95
95
  };
96
96
 
97
97
  _.extend(Luca, {
98
- VERSION: "0.9.6",
98
+ VERSION: "0.9.7",
99
99
  core: {},
100
+ collections: {},
100
101
  containers: {},
101
102
  components: {},
102
- modules: {},
103
+ models: {},
104
+ concerns: {},
103
105
  util: {},
104
106
  fields: {},
105
107
  registry: {},
@@ -109,6 +111,12 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
109
111
 
110
112
  _.extend(Luca, Backbone.Events);
111
113
 
114
+ Luca.config.maintainStyleHierarchy = true;
115
+
116
+ Luca.config.maintainClassHierarchy = true;
117
+
118
+ Luca.config.autoApplyClassHierarchyAsCssClasses = true;
119
+
112
120
  Luca.autoRegister = Luca.config.autoRegister = true;
113
121
 
114
122
  Luca.developmentMode = Luca.config.developmentMode = false;
@@ -182,36 +190,29 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
182
190
  };
183
191
 
184
192
  Luca.inheritanceChain = function(obj) {
185
- return _(Luca.parentClasses(obj)).map(function(className) {
186
- return Luca.util.resolve(className);
187
- });
193
+ return Luca.parentClasses(obj);
188
194
  };
189
195
 
190
196
  Luca.parentClasses = function(obj) {
191
- var classes, list, _ref;
197
+ var list, metaData, _base;
192
198
  list = [];
193
199
  if (_.isString(obj)) obj = Luca.util.resolve(obj);
194
- list.push(obj.displayName || ((_ref = obj.prototype) != null ? _ref.displayName : void 0) || Luca.parentClass(obj));
195
- classes = (function() {
196
- var _results;
197
- _results = [];
198
- while (!!(Luca.parentClass(obj) != null)) {
199
- _results.push(obj = Luca.parentClass(obj));
200
- }
201
- return _results;
202
- })();
203
- list = list.concat(classes);
204
- return _.uniq(list);
200
+ metaData = typeof obj.componentMetaData === "function" ? obj.componentMetaData() : void 0;
201
+ metaData || (metaData = typeof (_base = obj.prototype).componentMetaData === "function" ? _base.componentMetaData() : void 0);
202
+ return list = (metaData != null ? metaData.classHierarchy() : void 0) || [obj.displayName || obj.prototype.displayName];
205
203
  };
206
204
 
207
- Luca.parentClass = function(obj) {
208
- var list, _base, _ref;
209
- list = [];
205
+ Luca.parentClass = function(obj, resolve) {
206
+ var parent, _base, _ref, _ref2, _ref3;
207
+ if (resolve == null) resolve = true;
210
208
  if (_.isString(obj)) obj = Luca.util.resolve(obj);
211
- if (Luca.isComponent(obj)) {
212
- return obj.displayName;
213
- } else if (Luca.isComponentPrototype(obj)) {
214
- return typeof (_base = obj.prototype)._superClass === "function" ? (_ref = _base._superClass()) != null ? _ref.displayName : void 0 : void 0;
209
+ parent = typeof obj.componentMetaData === "function" ? (_ref = obj.componentMetaData()) != null ? _ref.meta["super class name"] : void 0 : void 0;
210
+ parent || (parent = typeof (_base = obj.prototype).componentMetaData === "function" ? (_ref2 = _base.componentMetaData()) != null ? _ref2.meta["super class name"] : void 0 : void 0);
211
+ parent || obj.displayName || ((_ref3 = obj.prototype) != null ? _ref3.displayName : void 0);
212
+ if (resolve) {
213
+ return Luca.util.resolve(parent);
214
+ } else {
215
+ return parent;
215
216
  }
216
217
  };
217
218
 
@@ -451,6 +452,25 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
451
452
  return fn = prefix + parts.join('');
452
453
  };
453
454
 
455
+ Luca.util.toCssClass = function() {
456
+ var componentName, exclusions, part, parts, transformed;
457
+ componentName = arguments[0], exclusions = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
458
+ parts = componentName.split('.');
459
+ transformed = (function() {
460
+ var _i, _len, _results;
461
+ _results = [];
462
+ for (_i = 0, _len = parts.length; _i < _len; _i++) {
463
+ part = parts[_i];
464
+ if (!(_(exclusions).indexOf(part) === -1)) continue;
465
+ part = _.str.underscored(part);
466
+ part = part.replace(/_/g, '-');
467
+ _results.push(part);
468
+ }
469
+ return _results;
470
+ })();
471
+ return transformed.join('-');
472
+ };
473
+
454
474
  Luca.util.isIE = function() {
455
475
  try {
456
476
  Object.defineProperty({}, '', {});
@@ -545,6 +565,48 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
545
565
  }, contents);
546
566
  };
547
567
 
568
+ Luca.util.setupHooks = function(set) {
569
+ var _this = this;
570
+ set || (set = this.hooks);
571
+ return _(set).each(function(eventId) {
572
+ var callback, fn;
573
+ fn = Luca.util.hook(eventId);
574
+ callback = function() {
575
+ var _ref;
576
+ return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
577
+ };
578
+ if (eventId != null ? eventId.match(/once:/) : void 0) {
579
+ callback = _.once(callback);
580
+ }
581
+ return _this.on(eventId, callback, _this);
582
+ });
583
+ };
584
+
585
+ Luca.util.setupHooksAdvanced = function(set) {
586
+ var _this = this;
587
+ set || (set = this.hooks);
588
+ return _(set).each(function(eventId) {
589
+ var callback, entry, fn, hookSetup, _i, _len, _results;
590
+ hookSetup = _this[Luca.util.hook(eventId)];
591
+ if (!_.isArray(hookSetup)) hookSetup = [hookSetup];
592
+ _results = [];
593
+ for (_i = 0, _len = hookSetup.length; _i < _len; _i++) {
594
+ entry = hookSetup[_i];
595
+ fn = _.isString(entry) ? _this[entry] : void 0;
596
+ if (_.isFunction(entry)) fn = entry;
597
+ callback = function() {
598
+ var _ref;
599
+ return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
600
+ };
601
+ if (eventId != null ? eventId.match(/once:/) : void 0) {
602
+ callback = _.once(callback);
603
+ }
604
+ _results.push(_this.on(eventId, callback, _this));
605
+ }
606
+ return _results;
607
+ });
608
+ };
609
+
548
610
  }).call(this);
549
611
  (function() {
550
612
 
@@ -701,6 +763,92 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
701
763
  }
702
764
  };
703
765
 
766
+ }).call(this);
767
+ (function() {
768
+
769
+ Luca.concern = function(mixinName) {
770
+ var namespace, resolved;
771
+ namespace = _(Luca.concern.namespaces).detect(function(space) {
772
+ var _ref;
773
+ return ((_ref = Luca.util.resolve(space)) != null ? _ref[mixinName] : void 0) != null;
774
+ });
775
+ namespace || (namespace = "Luca.concerns");
776
+ resolved = Luca.util.resolve(namespace)[mixinName];
777
+ if (resolved == null) {
778
+ console.log("Could not find " + mixinName + " in ", Luca.concern.namespaces);
779
+ }
780
+ return resolved;
781
+ };
782
+
783
+ Luca.concern.namespaces = ["Luca.concerns"];
784
+
785
+ Luca.concern.namespace = function(namespace) {
786
+ Luca.concern.namespaces.push(namespace);
787
+ return Luca.concern.namespaces = _(Luca.concern.namespaces).uniq();
788
+ };
789
+
790
+ Luca.concern.setup = function() {
791
+ var module, _i, _len, _ref, _ref2, _ref3, _ref4, _results;
792
+ if (((_ref = this.concerns) != null ? _ref.length : void 0) > 0) {
793
+ _ref2 = this.concerns;
794
+ _results = [];
795
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
796
+ module = _ref2[_i];
797
+ _results.push((_ref3 = Luca.concern(module)) != null ? (_ref4 = _ref3.__initializer) != null ? _ref4.call(this, this, module) : void 0 : void 0);
798
+ }
799
+ return _results;
800
+ }
801
+ };
802
+
803
+ Luca.decorate = function(target) {
804
+ var componentClass, componentName, componentPrototype;
805
+ try {
806
+ if (_.isString(target)) {
807
+ componentName = target;
808
+ componentClass = Luca.util.resolve(componentName);
809
+ }
810
+ if (_.isFunction(target)) componentClass = target;
811
+ componentPrototype = componentClass.prototype;
812
+ componentName = componentName || componentClass.displayName;
813
+ componentName || (componentName = componentPrototype.displayName);
814
+ } catch (e) {
815
+ console.log(e.message);
816
+ console.log(e.stack);
817
+ console.log("Error calling Luca.decorate on ", componentClass, componentPrototype, componentName);
818
+ throw e;
819
+ }
820
+ return {
821
+ "with": function(mixinName) {
822
+ var fn, method, mixinDefinition, mixinPrivates, sanitized, superclassMixins, _ref;
823
+ mixinDefinition = Luca.concern(mixinName);
824
+ mixinDefinition.__displayName || (mixinDefinition.__displayName = mixinName);
825
+ mixinPrivates = _(mixinDefinition).chain().keys().select(function(key) {
826
+ return ("" + key).match(/^__/) || key === "classMethods";
827
+ });
828
+ sanitized = _(mixinDefinition).omit(mixinPrivates.value());
829
+ _.extend(componentPrototype, sanitized);
830
+ if (mixinDefinition.classMethods != null) {
831
+ _ref = mixinDefinition.classMethods;
832
+ for (method in _ref) {
833
+ fn = _ref[method];
834
+ componentClass[method] = _.bind(fn, componentClass);
835
+ }
836
+ }
837
+ if (mixinDefinition != null) {
838
+ if (typeof mixinDefinition.__included === "function") {
839
+ mixinDefinition.__included(componentName, componentClass, mixinDefinition);
840
+ }
841
+ }
842
+ superclassMixins = componentPrototype._superClass().prototype.concerns;
843
+ componentPrototype.concerns || (componentPrototype.concerns = []);
844
+ componentPrototype.concerns.push(mixinName);
845
+ componentPrototype.concerns = componentPrototype.concerns.concat(superclassMixins);
846
+ componentPrototype.concerns = _(componentPrototype.concerns).chain().uniq().compact().value();
847
+ return componentPrototype;
848
+ }
849
+ };
850
+ };
851
+
704
852
  }).call(this);
705
853
  (function() {
706
854
  var DefineProxy,
@@ -709,7 +857,8 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
709
857
  _.mixin({
710
858
  def: Luca.component = Luca.define = Luca.register = function(componentName) {
711
859
  return new DefineProxy(componentName);
712
- }
860
+ },
861
+ register: Luca.register
713
862
  });
714
863
 
715
864
  DefineProxy = (function() {
@@ -719,6 +868,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
719
868
  this.namespace = Luca.util.namespace();
720
869
  this.componentId = this.componentName = componentName;
721
870
  this.superClassName = 'Luca.View';
871
+ this.properties || (this.properties = {});
722
872
  if (componentName.match(/\./)) {
723
873
  this.namespaced = true;
724
874
  parts = componentName.split('.');
@@ -728,6 +878,16 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
728
878
  }
729
879
  }
730
880
 
881
+ DefineProxy.prototype.meta = function(key, value) {
882
+ var data, metaKey;
883
+ metaKey = this.namespace + '.' + this.componentId;
884
+ metaKey = metaKey.replace(/^\./, '');
885
+ data = Luca.registry.addMetaData(metaKey, key, value);
886
+ return this.properties.componentMetaData = function() {
887
+ return Luca.registry.getMetaDataFor(metaKey);
888
+ };
889
+ };
890
+
731
891
  DefineProxy.prototype["in"] = function(namespace) {
732
892
  this.namespace = namespace;
733
893
  return this;
@@ -759,6 +919,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
759
919
  this.properties.hooks.push(hook);
760
920
  }
761
921
  this.properties.hooks = _.uniq(this.properties.hooks);
922
+ this.meta("hooks", this.properties.hooks);
762
923
  return this;
763
924
  };
764
925
 
@@ -773,25 +934,51 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
773
934
  this.properties.include.push(include);
774
935
  }
775
936
  this.properties.include = _.uniq(this.properties.include);
937
+ this.meta("includes", this.properties.include);
776
938
  return this;
777
939
  };
778
940
 
779
941
  DefineProxy.prototype.mixesIn = function() {
780
- var mixin, mixins, _i, _len;
781
- mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
942
+ var concern, concerns, _i, _len;
943
+ concerns = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
782
944
  _.defaults(this.properties || (this.properties = {}), {
783
- mixins: []
945
+ concerns: []
784
946
  });
785
- for (_i = 0, _len = mixins.length; _i < _len; _i++) {
786
- mixin = mixins[_i];
787
- this.properties.mixins.push(mixin);
947
+ for (_i = 0, _len = concerns.length; _i < _len; _i++) {
948
+ concern = concerns[_i];
949
+ this.properties.concerns.push(concern);
788
950
  }
789
- this.properties.mixins = _.uniq(this.properties.mixins);
951
+ this.properties.concerns = _.uniq(this.properties.concerns);
952
+ this.meta("concerns", this.properties.concerns);
790
953
  return this;
791
954
  };
792
955
 
793
- DefineProxy.prototype.defaultProperties = function(properties) {
794
- var at, componentType, _base;
956
+ DefineProxy.prototype.publicConfiguration = function(properties) {
957
+ if (properties == null) properties = {};
958
+ this.meta("public configuration", _.keys(properties));
959
+ return _.defaults((this.properties || (this.properties = {})), properties);
960
+ };
961
+
962
+ DefineProxy.prototype.privateConfiguration = function(properties) {
963
+ if (properties == null) properties = {};
964
+ this.meta("private configuration", _.keys(properties));
965
+ return _.defaults((this.properties || (this.properties = {})), properties);
966
+ };
967
+
968
+ DefineProxy.prototype.publicInterface = function(properties) {
969
+ if (properties == null) properties = {};
970
+ this.meta("public interface", _.keys(properties));
971
+ return _.defaults((this.properties || (this.properties = {})), properties);
972
+ };
973
+
974
+ DefineProxy.prototype.privateInterface = function(properties) {
975
+ if (properties == null) properties = {};
976
+ this.meta("private interface", _.keys(properties));
977
+ return _.defaults((this.properties || (this.properties = {})), properties);
978
+ };
979
+
980
+ DefineProxy.prototype.definePrototype = function(properties) {
981
+ var at, componentType, definition, _base;
795
982
  if (properties == null) properties = {};
796
983
  _.defaults((this.properties || (this.properties = {})), properties);
797
984
  at = this.namespaced ? Luca.util.resolve(this.namespace, window || global) : window || global;
@@ -799,35 +986,40 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
799
986
  eval("(window||global)." + this.namespace + " = {}");
800
987
  at = Luca.util.resolve(this.namespace, window || global);
801
988
  }
802
- at[this.componentId] = Luca.extend(this.superClassName, this.componentName, this.properties);
803
- if (Luca.autoRegister === true) {
804
- if (Luca.isViewPrototype(at[this.componentId])) componentType = "view";
805
- if (Luca.isCollectionPrototype(at[this.componentId])) {
989
+ this.meta("super class name", this.superClassName);
990
+ this.meta("display name", this.componentName);
991
+ this.properties.displayName = this.componentName;
992
+ this.properties.componentMetaData = function() {
993
+ return Luca.registry.getMetaDataFor(this.displayName);
994
+ };
995
+ definition = at[this.componentId] = Luca.extend(this.superClassName, this.componentName, this.properties);
996
+ if (Luca.config.autoRegister === true) {
997
+ if (Luca.isViewPrototype(definition)) componentType = "view";
998
+ if (Luca.isCollectionPrototype(definition)) {
806
999
  (_base = Luca.Collection).namespaces || (_base.namespaces = []);
807
1000
  Luca.Collection.namespaces.push(this.namespace);
808
1001
  componentType = "collection";
809
1002
  }
810
- if (Luca.isModelPrototype(at[this.componentId])) componentType = "model";
1003
+ if (Luca.isModelPrototype(definition)) componentType = "model";
811
1004
  Luca.registerComponent(_.string.underscored(this.componentId), this.componentName, componentType);
812
1005
  }
813
- return at[this.componentId];
1006
+ return definition;
814
1007
  };
815
1008
 
816
1009
  return DefineProxy;
817
1010
 
818
1011
  })();
819
1012
 
820
- DefineProxy.prototype.behavesAs = DefineProxy.prototype.uses = DefineProxy.prototype.mixesIn;
1013
+ DefineProxy.prototype.concerns = DefineProxy.prototype.behavesAs = DefineProxy.prototype.uses = DefineProxy.prototype.mixesIn;
821
1014
 
822
- DefineProxy.prototype.defines = DefineProxy.prototype.defaults = DefineProxy.prototype.exports = DefineProxy.prototype.defaultProperties;
1015
+ DefineProxy.prototype.defines = DefineProxy.prototype.defaults = DefineProxy.prototype.exports = DefineProxy.prototype.defaultProperties = DefineProxy.prototype.definePrototype;
823
1016
 
824
- DefineProxy.prototype.defaultsTo = DefineProxy.prototype.enhance = DefineProxy.prototype["with"] = DefineProxy.prototype.defaultProperties;
1017
+ DefineProxy.prototype.defaultsTo = DefineProxy.prototype.enhance = DefineProxy.prototype["with"] = DefineProxy.prototype.definePrototype;
825
1018
 
826
1019
  Luca.extend = function(superClassName, childName, properties) {
827
1020
  var definition, include, superClass, _i, _len, _ref;
828
1021
  if (properties == null) properties = {};
829
1022
  superClass = Luca.util.resolve(superClassName, window || global);
830
- superClass.__initializers || (superClass.__initializers = []);
831
1023
  if (!_.isFunction(superClass != null ? superClass.extend : void 0)) {
832
1024
  throw "Error defining " + childName + ". " + superClassName + " is not a valid component to extend from";
833
1025
  }
@@ -854,59 +1046,10 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
854
1046
  return definition;
855
1047
  };
856
1048
 
857
- Luca.mixin = function(mixinName) {
858
- var namespace, resolved;
859
- namespace = _(Luca.mixin.namespaces).detect(function(space) {
860
- var _ref;
861
- return ((_ref = Luca.util.resolve(space)) != null ? _ref[mixinName] : void 0) != null;
862
- });
863
- namespace || (namespace = "Luca.modules");
864
- resolved = Luca.util.resolve(namespace)[mixinName];
865
- if (resolved == null) {
866
- console.log("Could not find " + mixinName + " in ", Luca.mixin.namespaces);
867
- }
868
- return resolved;
869
- };
870
-
871
- Luca.mixin.namespaces = ["Luca.modules"];
872
-
873
- Luca.mixin.namespace = function(namespace) {
874
- Luca.mixin.namespaces.push(namespace);
875
- return Luca.mixin.namespaces = _(Luca.mixin.namespaces).uniq();
876
- };
877
-
878
- Luca.decorate = function(componentPrototype) {
879
- if (_.isString(componentPrototype)) {
880
- componentPrototype = Luca.util.resolve(componentPrototype).prototype;
881
- }
882
- return {
883
- "with": function(mixin) {
884
- var mixinDefinition, mixinPrivates, sanitized, superclassMixins, _ref;
885
- mixinDefinition = Luca.mixin(mixin);
886
- mixinPrivates = _(mixinDefinition).chain().keys().select(function(key) {
887
- return ("" + key).match(/^__/);
888
- });
889
- sanitized = _(mixinDefinition).omit(mixinPrivates.value());
890
- _.extend(componentPrototype, sanitized);
891
- if (mixinDefinition != null) {
892
- if ((_ref = mixinDefinition.__included) != null) {
893
- _ref.call(mixinDefinition, mixin);
894
- }
895
- }
896
- superclassMixins = componentPrototype._superClass().prototype.mixins;
897
- componentPrototype.mixins || (componentPrototype.mixins = []);
898
- componentPrototype.mixins.push(mixin);
899
- componentPrototype.mixins = componentPrototype.mixins.concat(superclassMixins);
900
- componentPrototype.mixins = _(componentPrototype.mixins).chain().uniq().compact().value();
901
- return componentPrototype;
902
- }
903
- };
904
- };
905
-
906
1049
  }).call(this);
907
1050
  (function() {
908
1051
 
909
- Luca.modules.ApplicationEventBindings = {
1052
+ Luca.concerns.ApplicationEventBindings = {
910
1053
  __initializer: function() {
911
1054
  var app, eventTrigger, handler, _len, _ref, _ref2, _results;
912
1055
  if (_.isEmpty(this.applicationEvents)) return;
@@ -934,7 +1077,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
934
1077
  }).call(this);
935
1078
  (function() {
936
1079
 
937
- Luca.modules.CollectionEventBindings = {
1080
+ Luca.concerns.CollectionEventBindings = {
938
1081
  __initializer: function() {
939
1082
  var collection, eventTrigger, handler, key, manager, signature, _ref, _ref2, _results;
940
1083
  if (_.isEmpty(this.collectionEvents)) return;
@@ -962,7 +1105,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
962
1105
  }).call(this);
963
1106
  (function() {
964
1107
 
965
- Luca.modules.Deferrable = {
1108
+ Luca.concerns.Deferrable = {
966
1109
  configure_collection: function(setAsDeferrable) {
967
1110
  var collectionManager, _ref, _ref2;
968
1111
  if (setAsDeferrable == null) setAsDeferrable = true;
@@ -983,9 +1126,9 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
983
1126
  }).call(this);
984
1127
  (function() {
985
1128
 
986
- Luca.modules.DomHelpers = {
1129
+ Luca.concerns.DomHelpers = {
987
1130
  __initializer: function() {
988
- var additional, additionalClasses, _i, _len, _results;
1131
+ var additional, additionalClasses, classes, cssClass, _i, _j, _len, _len2, _ref, _results;
989
1132
  additionalClasses = _(this.additionalClassNames || []).clone();
990
1133
  if (this.wrapperClass != null) this.$wrap(this.wrapperClass);
991
1134
  if (_.isString(additionalClasses)) {
@@ -996,21 +1139,34 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
996
1139
  if (this.gridRowFluid) additionalClasses.push("row-fluid");
997
1140
  if (this.gridRow) additionalClasses.push("row");
998
1141
  if (additionalClasses == null) return;
999
- _results = [];
1000
1142
  for (_i = 0, _len = additionalClasses.length; _i < _len; _i++) {
1001
1143
  additional = additionalClasses[_i];
1002
- _results.push(this.$el.addClass(additional));
1144
+ this.$el.addClass(additional);
1145
+ }
1146
+ if (Luca.config.autoApplyClassHierarchyAsCssClasses === true) {
1147
+ classes = (typeof this.componentMetaData === "function" ? (_ref = this.componentMetaData()) != null ? _ref.styleHierarchy() : void 0 : void 0) || [];
1148
+ _results = [];
1149
+ for (_j = 0, _len2 = classes.length; _j < _len2; _j++) {
1150
+ cssClass = classes[_j];
1151
+ if (cssClass !== "luca-view" && cssClass !== "backbone-view") {
1152
+ _results.push(this.$el.addClass(cssClass));
1153
+ }
1154
+ }
1155
+ return _results;
1003
1156
  }
1004
- return _results;
1005
1157
  },
1006
1158
  $wrap: function(wrapper) {
1007
1159
  if (_.isString(wrapper) && !wrapper.match(/[<>]/)) {
1008
1160
  wrapper = this.make("div", {
1009
- "class": wrapper
1161
+ "class": wrapper,
1162
+ "data-wrapper": true
1010
1163
  });
1011
1164
  }
1012
1165
  return this.$el.wrap(wrapper);
1013
1166
  },
1167
+ $wrapper: function() {
1168
+ return this.$el.parent('[data-wrapper="true"]');
1169
+ },
1014
1170
  $template: function(template, variables) {
1015
1171
  if (variables == null) variables = {};
1016
1172
  return this.$el.html(Luca.template(template, variables));
@@ -1035,7 +1191,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1035
1191
  }).call(this);
1036
1192
  (function() {
1037
1193
 
1038
- Luca.modules.EnhancedProperties = {
1194
+ Luca.concerns.EnhancedProperties = {
1039
1195
  __initializer: function() {
1040
1196
  if (Luca.config.enhancedViewProperties !== true) return;
1041
1197
  if (_.isString(this.collection) && Luca.CollectionManager.get()) {
@@ -1054,50 +1210,56 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1054
1210
  __hasProp = Object.prototype.hasOwnProperty,
1055
1211
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
1056
1212
 
1057
- Luca.modules.Filterable = {
1213
+ Luca.concerns.Filterable = {
1058
1214
  __included: function(component, module) {
1059
1215
  return _.extend(Luca.Collection.prototype, {
1060
1216
  __filters: {}
1061
1217
  });
1062
1218
  },
1063
1219
  __initializer: function(component, module) {
1064
- var filter,
1220
+ var filter, _base, _ref,
1065
1221
  _this = this;
1066
- if (this.filterable === false || !Luca.isBackboneCollection(this.collection)) {
1222
+ if (this.filterable === false) return;
1223
+ if (!Luca.isBackboneCollection(this.collection)) {
1224
+ this.collection = typeof (_base = Luca.CollectionManager).get === "function" ? (_ref = _base.get()) != null ? _ref.getOrCreate(this.collection) : void 0 : void 0;
1225
+ }
1226
+ if (!Luca.isBackboneCollection(this.collection)) {
1227
+ this.debug("Skipping Filterable due to no collection being present on " + (this.name || this.cid));
1228
+ this.debug("Collection", this.collection);
1067
1229
  return;
1068
1230
  }
1069
1231
  this.getCollection || (this.getCollection = function() {
1070
1232
  return this.collection;
1071
1233
  });
1072
1234
  filter = this.getFilterState();
1073
- filter.on("change", function(state) {
1074
- _this.trigger("collection:change:filter", state, _this.getCollection());
1075
- return _this.trigger("refresh");
1235
+ this.querySources || (this.querySources = []);
1236
+ this.optionsSources || (this.optionsSources = []);
1237
+ this.query || (this.query = {});
1238
+ this.queryOptions || (this.queryOptions = {});
1239
+ this.querySources.push((function() {
1240
+ return filter.toQuery();
1241
+ }));
1242
+ this.optionsSources.push((function() {
1243
+ return filter.toOptions();
1244
+ }));
1245
+ if (this.debugMode === true) {
1246
+ console.log("Filterable");
1247
+ console.log(this.querySources);
1248
+ console.log(this.optionsSources);
1249
+ }
1250
+ filter.on("change", function() {
1251
+ var merged;
1252
+ if (_this.isRemote()) {
1253
+ merged = _.extend(_this.getQuery(), _this.getQueryOptions());
1254
+ return _this.collection.applyFilter(merged, _this.getQueryOptions());
1255
+ } else {
1256
+ return _this.trigger("refresh");
1257
+ }
1076
1258
  });
1077
- if (this.getQuery != null) {
1078
- this.getQuery = _.compose(this.getQuery, function(query) {
1079
- var obj;
1080
- if (query == null) query = {};
1081
- obj = _.clone(query);
1082
- return _.extend(obj, filter.toQuery());
1083
- });
1084
- } else {
1085
- this.getQuery = function() {
1086
- return filter.toQuery();
1087
- };
1088
- }
1089
- if (this.getQueryOptions != null) {
1090
- return this.getQueryOptions = _.compose(this.getQueryOptions, function(options) {
1091
- var obj;
1092
- if (options == null) options = {};
1093
- obj = _.clone(options);
1094
- return _.extend(obj, filter.toOptions());
1095
- });
1096
- } else {
1097
- return this.getQueryOptions = function() {
1098
- return filter.toOptions();
1099
- };
1100
- }
1259
+ return module;
1260
+ },
1261
+ isRemote: function() {
1262
+ return this.getQueryOptions().remote === true;
1101
1263
  },
1102
1264
  getFilterState: function() {
1103
1265
  var _base, _name;
@@ -1108,18 +1270,14 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1108
1270
  return this.getFilterState().setOption('sortBy', sortBy, options);
1109
1271
  },
1110
1272
  applyFilter: function(query, options) {
1111
- var silent;
1112
1273
  if (query == null) query = {};
1113
1274
  if (options == null) options = {};
1114
1275
  options = _.defaults(options, this.getQueryOptions());
1115
1276
  query = _.defaults(query, this.getQuery());
1116
- silent = _(options)["delete"]('silent') === true;
1117
1277
  return this.getFilterState().set({
1118
1278
  query: query,
1119
1279
  options: options
1120
- }, {
1121
- silent: silent
1122
- });
1280
+ }, options);
1123
1281
  }
1124
1282
  };
1125
1283
 
@@ -1131,6 +1289,11 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1131
1289
  FilterModel.__super__.constructor.apply(this, arguments);
1132
1290
  }
1133
1291
 
1292
+ FilterModel.prototype.defaults = {
1293
+ options: {},
1294
+ query: {}
1295
+ };
1296
+
1134
1297
  FilterModel.prototype.setOption = function(option, value, options) {
1135
1298
  var payload;
1136
1299
  payload = {};
@@ -1153,6 +1316,16 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1153
1316
  return this.toJSON().query;
1154
1317
  };
1155
1318
 
1319
+ FilterModel.prototype.toRemote = function() {
1320
+ var options;
1321
+ options = this.toOptions();
1322
+ return _.extend(this.toQuery(), {
1323
+ limit: options.limit,
1324
+ page: options.page,
1325
+ sortBy: options.sortBy
1326
+ });
1327
+ };
1328
+
1156
1329
  return FilterModel;
1157
1330
 
1158
1331
  })(Backbone.Model);
@@ -1160,7 +1333,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1160
1333
  }).call(this);
1161
1334
  (function() {
1162
1335
 
1163
- Luca.modules.GridLayout = {
1336
+ Luca.concerns.GridLayout = {
1164
1337
  _initializer: function() {
1165
1338
  if (this.gridSpan) this.$el.addClass("span" + this.gridSpan);
1166
1339
  if (this.gridOffset) this.$el.addClass("offset" + this.gridOffset);
@@ -1172,7 +1345,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1172
1345
  }).call(this);
1173
1346
  (function() {
1174
1347
 
1175
- Luca.modules.LoadMaskable = {
1348
+ Luca.concerns.LoadMaskable = {
1176
1349
  __initializer: function() {
1177
1350
  var _this = this;
1178
1351
  if (this.loadMask !== true) return;
@@ -1319,7 +1492,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1319
1492
  (function() {
1320
1493
  var applyModalConfig;
1321
1494
 
1322
- Luca.modules.ModalView = {
1495
+ Luca.concerns.ModalView = {
1323
1496
  closeOnEscape: true,
1324
1497
  showOnInitialize: false,
1325
1498
  backdrop: false,
@@ -1357,7 +1530,38 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1357
1530
  }).call(this);
1358
1531
  (function() {
1359
1532
 
1360
- Luca.modules.Paginatable = {
1533
+ Luca.concerns.ModelPresenter = {
1534
+ classMethods: {
1535
+ getPresenter: function(format) {
1536
+ var _ref;
1537
+ return (_ref = this.presenters) != null ? _ref[format] : void 0;
1538
+ },
1539
+ registerPresenter: function(format, config) {
1540
+ this.presenters || (this.presenters = {});
1541
+ return this.presenters[format] = config;
1542
+ }
1543
+ },
1544
+ presentAs: function(format) {
1545
+ var attributeList,
1546
+ _this = this;
1547
+ try {
1548
+ attributeList = this.componentMetaData().componentDefinition().getPresenter(format);
1549
+ if (attributeList == null) return this.toJSON();
1550
+ return _(attributeList).reduce(function(memo, attribute) {
1551
+ memo[attribute] = _this.read(attribute);
1552
+ return memo;
1553
+ }, {});
1554
+ } catch (e) {
1555
+ console.log("Error presentAs", e.stack, e.message);
1556
+ return this.toJSON();
1557
+ }
1558
+ }
1559
+ };
1560
+
1561
+ }).call(this);
1562
+ (function() {
1563
+
1564
+ Luca.concerns.Paginatable = {
1361
1565
  paginatorViewClass: 'Luca.components.PaginationControl',
1362
1566
  paginationSelector: ".toolbar.bottom",
1363
1567
  __included: function() {
@@ -1366,38 +1570,54 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1366
1570
  });
1367
1571
  },
1368
1572
  __initializer: function() {
1369
- var collection, old, paginationState,
1573
+ var collection, paginationState, _base, _ref,
1370
1574
  _this = this;
1371
- if (this.paginatable === false || !Luca.isBackboneCollection(this.collection)) {
1575
+ if (this.paginatable === false) return;
1576
+ if (!Luca.isBackboneCollection(this.collection)) {
1577
+ this.collection = typeof (_base = Luca.CollectionManager).get === "function" ? (_ref = _base.get()) != null ? _ref.getOrCreate(this.collection) : void 0 : void 0;
1578
+ }
1579
+ if (!Luca.isBackboneCollection(this.collection)) {
1580
+ this.debug("Skipping Paginatable due to no collection being present on " + (this.name || this.cid));
1581
+ this.debug("collection", this.collection);
1372
1582
  return;
1373
1583
  }
1374
- _.bindAll(this, "paginationControl");
1584
+ _.bindAll(this, "paginationControl", "pager");
1375
1585
  this.getCollection || (this.getCollection = function() {
1376
1586
  return this.collection;
1377
1587
  });
1378
1588
  collection = this.getCollection();
1379
1589
  paginationState = this.getPaginationState();
1380
- paginationState.on("change", function(state) {
1381
- _this.trigger("collection:change:pagination", state, collection);
1382
- return _this.trigger("refresh");
1383
- });
1384
- this.on("after:refresh", function(models, query, options) {
1385
- return _.defer(function() {
1386
- return _this.updatePagination.call(_this, models, query, options);
1590
+ this.optionsSources || (this.optionsSources = []);
1591
+ this.queryOptions || (this.queryOptions = {});
1592
+ this.optionsSources.push(function() {
1593
+ var options;
1594
+ options = _(paginationState.toJSON()).pick('limit', 'page', 'sortBy');
1595
+ return _.extend(options, {
1596
+ pager: _this.pager
1387
1597
  });
1388
1598
  });
1389
- this.on("after:render", function() {
1390
- return _this.paginationControl().refresh();
1599
+ paginationState.on("change:page", function(state) {
1600
+ var filter;
1601
+ if (_this.isRemote()) {
1602
+ filter = _.extend(_this.toQuery(), _this.toQueryOptions());
1603
+ return _this.collection.applyFilter(filter, {
1604
+ remote: true
1605
+ });
1606
+ } else {
1607
+ return _this.trigger("refresh");
1608
+ }
1391
1609
  });
1392
- if (old = this.getQueryOptions) {
1393
- return this.getQueryOptions = function() {
1394
- return _.extend(old(), paginationState.toJSON());
1395
- };
1396
- } else {
1397
- return this.getQueryOptions = function() {
1398
- return paginationState.toJSON();
1399
- };
1400
- }
1610
+ return this.on("before:render", this.renderPaginationControl, this);
1611
+ },
1612
+ pager: function(numberOfPages, models) {
1613
+ this.getPaginationState().set({
1614
+ numberOfPages: numberOfPages,
1615
+ itemCount: models.length
1616
+ });
1617
+ return this.paginationControl().updateWithPageCount(numberOfPages, models);
1618
+ },
1619
+ isRemote: function() {
1620
+ return this.getQueryOptions().remote === true;
1401
1621
  },
1402
1622
  getPaginationState: function() {
1403
1623
  var _base, _name;
@@ -1411,32 +1631,16 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1411
1631
  if (options == null) options = {};
1412
1632
  return this.getPaginationState().set('page', page, options);
1413
1633
  },
1634
+ setPage: function(page, options) {
1635
+ if (page == null) page = 1;
1636
+ if (options == null) options = {};
1637
+ return this.getPaginationState().set('page', page, options);
1638
+ },
1414
1639
  setLimit: function(limit, options) {
1415
1640
  if (limit == null) limit = 0;
1416
1641
  if (options == null) options = {};
1417
1642
  return this.getPaginationState().set('limit', limit, options);
1418
1643
  },
1419
- updatePagination: function(models, query, options) {
1420
- var itemCount, paginator, totalCount, _ref;
1421
- if (models == null) models = [];
1422
- if (query == null) query = {};
1423
- if (options == null) options = {};
1424
- _.defaults(options, this.getQueryOptions(), {
1425
- limit: 0
1426
- });
1427
- paginator = this.paginationControl();
1428
- itemCount = (models != null ? models.length : void 0) || 0;
1429
- totalCount = (_ref = this.getCollection()) != null ? _ref.length : void 0;
1430
- if (itemCount === 0 || totalCount <= options.limit) {
1431
- paginator.$el.hide();
1432
- } else {
1433
- paginator.$el.show();
1434
- }
1435
- return paginator.state.set({
1436
- page: options.page,
1437
- limit: options.limit
1438
- });
1439
- },
1440
1644
  paginationControl: function() {
1441
1645
  if (this.paginator != null) return this.paginator;
1442
1646
  _.defaults(this.paginatable || (this.paginatable = {}), {
@@ -1446,20 +1650,24 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1446
1650
  this.paginator = Luca.util.lazyComponent({
1447
1651
  type: "pagination_control",
1448
1652
  collection: this.getCollection(),
1449
- defaultState: this.paginatable
1653
+ defaultState: this.paginatable,
1654
+ parent: this.name || this.cid,
1655
+ debugMode: this.debugMode
1450
1656
  });
1451
1657
  return this.paginator;
1452
1658
  },
1453
1659
  renderPaginationControl: function() {
1454
- this.paginationControl();
1455
- return this.paginationContainer().append(this.paginationControl().render().$el);
1660
+ var control;
1661
+ control = this.paginationControl();
1662
+ this.paginationContainer().append(control.render().$el);
1663
+ return control;
1456
1664
  }
1457
1665
  };
1458
1666
 
1459
1667
  }).call(this);
1460
1668
  (function() {
1461
1669
 
1462
- Luca.modules.StateModel = {
1670
+ Luca.concerns.StateModel = {
1463
1671
  __initializer: function() {
1464
1672
  var _this = this;
1465
1673
  if (this.stateful !== true) return;
@@ -1489,7 +1697,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1489
1697
  }).call(this);
1490
1698
  (function() {
1491
1699
 
1492
- Luca.modules.Templating = {
1700
+ Luca.concerns.Templating = {
1493
1701
  __initializer: function() {
1494
1702
  var template, templateContent, templateVars;
1495
1703
  templateVars = Luca.util.read.call(this, this.bodyTemplateVars) || {};
@@ -1640,6 +1848,61 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1640
1848
  return componentCacheStore.cid_index[lookup_id];
1641
1849
  };
1642
1850
 
1851
+ }).call(this);
1852
+ (function() {
1853
+ var MetaDataProxy;
1854
+
1855
+ Luca.registry.componentMetaData = {};
1856
+
1857
+ Luca.registry.getMetaDataFor = function(componentName) {
1858
+ return new MetaDataProxy(Luca.registry.componentMetaData[componentName]);
1859
+ };
1860
+
1861
+ Luca.registry.addMetaData = function(componentName, key, value) {
1862
+ var data, _base;
1863
+ data = (_base = Luca.registry.componentMetaData)[componentName] || (_base[componentName] = {});
1864
+ data[key] = _(value).clone();
1865
+ return data;
1866
+ };
1867
+
1868
+ MetaDataProxy = (function() {
1869
+
1870
+ function MetaDataProxy(meta) {
1871
+ this.meta = meta != null ? meta : {};
1872
+ this;
1873
+ }
1874
+
1875
+ MetaDataProxy.prototype.superClass = function() {
1876
+ return Luca.util.resolve(this.meta["super class name"]);
1877
+ };
1878
+
1879
+ MetaDataProxy.prototype.componentDefinition = function() {
1880
+ return Luca.util.resolve(this.meta["display name"]);
1881
+ };
1882
+
1883
+ MetaDataProxy.prototype.styleHierarchy = function() {
1884
+ var list;
1885
+ list = _(this.classHierarchy()).map(function(cls) {
1886
+ return Luca.util.toCssClass(cls, 'views', 'components', 'core', 'fields', 'containers');
1887
+ });
1888
+ return _(list).without('backbone-view', 'luca-view');
1889
+ };
1890
+
1891
+ MetaDataProxy.prototype.classHierarchy = function() {
1892
+ var list, proxy, _ref, _ref2, _ref3, _ref4;
1893
+ list = [this.meta["display name"], this.meta["super class name"]];
1894
+ proxy = (_ref = this.superClass()) != null ? (_ref2 = _ref.prototype) != null ? typeof _ref2.componentMetaData === "function" ? _ref2.componentMetaData() : void 0 : void 0 : void 0;
1895
+ while (!!proxy) {
1896
+ list = list.concat(proxy != null ? proxy.classHierarchy() : void 0);
1897
+ proxy = (_ref3 = proxy.superClass()) != null ? (_ref4 = _ref3.prototype) != null ? typeof _ref4.componentMetaData === "function" ? _ref4.componentMetaData() : void 0 : void 0 : void 0;
1898
+ }
1899
+ return _(list).uniq();
1900
+ };
1901
+
1902
+ return MetaDataProxy;
1903
+
1904
+ })();
1905
+
1643
1906
  }).call(this);
1644
1907
  (function() {
1645
1908
  var __slice = Array.prototype.slice;
@@ -1683,13 +1946,14 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1683
1946
 
1684
1947
  }).call(this);
1685
1948
  (function() {
1686
- var bindAllEventHandlers, bindEventHandlers, view;
1949
+ var bindAllEventHandlers, bindEventHandlers, view,
1950
+ __slice = Array.prototype.slice;
1687
1951
 
1688
1952
  view = Luca.register("Luca.View");
1689
1953
 
1690
1954
  view["extends"]("Backbone.View");
1691
1955
 
1692
- view.includes("Luca.Events", "Luca.modules.DomHelpers");
1956
+ view.includes("Luca.Events", "Luca.concerns.DomHelpers");
1693
1957
 
1694
1958
  view.mixesIn("DomHelpers", "Templating", "EnhancedProperties", "CollectionEventBindings", "ApplicationEventBindings", "StateModel");
1695
1959
 
@@ -1697,7 +1961,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1697
1961
 
1698
1962
  view.defines({
1699
1963
  initialize: function(options) {
1700
- var module, _i, _len, _ref, _ref2, _ref3, _ref4;
1701
1964
  this.options = options != null ? options : {};
1702
1965
  this.trigger("before:initialize", this, this.options);
1703
1966
  _.extend(this, this.options);
@@ -1708,36 +1971,11 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1708
1971
  this.$el.attr("data-luca-id", this.name || this.cid);
1709
1972
  Luca.cacheInstance(this.cid, this);
1710
1973
  this.setupHooks(_(Luca.View.prototype.hooks.concat(this.hooks)).uniq());
1711
- if (((_ref = this.mixins) != null ? _ref.length : void 0) > 0) {
1712
- _ref2 = this.mixins;
1713
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1714
- module = _ref2[_i];
1715
- if ((_ref3 = Luca.mixin(module)) != null) {
1716
- if ((_ref4 = _ref3.__initializer) != null) {
1717
- _ref4.call(this, this, module);
1718
- }
1719
- }
1720
- }
1721
- }
1974
+ Luca.concern.setup.call(this);
1722
1975
  this.delegateEvents();
1723
1976
  return this.trigger("after:initialize", this);
1724
1977
  },
1725
- setupHooks: function(set) {
1726
- var _this = this;
1727
- set || (set = this.hooks);
1728
- return _(set).each(function(eventId) {
1729
- var callback, fn;
1730
- fn = Luca.util.hook(eventId);
1731
- callback = function() {
1732
- var _ref;
1733
- return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
1734
- };
1735
- if (eventId != null ? eventId.match(/once:/) : void 0) {
1736
- callback = _.once(callback);
1737
- }
1738
- return _this.on(eventId, callback, _this);
1739
- });
1740
- },
1978
+ setupHooks: Luca.util.setupHooks,
1741
1979
  registerEvent: function(selector, handler) {
1742
1980
  this.events || (this.events = {});
1743
1981
  this.events[selector] = handler;
@@ -1757,14 +1995,10 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1757
1995
  return Luca.util.selectProperties(Luca.isBackboneView, this);
1758
1996
  },
1759
1997
  debug: function() {
1760
- var message, _i, _len, _results;
1998
+ var args;
1999
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
1761
2000
  if (!(this.debugMode || (window.LucaDebugMode != null))) return;
1762
- _results = [];
1763
- for (_i = 0, _len = arguments.length; _i < _len; _i++) {
1764
- message = arguments[_i];
1765
- _results.push(console.log([this.name || this.cid, message]));
1766
- }
1767
- return _results;
2001
+ return console.log([this.name || this.cid].concat(__slice.call(args)));
1768
2002
  },
1769
2003
  trigger: function() {
1770
2004
  if (Luca.enableGlobalObserver) {
@@ -1849,21 +2083,26 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1849
2083
  return _results;
1850
2084
  };
1851
2085
 
2086
+ Luca.View.deferrableEvent = "reset";
2087
+
1852
2088
  Luca.View.extend = function(definition) {
1853
- var module, _i, _len, _ref;
2089
+ var componentClass, module, _i, _len, _ref;
2090
+ if (definition == null) definition = {};
1854
2091
  definition = Luca.View.renderWrapper(definition);
1855
- if ((definition.mixins != null) && _.isArray(definition.mixins)) {
1856
- _ref = definition.mixins;
2092
+ if (definition.concerns != null) {
2093
+ definition.concerns || (definition.concerns = definition.concerns);
2094
+ }
2095
+ componentClass = Luca.View._originalExtend.call(this, definition);
2096
+ if ((definition.concerns != null) && _.isArray(definition.concerns)) {
2097
+ _ref = definition.concerns;
1857
2098
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1858
2099
  module = _ref[_i];
1859
- Luca.decorate(definition)["with"](module);
2100
+ Luca.decorate(componentClass)["with"](module);
1860
2101
  }
1861
2102
  }
1862
- return Luca.View._originalExtend.call(this, definition);
2103
+ return componentClass;
1863
2104
  };
1864
2105
 
1865
- Luca.View.deferrableEvent = "reset";
1866
-
1867
2106
  }).call(this);
1868
2107
  (function() {
1869
2108
  var model, setupComputedProperties;
@@ -1877,13 +2116,14 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1877
2116
  model.defines({
1878
2117
  initialize: function() {
1879
2118
  Backbone.Model.prototype.initialize(this, arguments);
1880
- return setupComputedProperties.call(this);
2119
+ setupComputedProperties.call(this);
2120
+ return Luca.concern.setup.call(this);
1881
2121
  },
1882
2122
  read: function(attr) {
1883
2123
  if (_.isFunction(this[attr])) {
1884
2124
  return this[attr].call(this);
1885
2125
  } else {
1886
- return this.get(attr);
2126
+ return this.get(attr) || this[attr];
1887
2127
  }
1888
2128
  },
1889
2129
  get: function(attr) {
@@ -1919,6 +2159,25 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1919
2159
  return _results;
1920
2160
  };
1921
2161
 
2162
+ Luca.Model._originalExtend = Backbone.Model.extend;
2163
+
2164
+ Luca.Model.extend = function(definition) {
2165
+ var componentClass, module, _i, _len, _ref;
2166
+ if (definition == null) definition = {};
2167
+ if (definition.concerns != null) {
2168
+ definition.concerns || (definition.concerns = definition.concerns);
2169
+ }
2170
+ componentClass = Luca.Model._originalExtend.call(this, definition);
2171
+ if ((definition.concerns != null) && _.isArray(definition.concerns)) {
2172
+ _ref = definition.concerns;
2173
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2174
+ module = _ref[_i];
2175
+ Luca.decorate(componentClass)["with"](module);
2176
+ }
2177
+ }
2178
+ return componentClass;
2179
+ };
2180
+
1922
2181
  }).call(this);
1923
2182
  (function() {
1924
2183
  var collection;
@@ -1983,6 +2242,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
1983
2242
  parse: options != null ? options.parse : void 0
1984
2243
  });
1985
2244
  }
2245
+ Luca.concern.setup.call(this);
1986
2246
  return this.trigger("after:initialize");
1987
2247
  },
1988
2248
  __wrapUrl: function() {
@@ -2078,7 +2338,9 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2078
2338
  if (options == null) options = {};
2079
2339
  this.trigger("before:fetch", this);
2080
2340
  if (this.memoryCollection === true) return this.reset(this.data);
2081
- if (this.cached_models().length && !options.refresh) return this.bootstrap();
2341
+ if (this.cached_models().length && !(options.refresh === true || options.remote === true)) {
2342
+ return this.bootstrap();
2343
+ }
2082
2344
  url = _.isFunction(this.url) ? this.url() : this.url;
2083
2345
  if (!((url && url.length > 1) || this.localStorage)) return true;
2084
2346
  this.fetching = true;
@@ -2227,6 +2489,25 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2227
2489
  }
2228
2490
  });
2229
2491
 
2492
+ Luca.Collection._originalExtend = Backbone.Collection.extend;
2493
+
2494
+ Luca.Collection.extend = function(definition) {
2495
+ var componentClass, module, _i, _len, _ref;
2496
+ if (definition == null) definition = {};
2497
+ if (definition.concerns != null) {
2498
+ definition.concerns || (definition.concerns = definition.concerns);
2499
+ }
2500
+ componentClass = Luca.Collection._originalExtend.call(this, definition);
2501
+ if ((definition.concerns != null) && _.isArray(definition.concerns)) {
2502
+ _ref = definition.concerns;
2503
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2504
+ module = _ref[_i];
2505
+ Luca.decorate(componentClass)["with"](module);
2506
+ }
2507
+ }
2508
+ return componentClass;
2509
+ };
2510
+
2230
2511
  Luca.Collection.baseParams = function(obj) {
2231
2512
  if (obj) return Luca.Collection._baseParams = obj;
2232
2513
  if (_.isFunction(Luca.Collection._baseParams)) {
@@ -2375,40 +2656,21 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2375
2656
 
2376
2657
  }).call(this);
2377
2658
  (function() {
2659
+ var field;
2378
2660
 
2379
- _.def('Luca.core.Field')["extends"]('Luca.View')["with"]({
2380
- className: 'luca-ui-text-field luca-ui-field',
2381
- isField: true,
2382
- template: 'fields/text_field',
2661
+ field = Luca.register("Luca.core.Field");
2662
+
2663
+ field["extends"]("Luca.View");
2664
+
2665
+ field.triggers("before:validation", "after:validation", "on:change");
2666
+
2667
+ field.publicConfiguration({
2383
2668
  labelAlign: 'top',
2384
- hooks: ["before:validation", "after:validation", "on:change"],
2385
- statuses: ["warning", "error", "success"],
2386
- initialize: function(options) {
2387
- var _ref;
2388
- this.options = options != null ? options : {};
2389
- _.extend(this, this.options);
2390
- this.input_id || (this.input_id = _.uniqueId('field'));
2391
- this.input_name || (this.input_name = this.name);
2392
- this.input_class || (this.input_class = "");
2393
- this.input_type || (this.input_type = "");
2394
- this.helperText || (this.helperText = "");
2395
- if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) {
2396
- this.label || (this.label = "*" + this.label);
2397
- }
2398
- this.inputStyles || (this.inputStyles = "");
2399
- this.input_value || (this.input_value = this.value || "");
2400
- if (this.disabled) this.disable();
2401
- this.updateState(this.state);
2402
- this.placeHolder || (this.placeHolder = "");
2403
- return Luca.View.prototype.initialize.apply(this, arguments);
2404
- },
2405
- beforeRender: function() {
2406
- if (Luca.enableBootstrap) this.$el.addClass('control-group');
2407
- if (this.required) return this.$el.addClass('required');
2408
- },
2409
- change_handler: function(e) {
2410
- return this.trigger("on:change", this, e);
2411
- },
2669
+ className: 'luca-ui-text-field luca-ui-field',
2670
+ statuses: ["warning", "error", "success"]
2671
+ });
2672
+
2673
+ field.publicInterface({
2412
2674
  disable: function() {
2413
2675
  return this.getInputElement().attr('disabled', true);
2414
2676
  },
@@ -2434,9 +2696,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2434
2696
  var _ref;
2435
2697
  return (_ref = this.getInputElement()) != null ? _ref.attr('value', value) : void 0;
2436
2698
  },
2437
- getInputElement: function() {
2438
- return this.input || (this.input = this.$('input').eq(0));
2439
- },
2440
2699
  updateState: function(state) {
2441
2700
  var _this = this;
2442
2701
  return _(this.statuses).each(function(cls) {
@@ -2446,6 +2705,44 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2446
2705
  }
2447
2706
  });
2448
2707
 
2708
+ field.privateConfiguration({
2709
+ isField: true,
2710
+ template: 'fields/text_field'
2711
+ });
2712
+
2713
+ field.defines({
2714
+ initialize: function(options) {
2715
+ var _ref;
2716
+ this.options = options != null ? options : {};
2717
+ _.extend(this, this.options);
2718
+ this.input_id || (this.input_id = _.uniqueId('field'));
2719
+ this.input_name || (this.input_name = this.name);
2720
+ this.input_class || (this.input_class = "");
2721
+ this.input_type || (this.input_type = "");
2722
+ this.helperText || (this.helperText = "");
2723
+ if (!(this.label != null) || this.label.length === 0) this.label = this.name;
2724
+ if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) {
2725
+ this.label || (this.label = "*" + this.label);
2726
+ }
2727
+ this.inputStyles || (this.inputStyles = "");
2728
+ this.input_value || (this.input_value = this.value || "");
2729
+ if (this.disabled) this.disable();
2730
+ this.updateState(this.state);
2731
+ this.placeHolder || (this.placeHolder = "");
2732
+ return Luca.View.prototype.initialize.apply(this, arguments);
2733
+ },
2734
+ beforeRender: function() {
2735
+ if (Luca.enableBootstrap) this.$el.addClass('control-group');
2736
+ if (this.required) return this.$el.addClass('required');
2737
+ },
2738
+ change_handler: function(e) {
2739
+ return this.trigger("on:change", this, e);
2740
+ },
2741
+ getInputElement: function() {
2742
+ return this.input || (this.input = this.$('input').eq(0));
2743
+ }
2744
+ });
2745
+
2449
2746
  }).call(this);
2450
2747
  (function() {
2451
2748
  var applyDOMConfig, container, createGetterMethods, createMethodsToGetComponentsByRole, doComponents, doLayout, indexComponent, validateContainerConfiguration;
@@ -2490,6 +2787,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2490
2787
  prepareComponents: function() {
2491
2788
  var component, _i, _len, _ref,
2492
2789
  _this = this;
2790
+ container = this;
2493
2791
  _ref = this.components;
2494
2792
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2495
2793
  component = _ref[_i];
@@ -2500,13 +2798,24 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2500
2798
  }
2501
2799
  }
2502
2800
  return _(this.components).each(function(component, index) {
2503
- var ce, componentContainerElement, panel, _ref2;
2801
+ var ce, componentContainerElement, componentExtension, panel, _ref2, _ref3;
2504
2802
  ce = componentContainerElement = (_ref2 = _this.componentContainers) != null ? _ref2[index] : void 0;
2505
2803
  ce["class"] = ce["class"] || ce.className || ce.classes;
2506
2804
  if (_this.generateComponentElements) {
2507
2805
  panel = _this.make(_this.componentTag, componentContainerElement, '');
2508
2806
  _this.$append(panel);
2509
2807
  }
2808
+ if (container.defaults != null) {
2809
+ component = _.defaults(component, container.defaults || {});
2810
+ }
2811
+ if (_.isArray(container.extensions) && _.isObject((_ref3 = container.extensions) != null ? _ref3[index] : void 0)) {
2812
+ componentExtension = container.extensions[index];
2813
+ component = _.extend(component, componentExtension);
2814
+ }
2815
+ if ((component.role != null) && _.isObject(container.extensions) && _.isObject(container.extensions[component.role])) {
2816
+ componentExtension = container.extensions[component.role];
2817
+ component = _.extend(component, componentExtension);
2818
+ }
2510
2819
  if (component.container == null) {
2511
2820
  if (_this.generateComponentElements) {
2512
2821
  component.container = "#" + componentContainerElement.id;
@@ -2526,11 +2835,15 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2526
2835
  };
2527
2836
  container = this;
2528
2837
  this.components = _(this.components).map(function(object, index) {
2529
- var component, created;
2530
- component = Luca.isBackboneView(object) ? object : (object.type || (object.type = object.ctype), !(object.type != null) ? object.components != null ? object.type = object.ctype = 'container' : object.type = object.ctype = Luca.defaultComponentType : void 0, object = _.defaults(object, container.defaults || {}), created = Luca.util.lazyComponent(object));
2531
- if (!component.container && component.options.container) {
2838
+ var component, created, _ref;
2839
+ component = Luca.isComponent(object) ? object : (object.type || (object.type = object.ctype), !(object.type != null) ? object.components != null ? object.type = object.ctype = 'container' : object.type = object.ctype = Luca.defaultComponentType : void 0, created = Luca.util.lazyComponent(object));
2840
+ if (!component.container && ((_ref = component.options) != null ? _ref.container : void 0)) {
2532
2841
  component.container = component.options.container;
2533
2842
  }
2843
+ if (!(component.container != null)) {
2844
+ console.log(component, index, _this);
2845
+ console.error("could not assign container property to component on container " + (_this.name || _this.cid));
2846
+ }
2534
2847
  indexComponent(component).at(index)["in"](_this.componentIndex);
2535
2848
  return component;
2536
2849
  });
@@ -2546,7 +2859,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2546
2859
  return container;
2547
2860
  };
2548
2861
  try {
2549
- $(component.container).append(component.el);
2862
+ this.$(component.container).eq(0).append(component.el);
2550
2863
  return component.render();
2551
2864
  } catch (e) {
2552
2865
  console.log("Error Rendering Component " + (component.name || component.cid), component);
@@ -2594,11 +2907,11 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2594
2907
  map: function(fn) {
2595
2908
  return this._().map(fn);
2596
2909
  },
2597
- registerComponentEvents: function() {
2910
+ registerComponentEvents: function(eventList) {
2598
2911
  var component, componentNameOrRole, eventId, handler, listener, _ref, _ref2, _results,
2599
2912
  _this = this;
2600
2913
  container = this;
2601
- _ref = this.componentEvents || {};
2914
+ _ref = eventList || this.componentEvents || {};
2602
2915
  _results = [];
2603
2916
  for (listener in _ref) {
2604
2917
  handler = _ref[listener];
@@ -2634,10 +2947,10 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2634
2947
  var children, grandchildren;
2635
2948
  children = this.components;
2636
2949
  grandchildren = _(this.subContainers()).invoke('allChildren');
2637
- return this._allChildren || (this._allChildren = _([children, grandchildren]).chain().compact().flatten().uniq().value());
2950
+ return _([children, grandchildren]).chain().compact().flatten().value();
2638
2951
  },
2639
2952
  findComponentForEventBinding: function(nameRoleOrGetter, deep) {
2640
- if (deep == null) deep = false;
2953
+ if (deep == null) deep = true;
2641
2954
  return this.findComponentByName(nameRoleOrGetter, deep) || this.findComponentByGetter(nameRoleOrGetter, deep) || this.findComponentByRole(nameRoleOrGetter, deep);
2642
2955
  },
2643
2956
  findComponentByGetter: function(getter, deep) {
@@ -2649,7 +2962,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2649
2962
  findComponentByRole: function(role, deep) {
2650
2963
  if (deep == null) deep = false;
2651
2964
  return _(this.allChildren()).detect(function(component) {
2652
- return component.role === role;
2965
+ return component.role === role || component.type === role || component.ctype === role;
2653
2966
  });
2654
2967
  },
2655
2968
  findComponentByName: function(name, deep) {
@@ -2779,7 +3092,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2779
3092
  return _(childrenWithGetter).each(function(component) {
2780
3093
  var _name;
2781
3094
  return container[_name = component.getter] || (container[_name] = function() {
2782
- console.log("getter is being deprecated in favor of role");
2783
3095
  console.log(component.getter, component, container);
2784
3096
  return component;
2785
3097
  });
@@ -2808,8 +3120,10 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
2808
3120
  this.trigger("before:render:components", this, this.components);
2809
3121
  this.renderComponents();
2810
3122
  this.trigger("after:components", this, this.components);
2811
- createGetterMethods.call(this);
2812
- createMethodsToGetComponentsByRole.call(this);
3123
+ if (this.skipGetterMethods !== true) {
3124
+ createGetterMethods.call(this);
3125
+ createMethodsToGetComponentsByRole.call(this);
3126
+ }
2813
3127
  return this.registerComponentEvents();
2814
3128
  };
2815
3129
 
@@ -3492,16 +3806,27 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3492
3806
 
3493
3807
  }).call(this);
3494
3808
  (function() {
3809
+ var tabView;
3810
+
3811
+ _.def('Luca.containers.TabView')["extends"]('Luca.containers.CardView')["with"];
3812
+
3813
+ tabView = Luca.register("Luca.containers.TabView");
3814
+
3815
+ tabView.triggers("before:select", "after:select");
3495
3816
 
3496
- _.def('Luca.containers.TabView')["extends"]('Luca.containers.CardView')["with"]({
3497
- hooks: ["before:select", "after:select"],
3498
- componentType: 'tab_view',
3499
- className: 'luca-ui-tab-view tabbable',
3817
+ tabView.publicConfiguration({
3500
3818
  tab_position: 'top',
3501
- tabVerticalOffset: '50px',
3819
+ tabVerticalOffset: '50px'
3820
+ });
3821
+
3822
+ tabView.privateConfiguration({
3823
+ additionalClassNames: 'tabbable',
3502
3824
  navClass: "nav-tabs",
3503
3825
  bodyTemplate: "containers/tab_view",
3504
- bodyEl: "div.tab-content",
3826
+ bodyEl: "div.tab-content"
3827
+ });
3828
+
3829
+ tabView.defines({
3505
3830
  initialize: function(options) {
3506
3831
  this.options = options != null ? options : {};
3507
3832
  if (this.navStyle === "list") this.navClass = "nav-list";
@@ -3533,7 +3858,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3533
3858
  }
3534
3859
  },
3535
3860
  createTabSelectors: function() {
3536
- var tabView;
3537
3861
  tabView = this;
3538
3862
  return this.each(function(component, index) {
3539
3863
  var icon, link, selector, _ref;
@@ -3683,13 +4007,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3683
4007
 
3684
4008
  }).call(this);
3685
4009
  (function() {
3686
- var startHistory;
4010
+ var application;
3687
4011
 
3688
- startHistory = function() {
3689
- return Backbone.history.start();
3690
- };
4012
+ application = Luca.register("Luca.Application");
3691
4013
 
3692
- _.def('Luca.Application')["extends"]('Luca.containers.Viewport')["with"]({
4014
+ application["extends"]("Luca.containers.Viewport");
4015
+
4016
+ application.defines({
3693
4017
  name: "MyApp",
3694
4018
  defaultState: {},
3695
4019
  autoBoot: false,
@@ -3887,7 +4211,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3887
4211
  if (this.autoStartHistory === true) {
3888
4212
  this.autoStartHistory = "before:render";
3889
4213
  }
3890
- return this.defer(startHistory, false).until(this, this.autoStartHistory);
4214
+ return this.defer(Luca.util.startHistory, false).until(this, this.autoStartHistory);
3891
4215
  }
3892
4216
  },
3893
4217
  setupKeyHandler: function() {
@@ -3908,16 +4232,23 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3908
4232
  }
3909
4233
  });
3910
4234
 
4235
+ Luca.util.startHistory = function() {
4236
+ return Backbone.history.start();
4237
+ };
4238
+
3911
4239
  }).call(this);
3912
4240
  (function() {
4241
+ var toolbar;
4242
+
4243
+ _.def('Luca.components.Toolbar')["extends"]('Luca.core.Container')["with"];
4244
+
4245
+ toolbar = Luca.register("Luca.components.Toolbar");
3913
4246
 
3914
- _.def('Luca.components.Toolbar')["extends"]('Luca.core.Container')["with"]({
4247
+ toolbar["extends"]("Luca.core.Container");
4248
+
4249
+ toolbar.defines({
3915
4250
  className: 'luca-ui-toolbar toolbar',
3916
4251
  position: 'bottom',
3917
- initialize: function(options) {
3918
- this.options = options != null ? options : {};
3919
- return Luca.core.Container.prototype.initialize.apply(this, arguments);
3920
- },
3921
4252
  prepareComponents: function() {
3922
4253
  var _this = this;
3923
4254
  return _(this.components).each(function(component) {
@@ -3925,14 +4256,20 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3925
4256
  });
3926
4257
  },
3927
4258
  render: function() {
3928
- return $(this.container).append(this.el);
4259
+ $(this.container).append(this.el);
4260
+ return this;
3929
4261
  }
3930
4262
  });
3931
4263
 
3932
4264
  }).call(this);
3933
4265
  (function() {
4266
+ var loaderView;
4267
+
4268
+ loaderView = Luca.register("Luca.components.CollectionLoaderView");
4269
+
4270
+ loaderView["extends"]("Luca.View");
3934
4271
 
3935
- _.def('Luca.components.CollectionLoaderView')["extends"]('Luca.components.Template')["with"]({
4272
+ loaderView.defines({
3936
4273
  className: 'luca-ui-collection-loader-view',
3937
4274
  template: "components/collection_loader_view",
3938
4275
  initialize: function(options) {
@@ -3969,15 +4306,15 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3969
4306
  (function() {
3970
4307
  var collectionView, make;
3971
4308
 
3972
- collectionView = Luca.define("Luca.components.CollectionView");
4309
+ collectionView = Luca.register("Luca.components.CollectionView");
3973
4310
 
3974
4311
  collectionView["extends"]("Luca.components.Panel");
3975
4312
 
3976
- collectionView.behavesAs("LoadMaskable", "Filterable", "Paginatable");
4313
+ collectionView.mixesIn("LoadMaskable", "Filterable", "Paginatable");
3977
4314
 
3978
4315
  collectionView.triggers("before:refresh", "after:refresh", "refresh", "empty:results");
3979
4316
 
3980
- collectionView.defaults({
4317
+ collectionView.defines({
3981
4318
  tagName: "ol",
3982
4319
  className: "luca-ui-collection-view",
3983
4320
  bodyClassName: "collection-ui-panel",
@@ -3997,11 +4334,15 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
3997
4334
  if (!((this.itemTemplate != null) || (this.itemRenderer != null) || (this.itemProperty != null))) {
3998
4335
  throw "Collection Views must specify an item template or item renderer function";
3999
4336
  }
4000
- Luca.components.Panel.prototype.initialize.apply(this, arguments);
4001
- if (_.isString(this.collection) && Luca.CollectionManager.get()) {
4002
- this.collection = Luca.CollectionManager.get().getOrCreate(this.collection);
4337
+ if (_.isString(this.collection)) {
4338
+ if (Luca.CollectionManager.get()) {
4339
+ this.collection = Luca.CollectionManager.get().getOrCreate(this.collection);
4340
+ } else {
4341
+ console.log("String Collection but no collection manager");
4342
+ }
4003
4343
  }
4004
4344
  if (!Luca.isBackboneCollection(this.collection)) {
4345
+ console.log("Missing Collection on " + (this.name || this.cid), this, this.collection);
4005
4346
  throw "Collection Views must have a valid backbone collection";
4006
4347
  this.collection.on("before:fetch", function() {
4007
4348
  return _this.trigger("enable:loadmask");
@@ -4020,12 +4361,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4020
4361
  this.collection.on("change", this.refreshModel, this);
4021
4362
  }
4022
4363
  }
4364
+ Luca.components.Panel.prototype.initialize.apply(this, arguments);
4023
4365
  if (this.autoRefreshOnModelsPresent !== false) {
4024
4366
  this.defer(function() {
4025
4367
  if (_this.collection.length > 0) return _this.refresh();
4026
4368
  }).until("after:render");
4027
4369
  }
4028
- return this.on("collection:change", this.refresh, this);
4370
+ return this.on("refresh", this.refresh, this);
4029
4371
  },
4030
4372
  attributesForItem: function(item, model) {
4031
4373
  return _.extend({}, {
@@ -4065,11 +4407,39 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4065
4407
  getCollection: function() {
4066
4408
  return this.collection;
4067
4409
  },
4410
+ loadModels: function(models, options) {
4411
+ var _ref;
4412
+ if (models == null) models = [];
4413
+ if (options == null) options = {};
4414
+ return (_ref = this.getCollection()) != null ? _ref.reset(models, options) : void 0;
4415
+ },
4416
+ applyQuery: function(query, queryOptions) {
4417
+ if (query == null) query = {};
4418
+ if (queryOptions == null) queryOptions = {};
4419
+ this.query = query;
4420
+ this.queryOptions = queryOptions;
4421
+ this.refresh();
4422
+ return this;
4423
+ },
4068
4424
  getQuery: function() {
4069
- return this.query || (this.query = {});
4425
+ var query, querySource, _i, _len, _ref;
4426
+ query = this.query || (this.query = {});
4427
+ _ref = _(this.querySources || []).compact();
4428
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4429
+ querySource = _ref[_i];
4430
+ query = _.extend(query, querySource() || {});
4431
+ }
4432
+ return query;
4070
4433
  },
4071
4434
  getQueryOptions: function() {
4072
- return this.queryOptions || (this.queryOptions = {});
4435
+ var optionSource, options, _i, _len, _ref;
4436
+ options = this.queryOptions || (this.queryOptions = {});
4437
+ _ref = _(this.optionsSources || []).compact();
4438
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4439
+ optionSource = _ref[_i];
4440
+ options = _.extend(options, optionSource() || {});
4441
+ }
4442
+ return options;
4073
4443
  },
4074
4444
  getModels: function(query, options) {
4075
4445
  var _ref;
@@ -4093,12 +4463,12 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4093
4463
  }, model));
4094
4464
  return this.trigger("model:refreshed", index, model);
4095
4465
  },
4096
- refresh: function(query, options) {
4097
- var index, model, models, _i, _len;
4466
+ refresh: function(query, options, models) {
4467
+ var index, model, _i, _len;
4098
4468
  query || (query = this.getQuery());
4099
4469
  options || (options = this.getQueryOptions());
4470
+ models || (models = this.getModels(query, options));
4100
4471
  this.$bodyEl().empty();
4101
- models = this.getModels(query, options);
4102
4472
  this.trigger("before:refresh", models, query, options);
4103
4473
  if (models.length === 0) this.trigger("empty:results");
4104
4474
  index = 0;
@@ -4129,8 +4499,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4129
4499
 
4130
4500
  }).call(this);
4131
4501
  (function() {
4502
+ var controller;
4503
+
4504
+ controller = Luca.register("Luca.components.Controller");
4505
+
4506
+ controller["extends"]("Luca.containers.CardView");
4132
4507
 
4133
- _.def('Luca.components.Controller')["extends"]('Luca.containers.CardView')["with"]({
4508
+ controller.defines({
4134
4509
  additionalClassNames: ['luca-ui-controller'],
4135
4510
  activeAttribute: "active-section",
4136
4511
  initialize: function(options) {
@@ -4190,15 +4565,31 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4190
4565
 
4191
4566
  }).call(this);
4192
4567
  (function() {
4568
+ var buttonField;
4193
4569
 
4194
- _.def('Luca.fields.ButtonField')["extends"]('Luca.core.Field')["with"]({
4570
+ buttonField = Luca.register("Luca.fields.ButtonField");
4571
+
4572
+ buttonField["extends"]("Luca.core.Field");
4573
+
4574
+ buttonField.triggers("button:click");
4575
+
4576
+ buttonField.publicConfiguration({
4195
4577
  readOnly: true,
4578
+ input_value: void 0,
4579
+ input_type: "button",
4580
+ icon_class: void 0,
4581
+ input_name: void 0,
4582
+ white: void 0
4583
+ });
4584
+
4585
+ buttonField.privateConfiguration({
4586
+ template: "fields/button_field",
4196
4587
  events: {
4197
4588
  "click input": "click_handler"
4198
- },
4199
- hooks: ["button:click"],
4200
- className: 'luca-ui-field luca-ui-button-field',
4201
- template: 'fields/button_field',
4589
+ }
4590
+ });
4591
+
4592
+ buttonField.privateInterface({
4202
4593
  click_handler: function(e) {
4203
4594
  var me, my;
4204
4595
  me = my = $(e.currentTarget);
@@ -4218,7 +4609,6 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4218
4609
  this.input_id || (this.input_id = _.uniqueId('button'));
4219
4610
  this.input_name || (this.input_name = this.name || (this.name = this.input_id));
4220
4611
  this.input_value || (this.input_value = this.label || (this.label = this.text));
4221
- this.input_type || (this.input_type = "button");
4222
4612
  this.input_class || (this.input_class = this["class"]);
4223
4613
  this.icon_class || (this.icon_class = "");
4224
4614
  if (this.icon_class.length && !this.icon_class.match(/^icon-/)) {
@@ -4231,13 +4621,21 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4231
4621
  }
4232
4622
  });
4233
4623
 
4624
+ buttonField.defines({
4625
+ version: 1
4626
+ });
4627
+
4234
4628
  }).call(this);
4235
4629
  (function() {
4236
- var make;
4630
+ var checkboxArray, make;
4237
4631
 
4238
4632
  make = Luca.View.prototype.make;
4239
4633
 
4240
- _.def('Luca.fields.CheckboxArray')["extends"]('Luca.core.Field')["with"]({
4634
+ checkboxArray = Luca.register("Luca.fields.CheckboxArray");
4635
+
4636
+ checkboxArray["extends"]("Luca.core.Field");
4637
+
4638
+ checkboxArray.defines({
4241
4639
  version: 2,
4242
4640
  template: "fields/checkbox_array",
4243
4641
  className: "luca-ui-checkbox-array",
@@ -4248,7 +4646,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4248
4646
  initialize: function(options) {
4249
4647
  this.options = options != null ? options : {};
4250
4648
  _.extend(this, this.options);
4251
- _.extend(this, Luca.modules.Deferrable);
4649
+ _.extend(this, Luca.concerns.Deferrable);
4252
4650
  _.bindAll(this, "renderCheckboxes", "clickHandler", "checkSelected");
4253
4651
  Luca.core.Field.prototype.initialize.apply(this, arguments);
4254
4652
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4266,6 +4664,9 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4266
4664
  console.log("Error Configuring Collection", this, e.message);
4267
4665
  }
4268
4666
  cbArray = this;
4667
+ if (!Luca.isBackboneCollection(this.collection)) {
4668
+ throw "Checkbox Array Fields must specify a @collection property";
4669
+ }
4269
4670
  if (this.collection.length > 0) {
4270
4671
  return this.renderCheckboxes();
4271
4672
  } else {
@@ -4361,15 +4762,27 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4361
4762
 
4362
4763
  }).call(this);
4363
4764
  (function() {
4765
+ var checkboxField;
4766
+
4767
+ checkboxField = Luca.register("Luca.fields.CheckboxField");
4768
+
4769
+ checkboxField["extends"]("Luca.core.Field");
4770
+
4771
+ checkboxField.triggers("checked", "unchecked");
4772
+
4773
+ checkboxField.publicConfiguration({
4774
+ send_blanks: true,
4775
+ input_value: 1
4776
+ });
4364
4777
 
4365
- _.def('Luca.fields.CheckboxField')["extends"]('Luca.core.Field')["with"]({
4778
+ checkboxField.privateConfiguration({
4779
+ template: 'fields/checkbox_field',
4366
4780
  events: {
4367
4781
  "change input": "change_handler"
4368
- },
4369
- className: 'luca-ui-checkbox-field luca-ui-field',
4370
- template: 'fields/checkbox_field',
4371
- hooks: ["checked", "unchecked"],
4372
- send_blanks: true,
4782
+ }
4783
+ });
4784
+
4785
+ checkboxField.privateInterface({
4373
4786
  change_handler: function(e) {
4374
4787
  var me, my;
4375
4788
  me = my = $(e.target);
@@ -4384,14 +4797,14 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4384
4797
  this.options = options != null ? options : {};
4385
4798
  _.extend(this, this.options);
4386
4799
  _.bindAll(this, "change_handler");
4387
- return Luca.core.Field.prototype.initialize.apply(this, arguments);
4388
- },
4389
- afterInitialize: function() {
4800
+ Luca.core.Field.prototype.initialize.apply(this, arguments);
4390
4801
  this.input_id || (this.input_id = _.uniqueId('field'));
4391
4802
  this.input_name || (this.input_name = this.name);
4392
- this.input_value || (this.input_value = 1);
4393
4803
  return this.label || (this.label = this.name);
4394
- },
4804
+ }
4805
+ });
4806
+
4807
+ checkboxField.publicInterface({
4395
4808
  setValue: function(checked) {
4396
4809
  return this.getInputElement().attr('checked', checked);
4397
4810
  },
@@ -4400,10 +4813,20 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4400
4813
  }
4401
4814
  });
4402
4815
 
4816
+ checkboxField.defines({
4817
+ version: 1
4818
+ });
4819
+
4403
4820
  }).call(this);
4404
4821
  (function() {
4822
+ var fileUpload;
4823
+
4824
+ fileUpload = Luca.register("Luca.fields.FileUploadField");
4405
4825
 
4406
- _.def('Luca.fields.FileUploadField')["extends"]('Luca.core.Field')["with"]({
4826
+ fileUpload["extends"]("Luca.core.Field");
4827
+
4828
+ fileUpload.defines({
4829
+ version: 1,
4407
4830
  template: 'fields/file_upload_field',
4408
4831
  afterInitialize: function() {
4409
4832
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4415,8 +4838,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4415
4838
 
4416
4839
  }).call(this);
4417
4840
  (function() {
4841
+ var hiddenField;
4842
+
4843
+ hiddenField = Luca.register("Luca.fields.HiddenField");
4844
+
4845
+ hiddenField["extends"]("Luca.core.Field");
4418
4846
 
4419
- _.def('Luca.fields.HiddenField')["extends"]('Luca.core.Field')["with"]({
4847
+ hiddenField.defines({
4420
4848
  template: 'fields/hidden_field',
4421
4849
  afterInitialize: function() {
4422
4850
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4428,9 +4856,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4428
4856
 
4429
4857
  }).call(this);
4430
4858
  (function() {
4859
+ var labelField;
4431
4860
 
4432
- _.def("Luca.components.LabelField")["extends"]("Luca.core.Field")["with"]({
4433
- className: "luca-ui-field luca-ui-label-field",
4861
+ labelField = Luca.register("Luca.components.LabelField");
4862
+
4863
+ labelField["extends"]("Luca.core.Field");
4864
+
4865
+ labelField.defines({
4434
4866
  formatter: function(value) {
4435
4867
  value || (value = this.getValue());
4436
4868
  return _.str.titleize(value);
@@ -4444,13 +4876,18 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4444
4876
 
4445
4877
  }).call(this);
4446
4878
  (function() {
4879
+ var selectField;
4880
+
4881
+ selectField = Luca.register("Luca.fields.SelectField");
4882
+
4883
+ selectField["extends"]("Luca.core.Field");
4447
4884
 
4448
- _.def('Luca.fields.SelectField')["extends"]('Luca.core.Field')["with"]({
4885
+ selectField.triggers("after:select");
4886
+
4887
+ selectField.defines({
4449
4888
  events: {
4450
4889
  "change select": "change_handler"
4451
4890
  },
4452
- hooks: ["after:select"],
4453
- className: 'luca-ui-select-field luca-ui-field',
4454
4891
  template: "fields/select_field",
4455
4892
  includeBlank: true,
4456
4893
  blankValue: '',
@@ -4458,7 +4895,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4458
4895
  initialize: function(options) {
4459
4896
  this.options = options != null ? options : {};
4460
4897
  _.extend(this, this.options);
4461
- _.extend(this, Luca.modules.Deferrable);
4898
+ _.extend(this, Luca.concerns.Deferrable);
4462
4899
  _.bindAll(this, "change_handler", "populateOptions", "beforeFetch");
4463
4900
  Luca.core.Field.prototype.initialize.apply(this, arguments);
4464
4901
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4586,8 +5023,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4586
5023
 
4587
5024
  }).call(this);
4588
5025
  (function() {
5026
+ var textField;
5027
+
5028
+ textField = Luca.register('Luca.fields.TextField');
4589
5029
 
4590
- _.def('Luca.fields.TextField')["extends"]('Luca.core.Field')["with"]({
5030
+ textField["extends"]('Luca.core.Field');
5031
+
5032
+ textField.defines({
4591
5033
  events: {
4592
5034
  "blur input": "blur_handler",
4593
5035
  "focus input": "focus_handler",
@@ -4631,9 +5073,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4631
5073
 
4632
5074
  }).call(this);
4633
5075
  (function() {
5076
+ var typeAheadField;
5077
+
5078
+ typeAheadField = Luca.register("Luca.fields.TypeAheadField");
4634
5079
 
4635
- _.def('Luca.fields.TypeAheadField')["extends"]('Luca.fields.TextField')["with"]({
4636
- className: 'luca-ui-field',
5080
+ typeAheadField["extends"]("Luca.fields.TextField");
5081
+
5082
+ typeAheadField.defines({
4637
5083
  getSource: function() {
4638
5084
  return Luca.util.read(this.source) || [];
4639
5085
  },
@@ -4655,13 +5101,19 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4655
5101
 
4656
5102
  }).call(this);
4657
5103
  (function() {
5104
+ var toolbar;
5105
+
5106
+ toolbar = Luca.register("Luca.components.FormButtonToolbar");
4658
5107
 
4659
- _.def('Luca.components.FormButtonToolbar')["extends"]('Luca.components.Toolbar')["with"]({
5108
+ toolbar["extends"]("Luca.components.Toolbar");
5109
+
5110
+ toolbar.defines({
4660
5111
  className: 'luca-ui-form-toolbar form-actions',
4661
5112
  position: 'bottom',
4662
5113
  includeReset: false,
4663
5114
  render: function() {
4664
- return $(this.container).append(this.el);
5115
+ $(this.container).append(this.el);
5116
+ return this;
4665
5117
  },
4666
5118
  initialize: function(options) {
4667
5119
  this.options = options != null ? options : {};
@@ -4685,32 +5137,17 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4685
5137
 
4686
5138
  }).call(this);
4687
5139
  (function() {
4688
- var defaultToolbar;
5140
+ var formView;
4689
5141
 
4690
- defaultToolbar = {
4691
- buttons: [
4692
- {
4693
- icon: "remove-sign",
4694
- label: "Reset",
4695
- eventId: "click:reset",
4696
- className: "reset-button",
4697
- align: 'right'
4698
- }, {
4699
- icon: "ok-sign",
4700
- white: true,
4701
- label: "Save Changes",
4702
- eventId: "click:submit",
4703
- color: "success",
4704
- className: 'submit-button',
4705
- align: 'right'
4706
- }
4707
- ]
4708
- };
5142
+ formView = Luca.register("Luca.components.FormView");
5143
+
5144
+ formView["extends"]("Luca.core.Container");
5145
+
5146
+ formView.triggers("before:submit", "before:reset", "before:load", "before:load:new", "before:load:existing", "after:submit", "after:reset", "after:load", "after:load:new", "after:load:existing", "after:submit:success", "after:submit:fatal_error", "after:submit:error");
4709
5147
 
4710
- _.def("Luca.components.FormView")["extends"]('Luca.core.Container')["with"]({
5148
+ formView.defines({
4711
5149
  tagName: 'form',
4712
5150
  className: 'luca-ui-form-view',
4713
- 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"],
4714
5151
  events: {
4715
5152
  "click .submit-button": "submitHandler",
4716
5153
  "click .reset-button": "resetHandler"
@@ -4718,13 +5155,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4718
5155
  toolbar: true,
4719
5156
  legend: "",
4720
5157
  bodyClassName: "form-view-body",
4721
- version: "0.9.33333333",
5158
+ version: 1,
4722
5159
  initialize: function(options) {
4723
5160
  this.options = options != null ? options : {};
4724
5161
  if (this.loadMask == null) this.loadMask = Luca.enableBootstrap;
4725
5162
  Luca.core.Container.prototype.initialize.apply(this, arguments);
4726
5163
  this.components || (this.components = this.fields);
4727
- _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars", "applyLoadMask");
5164
+ _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars");
4728
5165
  this.state || (this.state = new Backbone.Model);
4729
5166
  this.setupHooks(this.hooks);
4730
5167
  this.applyStyleClasses();
@@ -4738,7 +5175,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4738
5175
  }
4739
5176
  },
4740
5177
  getDefaultToolbar: function() {
4741
- return defaultToolbar;
5178
+ return Luca.components.FormView.defaultFormViewToolbar;
4742
5179
  },
4743
5180
  applyStyleClasses: function() {
4744
5181
  if (Luca.enableBootstrap) this.applyBootstrapStyleClasses();
@@ -4952,6 +5389,26 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4952
5389
  }
4953
5390
  });
4954
5391
 
5392
+ Luca.components.FormView.defaultFormViewToolbar = {
5393
+ buttons: [
5394
+ {
5395
+ icon: "remove-sign",
5396
+ label: "Reset",
5397
+ eventId: "click:reset",
5398
+ className: "reset-button",
5399
+ align: 'right'
5400
+ }, {
5401
+ icon: "ok-sign",
5402
+ white: true,
5403
+ label: "Save Changes",
5404
+ eventId: "click:submit",
5405
+ color: "success",
5406
+ className: 'submit-button',
5407
+ align: 'right'
5408
+ }
5409
+ ]
5410
+ };
5411
+
4955
5412
  }).call(this);
4956
5413
  (function() {
4957
5414
 
@@ -4978,7 +5435,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
4978
5435
  var _this = this;
4979
5436
  this.options = options != null ? options : {};
4980
5437
  _.extend(this, this.options);
4981
- _.extend(this, Luca.modules.Deferrable);
5438
+ _.extend(this, Luca.concerns.Deferrable);
4982
5439
  if (this.loadMask == null) this.loadMask = Luca.enableBootstrap;
4983
5440
  if (this.loadMask === true) {
4984
5441
  this.loadMaskEl || (this.loadMaskEl = ".luca-ui-g-view-body");
@@ -5204,13 +5661,13 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5204
5661
 
5205
5662
  }).call(this);
5206
5663
  (function() {
5207
- var bubbleCollectionEvents, multiView, propagateCollectionComponents, validateComponent;
5664
+ var multiView, propagateCollectionComponents, validateComponent;
5208
5665
 
5209
- multiView = Luca.define("Luca.components.MultiCollectionView");
5666
+ multiView = Luca.register("Luca.components.MultiCollectionView");
5210
5667
 
5211
5668
  multiView["extends"]("Luca.containers.CardView");
5212
5669
 
5213
- multiView.behavesAs("LoadMaskable", "Filterable", "Paginatable");
5670
+ multiView.mixesIn("LoadMaskable", "Filterable", "Paginatable");
5214
5671
 
5215
5672
  multiView.triggers("before:refresh", "after:refresh", "refresh", "empty:results");
5216
5673
 
@@ -5230,51 +5687,73 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5230
5687
  view = _ref[_i];
5231
5688
  validateComponent(view);
5232
5689
  }
5233
- this.on("collection:change", this.refresh, this);
5690
+ this.on("refresh", this.refresh, this);
5234
5691
  this.on("after:card:switch", this.refresh, this);
5235
- this.on("before:components", propagateCollectionComponents, this);
5236
- this.on("after:components", bubbleCollectionEvents, this);
5692
+ this.on("after:components", propagateCollectionComponents, this);
5693
+ this.debug("multi collection , proto initialize");
5237
5694
  return Luca.containers.CardView.prototype.initialize.apply(this, arguments);
5238
5695
  },
5696
+ relayAfterRefresh: function(models, query, options) {
5697
+ return this.trigger("after:refresh", models, query, options);
5698
+ },
5239
5699
  refresh: function() {
5240
5700
  var _ref;
5241
5701
  return (_ref = this.activeComponent()) != null ? _ref.trigger("refresh") : void 0;
5242
5702
  },
5243
- getQuery: Luca.components.CollectionView.prototype.getQuery,
5244
- getQueryOptions: Luca.components.CollectionView.prototype.getQueryOptions,
5245
- getCollection: Luca.components.CollectionView.prototype.getCollection
5246
- });
5247
-
5248
- bubbleCollectionEvents = function() {
5249
- var container;
5250
- container = this;
5251
- return container.eachComponent(function(component) {
5252
- var eventId, _i, _len, _ref, _results;
5253
- _ref = ['refresh', 'before:refresh', 'after:refresh', 'empty:results'];
5254
- _results = [];
5703
+ getCollection: function() {
5704
+ return this.collection;
5705
+ },
5706
+ applyQuery: function(query, queryOptions) {
5707
+ if (query == null) query = {};
5708
+ if (queryOptions == null) queryOptions = {};
5709
+ this.query = query;
5710
+ this.queryOptions = queryOptions;
5711
+ return this;
5712
+ },
5713
+ getQuery: function() {
5714
+ var query, querySource, _i, _len, _ref;
5715
+ this.debug("Get Query");
5716
+ query = this.query || (this.query = {});
5717
+ _ref = this.querySources;
5255
5718
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5256
- eventId = _ref[_i];
5257
- _results.push(component.on(eventId, function() {
5258
- if (component === container.activeComponent()) {
5259
- return container.trigger(eventId);
5260
- }
5261
- }));
5719
+ querySource = _ref[_i];
5720
+ query = _.extend(query, querySource() || {});
5262
5721
  }
5263
- return _results;
5264
- });
5265
- };
5722
+ return query;
5723
+ },
5724
+ getQueryOptions: function() {
5725
+ var optionSource, options, _i, _len, _ref;
5726
+ this.debug("Get Query Options");
5727
+ options = this.queryOptions || (this.queryOptions = {});
5728
+ _ref = this.optionsSources;
5729
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5730
+ optionSource = _ref[_i];
5731
+ options = _.extend(options, optionSource() || {});
5732
+ }
5733
+ return options;
5734
+ }
5735
+ });
5266
5736
 
5267
5737
  propagateCollectionComponents = function() {
5268
- var component, container, _i, _len, _ref, _results;
5738
+ var component, container, _i, _len, _ref, _results,
5739
+ _this = this;
5269
5740
  container = this;
5270
5741
  _ref = this.components;
5271
5742
  _results = [];
5272
5743
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5273
5744
  component = _ref[_i];
5745
+ component.on("after:refresh", function(models, query, options) {
5746
+ _this.debug("collection member after refresh");
5747
+ return _this.trigger("after:refresh", models, query, options);
5748
+ });
5274
5749
  _results.push(_.extend(component, {
5275
- collection: (typeof container.getCollection === "function" ? container.getCollection() : void 0) || this.collection,
5276
- getQuery: container.getQuery,
5277
- getQueryOptions: container.getQueryOptions
5750
+ collection: container.getCollection(),
5751
+ getQuery: function() {
5752
+ return container.getQuery.call(container);
5753
+ },
5754
+ getQueryOptions: function() {
5755
+ return container.getQueryOptions.call(container);
5756
+ }
5278
5757
  }));
5279
5758
  }
5280
5759
  return _results;
@@ -5341,8 +5820,12 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5341
5820
  "click a.prev": "previousPage"
5342
5821
  },
5343
5822
  afterInitialize: function() {
5344
- _.bindAll(this, "refresh");
5345
- return this.state.on("change", this.refresh, this);
5823
+ var _ref,
5824
+ _this = this;
5825
+ _.bindAll(this, "updateWithPageCount");
5826
+ return (_ref = this.state) != null ? _ref.on("change", function(state, numberOfPages) {
5827
+ return _this.updateWithPageCount(state.get('numberOfPages'));
5828
+ }) : void 0;
5346
5829
  },
5347
5830
  limit: function() {
5348
5831
  var _ref;
@@ -5395,16 +5878,22 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5395
5878
  pageButtons: function() {
5396
5879
  return this.$('a[data-page-number]', this.pageButtonContainer());
5397
5880
  },
5398
- refresh: function() {
5399
- var button, page, _ref;
5881
+ updateWithPageCount: function(pageCount, models) {
5882
+ var modelCount,
5883
+ _this = this;
5884
+ this.pageCount = pageCount;
5885
+ if (models == null) models = [];
5886
+ modelCount = models.length;
5400
5887
  this.pageButtonContainer().empty();
5401
- for (page = 1, _ref = this.totalPages(); 1 <= _ref ? page <= _ref : page >= _ref; 1 <= _ref ? page++ : page--) {
5402
- button = this.make("a", {
5888
+ _(this.pageCount).times(function(index) {
5889
+ var button, page;
5890
+ page = index + 1;
5891
+ button = _this.make("a", {
5403
5892
  "data-page-number": page,
5404
5893
  "class": "page"
5405
5894
  }, page);
5406
- this.pageButtonContainer().append(button);
5407
- }
5895
+ return _this.pageButtonContainer().append(button);
5896
+ });
5408
5897
  this.toggleNavigationButtons();
5409
5898
  this.selectActivePageButton();
5410
5899
  return this;
@@ -5423,7 +5912,7 @@ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property
5423
5912
  return this.pageButtons().filter("[data-page-number='" + (this.page()) + "']");
5424
5913
  },
5425
5914
  totalPages: function() {
5426
- return parseInt(Math.ceil(this.totalItems() / this.itemsPerPage()));
5915
+ return this.pageCount;
5427
5916
  },
5428
5917
  totalItems: function() {
5429
5918
  var _ref;