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
@@ -18,11 +18,13 @@
18
18
  };
19
19
 
20
20
  _.extend(Luca, {
21
- VERSION: "0.9.6",
21
+ VERSION: "0.9.7",
22
22
  core: {},
23
+ collections: {},
23
24
  containers: {},
24
25
  components: {},
25
- modules: {},
26
+ models: {},
27
+ concerns: {},
26
28
  util: {},
27
29
  fields: {},
28
30
  registry: {},
@@ -32,6 +34,12 @@
32
34
 
33
35
  _.extend(Luca, Backbone.Events);
34
36
 
37
+ Luca.config.maintainStyleHierarchy = true;
38
+
39
+ Luca.config.maintainClassHierarchy = true;
40
+
41
+ Luca.config.autoApplyClassHierarchyAsCssClasses = true;
42
+
35
43
  Luca.autoRegister = Luca.config.autoRegister = true;
36
44
 
37
45
  Luca.developmentMode = Luca.config.developmentMode = false;
@@ -105,36 +113,29 @@
105
113
  };
106
114
 
107
115
  Luca.inheritanceChain = function(obj) {
108
- return _(Luca.parentClasses(obj)).map(function(className) {
109
- return Luca.util.resolve(className);
110
- });
116
+ return Luca.parentClasses(obj);
111
117
  };
112
118
 
113
119
  Luca.parentClasses = function(obj) {
114
- var classes, list, _ref;
120
+ var list, metaData, _base;
115
121
  list = [];
116
122
  if (_.isString(obj)) obj = Luca.util.resolve(obj);
117
- list.push(obj.displayName || ((_ref = obj.prototype) != null ? _ref.displayName : void 0) || Luca.parentClass(obj));
118
- classes = (function() {
119
- var _results;
120
- _results = [];
121
- while (!!(Luca.parentClass(obj) != null)) {
122
- _results.push(obj = Luca.parentClass(obj));
123
- }
124
- return _results;
125
- })();
126
- list = list.concat(classes);
127
- return _.uniq(list);
123
+ metaData = typeof obj.componentMetaData === "function" ? obj.componentMetaData() : void 0;
124
+ metaData || (metaData = typeof (_base = obj.prototype).componentMetaData === "function" ? _base.componentMetaData() : void 0);
125
+ return list = (metaData != null ? metaData.classHierarchy() : void 0) || [obj.displayName || obj.prototype.displayName];
128
126
  };
129
127
 
130
- Luca.parentClass = function(obj) {
131
- var list, _base, _ref;
132
- list = [];
128
+ Luca.parentClass = function(obj, resolve) {
129
+ var parent, _base, _ref, _ref2, _ref3;
130
+ if (resolve == null) resolve = true;
133
131
  if (_.isString(obj)) obj = Luca.util.resolve(obj);
134
- if (Luca.isComponent(obj)) {
135
- return obj.displayName;
136
- } else if (Luca.isComponentPrototype(obj)) {
137
- return typeof (_base = obj.prototype)._superClass === "function" ? (_ref = _base._superClass()) != null ? _ref.displayName : void 0 : void 0;
132
+ parent = typeof obj.componentMetaData === "function" ? (_ref = obj.componentMetaData()) != null ? _ref.meta["super class name"] : void 0 : void 0;
133
+ parent || (parent = typeof (_base = obj.prototype).componentMetaData === "function" ? (_ref2 = _base.componentMetaData()) != null ? _ref2.meta["super class name"] : void 0 : void 0);
134
+ parent || obj.displayName || ((_ref3 = obj.prototype) != null ? _ref3.displayName : void 0);
135
+ if (resolve) {
136
+ return Luca.util.resolve(parent);
137
+ } else {
138
+ return parent;
138
139
  }
139
140
  };
140
141
 
@@ -374,6 +375,25 @@
374
375
  return fn = prefix + parts.join('');
375
376
  };
376
377
 
378
+ Luca.util.toCssClass = function() {
379
+ var componentName, exclusions, part, parts, transformed;
380
+ componentName = arguments[0], exclusions = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
381
+ parts = componentName.split('.');
382
+ transformed = (function() {
383
+ var _i, _len, _results;
384
+ _results = [];
385
+ for (_i = 0, _len = parts.length; _i < _len; _i++) {
386
+ part = parts[_i];
387
+ if (!(_(exclusions).indexOf(part) === -1)) continue;
388
+ part = _.str.underscored(part);
389
+ part = part.replace(/_/g, '-');
390
+ _results.push(part);
391
+ }
392
+ return _results;
393
+ })();
394
+ return transformed.join('-');
395
+ };
396
+
377
397
  Luca.util.isIE = function() {
378
398
  try {
379
399
  Object.defineProperty({}, '', {});
@@ -468,6 +488,48 @@
468
488
  }, contents);
469
489
  };
470
490
 
491
+ Luca.util.setupHooks = function(set) {
492
+ var _this = this;
493
+ set || (set = this.hooks);
494
+ return _(set).each(function(eventId) {
495
+ var callback, fn;
496
+ fn = Luca.util.hook(eventId);
497
+ callback = function() {
498
+ var _ref;
499
+ return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
500
+ };
501
+ if (eventId != null ? eventId.match(/once:/) : void 0) {
502
+ callback = _.once(callback);
503
+ }
504
+ return _this.on(eventId, callback, _this);
505
+ });
506
+ };
507
+
508
+ Luca.util.setupHooksAdvanced = function(set) {
509
+ var _this = this;
510
+ set || (set = this.hooks);
511
+ return _(set).each(function(eventId) {
512
+ var callback, entry, fn, hookSetup, _i, _len, _results;
513
+ hookSetup = _this[Luca.util.hook(eventId)];
514
+ if (!_.isArray(hookSetup)) hookSetup = [hookSetup];
515
+ _results = [];
516
+ for (_i = 0, _len = hookSetup.length; _i < _len; _i++) {
517
+ entry = hookSetup[_i];
518
+ fn = _.isString(entry) ? _this[entry] : void 0;
519
+ if (_.isFunction(entry)) fn = entry;
520
+ callback = function() {
521
+ var _ref;
522
+ return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
523
+ };
524
+ if (eventId != null ? eventId.match(/once:/) : void 0) {
525
+ callback = _.once(callback);
526
+ }
527
+ _results.push(_this.on(eventId, callback, _this));
528
+ }
529
+ return _results;
530
+ });
531
+ };
532
+
471
533
  }).call(this);
472
534
  (function() {
473
535
 
@@ -624,6 +686,92 @@
624
686
  }
625
687
  };
626
688
 
689
+ }).call(this);
690
+ (function() {
691
+
692
+ Luca.concern = function(mixinName) {
693
+ var namespace, resolved;
694
+ namespace = _(Luca.concern.namespaces).detect(function(space) {
695
+ var _ref;
696
+ return ((_ref = Luca.util.resolve(space)) != null ? _ref[mixinName] : void 0) != null;
697
+ });
698
+ namespace || (namespace = "Luca.concerns");
699
+ resolved = Luca.util.resolve(namespace)[mixinName];
700
+ if (resolved == null) {
701
+ console.log("Could not find " + mixinName + " in ", Luca.concern.namespaces);
702
+ }
703
+ return resolved;
704
+ };
705
+
706
+ Luca.concern.namespaces = ["Luca.concerns"];
707
+
708
+ Luca.concern.namespace = function(namespace) {
709
+ Luca.concern.namespaces.push(namespace);
710
+ return Luca.concern.namespaces = _(Luca.concern.namespaces).uniq();
711
+ };
712
+
713
+ Luca.concern.setup = function() {
714
+ var module, _i, _len, _ref, _ref2, _ref3, _ref4, _results;
715
+ if (((_ref = this.concerns) != null ? _ref.length : void 0) > 0) {
716
+ _ref2 = this.concerns;
717
+ _results = [];
718
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
719
+ module = _ref2[_i];
720
+ _results.push((_ref3 = Luca.concern(module)) != null ? (_ref4 = _ref3.__initializer) != null ? _ref4.call(this, this, module) : void 0 : void 0);
721
+ }
722
+ return _results;
723
+ }
724
+ };
725
+
726
+ Luca.decorate = function(target) {
727
+ var componentClass, componentName, componentPrototype;
728
+ try {
729
+ if (_.isString(target)) {
730
+ componentName = target;
731
+ componentClass = Luca.util.resolve(componentName);
732
+ }
733
+ if (_.isFunction(target)) componentClass = target;
734
+ componentPrototype = componentClass.prototype;
735
+ componentName = componentName || componentClass.displayName;
736
+ componentName || (componentName = componentPrototype.displayName);
737
+ } catch (e) {
738
+ console.log(e.message);
739
+ console.log(e.stack);
740
+ console.log("Error calling Luca.decorate on ", componentClass, componentPrototype, componentName);
741
+ throw e;
742
+ }
743
+ return {
744
+ "with": function(mixinName) {
745
+ var fn, method, mixinDefinition, mixinPrivates, sanitized, superclassMixins, _ref;
746
+ mixinDefinition = Luca.concern(mixinName);
747
+ mixinDefinition.__displayName || (mixinDefinition.__displayName = mixinName);
748
+ mixinPrivates = _(mixinDefinition).chain().keys().select(function(key) {
749
+ return ("" + key).match(/^__/) || key === "classMethods";
750
+ });
751
+ sanitized = _(mixinDefinition).omit(mixinPrivates.value());
752
+ _.extend(componentPrototype, sanitized);
753
+ if (mixinDefinition.classMethods != null) {
754
+ _ref = mixinDefinition.classMethods;
755
+ for (method in _ref) {
756
+ fn = _ref[method];
757
+ componentClass[method] = _.bind(fn, componentClass);
758
+ }
759
+ }
760
+ if (mixinDefinition != null) {
761
+ if (typeof mixinDefinition.__included === "function") {
762
+ mixinDefinition.__included(componentName, componentClass, mixinDefinition);
763
+ }
764
+ }
765
+ superclassMixins = componentPrototype._superClass().prototype.concerns;
766
+ componentPrototype.concerns || (componentPrototype.concerns = []);
767
+ componentPrototype.concerns.push(mixinName);
768
+ componentPrototype.concerns = componentPrototype.concerns.concat(superclassMixins);
769
+ componentPrototype.concerns = _(componentPrototype.concerns).chain().uniq().compact().value();
770
+ return componentPrototype;
771
+ }
772
+ };
773
+ };
774
+
627
775
  }).call(this);
628
776
  (function() {
629
777
  var DefineProxy,
@@ -632,7 +780,8 @@
632
780
  _.mixin({
633
781
  def: Luca.component = Luca.define = Luca.register = function(componentName) {
634
782
  return new DefineProxy(componentName);
635
- }
783
+ },
784
+ register: Luca.register
636
785
  });
637
786
 
638
787
  DefineProxy = (function() {
@@ -642,6 +791,7 @@
642
791
  this.namespace = Luca.util.namespace();
643
792
  this.componentId = this.componentName = componentName;
644
793
  this.superClassName = 'Luca.View';
794
+ this.properties || (this.properties = {});
645
795
  if (componentName.match(/\./)) {
646
796
  this.namespaced = true;
647
797
  parts = componentName.split('.');
@@ -651,6 +801,16 @@
651
801
  }
652
802
  }
653
803
 
804
+ DefineProxy.prototype.meta = function(key, value) {
805
+ var data, metaKey;
806
+ metaKey = this.namespace + '.' + this.componentId;
807
+ metaKey = metaKey.replace(/^\./, '');
808
+ data = Luca.registry.addMetaData(metaKey, key, value);
809
+ return this.properties.componentMetaData = function() {
810
+ return Luca.registry.getMetaDataFor(metaKey);
811
+ };
812
+ };
813
+
654
814
  DefineProxy.prototype["in"] = function(namespace) {
655
815
  this.namespace = namespace;
656
816
  return this;
@@ -682,6 +842,7 @@
682
842
  this.properties.hooks.push(hook);
683
843
  }
684
844
  this.properties.hooks = _.uniq(this.properties.hooks);
845
+ this.meta("hooks", this.properties.hooks);
685
846
  return this;
686
847
  };
687
848
 
@@ -696,25 +857,51 @@
696
857
  this.properties.include.push(include);
697
858
  }
698
859
  this.properties.include = _.uniq(this.properties.include);
860
+ this.meta("includes", this.properties.include);
699
861
  return this;
700
862
  };
701
863
 
702
864
  DefineProxy.prototype.mixesIn = function() {
703
- var mixin, mixins, _i, _len;
704
- mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
865
+ var concern, concerns, _i, _len;
866
+ concerns = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
705
867
  _.defaults(this.properties || (this.properties = {}), {
706
- mixins: []
868
+ concerns: []
707
869
  });
708
- for (_i = 0, _len = mixins.length; _i < _len; _i++) {
709
- mixin = mixins[_i];
710
- this.properties.mixins.push(mixin);
870
+ for (_i = 0, _len = concerns.length; _i < _len; _i++) {
871
+ concern = concerns[_i];
872
+ this.properties.concerns.push(concern);
711
873
  }
712
- this.properties.mixins = _.uniq(this.properties.mixins);
874
+ this.properties.concerns = _.uniq(this.properties.concerns);
875
+ this.meta("concerns", this.properties.concerns);
713
876
  return this;
714
877
  };
715
878
 
716
- DefineProxy.prototype.defaultProperties = function(properties) {
717
- var at, componentType, _base;
879
+ DefineProxy.prototype.publicConfiguration = function(properties) {
880
+ if (properties == null) properties = {};
881
+ this.meta("public configuration", _.keys(properties));
882
+ return _.defaults((this.properties || (this.properties = {})), properties);
883
+ };
884
+
885
+ DefineProxy.prototype.privateConfiguration = function(properties) {
886
+ if (properties == null) properties = {};
887
+ this.meta("private configuration", _.keys(properties));
888
+ return _.defaults((this.properties || (this.properties = {})), properties);
889
+ };
890
+
891
+ DefineProxy.prototype.publicInterface = function(properties) {
892
+ if (properties == null) properties = {};
893
+ this.meta("public interface", _.keys(properties));
894
+ return _.defaults((this.properties || (this.properties = {})), properties);
895
+ };
896
+
897
+ DefineProxy.prototype.privateInterface = function(properties) {
898
+ if (properties == null) properties = {};
899
+ this.meta("private interface", _.keys(properties));
900
+ return _.defaults((this.properties || (this.properties = {})), properties);
901
+ };
902
+
903
+ DefineProxy.prototype.definePrototype = function(properties) {
904
+ var at, componentType, definition, _base;
718
905
  if (properties == null) properties = {};
719
906
  _.defaults((this.properties || (this.properties = {})), properties);
720
907
  at = this.namespaced ? Luca.util.resolve(this.namespace, window || global) : window || global;
@@ -722,35 +909,40 @@
722
909
  eval("(window||global)." + this.namespace + " = {}");
723
910
  at = Luca.util.resolve(this.namespace, window || global);
724
911
  }
725
- at[this.componentId] = Luca.extend(this.superClassName, this.componentName, this.properties);
726
- if (Luca.autoRegister === true) {
727
- if (Luca.isViewPrototype(at[this.componentId])) componentType = "view";
728
- if (Luca.isCollectionPrototype(at[this.componentId])) {
912
+ this.meta("super class name", this.superClassName);
913
+ this.meta("display name", this.componentName);
914
+ this.properties.displayName = this.componentName;
915
+ this.properties.componentMetaData = function() {
916
+ return Luca.registry.getMetaDataFor(this.displayName);
917
+ };
918
+ definition = at[this.componentId] = Luca.extend(this.superClassName, this.componentName, this.properties);
919
+ if (Luca.config.autoRegister === true) {
920
+ if (Luca.isViewPrototype(definition)) componentType = "view";
921
+ if (Luca.isCollectionPrototype(definition)) {
729
922
  (_base = Luca.Collection).namespaces || (_base.namespaces = []);
730
923
  Luca.Collection.namespaces.push(this.namespace);
731
924
  componentType = "collection";
732
925
  }
733
- if (Luca.isModelPrototype(at[this.componentId])) componentType = "model";
926
+ if (Luca.isModelPrototype(definition)) componentType = "model";
734
927
  Luca.registerComponent(_.string.underscored(this.componentId), this.componentName, componentType);
735
928
  }
736
- return at[this.componentId];
929
+ return definition;
737
930
  };
738
931
 
739
932
  return DefineProxy;
740
933
 
741
934
  })();
742
935
 
743
- DefineProxy.prototype.behavesAs = DefineProxy.prototype.uses = DefineProxy.prototype.mixesIn;
936
+ DefineProxy.prototype.concerns = DefineProxy.prototype.behavesAs = DefineProxy.prototype.uses = DefineProxy.prototype.mixesIn;
744
937
 
745
- DefineProxy.prototype.defines = DefineProxy.prototype.defaults = DefineProxy.prototype.exports = DefineProxy.prototype.defaultProperties;
938
+ DefineProxy.prototype.defines = DefineProxy.prototype.defaults = DefineProxy.prototype.exports = DefineProxy.prototype.defaultProperties = DefineProxy.prototype.definePrototype;
746
939
 
747
- DefineProxy.prototype.defaultsTo = DefineProxy.prototype.enhance = DefineProxy.prototype["with"] = DefineProxy.prototype.defaultProperties;
940
+ DefineProxy.prototype.defaultsTo = DefineProxy.prototype.enhance = DefineProxy.prototype["with"] = DefineProxy.prototype.definePrototype;
748
941
 
749
942
  Luca.extend = function(superClassName, childName, properties) {
750
943
  var definition, include, superClass, _i, _len, _ref;
751
944
  if (properties == null) properties = {};
752
945
  superClass = Luca.util.resolve(superClassName, window || global);
753
- superClass.__initializers || (superClass.__initializers = []);
754
946
  if (!_.isFunction(superClass != null ? superClass.extend : void 0)) {
755
947
  throw "Error defining " + childName + ". " + superClassName + " is not a valid component to extend from";
756
948
  }
@@ -777,59 +969,10 @@
777
969
  return definition;
778
970
  };
779
971
 
780
- Luca.mixin = function(mixinName) {
781
- var namespace, resolved;
782
- namespace = _(Luca.mixin.namespaces).detect(function(space) {
783
- var _ref;
784
- return ((_ref = Luca.util.resolve(space)) != null ? _ref[mixinName] : void 0) != null;
785
- });
786
- namespace || (namespace = "Luca.modules");
787
- resolved = Luca.util.resolve(namespace)[mixinName];
788
- if (resolved == null) {
789
- console.log("Could not find " + mixinName + " in ", Luca.mixin.namespaces);
790
- }
791
- return resolved;
792
- };
793
-
794
- Luca.mixin.namespaces = ["Luca.modules"];
795
-
796
- Luca.mixin.namespace = function(namespace) {
797
- Luca.mixin.namespaces.push(namespace);
798
- return Luca.mixin.namespaces = _(Luca.mixin.namespaces).uniq();
799
- };
800
-
801
- Luca.decorate = function(componentPrototype) {
802
- if (_.isString(componentPrototype)) {
803
- componentPrototype = Luca.util.resolve(componentPrototype).prototype;
804
- }
805
- return {
806
- "with": function(mixin) {
807
- var mixinDefinition, mixinPrivates, sanitized, superclassMixins, _ref;
808
- mixinDefinition = Luca.mixin(mixin);
809
- mixinPrivates = _(mixinDefinition).chain().keys().select(function(key) {
810
- return ("" + key).match(/^__/);
811
- });
812
- sanitized = _(mixinDefinition).omit(mixinPrivates.value());
813
- _.extend(componentPrototype, sanitized);
814
- if (mixinDefinition != null) {
815
- if ((_ref = mixinDefinition.__included) != null) {
816
- _ref.call(mixinDefinition, mixin);
817
- }
818
- }
819
- superclassMixins = componentPrototype._superClass().prototype.mixins;
820
- componentPrototype.mixins || (componentPrototype.mixins = []);
821
- componentPrototype.mixins.push(mixin);
822
- componentPrototype.mixins = componentPrototype.mixins.concat(superclassMixins);
823
- componentPrototype.mixins = _(componentPrototype.mixins).chain().uniq().compact().value();
824
- return componentPrototype;
825
- }
826
- };
827
- };
828
-
829
972
  }).call(this);
830
973
  (function() {
831
974
 
832
- Luca.modules.ApplicationEventBindings = {
975
+ Luca.concerns.ApplicationEventBindings = {
833
976
  __initializer: function() {
834
977
  var app, eventTrigger, handler, _len, _ref, _ref2, _results;
835
978
  if (_.isEmpty(this.applicationEvents)) return;
@@ -857,7 +1000,7 @@
857
1000
  }).call(this);
858
1001
  (function() {
859
1002
 
860
- Luca.modules.CollectionEventBindings = {
1003
+ Luca.concerns.CollectionEventBindings = {
861
1004
  __initializer: function() {
862
1005
  var collection, eventTrigger, handler, key, manager, signature, _ref, _ref2, _results;
863
1006
  if (_.isEmpty(this.collectionEvents)) return;
@@ -885,7 +1028,7 @@
885
1028
  }).call(this);
886
1029
  (function() {
887
1030
 
888
- Luca.modules.Deferrable = {
1031
+ Luca.concerns.Deferrable = {
889
1032
  configure_collection: function(setAsDeferrable) {
890
1033
  var collectionManager, _ref, _ref2;
891
1034
  if (setAsDeferrable == null) setAsDeferrable = true;
@@ -906,9 +1049,9 @@
906
1049
  }).call(this);
907
1050
  (function() {
908
1051
 
909
- Luca.modules.DomHelpers = {
1052
+ Luca.concerns.DomHelpers = {
910
1053
  __initializer: function() {
911
- var additional, additionalClasses, _i, _len, _results;
1054
+ var additional, additionalClasses, classes, cssClass, _i, _j, _len, _len2, _ref, _results;
912
1055
  additionalClasses = _(this.additionalClassNames || []).clone();
913
1056
  if (this.wrapperClass != null) this.$wrap(this.wrapperClass);
914
1057
  if (_.isString(additionalClasses)) {
@@ -919,21 +1062,34 @@
919
1062
  if (this.gridRowFluid) additionalClasses.push("row-fluid");
920
1063
  if (this.gridRow) additionalClasses.push("row");
921
1064
  if (additionalClasses == null) return;
922
- _results = [];
923
1065
  for (_i = 0, _len = additionalClasses.length; _i < _len; _i++) {
924
1066
  additional = additionalClasses[_i];
925
- _results.push(this.$el.addClass(additional));
1067
+ this.$el.addClass(additional);
1068
+ }
1069
+ if (Luca.config.autoApplyClassHierarchyAsCssClasses === true) {
1070
+ classes = (typeof this.componentMetaData === "function" ? (_ref = this.componentMetaData()) != null ? _ref.styleHierarchy() : void 0 : void 0) || [];
1071
+ _results = [];
1072
+ for (_j = 0, _len2 = classes.length; _j < _len2; _j++) {
1073
+ cssClass = classes[_j];
1074
+ if (cssClass !== "luca-view" && cssClass !== "backbone-view") {
1075
+ _results.push(this.$el.addClass(cssClass));
1076
+ }
1077
+ }
1078
+ return _results;
926
1079
  }
927
- return _results;
928
1080
  },
929
1081
  $wrap: function(wrapper) {
930
1082
  if (_.isString(wrapper) && !wrapper.match(/[<>]/)) {
931
1083
  wrapper = this.make("div", {
932
- "class": wrapper
1084
+ "class": wrapper,
1085
+ "data-wrapper": true
933
1086
  });
934
1087
  }
935
1088
  return this.$el.wrap(wrapper);
936
1089
  },
1090
+ $wrapper: function() {
1091
+ return this.$el.parent('[data-wrapper="true"]');
1092
+ },
937
1093
  $template: function(template, variables) {
938
1094
  if (variables == null) variables = {};
939
1095
  return this.$el.html(Luca.template(template, variables));
@@ -958,7 +1114,7 @@
958
1114
  }).call(this);
959
1115
  (function() {
960
1116
 
961
- Luca.modules.EnhancedProperties = {
1117
+ Luca.concerns.EnhancedProperties = {
962
1118
  __initializer: function() {
963
1119
  if (Luca.config.enhancedViewProperties !== true) return;
964
1120
  if (_.isString(this.collection) && Luca.CollectionManager.get()) {
@@ -977,50 +1133,56 @@
977
1133
  __hasProp = Object.prototype.hasOwnProperty,
978
1134
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
979
1135
 
980
- Luca.modules.Filterable = {
1136
+ Luca.concerns.Filterable = {
981
1137
  __included: function(component, module) {
982
1138
  return _.extend(Luca.Collection.prototype, {
983
1139
  __filters: {}
984
1140
  });
985
1141
  },
986
1142
  __initializer: function(component, module) {
987
- var filter,
1143
+ var filter, _base, _ref,
988
1144
  _this = this;
989
- if (this.filterable === false || !Luca.isBackboneCollection(this.collection)) {
1145
+ if (this.filterable === false) return;
1146
+ if (!Luca.isBackboneCollection(this.collection)) {
1147
+ this.collection = typeof (_base = Luca.CollectionManager).get === "function" ? (_ref = _base.get()) != null ? _ref.getOrCreate(this.collection) : void 0 : void 0;
1148
+ }
1149
+ if (!Luca.isBackboneCollection(this.collection)) {
1150
+ this.debug("Skipping Filterable due to no collection being present on " + (this.name || this.cid));
1151
+ this.debug("Collection", this.collection);
990
1152
  return;
991
1153
  }
992
1154
  this.getCollection || (this.getCollection = function() {
993
1155
  return this.collection;
994
1156
  });
995
1157
  filter = this.getFilterState();
996
- filter.on("change", function(state) {
997
- _this.trigger("collection:change:filter", state, _this.getCollection());
998
- return _this.trigger("refresh");
1158
+ this.querySources || (this.querySources = []);
1159
+ this.optionsSources || (this.optionsSources = []);
1160
+ this.query || (this.query = {});
1161
+ this.queryOptions || (this.queryOptions = {});
1162
+ this.querySources.push((function() {
1163
+ return filter.toQuery();
1164
+ }));
1165
+ this.optionsSources.push((function() {
1166
+ return filter.toOptions();
1167
+ }));
1168
+ if (this.debugMode === true) {
1169
+ console.log("Filterable");
1170
+ console.log(this.querySources);
1171
+ console.log(this.optionsSources);
1172
+ }
1173
+ filter.on("change", function() {
1174
+ var merged;
1175
+ if (_this.isRemote()) {
1176
+ merged = _.extend(_this.getQuery(), _this.getQueryOptions());
1177
+ return _this.collection.applyFilter(merged, _this.getQueryOptions());
1178
+ } else {
1179
+ return _this.trigger("refresh");
1180
+ }
999
1181
  });
1000
- if (this.getQuery != null) {
1001
- this.getQuery = _.compose(this.getQuery, function(query) {
1002
- var obj;
1003
- if (query == null) query = {};
1004
- obj = _.clone(query);
1005
- return _.extend(obj, filter.toQuery());
1006
- });
1007
- } else {
1008
- this.getQuery = function() {
1009
- return filter.toQuery();
1010
- };
1011
- }
1012
- if (this.getQueryOptions != null) {
1013
- return this.getQueryOptions = _.compose(this.getQueryOptions, function(options) {
1014
- var obj;
1015
- if (options == null) options = {};
1016
- obj = _.clone(options);
1017
- return _.extend(obj, filter.toOptions());
1018
- });
1019
- } else {
1020
- return this.getQueryOptions = function() {
1021
- return filter.toOptions();
1022
- };
1023
- }
1182
+ return module;
1183
+ },
1184
+ isRemote: function() {
1185
+ return this.getQueryOptions().remote === true;
1024
1186
  },
1025
1187
  getFilterState: function() {
1026
1188
  var _base, _name;
@@ -1031,18 +1193,14 @@
1031
1193
  return this.getFilterState().setOption('sortBy', sortBy, options);
1032
1194
  },
1033
1195
  applyFilter: function(query, options) {
1034
- var silent;
1035
1196
  if (query == null) query = {};
1036
1197
  if (options == null) options = {};
1037
1198
  options = _.defaults(options, this.getQueryOptions());
1038
1199
  query = _.defaults(query, this.getQuery());
1039
- silent = _(options)["delete"]('silent') === true;
1040
1200
  return this.getFilterState().set({
1041
1201
  query: query,
1042
1202
  options: options
1043
- }, {
1044
- silent: silent
1045
- });
1203
+ }, options);
1046
1204
  }
1047
1205
  };
1048
1206
 
@@ -1054,6 +1212,11 @@
1054
1212
  FilterModel.__super__.constructor.apply(this, arguments);
1055
1213
  }
1056
1214
 
1215
+ FilterModel.prototype.defaults = {
1216
+ options: {},
1217
+ query: {}
1218
+ };
1219
+
1057
1220
  FilterModel.prototype.setOption = function(option, value, options) {
1058
1221
  var payload;
1059
1222
  payload = {};
@@ -1076,6 +1239,16 @@
1076
1239
  return this.toJSON().query;
1077
1240
  };
1078
1241
 
1242
+ FilterModel.prototype.toRemote = function() {
1243
+ var options;
1244
+ options = this.toOptions();
1245
+ return _.extend(this.toQuery(), {
1246
+ limit: options.limit,
1247
+ page: options.page,
1248
+ sortBy: options.sortBy
1249
+ });
1250
+ };
1251
+
1079
1252
  return FilterModel;
1080
1253
 
1081
1254
  })(Backbone.Model);
@@ -1083,7 +1256,7 @@
1083
1256
  }).call(this);
1084
1257
  (function() {
1085
1258
 
1086
- Luca.modules.GridLayout = {
1259
+ Luca.concerns.GridLayout = {
1087
1260
  _initializer: function() {
1088
1261
  if (this.gridSpan) this.$el.addClass("span" + this.gridSpan);
1089
1262
  if (this.gridOffset) this.$el.addClass("offset" + this.gridOffset);
@@ -1095,7 +1268,7 @@
1095
1268
  }).call(this);
1096
1269
  (function() {
1097
1270
 
1098
- Luca.modules.LoadMaskable = {
1271
+ Luca.concerns.LoadMaskable = {
1099
1272
  __initializer: function() {
1100
1273
  var _this = this;
1101
1274
  if (this.loadMask !== true) return;
@@ -1242,7 +1415,7 @@
1242
1415
  (function() {
1243
1416
  var applyModalConfig;
1244
1417
 
1245
- Luca.modules.ModalView = {
1418
+ Luca.concerns.ModalView = {
1246
1419
  closeOnEscape: true,
1247
1420
  showOnInitialize: false,
1248
1421
  backdrop: false,
@@ -1280,7 +1453,38 @@
1280
1453
  }).call(this);
1281
1454
  (function() {
1282
1455
 
1283
- Luca.modules.Paginatable = {
1456
+ Luca.concerns.ModelPresenter = {
1457
+ classMethods: {
1458
+ getPresenter: function(format) {
1459
+ var _ref;
1460
+ return (_ref = this.presenters) != null ? _ref[format] : void 0;
1461
+ },
1462
+ registerPresenter: function(format, config) {
1463
+ this.presenters || (this.presenters = {});
1464
+ return this.presenters[format] = config;
1465
+ }
1466
+ },
1467
+ presentAs: function(format) {
1468
+ var attributeList,
1469
+ _this = this;
1470
+ try {
1471
+ attributeList = this.componentMetaData().componentDefinition().getPresenter(format);
1472
+ if (attributeList == null) return this.toJSON();
1473
+ return _(attributeList).reduce(function(memo, attribute) {
1474
+ memo[attribute] = _this.read(attribute);
1475
+ return memo;
1476
+ }, {});
1477
+ } catch (e) {
1478
+ console.log("Error presentAs", e.stack, e.message);
1479
+ return this.toJSON();
1480
+ }
1481
+ }
1482
+ };
1483
+
1484
+ }).call(this);
1485
+ (function() {
1486
+
1487
+ Luca.concerns.Paginatable = {
1284
1488
  paginatorViewClass: 'Luca.components.PaginationControl',
1285
1489
  paginationSelector: ".toolbar.bottom",
1286
1490
  __included: function() {
@@ -1289,38 +1493,54 @@
1289
1493
  });
1290
1494
  },
1291
1495
  __initializer: function() {
1292
- var collection, old, paginationState,
1496
+ var collection, paginationState, _base, _ref,
1293
1497
  _this = this;
1294
- if (this.paginatable === false || !Luca.isBackboneCollection(this.collection)) {
1498
+ if (this.paginatable === false) return;
1499
+ if (!Luca.isBackboneCollection(this.collection)) {
1500
+ this.collection = typeof (_base = Luca.CollectionManager).get === "function" ? (_ref = _base.get()) != null ? _ref.getOrCreate(this.collection) : void 0 : void 0;
1501
+ }
1502
+ if (!Luca.isBackboneCollection(this.collection)) {
1503
+ this.debug("Skipping Paginatable due to no collection being present on " + (this.name || this.cid));
1504
+ this.debug("collection", this.collection);
1295
1505
  return;
1296
1506
  }
1297
- _.bindAll(this, "paginationControl");
1507
+ _.bindAll(this, "paginationControl", "pager");
1298
1508
  this.getCollection || (this.getCollection = function() {
1299
1509
  return this.collection;
1300
1510
  });
1301
1511
  collection = this.getCollection();
1302
1512
  paginationState = this.getPaginationState();
1303
- paginationState.on("change", function(state) {
1304
- _this.trigger("collection:change:pagination", state, collection);
1305
- return _this.trigger("refresh");
1306
- });
1307
- this.on("after:refresh", function(models, query, options) {
1308
- return _.defer(function() {
1309
- return _this.updatePagination.call(_this, models, query, options);
1513
+ this.optionsSources || (this.optionsSources = []);
1514
+ this.queryOptions || (this.queryOptions = {});
1515
+ this.optionsSources.push(function() {
1516
+ var options;
1517
+ options = _(paginationState.toJSON()).pick('limit', 'page', 'sortBy');
1518
+ return _.extend(options, {
1519
+ pager: _this.pager
1310
1520
  });
1311
1521
  });
1312
- this.on("after:render", function() {
1313
- return _this.paginationControl().refresh();
1522
+ paginationState.on("change:page", function(state) {
1523
+ var filter;
1524
+ if (_this.isRemote()) {
1525
+ filter = _.extend(_this.toQuery(), _this.toQueryOptions());
1526
+ return _this.collection.applyFilter(filter, {
1527
+ remote: true
1528
+ });
1529
+ } else {
1530
+ return _this.trigger("refresh");
1531
+ }
1314
1532
  });
1315
- if (old = this.getQueryOptions) {
1316
- return this.getQueryOptions = function() {
1317
- return _.extend(old(), paginationState.toJSON());
1318
- };
1319
- } else {
1320
- return this.getQueryOptions = function() {
1321
- return paginationState.toJSON();
1322
- };
1323
- }
1533
+ return this.on("before:render", this.renderPaginationControl, this);
1534
+ },
1535
+ pager: function(numberOfPages, models) {
1536
+ this.getPaginationState().set({
1537
+ numberOfPages: numberOfPages,
1538
+ itemCount: models.length
1539
+ });
1540
+ return this.paginationControl().updateWithPageCount(numberOfPages, models);
1541
+ },
1542
+ isRemote: function() {
1543
+ return this.getQueryOptions().remote === true;
1324
1544
  },
1325
1545
  getPaginationState: function() {
1326
1546
  var _base, _name;
@@ -1334,32 +1554,16 @@
1334
1554
  if (options == null) options = {};
1335
1555
  return this.getPaginationState().set('page', page, options);
1336
1556
  },
1557
+ setPage: function(page, options) {
1558
+ if (page == null) page = 1;
1559
+ if (options == null) options = {};
1560
+ return this.getPaginationState().set('page', page, options);
1561
+ },
1337
1562
  setLimit: function(limit, options) {
1338
1563
  if (limit == null) limit = 0;
1339
1564
  if (options == null) options = {};
1340
1565
  return this.getPaginationState().set('limit', limit, options);
1341
1566
  },
1342
- updatePagination: function(models, query, options) {
1343
- var itemCount, paginator, totalCount, _ref;
1344
- if (models == null) models = [];
1345
- if (query == null) query = {};
1346
- if (options == null) options = {};
1347
- _.defaults(options, this.getQueryOptions(), {
1348
- limit: 0
1349
- });
1350
- paginator = this.paginationControl();
1351
- itemCount = (models != null ? models.length : void 0) || 0;
1352
- totalCount = (_ref = this.getCollection()) != null ? _ref.length : void 0;
1353
- if (itemCount === 0 || totalCount <= options.limit) {
1354
- paginator.$el.hide();
1355
- } else {
1356
- paginator.$el.show();
1357
- }
1358
- return paginator.state.set({
1359
- page: options.page,
1360
- limit: options.limit
1361
- });
1362
- },
1363
1567
  paginationControl: function() {
1364
1568
  if (this.paginator != null) return this.paginator;
1365
1569
  _.defaults(this.paginatable || (this.paginatable = {}), {
@@ -1369,20 +1573,24 @@
1369
1573
  this.paginator = Luca.util.lazyComponent({
1370
1574
  type: "pagination_control",
1371
1575
  collection: this.getCollection(),
1372
- defaultState: this.paginatable
1576
+ defaultState: this.paginatable,
1577
+ parent: this.name || this.cid,
1578
+ debugMode: this.debugMode
1373
1579
  });
1374
1580
  return this.paginator;
1375
1581
  },
1376
1582
  renderPaginationControl: function() {
1377
- this.paginationControl();
1378
- return this.paginationContainer().append(this.paginationControl().render().$el);
1583
+ var control;
1584
+ control = this.paginationControl();
1585
+ this.paginationContainer().append(control.render().$el);
1586
+ return control;
1379
1587
  }
1380
1588
  };
1381
1589
 
1382
1590
  }).call(this);
1383
1591
  (function() {
1384
1592
 
1385
- Luca.modules.StateModel = {
1593
+ Luca.concerns.StateModel = {
1386
1594
  __initializer: function() {
1387
1595
  var _this = this;
1388
1596
  if (this.stateful !== true) return;
@@ -1412,7 +1620,7 @@
1412
1620
  }).call(this);
1413
1621
  (function() {
1414
1622
 
1415
- Luca.modules.Templating = {
1623
+ Luca.concerns.Templating = {
1416
1624
  __initializer: function() {
1417
1625
  var template, templateContent, templateVars;
1418
1626
  templateVars = Luca.util.read.call(this, this.bodyTemplateVars) || {};
@@ -1563,6 +1771,61 @@
1563
1771
  return componentCacheStore.cid_index[lookup_id];
1564
1772
  };
1565
1773
 
1774
+ }).call(this);
1775
+ (function() {
1776
+ var MetaDataProxy;
1777
+
1778
+ Luca.registry.componentMetaData = {};
1779
+
1780
+ Luca.registry.getMetaDataFor = function(componentName) {
1781
+ return new MetaDataProxy(Luca.registry.componentMetaData[componentName]);
1782
+ };
1783
+
1784
+ Luca.registry.addMetaData = function(componentName, key, value) {
1785
+ var data, _base;
1786
+ data = (_base = Luca.registry.componentMetaData)[componentName] || (_base[componentName] = {});
1787
+ data[key] = _(value).clone();
1788
+ return data;
1789
+ };
1790
+
1791
+ MetaDataProxy = (function() {
1792
+
1793
+ function MetaDataProxy(meta) {
1794
+ this.meta = meta != null ? meta : {};
1795
+ this;
1796
+ }
1797
+
1798
+ MetaDataProxy.prototype.superClass = function() {
1799
+ return Luca.util.resolve(this.meta["super class name"]);
1800
+ };
1801
+
1802
+ MetaDataProxy.prototype.componentDefinition = function() {
1803
+ return Luca.util.resolve(this.meta["display name"]);
1804
+ };
1805
+
1806
+ MetaDataProxy.prototype.styleHierarchy = function() {
1807
+ var list;
1808
+ list = _(this.classHierarchy()).map(function(cls) {
1809
+ return Luca.util.toCssClass(cls, 'views', 'components', 'core', 'fields', 'containers');
1810
+ });
1811
+ return _(list).without('backbone-view', 'luca-view');
1812
+ };
1813
+
1814
+ MetaDataProxy.prototype.classHierarchy = function() {
1815
+ var list, proxy, _ref, _ref2, _ref3, _ref4;
1816
+ list = [this.meta["display name"], this.meta["super class name"]];
1817
+ proxy = (_ref = this.superClass()) != null ? (_ref2 = _ref.prototype) != null ? typeof _ref2.componentMetaData === "function" ? _ref2.componentMetaData() : void 0 : void 0 : void 0;
1818
+ while (!!proxy) {
1819
+ list = list.concat(proxy != null ? proxy.classHierarchy() : void 0);
1820
+ proxy = (_ref3 = proxy.superClass()) != null ? (_ref4 = _ref3.prototype) != null ? typeof _ref4.componentMetaData === "function" ? _ref4.componentMetaData() : void 0 : void 0 : void 0;
1821
+ }
1822
+ return _(list).uniq();
1823
+ };
1824
+
1825
+ return MetaDataProxy;
1826
+
1827
+ })();
1828
+
1566
1829
  }).call(this);
1567
1830
  (function() {
1568
1831
  var __slice = Array.prototype.slice;
@@ -1606,13 +1869,14 @@
1606
1869
 
1607
1870
  }).call(this);
1608
1871
  (function() {
1609
- var bindAllEventHandlers, bindEventHandlers, view;
1872
+ var bindAllEventHandlers, bindEventHandlers, view,
1873
+ __slice = Array.prototype.slice;
1610
1874
 
1611
1875
  view = Luca.register("Luca.View");
1612
1876
 
1613
1877
  view["extends"]("Backbone.View");
1614
1878
 
1615
- view.includes("Luca.Events", "Luca.modules.DomHelpers");
1879
+ view.includes("Luca.Events", "Luca.concerns.DomHelpers");
1616
1880
 
1617
1881
  view.mixesIn("DomHelpers", "Templating", "EnhancedProperties", "CollectionEventBindings", "ApplicationEventBindings", "StateModel");
1618
1882
 
@@ -1620,7 +1884,6 @@
1620
1884
 
1621
1885
  view.defines({
1622
1886
  initialize: function(options) {
1623
- var module, _i, _len, _ref, _ref2, _ref3, _ref4;
1624
1887
  this.options = options != null ? options : {};
1625
1888
  this.trigger("before:initialize", this, this.options);
1626
1889
  _.extend(this, this.options);
@@ -1631,36 +1894,11 @@
1631
1894
  this.$el.attr("data-luca-id", this.name || this.cid);
1632
1895
  Luca.cacheInstance(this.cid, this);
1633
1896
  this.setupHooks(_(Luca.View.prototype.hooks.concat(this.hooks)).uniq());
1634
- if (((_ref = this.mixins) != null ? _ref.length : void 0) > 0) {
1635
- _ref2 = this.mixins;
1636
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1637
- module = _ref2[_i];
1638
- if ((_ref3 = Luca.mixin(module)) != null) {
1639
- if ((_ref4 = _ref3.__initializer) != null) {
1640
- _ref4.call(this, this, module);
1641
- }
1642
- }
1643
- }
1644
- }
1897
+ Luca.concern.setup.call(this);
1645
1898
  this.delegateEvents();
1646
1899
  return this.trigger("after:initialize", this);
1647
1900
  },
1648
- setupHooks: function(set) {
1649
- var _this = this;
1650
- set || (set = this.hooks);
1651
- return _(set).each(function(eventId) {
1652
- var callback, fn;
1653
- fn = Luca.util.hook(eventId);
1654
- callback = function() {
1655
- var _ref;
1656
- return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0;
1657
- };
1658
- if (eventId != null ? eventId.match(/once:/) : void 0) {
1659
- callback = _.once(callback);
1660
- }
1661
- return _this.on(eventId, callback, _this);
1662
- });
1663
- },
1901
+ setupHooks: Luca.util.setupHooks,
1664
1902
  registerEvent: function(selector, handler) {
1665
1903
  this.events || (this.events = {});
1666
1904
  this.events[selector] = handler;
@@ -1680,14 +1918,10 @@
1680
1918
  return Luca.util.selectProperties(Luca.isBackboneView, this);
1681
1919
  },
1682
1920
  debug: function() {
1683
- var message, _i, _len, _results;
1921
+ var args;
1922
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
1684
1923
  if (!(this.debugMode || (window.LucaDebugMode != null))) return;
1685
- _results = [];
1686
- for (_i = 0, _len = arguments.length; _i < _len; _i++) {
1687
- message = arguments[_i];
1688
- _results.push(console.log([this.name || this.cid, message]));
1689
- }
1690
- return _results;
1924
+ return console.log([this.name || this.cid].concat(__slice.call(args)));
1691
1925
  },
1692
1926
  trigger: function() {
1693
1927
  if (Luca.enableGlobalObserver) {
@@ -1772,21 +2006,26 @@
1772
2006
  return _results;
1773
2007
  };
1774
2008
 
2009
+ Luca.View.deferrableEvent = "reset";
2010
+
1775
2011
  Luca.View.extend = function(definition) {
1776
- var module, _i, _len, _ref;
2012
+ var componentClass, module, _i, _len, _ref;
2013
+ if (definition == null) definition = {};
1777
2014
  definition = Luca.View.renderWrapper(definition);
1778
- if ((definition.mixins != null) && _.isArray(definition.mixins)) {
1779
- _ref = definition.mixins;
2015
+ if (definition.concerns != null) {
2016
+ definition.concerns || (definition.concerns = definition.concerns);
2017
+ }
2018
+ componentClass = Luca.View._originalExtend.call(this, definition);
2019
+ if ((definition.concerns != null) && _.isArray(definition.concerns)) {
2020
+ _ref = definition.concerns;
1780
2021
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1781
2022
  module = _ref[_i];
1782
- Luca.decorate(definition)["with"](module);
2023
+ Luca.decorate(componentClass)["with"](module);
1783
2024
  }
1784
2025
  }
1785
- return Luca.View._originalExtend.call(this, definition);
2026
+ return componentClass;
1786
2027
  };
1787
2028
 
1788
- Luca.View.deferrableEvent = "reset";
1789
-
1790
2029
  }).call(this);
1791
2030
  (function() {
1792
2031
  var model, setupComputedProperties;
@@ -1800,13 +2039,14 @@
1800
2039
  model.defines({
1801
2040
  initialize: function() {
1802
2041
  Backbone.Model.prototype.initialize(this, arguments);
1803
- return setupComputedProperties.call(this);
2042
+ setupComputedProperties.call(this);
2043
+ return Luca.concern.setup.call(this);
1804
2044
  },
1805
2045
  read: function(attr) {
1806
2046
  if (_.isFunction(this[attr])) {
1807
2047
  return this[attr].call(this);
1808
2048
  } else {
1809
- return this.get(attr);
2049
+ return this.get(attr) || this[attr];
1810
2050
  }
1811
2051
  },
1812
2052
  get: function(attr) {
@@ -1842,6 +2082,25 @@
1842
2082
  return _results;
1843
2083
  };
1844
2084
 
2085
+ Luca.Model._originalExtend = Backbone.Model.extend;
2086
+
2087
+ Luca.Model.extend = function(definition) {
2088
+ var componentClass, module, _i, _len, _ref;
2089
+ if (definition == null) definition = {};
2090
+ if (definition.concerns != null) {
2091
+ definition.concerns || (definition.concerns = definition.concerns);
2092
+ }
2093
+ componentClass = Luca.Model._originalExtend.call(this, definition);
2094
+ if ((definition.concerns != null) && _.isArray(definition.concerns)) {
2095
+ _ref = definition.concerns;
2096
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2097
+ module = _ref[_i];
2098
+ Luca.decorate(componentClass)["with"](module);
2099
+ }
2100
+ }
2101
+ return componentClass;
2102
+ };
2103
+
1845
2104
  }).call(this);
1846
2105
  (function() {
1847
2106
  var collection;
@@ -1906,6 +2165,7 @@
1906
2165
  parse: options != null ? options.parse : void 0
1907
2166
  });
1908
2167
  }
2168
+ Luca.concern.setup.call(this);
1909
2169
  return this.trigger("after:initialize");
1910
2170
  },
1911
2171
  __wrapUrl: function() {
@@ -2001,7 +2261,9 @@
2001
2261
  if (options == null) options = {};
2002
2262
  this.trigger("before:fetch", this);
2003
2263
  if (this.memoryCollection === true) return this.reset(this.data);
2004
- if (this.cached_models().length && !options.refresh) return this.bootstrap();
2264
+ if (this.cached_models().length && !(options.refresh === true || options.remote === true)) {
2265
+ return this.bootstrap();
2266
+ }
2005
2267
  url = _.isFunction(this.url) ? this.url() : this.url;
2006
2268
  if (!((url && url.length > 1) || this.localStorage)) return true;
2007
2269
  this.fetching = true;
@@ -2150,6 +2412,25 @@
2150
2412
  }
2151
2413
  });
2152
2414
 
2415
+ Luca.Collection._originalExtend = Backbone.Collection.extend;
2416
+
2417
+ Luca.Collection.extend = function(definition) {
2418
+ var componentClass, module, _i, _len, _ref;
2419
+ if (definition == null) definition = {};
2420
+ if (definition.concerns != null) {
2421
+ definition.concerns || (definition.concerns = definition.concerns);
2422
+ }
2423
+ componentClass = Luca.Collection._originalExtend.call(this, definition);
2424
+ if ((definition.concerns != null) && _.isArray(definition.concerns)) {
2425
+ _ref = definition.concerns;
2426
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2427
+ module = _ref[_i];
2428
+ Luca.decorate(componentClass)["with"](module);
2429
+ }
2430
+ }
2431
+ return componentClass;
2432
+ };
2433
+
2153
2434
  Luca.Collection.baseParams = function(obj) {
2154
2435
  if (obj) return Luca.Collection._baseParams = obj;
2155
2436
  if (_.isFunction(Luca.Collection._baseParams)) {
@@ -2298,40 +2579,21 @@
2298
2579
 
2299
2580
  }).call(this);
2300
2581
  (function() {
2582
+ var field;
2301
2583
 
2302
- _.def('Luca.core.Field')["extends"]('Luca.View')["with"]({
2303
- className: 'luca-ui-text-field luca-ui-field',
2304
- isField: true,
2305
- template: 'fields/text_field',
2584
+ field = Luca.register("Luca.core.Field");
2585
+
2586
+ field["extends"]("Luca.View");
2587
+
2588
+ field.triggers("before:validation", "after:validation", "on:change");
2589
+
2590
+ field.publicConfiguration({
2306
2591
  labelAlign: 'top',
2307
- hooks: ["before:validation", "after:validation", "on:change"],
2308
- statuses: ["warning", "error", "success"],
2309
- initialize: function(options) {
2310
- var _ref;
2311
- this.options = options != null ? options : {};
2312
- _.extend(this, this.options);
2313
- this.input_id || (this.input_id = _.uniqueId('field'));
2314
- this.input_name || (this.input_name = this.name);
2315
- this.input_class || (this.input_class = "");
2316
- this.input_type || (this.input_type = "");
2317
- this.helperText || (this.helperText = "");
2318
- if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) {
2319
- this.label || (this.label = "*" + this.label);
2320
- }
2321
- this.inputStyles || (this.inputStyles = "");
2322
- this.input_value || (this.input_value = this.value || "");
2323
- if (this.disabled) this.disable();
2324
- this.updateState(this.state);
2325
- this.placeHolder || (this.placeHolder = "");
2326
- return Luca.View.prototype.initialize.apply(this, arguments);
2327
- },
2328
- beforeRender: function() {
2329
- if (Luca.enableBootstrap) this.$el.addClass('control-group');
2330
- if (this.required) return this.$el.addClass('required');
2331
- },
2332
- change_handler: function(e) {
2333
- return this.trigger("on:change", this, e);
2334
- },
2592
+ className: 'luca-ui-text-field luca-ui-field',
2593
+ statuses: ["warning", "error", "success"]
2594
+ });
2595
+
2596
+ field.publicInterface({
2335
2597
  disable: function() {
2336
2598
  return this.getInputElement().attr('disabled', true);
2337
2599
  },
@@ -2357,9 +2619,6 @@
2357
2619
  var _ref;
2358
2620
  return (_ref = this.getInputElement()) != null ? _ref.attr('value', value) : void 0;
2359
2621
  },
2360
- getInputElement: function() {
2361
- return this.input || (this.input = this.$('input').eq(0));
2362
- },
2363
2622
  updateState: function(state) {
2364
2623
  var _this = this;
2365
2624
  return _(this.statuses).each(function(cls) {
@@ -2369,6 +2628,44 @@
2369
2628
  }
2370
2629
  });
2371
2630
 
2631
+ field.privateConfiguration({
2632
+ isField: true,
2633
+ template: 'fields/text_field'
2634
+ });
2635
+
2636
+ field.defines({
2637
+ initialize: function(options) {
2638
+ var _ref;
2639
+ this.options = options != null ? options : {};
2640
+ _.extend(this, this.options);
2641
+ this.input_id || (this.input_id = _.uniqueId('field'));
2642
+ this.input_name || (this.input_name = this.name);
2643
+ this.input_class || (this.input_class = "");
2644
+ this.input_type || (this.input_type = "");
2645
+ this.helperText || (this.helperText = "");
2646
+ if (!(this.label != null) || this.label.length === 0) this.label = this.name;
2647
+ if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) {
2648
+ this.label || (this.label = "*" + this.label);
2649
+ }
2650
+ this.inputStyles || (this.inputStyles = "");
2651
+ this.input_value || (this.input_value = this.value || "");
2652
+ if (this.disabled) this.disable();
2653
+ this.updateState(this.state);
2654
+ this.placeHolder || (this.placeHolder = "");
2655
+ return Luca.View.prototype.initialize.apply(this, arguments);
2656
+ },
2657
+ beforeRender: function() {
2658
+ if (Luca.enableBootstrap) this.$el.addClass('control-group');
2659
+ if (this.required) return this.$el.addClass('required');
2660
+ },
2661
+ change_handler: function(e) {
2662
+ return this.trigger("on:change", this, e);
2663
+ },
2664
+ getInputElement: function() {
2665
+ return this.input || (this.input = this.$('input').eq(0));
2666
+ }
2667
+ });
2668
+
2372
2669
  }).call(this);
2373
2670
  (function() {
2374
2671
  var applyDOMConfig, container, createGetterMethods, createMethodsToGetComponentsByRole, doComponents, doLayout, indexComponent, validateContainerConfiguration;
@@ -2413,6 +2710,7 @@
2413
2710
  prepareComponents: function() {
2414
2711
  var component, _i, _len, _ref,
2415
2712
  _this = this;
2713
+ container = this;
2416
2714
  _ref = this.components;
2417
2715
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2418
2716
  component = _ref[_i];
@@ -2423,13 +2721,24 @@
2423
2721
  }
2424
2722
  }
2425
2723
  return _(this.components).each(function(component, index) {
2426
- var ce, componentContainerElement, panel, _ref2;
2724
+ var ce, componentContainerElement, componentExtension, panel, _ref2, _ref3;
2427
2725
  ce = componentContainerElement = (_ref2 = _this.componentContainers) != null ? _ref2[index] : void 0;
2428
2726
  ce["class"] = ce["class"] || ce.className || ce.classes;
2429
2727
  if (_this.generateComponentElements) {
2430
2728
  panel = _this.make(_this.componentTag, componentContainerElement, '');
2431
2729
  _this.$append(panel);
2432
2730
  }
2731
+ if (container.defaults != null) {
2732
+ component = _.defaults(component, container.defaults || {});
2733
+ }
2734
+ if (_.isArray(container.extensions) && _.isObject((_ref3 = container.extensions) != null ? _ref3[index] : void 0)) {
2735
+ componentExtension = container.extensions[index];
2736
+ component = _.extend(component, componentExtension);
2737
+ }
2738
+ if ((component.role != null) && _.isObject(container.extensions) && _.isObject(container.extensions[component.role])) {
2739
+ componentExtension = container.extensions[component.role];
2740
+ component = _.extend(component, componentExtension);
2741
+ }
2433
2742
  if (component.container == null) {
2434
2743
  if (_this.generateComponentElements) {
2435
2744
  component.container = "#" + componentContainerElement.id;
@@ -2449,11 +2758,15 @@
2449
2758
  };
2450
2759
  container = this;
2451
2760
  this.components = _(this.components).map(function(object, index) {
2452
- var component, created;
2453
- 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));
2454
- if (!component.container && component.options.container) {
2761
+ var component, created, _ref;
2762
+ 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));
2763
+ if (!component.container && ((_ref = component.options) != null ? _ref.container : void 0)) {
2455
2764
  component.container = component.options.container;
2456
2765
  }
2766
+ if (!(component.container != null)) {
2767
+ console.log(component, index, _this);
2768
+ console.error("could not assign container property to component on container " + (_this.name || _this.cid));
2769
+ }
2457
2770
  indexComponent(component).at(index)["in"](_this.componentIndex);
2458
2771
  return component;
2459
2772
  });
@@ -2469,7 +2782,7 @@
2469
2782
  return container;
2470
2783
  };
2471
2784
  try {
2472
- $(component.container).append(component.el);
2785
+ this.$(component.container).eq(0).append(component.el);
2473
2786
  return component.render();
2474
2787
  } catch (e) {
2475
2788
  console.log("Error Rendering Component " + (component.name || component.cid), component);
@@ -2517,11 +2830,11 @@
2517
2830
  map: function(fn) {
2518
2831
  return this._().map(fn);
2519
2832
  },
2520
- registerComponentEvents: function() {
2833
+ registerComponentEvents: function(eventList) {
2521
2834
  var component, componentNameOrRole, eventId, handler, listener, _ref, _ref2, _results,
2522
2835
  _this = this;
2523
2836
  container = this;
2524
- _ref = this.componentEvents || {};
2837
+ _ref = eventList || this.componentEvents || {};
2525
2838
  _results = [];
2526
2839
  for (listener in _ref) {
2527
2840
  handler = _ref[listener];
@@ -2557,10 +2870,10 @@
2557
2870
  var children, grandchildren;
2558
2871
  children = this.components;
2559
2872
  grandchildren = _(this.subContainers()).invoke('allChildren');
2560
- return this._allChildren || (this._allChildren = _([children, grandchildren]).chain().compact().flatten().uniq().value());
2873
+ return _([children, grandchildren]).chain().compact().flatten().value();
2561
2874
  },
2562
2875
  findComponentForEventBinding: function(nameRoleOrGetter, deep) {
2563
- if (deep == null) deep = false;
2876
+ if (deep == null) deep = true;
2564
2877
  return this.findComponentByName(nameRoleOrGetter, deep) || this.findComponentByGetter(nameRoleOrGetter, deep) || this.findComponentByRole(nameRoleOrGetter, deep);
2565
2878
  },
2566
2879
  findComponentByGetter: function(getter, deep) {
@@ -2572,7 +2885,7 @@
2572
2885
  findComponentByRole: function(role, deep) {
2573
2886
  if (deep == null) deep = false;
2574
2887
  return _(this.allChildren()).detect(function(component) {
2575
- return component.role === role;
2888
+ return component.role === role || component.type === role || component.ctype === role;
2576
2889
  });
2577
2890
  },
2578
2891
  findComponentByName: function(name, deep) {
@@ -2702,7 +3015,6 @@
2702
3015
  return _(childrenWithGetter).each(function(component) {
2703
3016
  var _name;
2704
3017
  return container[_name = component.getter] || (container[_name] = function() {
2705
- console.log("getter is being deprecated in favor of role");
2706
3018
  console.log(component.getter, component, container);
2707
3019
  return component;
2708
3020
  });
@@ -2731,8 +3043,10 @@
2731
3043
  this.trigger("before:render:components", this, this.components);
2732
3044
  this.renderComponents();
2733
3045
  this.trigger("after:components", this, this.components);
2734
- createGetterMethods.call(this);
2735
- createMethodsToGetComponentsByRole.call(this);
3046
+ if (this.skipGetterMethods !== true) {
3047
+ createGetterMethods.call(this);
3048
+ createMethodsToGetComponentsByRole.call(this);
3049
+ }
2736
3050
  return this.registerComponentEvents();
2737
3051
  };
2738
3052
 
@@ -3415,16 +3729,27 @@
3415
3729
 
3416
3730
  }).call(this);
3417
3731
  (function() {
3732
+ var tabView;
3733
+
3734
+ _.def('Luca.containers.TabView')["extends"]('Luca.containers.CardView')["with"];
3735
+
3736
+ tabView = Luca.register("Luca.containers.TabView");
3737
+
3738
+ tabView.triggers("before:select", "after:select");
3418
3739
 
3419
- _.def('Luca.containers.TabView')["extends"]('Luca.containers.CardView')["with"]({
3420
- hooks: ["before:select", "after:select"],
3421
- componentType: 'tab_view',
3422
- className: 'luca-ui-tab-view tabbable',
3740
+ tabView.publicConfiguration({
3423
3741
  tab_position: 'top',
3424
- tabVerticalOffset: '50px',
3742
+ tabVerticalOffset: '50px'
3743
+ });
3744
+
3745
+ tabView.privateConfiguration({
3746
+ additionalClassNames: 'tabbable',
3425
3747
  navClass: "nav-tabs",
3426
3748
  bodyTemplate: "containers/tab_view",
3427
- bodyEl: "div.tab-content",
3749
+ bodyEl: "div.tab-content"
3750
+ });
3751
+
3752
+ tabView.defines({
3428
3753
  initialize: function(options) {
3429
3754
  this.options = options != null ? options : {};
3430
3755
  if (this.navStyle === "list") this.navClass = "nav-list";
@@ -3456,7 +3781,6 @@
3456
3781
  }
3457
3782
  },
3458
3783
  createTabSelectors: function() {
3459
- var tabView;
3460
3784
  tabView = this;
3461
3785
  return this.each(function(component, index) {
3462
3786
  var icon, link, selector, _ref;
@@ -3606,13 +3930,13 @@
3606
3930
 
3607
3931
  }).call(this);
3608
3932
  (function() {
3609
- var startHistory;
3933
+ var application;
3610
3934
 
3611
- startHistory = function() {
3612
- return Backbone.history.start();
3613
- };
3935
+ application = Luca.register("Luca.Application");
3614
3936
 
3615
- _.def('Luca.Application')["extends"]('Luca.containers.Viewport')["with"]({
3937
+ application["extends"]("Luca.containers.Viewport");
3938
+
3939
+ application.defines({
3616
3940
  name: "MyApp",
3617
3941
  defaultState: {},
3618
3942
  autoBoot: false,
@@ -3810,7 +4134,7 @@
3810
4134
  if (this.autoStartHistory === true) {
3811
4135
  this.autoStartHistory = "before:render";
3812
4136
  }
3813
- return this.defer(startHistory, false).until(this, this.autoStartHistory);
4137
+ return this.defer(Luca.util.startHistory, false).until(this, this.autoStartHistory);
3814
4138
  }
3815
4139
  },
3816
4140
  setupKeyHandler: function() {
@@ -3831,16 +4155,23 @@
3831
4155
  }
3832
4156
  });
3833
4157
 
4158
+ Luca.util.startHistory = function() {
4159
+ return Backbone.history.start();
4160
+ };
4161
+
3834
4162
  }).call(this);
3835
4163
  (function() {
4164
+ var toolbar;
4165
+
4166
+ _.def('Luca.components.Toolbar')["extends"]('Luca.core.Container')["with"];
4167
+
4168
+ toolbar = Luca.register("Luca.components.Toolbar");
3836
4169
 
3837
- _.def('Luca.components.Toolbar')["extends"]('Luca.core.Container')["with"]({
4170
+ toolbar["extends"]("Luca.core.Container");
4171
+
4172
+ toolbar.defines({
3838
4173
  className: 'luca-ui-toolbar toolbar',
3839
4174
  position: 'bottom',
3840
- initialize: function(options) {
3841
- this.options = options != null ? options : {};
3842
- return Luca.core.Container.prototype.initialize.apply(this, arguments);
3843
- },
3844
4175
  prepareComponents: function() {
3845
4176
  var _this = this;
3846
4177
  return _(this.components).each(function(component) {
@@ -3848,14 +4179,20 @@
3848
4179
  });
3849
4180
  },
3850
4181
  render: function() {
3851
- return $(this.container).append(this.el);
4182
+ $(this.container).append(this.el);
4183
+ return this;
3852
4184
  }
3853
4185
  });
3854
4186
 
3855
4187
  }).call(this);
3856
4188
  (function() {
4189
+ var loaderView;
4190
+
4191
+ loaderView = Luca.register("Luca.components.CollectionLoaderView");
4192
+
4193
+ loaderView["extends"]("Luca.View");
3857
4194
 
3858
- _.def('Luca.components.CollectionLoaderView')["extends"]('Luca.components.Template')["with"]({
4195
+ loaderView.defines({
3859
4196
  className: 'luca-ui-collection-loader-view',
3860
4197
  template: "components/collection_loader_view",
3861
4198
  initialize: function(options) {
@@ -3892,15 +4229,15 @@
3892
4229
  (function() {
3893
4230
  var collectionView, make;
3894
4231
 
3895
- collectionView = Luca.define("Luca.components.CollectionView");
4232
+ collectionView = Luca.register("Luca.components.CollectionView");
3896
4233
 
3897
4234
  collectionView["extends"]("Luca.components.Panel");
3898
4235
 
3899
- collectionView.behavesAs("LoadMaskable", "Filterable", "Paginatable");
4236
+ collectionView.mixesIn("LoadMaskable", "Filterable", "Paginatable");
3900
4237
 
3901
4238
  collectionView.triggers("before:refresh", "after:refresh", "refresh", "empty:results");
3902
4239
 
3903
- collectionView.defaults({
4240
+ collectionView.defines({
3904
4241
  tagName: "ol",
3905
4242
  className: "luca-ui-collection-view",
3906
4243
  bodyClassName: "collection-ui-panel",
@@ -3920,11 +4257,15 @@
3920
4257
  if (!((this.itemTemplate != null) || (this.itemRenderer != null) || (this.itemProperty != null))) {
3921
4258
  throw "Collection Views must specify an item template or item renderer function";
3922
4259
  }
3923
- Luca.components.Panel.prototype.initialize.apply(this, arguments);
3924
- if (_.isString(this.collection) && Luca.CollectionManager.get()) {
3925
- this.collection = Luca.CollectionManager.get().getOrCreate(this.collection);
4260
+ if (_.isString(this.collection)) {
4261
+ if (Luca.CollectionManager.get()) {
4262
+ this.collection = Luca.CollectionManager.get().getOrCreate(this.collection);
4263
+ } else {
4264
+ console.log("String Collection but no collection manager");
4265
+ }
3926
4266
  }
3927
4267
  if (!Luca.isBackboneCollection(this.collection)) {
4268
+ console.log("Missing Collection on " + (this.name || this.cid), this, this.collection);
3928
4269
  throw "Collection Views must have a valid backbone collection";
3929
4270
  this.collection.on("before:fetch", function() {
3930
4271
  return _this.trigger("enable:loadmask");
@@ -3943,12 +4284,13 @@
3943
4284
  this.collection.on("change", this.refreshModel, this);
3944
4285
  }
3945
4286
  }
4287
+ Luca.components.Panel.prototype.initialize.apply(this, arguments);
3946
4288
  if (this.autoRefreshOnModelsPresent !== false) {
3947
4289
  this.defer(function() {
3948
4290
  if (_this.collection.length > 0) return _this.refresh();
3949
4291
  }).until("after:render");
3950
4292
  }
3951
- return this.on("collection:change", this.refresh, this);
4293
+ return this.on("refresh", this.refresh, this);
3952
4294
  },
3953
4295
  attributesForItem: function(item, model) {
3954
4296
  return _.extend({}, {
@@ -3988,11 +4330,39 @@
3988
4330
  getCollection: function() {
3989
4331
  return this.collection;
3990
4332
  },
4333
+ loadModels: function(models, options) {
4334
+ var _ref;
4335
+ if (models == null) models = [];
4336
+ if (options == null) options = {};
4337
+ return (_ref = this.getCollection()) != null ? _ref.reset(models, options) : void 0;
4338
+ },
4339
+ applyQuery: function(query, queryOptions) {
4340
+ if (query == null) query = {};
4341
+ if (queryOptions == null) queryOptions = {};
4342
+ this.query = query;
4343
+ this.queryOptions = queryOptions;
4344
+ this.refresh();
4345
+ return this;
4346
+ },
3991
4347
  getQuery: function() {
3992
- return this.query || (this.query = {});
4348
+ var query, querySource, _i, _len, _ref;
4349
+ query = this.query || (this.query = {});
4350
+ _ref = _(this.querySources || []).compact();
4351
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4352
+ querySource = _ref[_i];
4353
+ query = _.extend(query, querySource() || {});
4354
+ }
4355
+ return query;
3993
4356
  },
3994
4357
  getQueryOptions: function() {
3995
- return this.queryOptions || (this.queryOptions = {});
4358
+ var optionSource, options, _i, _len, _ref;
4359
+ options = this.queryOptions || (this.queryOptions = {});
4360
+ _ref = _(this.optionsSources || []).compact();
4361
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4362
+ optionSource = _ref[_i];
4363
+ options = _.extend(options, optionSource() || {});
4364
+ }
4365
+ return options;
3996
4366
  },
3997
4367
  getModels: function(query, options) {
3998
4368
  var _ref;
@@ -4016,12 +4386,12 @@
4016
4386
  }, model));
4017
4387
  return this.trigger("model:refreshed", index, model);
4018
4388
  },
4019
- refresh: function(query, options) {
4020
- var index, model, models, _i, _len;
4389
+ refresh: function(query, options, models) {
4390
+ var index, model, _i, _len;
4021
4391
  query || (query = this.getQuery());
4022
4392
  options || (options = this.getQueryOptions());
4393
+ models || (models = this.getModels(query, options));
4023
4394
  this.$bodyEl().empty();
4024
- models = this.getModels(query, options);
4025
4395
  this.trigger("before:refresh", models, query, options);
4026
4396
  if (models.length === 0) this.trigger("empty:results");
4027
4397
  index = 0;
@@ -4052,8 +4422,13 @@
4052
4422
 
4053
4423
  }).call(this);
4054
4424
  (function() {
4425
+ var controller;
4426
+
4427
+ controller = Luca.register("Luca.components.Controller");
4428
+
4429
+ controller["extends"]("Luca.containers.CardView");
4055
4430
 
4056
- _.def('Luca.components.Controller')["extends"]('Luca.containers.CardView')["with"]({
4431
+ controller.defines({
4057
4432
  additionalClassNames: ['luca-ui-controller'],
4058
4433
  activeAttribute: "active-section",
4059
4434
  initialize: function(options) {
@@ -4113,15 +4488,31 @@
4113
4488
 
4114
4489
  }).call(this);
4115
4490
  (function() {
4491
+ var buttonField;
4116
4492
 
4117
- _.def('Luca.fields.ButtonField')["extends"]('Luca.core.Field')["with"]({
4493
+ buttonField = Luca.register("Luca.fields.ButtonField");
4494
+
4495
+ buttonField["extends"]("Luca.core.Field");
4496
+
4497
+ buttonField.triggers("button:click");
4498
+
4499
+ buttonField.publicConfiguration({
4118
4500
  readOnly: true,
4501
+ input_value: void 0,
4502
+ input_type: "button",
4503
+ icon_class: void 0,
4504
+ input_name: void 0,
4505
+ white: void 0
4506
+ });
4507
+
4508
+ buttonField.privateConfiguration({
4509
+ template: "fields/button_field",
4119
4510
  events: {
4120
4511
  "click input": "click_handler"
4121
- },
4122
- hooks: ["button:click"],
4123
- className: 'luca-ui-field luca-ui-button-field',
4124
- template: 'fields/button_field',
4512
+ }
4513
+ });
4514
+
4515
+ buttonField.privateInterface({
4125
4516
  click_handler: function(e) {
4126
4517
  var me, my;
4127
4518
  me = my = $(e.currentTarget);
@@ -4141,7 +4532,6 @@
4141
4532
  this.input_id || (this.input_id = _.uniqueId('button'));
4142
4533
  this.input_name || (this.input_name = this.name || (this.name = this.input_id));
4143
4534
  this.input_value || (this.input_value = this.label || (this.label = this.text));
4144
- this.input_type || (this.input_type = "button");
4145
4535
  this.input_class || (this.input_class = this["class"]);
4146
4536
  this.icon_class || (this.icon_class = "");
4147
4537
  if (this.icon_class.length && !this.icon_class.match(/^icon-/)) {
@@ -4154,13 +4544,21 @@
4154
4544
  }
4155
4545
  });
4156
4546
 
4547
+ buttonField.defines({
4548
+ version: 1
4549
+ });
4550
+
4157
4551
  }).call(this);
4158
4552
  (function() {
4159
- var make;
4553
+ var checkboxArray, make;
4160
4554
 
4161
4555
  make = Luca.View.prototype.make;
4162
4556
 
4163
- _.def('Luca.fields.CheckboxArray')["extends"]('Luca.core.Field')["with"]({
4557
+ checkboxArray = Luca.register("Luca.fields.CheckboxArray");
4558
+
4559
+ checkboxArray["extends"]("Luca.core.Field");
4560
+
4561
+ checkboxArray.defines({
4164
4562
  version: 2,
4165
4563
  template: "fields/checkbox_array",
4166
4564
  className: "luca-ui-checkbox-array",
@@ -4171,7 +4569,7 @@
4171
4569
  initialize: function(options) {
4172
4570
  this.options = options != null ? options : {};
4173
4571
  _.extend(this, this.options);
4174
- _.extend(this, Luca.modules.Deferrable);
4572
+ _.extend(this, Luca.concerns.Deferrable);
4175
4573
  _.bindAll(this, "renderCheckboxes", "clickHandler", "checkSelected");
4176
4574
  Luca.core.Field.prototype.initialize.apply(this, arguments);
4177
4575
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4189,6 +4587,9 @@
4189
4587
  console.log("Error Configuring Collection", this, e.message);
4190
4588
  }
4191
4589
  cbArray = this;
4590
+ if (!Luca.isBackboneCollection(this.collection)) {
4591
+ throw "Checkbox Array Fields must specify a @collection property";
4592
+ }
4192
4593
  if (this.collection.length > 0) {
4193
4594
  return this.renderCheckboxes();
4194
4595
  } else {
@@ -4284,15 +4685,27 @@
4284
4685
 
4285
4686
  }).call(this);
4286
4687
  (function() {
4688
+ var checkboxField;
4689
+
4690
+ checkboxField = Luca.register("Luca.fields.CheckboxField");
4691
+
4692
+ checkboxField["extends"]("Luca.core.Field");
4693
+
4694
+ checkboxField.triggers("checked", "unchecked");
4695
+
4696
+ checkboxField.publicConfiguration({
4697
+ send_blanks: true,
4698
+ input_value: 1
4699
+ });
4287
4700
 
4288
- _.def('Luca.fields.CheckboxField')["extends"]('Luca.core.Field')["with"]({
4701
+ checkboxField.privateConfiguration({
4702
+ template: 'fields/checkbox_field',
4289
4703
  events: {
4290
4704
  "change input": "change_handler"
4291
- },
4292
- className: 'luca-ui-checkbox-field luca-ui-field',
4293
- template: 'fields/checkbox_field',
4294
- hooks: ["checked", "unchecked"],
4295
- send_blanks: true,
4705
+ }
4706
+ });
4707
+
4708
+ checkboxField.privateInterface({
4296
4709
  change_handler: function(e) {
4297
4710
  var me, my;
4298
4711
  me = my = $(e.target);
@@ -4307,14 +4720,14 @@
4307
4720
  this.options = options != null ? options : {};
4308
4721
  _.extend(this, this.options);
4309
4722
  _.bindAll(this, "change_handler");
4310
- return Luca.core.Field.prototype.initialize.apply(this, arguments);
4311
- },
4312
- afterInitialize: function() {
4723
+ Luca.core.Field.prototype.initialize.apply(this, arguments);
4313
4724
  this.input_id || (this.input_id = _.uniqueId('field'));
4314
4725
  this.input_name || (this.input_name = this.name);
4315
- this.input_value || (this.input_value = 1);
4316
4726
  return this.label || (this.label = this.name);
4317
- },
4727
+ }
4728
+ });
4729
+
4730
+ checkboxField.publicInterface({
4318
4731
  setValue: function(checked) {
4319
4732
  return this.getInputElement().attr('checked', checked);
4320
4733
  },
@@ -4323,10 +4736,20 @@
4323
4736
  }
4324
4737
  });
4325
4738
 
4739
+ checkboxField.defines({
4740
+ version: 1
4741
+ });
4742
+
4326
4743
  }).call(this);
4327
4744
  (function() {
4745
+ var fileUpload;
4746
+
4747
+ fileUpload = Luca.register("Luca.fields.FileUploadField");
4328
4748
 
4329
- _.def('Luca.fields.FileUploadField')["extends"]('Luca.core.Field')["with"]({
4749
+ fileUpload["extends"]("Luca.core.Field");
4750
+
4751
+ fileUpload.defines({
4752
+ version: 1,
4330
4753
  template: 'fields/file_upload_field',
4331
4754
  afterInitialize: function() {
4332
4755
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4338,8 +4761,13 @@
4338
4761
 
4339
4762
  }).call(this);
4340
4763
  (function() {
4764
+ var hiddenField;
4765
+
4766
+ hiddenField = Luca.register("Luca.fields.HiddenField");
4767
+
4768
+ hiddenField["extends"]("Luca.core.Field");
4341
4769
 
4342
- _.def('Luca.fields.HiddenField')["extends"]('Luca.core.Field')["with"]({
4770
+ hiddenField.defines({
4343
4771
  template: 'fields/hidden_field',
4344
4772
  afterInitialize: function() {
4345
4773
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4351,9 +4779,13 @@
4351
4779
 
4352
4780
  }).call(this);
4353
4781
  (function() {
4782
+ var labelField;
4354
4783
 
4355
- _.def("Luca.components.LabelField")["extends"]("Luca.core.Field")["with"]({
4356
- className: "luca-ui-field luca-ui-label-field",
4784
+ labelField = Luca.register("Luca.components.LabelField");
4785
+
4786
+ labelField["extends"]("Luca.core.Field");
4787
+
4788
+ labelField.defines({
4357
4789
  formatter: function(value) {
4358
4790
  value || (value = this.getValue());
4359
4791
  return _.str.titleize(value);
@@ -4367,13 +4799,18 @@
4367
4799
 
4368
4800
  }).call(this);
4369
4801
  (function() {
4802
+ var selectField;
4803
+
4804
+ selectField = Luca.register("Luca.fields.SelectField");
4805
+
4806
+ selectField["extends"]("Luca.core.Field");
4370
4807
 
4371
- _.def('Luca.fields.SelectField')["extends"]('Luca.core.Field')["with"]({
4808
+ selectField.triggers("after:select");
4809
+
4810
+ selectField.defines({
4372
4811
  events: {
4373
4812
  "change select": "change_handler"
4374
4813
  },
4375
- hooks: ["after:select"],
4376
- className: 'luca-ui-select-field luca-ui-field',
4377
4814
  template: "fields/select_field",
4378
4815
  includeBlank: true,
4379
4816
  blankValue: '',
@@ -4381,7 +4818,7 @@
4381
4818
  initialize: function(options) {
4382
4819
  this.options = options != null ? options : {};
4383
4820
  _.extend(this, this.options);
4384
- _.extend(this, Luca.modules.Deferrable);
4821
+ _.extend(this, Luca.concerns.Deferrable);
4385
4822
  _.bindAll(this, "change_handler", "populateOptions", "beforeFetch");
4386
4823
  Luca.core.Field.prototype.initialize.apply(this, arguments);
4387
4824
  this.input_id || (this.input_id = _.uniqueId('field'));
@@ -4509,8 +4946,13 @@
4509
4946
 
4510
4947
  }).call(this);
4511
4948
  (function() {
4949
+ var textField;
4950
+
4951
+ textField = Luca.register('Luca.fields.TextField');
4512
4952
 
4513
- _.def('Luca.fields.TextField')["extends"]('Luca.core.Field')["with"]({
4953
+ textField["extends"]('Luca.core.Field');
4954
+
4955
+ textField.defines({
4514
4956
  events: {
4515
4957
  "blur input": "blur_handler",
4516
4958
  "focus input": "focus_handler",
@@ -4554,9 +4996,13 @@
4554
4996
 
4555
4997
  }).call(this);
4556
4998
  (function() {
4999
+ var typeAheadField;
5000
+
5001
+ typeAheadField = Luca.register("Luca.fields.TypeAheadField");
4557
5002
 
4558
- _.def('Luca.fields.TypeAheadField')["extends"]('Luca.fields.TextField')["with"]({
4559
- className: 'luca-ui-field',
5003
+ typeAheadField["extends"]("Luca.fields.TextField");
5004
+
5005
+ typeAheadField.defines({
4560
5006
  getSource: function() {
4561
5007
  return Luca.util.read(this.source) || [];
4562
5008
  },
@@ -4578,13 +5024,19 @@
4578
5024
 
4579
5025
  }).call(this);
4580
5026
  (function() {
5027
+ var toolbar;
5028
+
5029
+ toolbar = Luca.register("Luca.components.FormButtonToolbar");
4581
5030
 
4582
- _.def('Luca.components.FormButtonToolbar')["extends"]('Luca.components.Toolbar')["with"]({
5031
+ toolbar["extends"]("Luca.components.Toolbar");
5032
+
5033
+ toolbar.defines({
4583
5034
  className: 'luca-ui-form-toolbar form-actions',
4584
5035
  position: 'bottom',
4585
5036
  includeReset: false,
4586
5037
  render: function() {
4587
- return $(this.container).append(this.el);
5038
+ $(this.container).append(this.el);
5039
+ return this;
4588
5040
  },
4589
5041
  initialize: function(options) {
4590
5042
  this.options = options != null ? options : {};
@@ -4608,32 +5060,17 @@
4608
5060
 
4609
5061
  }).call(this);
4610
5062
  (function() {
4611
- var defaultToolbar;
5063
+ var formView;
4612
5064
 
4613
- defaultToolbar = {
4614
- buttons: [
4615
- {
4616
- icon: "remove-sign",
4617
- label: "Reset",
4618
- eventId: "click:reset",
4619
- className: "reset-button",
4620
- align: 'right'
4621
- }, {
4622
- icon: "ok-sign",
4623
- white: true,
4624
- label: "Save Changes",
4625
- eventId: "click:submit",
4626
- color: "success",
4627
- className: 'submit-button',
4628
- align: 'right'
4629
- }
4630
- ]
4631
- };
5065
+ formView = Luca.register("Luca.components.FormView");
5066
+
5067
+ formView["extends"]("Luca.core.Container");
5068
+
5069
+ 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");
4632
5070
 
4633
- _.def("Luca.components.FormView")["extends"]('Luca.core.Container')["with"]({
5071
+ formView.defines({
4634
5072
  tagName: 'form',
4635
5073
  className: 'luca-ui-form-view',
4636
- 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"],
4637
5074
  events: {
4638
5075
  "click .submit-button": "submitHandler",
4639
5076
  "click .reset-button": "resetHandler"
@@ -4641,13 +5078,13 @@
4641
5078
  toolbar: true,
4642
5079
  legend: "",
4643
5080
  bodyClassName: "form-view-body",
4644
- version: "0.9.33333333",
5081
+ version: 1,
4645
5082
  initialize: function(options) {
4646
5083
  this.options = options != null ? options : {};
4647
5084
  if (this.loadMask == null) this.loadMask = Luca.enableBootstrap;
4648
5085
  Luca.core.Container.prototype.initialize.apply(this, arguments);
4649
5086
  this.components || (this.components = this.fields);
4650
- _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars", "applyLoadMask");
5087
+ _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars");
4651
5088
  this.state || (this.state = new Backbone.Model);
4652
5089
  this.setupHooks(this.hooks);
4653
5090
  this.applyStyleClasses();
@@ -4661,7 +5098,7 @@
4661
5098
  }
4662
5099
  },
4663
5100
  getDefaultToolbar: function() {
4664
- return defaultToolbar;
5101
+ return Luca.components.FormView.defaultFormViewToolbar;
4665
5102
  },
4666
5103
  applyStyleClasses: function() {
4667
5104
  if (Luca.enableBootstrap) this.applyBootstrapStyleClasses();
@@ -4875,6 +5312,26 @@
4875
5312
  }
4876
5313
  });
4877
5314
 
5315
+ Luca.components.FormView.defaultFormViewToolbar = {
5316
+ buttons: [
5317
+ {
5318
+ icon: "remove-sign",
5319
+ label: "Reset",
5320
+ eventId: "click:reset",
5321
+ className: "reset-button",
5322
+ align: 'right'
5323
+ }, {
5324
+ icon: "ok-sign",
5325
+ white: true,
5326
+ label: "Save Changes",
5327
+ eventId: "click:submit",
5328
+ color: "success",
5329
+ className: 'submit-button',
5330
+ align: 'right'
5331
+ }
5332
+ ]
5333
+ };
5334
+
4878
5335
  }).call(this);
4879
5336
  (function() {
4880
5337
 
@@ -4901,7 +5358,7 @@
4901
5358
  var _this = this;
4902
5359
  this.options = options != null ? options : {};
4903
5360
  _.extend(this, this.options);
4904
- _.extend(this, Luca.modules.Deferrable);
5361
+ _.extend(this, Luca.concerns.Deferrable);
4905
5362
  if (this.loadMask == null) this.loadMask = Luca.enableBootstrap;
4906
5363
  if (this.loadMask === true) {
4907
5364
  this.loadMaskEl || (this.loadMaskEl = ".luca-ui-g-view-body");
@@ -5127,13 +5584,13 @@
5127
5584
 
5128
5585
  }).call(this);
5129
5586
  (function() {
5130
- var bubbleCollectionEvents, multiView, propagateCollectionComponents, validateComponent;
5587
+ var multiView, propagateCollectionComponents, validateComponent;
5131
5588
 
5132
- multiView = Luca.define("Luca.components.MultiCollectionView");
5589
+ multiView = Luca.register("Luca.components.MultiCollectionView");
5133
5590
 
5134
5591
  multiView["extends"]("Luca.containers.CardView");
5135
5592
 
5136
- multiView.behavesAs("LoadMaskable", "Filterable", "Paginatable");
5593
+ multiView.mixesIn("LoadMaskable", "Filterable", "Paginatable");
5137
5594
 
5138
5595
  multiView.triggers("before:refresh", "after:refresh", "refresh", "empty:results");
5139
5596
 
@@ -5153,51 +5610,73 @@
5153
5610
  view = _ref[_i];
5154
5611
  validateComponent(view);
5155
5612
  }
5156
- this.on("collection:change", this.refresh, this);
5613
+ this.on("refresh", this.refresh, this);
5157
5614
  this.on("after:card:switch", this.refresh, this);
5158
- this.on("before:components", propagateCollectionComponents, this);
5159
- this.on("after:components", bubbleCollectionEvents, this);
5615
+ this.on("after:components", propagateCollectionComponents, this);
5616
+ this.debug("multi collection , proto initialize");
5160
5617
  return Luca.containers.CardView.prototype.initialize.apply(this, arguments);
5161
5618
  },
5619
+ relayAfterRefresh: function(models, query, options) {
5620
+ return this.trigger("after:refresh", models, query, options);
5621
+ },
5162
5622
  refresh: function() {
5163
5623
  var _ref;
5164
5624
  return (_ref = this.activeComponent()) != null ? _ref.trigger("refresh") : void 0;
5165
5625
  },
5166
- getQuery: Luca.components.CollectionView.prototype.getQuery,
5167
- getQueryOptions: Luca.components.CollectionView.prototype.getQueryOptions,
5168
- getCollection: Luca.components.CollectionView.prototype.getCollection
5169
- });
5170
-
5171
- bubbleCollectionEvents = function() {
5172
- var container;
5173
- container = this;
5174
- return container.eachComponent(function(component) {
5175
- var eventId, _i, _len, _ref, _results;
5176
- _ref = ['refresh', 'before:refresh', 'after:refresh', 'empty:results'];
5177
- _results = [];
5626
+ getCollection: function() {
5627
+ return this.collection;
5628
+ },
5629
+ applyQuery: function(query, queryOptions) {
5630
+ if (query == null) query = {};
5631
+ if (queryOptions == null) queryOptions = {};
5632
+ this.query = query;
5633
+ this.queryOptions = queryOptions;
5634
+ return this;
5635
+ },
5636
+ getQuery: function() {
5637
+ var query, querySource, _i, _len, _ref;
5638
+ this.debug("Get Query");
5639
+ query = this.query || (this.query = {});
5640
+ _ref = this.querySources;
5178
5641
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5179
- eventId = _ref[_i];
5180
- _results.push(component.on(eventId, function() {
5181
- if (component === container.activeComponent()) {
5182
- return container.trigger(eventId);
5183
- }
5184
- }));
5642
+ querySource = _ref[_i];
5643
+ query = _.extend(query, querySource() || {});
5185
5644
  }
5186
- return _results;
5187
- });
5188
- };
5645
+ return query;
5646
+ },
5647
+ getQueryOptions: function() {
5648
+ var optionSource, options, _i, _len, _ref;
5649
+ this.debug("Get Query Options");
5650
+ options = this.queryOptions || (this.queryOptions = {});
5651
+ _ref = this.optionsSources;
5652
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5653
+ optionSource = _ref[_i];
5654
+ options = _.extend(options, optionSource() || {});
5655
+ }
5656
+ return options;
5657
+ }
5658
+ });
5189
5659
 
5190
5660
  propagateCollectionComponents = function() {
5191
- var component, container, _i, _len, _ref, _results;
5661
+ var component, container, _i, _len, _ref, _results,
5662
+ _this = this;
5192
5663
  container = this;
5193
5664
  _ref = this.components;
5194
5665
  _results = [];
5195
5666
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
5196
5667
  component = _ref[_i];
5668
+ component.on("after:refresh", function(models, query, options) {
5669
+ _this.debug("collection member after refresh");
5670
+ return _this.trigger("after:refresh", models, query, options);
5671
+ });
5197
5672
  _results.push(_.extend(component, {
5198
- collection: (typeof container.getCollection === "function" ? container.getCollection() : void 0) || this.collection,
5199
- getQuery: container.getQuery,
5200
- getQueryOptions: container.getQueryOptions
5673
+ collection: container.getCollection(),
5674
+ getQuery: function() {
5675
+ return container.getQuery.call(container);
5676
+ },
5677
+ getQueryOptions: function() {
5678
+ return container.getQueryOptions.call(container);
5679
+ }
5201
5680
  }));
5202
5681
  }
5203
5682
  return _results;
@@ -5264,8 +5743,12 @@
5264
5743
  "click a.prev": "previousPage"
5265
5744
  },
5266
5745
  afterInitialize: function() {
5267
- _.bindAll(this, "refresh");
5268
- return this.state.on("change", this.refresh, this);
5746
+ var _ref,
5747
+ _this = this;
5748
+ _.bindAll(this, "updateWithPageCount");
5749
+ return (_ref = this.state) != null ? _ref.on("change", function(state, numberOfPages) {
5750
+ return _this.updateWithPageCount(state.get('numberOfPages'));
5751
+ }) : void 0;
5269
5752
  },
5270
5753
  limit: function() {
5271
5754
  var _ref;
@@ -5318,16 +5801,22 @@
5318
5801
  pageButtons: function() {
5319
5802
  return this.$('a[data-page-number]', this.pageButtonContainer());
5320
5803
  },
5321
- refresh: function() {
5322
- var button, page, _ref;
5804
+ updateWithPageCount: function(pageCount, models) {
5805
+ var modelCount,
5806
+ _this = this;
5807
+ this.pageCount = pageCount;
5808
+ if (models == null) models = [];
5809
+ modelCount = models.length;
5323
5810
  this.pageButtonContainer().empty();
5324
- for (page = 1, _ref = this.totalPages(); 1 <= _ref ? page <= _ref : page >= _ref; 1 <= _ref ? page++ : page--) {
5325
- button = this.make("a", {
5811
+ _(this.pageCount).times(function(index) {
5812
+ var button, page;
5813
+ page = index + 1;
5814
+ button = _this.make("a", {
5326
5815
  "data-page-number": page,
5327
5816
  "class": "page"
5328
5817
  }, page);
5329
- this.pageButtonContainer().append(button);
5330
- }
5818
+ return _this.pageButtonContainer().append(button);
5819
+ });
5331
5820
  this.toggleNavigationButtons();
5332
5821
  this.selectActivePageButton();
5333
5822
  return this;
@@ -5346,7 +5835,7 @@
5346
5835
  return this.pageButtons().filter("[data-page-number='" + (this.page()) + "']");
5347
5836
  },
5348
5837
  totalPages: function() {
5349
- return parseInt(Math.ceil(this.totalItems() / this.itemsPerPage()));
5838
+ return this.pageCount;
5350
5839
  },
5351
5840
  totalItems: function() {
5352
5841
  var _ref;