luca 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. data/CHANGELOG +37 -14
  2. data/lib/luca/rails/version.rb +1 -1
  3. data/spec/components/collection_view_spec.coffee +24 -2
  4. data/spec/components/pagination_control_spec.coffee +0 -0
  5. data/spec/concerns/dom_helpers_spec.coffee +16 -0
  6. data/spec/concerns/filterable_spec.coffee +25 -0
  7. data/spec/concerns/model_presenter_spec.coffee +31 -0
  8. data/spec/concerns/paginatable_spec.coffee +0 -0
  9. data/spec/concerns/state_model_spec.coffee +0 -0
  10. data/spec/concerns_spec.coffee +88 -0
  11. data/spec/core/container_spec.coffee +74 -12
  12. data/spec/core/model_spec.coffee +6 -1
  13. data/spec/define_spec.coffee +0 -6
  14. data/spec/util_spec.coffee +24 -0
  15. data/src/components/application.coffee +32 -30
  16. data/src/components/base_toolbar.coffee +6 -4
  17. data/src/components/collection_loader_view.coffee +3 -1
  18. data/src/components/collection_view.coffee +42 -21
  19. data/src/components/controller.coffee +3 -1
  20. data/src/components/fields/button_field.coffee +19 -12
  21. data/src/components/fields/checkbox_array.coffee +8 -2
  22. data/src/components/fields/checkbox_field.coffee +18 -9
  23. data/src/components/fields/file_upload_field.coffee +5 -1
  24. data/src/components/fields/hidden_field.coffee +3 -1
  25. data/src/components/fields/label_field.coffee +4 -3
  26. data/src/components/fields/select_field.coffee +7 -8
  27. data/src/components/fields/text_field.coffee +3 -1
  28. data/src/components/fields/type_ahead_field.coffee +4 -2
  29. data/src/components/form_button_toolbar.coffee +4 -1
  30. data/src/components/form_view.coffee +49 -44
  31. data/src/components/grid_view.coffee +1 -1
  32. data/src/components/multi_collection_view.coffee +49 -22
  33. data/src/components/pagination_control.coffee +17 -13
  34. data/src/{modules → concerns}/application_event_bindings.coffee +1 -1
  35. data/src/{modules → concerns}/collection_event_bindings.coffee +1 -1
  36. data/src/{modules → concerns}/deferrable.coffee +1 -1
  37. data/src/{modules → concerns}/dom_helpers.coffee +11 -2
  38. data/src/{modules → concerns}/enhanced_properties.coffee +1 -1
  39. data/src/concerns/filterable.coffee +82 -0
  40. data/src/{modules → concerns}/grid_layout.coffee +1 -1
  41. data/src/{modules → concerns}/loadmaskable.coffee +1 -1
  42. data/src/{modules → concerns}/local_storage.coffee +0 -0
  43. data/src/{modules → concerns}/modal_view.coffee +1 -1
  44. data/src/concerns/model_presenter.coffee +23 -0
  45. data/src/concerns/paginatable.coffee +87 -0
  46. data/src/{modules → concerns}/state_model.coffee +1 -1
  47. data/src/{modules → concerns}/templating.coffee +1 -1
  48. data/src/concerns.coffee +70 -0
  49. data/src/containers/tab_view.coffee +7 -10
  50. data/src/core/collection.coffee +17 -1
  51. data/src/core/container.coffee +56 -31
  52. data/src/core/field.coffee +39 -38
  53. data/src/core/meta_data.coffee +37 -0
  54. data/src/core/model.coffee +18 -1
  55. data/src/core/view.coffee +25 -29
  56. data/src/define.coffee +54 -66
  57. data/src/framework.coffee +23 -18
  58. data/src/index.coffee +3 -1
  59. data/src/stylesheets/components/checkbox_array.scss +1 -1
  60. data/src/stylesheets/components/form_view.scss +5 -5
  61. data/src/stylesheets/components/viewport.scss +2 -1
  62. data/src/stylesheets/containers/container.scss +0 -5
  63. data/src/stylesheets/containers/tab_view.scss +5 -5
  64. data/src/tools/console.coffee +5 -5
  65. data/src/util.coffee +47 -0
  66. data/vendor/assets/javascripts/luca-ui-development-tools.js +5 -5
  67. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
  68. data/vendor/assets/javascripts/luca-ui-full.js +905 -416
  69. data/vendor/assets/javascripts/luca-ui-full.min.js +5 -5
  70. data/vendor/assets/javascripts/luca-ui.js +905 -416
  71. data/vendor/assets/javascripts/luca-ui.min.js +5 -4
  72. data/vendor/assets/stylesheets/luca-ui.css +15 -15
  73. metadata +27 -17
  74. data/spec/mixin_spec.coffee +0 -49
  75. data/src/modules/filterable.coffee +0 -60
  76. data/src/modules/paginatable.coffee +0 -79
@@ -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;