luca 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
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;