vendor/assets/javascripts/luca-ui-full.js in luca-0.9.6 vs vendor/assets/javascripts/luca-ui-full.js in luca-0.9.7

- old
+ new

@@ -93,24 +93,32 @@ } if (_.isFunction(fallback = _(args).last())) return fallback(); }; _.extend(Luca, { - VERSION: "0.9.6", + VERSION: "0.9.7", core: {}, + collections: {}, containers: {}, components: {}, - modules: {}, + models: {}, + concerns: {}, util: {}, fields: {}, registry: {}, options: {}, config: {} }); _.extend(Luca, Backbone.Events); + Luca.config.maintainStyleHierarchy = true; + + Luca.config.maintainClassHierarchy = true; + + Luca.config.autoApplyClassHierarchyAsCssClasses = true; + Luca.autoRegister = Luca.config.autoRegister = true; Luca.developmentMode = Luca.config.developmentMode = false; Luca.enableGlobalObserver = Luca.config.enableGlobalObserver = false; @@ -180,40 +188,33 @@ if (_.isString(obj)) obj = Luca.util.resolve(obj); return (obj != null) && (obj.prototype != null) && !Luca.isModelPrototype(obj) && (obj.prototype.reset != null) && (obj.prototype.select != null) && (obj.prototype.reject != null); }; Luca.inheritanceChain = function(obj) { - return _(Luca.parentClasses(obj)).map(function(className) { - return Luca.util.resolve(className); - }); + return Luca.parentClasses(obj); }; Luca.parentClasses = function(obj) { - var classes, list, _ref; + var list, metaData, _base; list = []; if (_.isString(obj)) obj = Luca.util.resolve(obj); - list.push(obj.displayName || ((_ref = obj.prototype) != null ? _ref.displayName : void 0) || Luca.parentClass(obj)); - classes = (function() { - var _results; - _results = []; - while (!!(Luca.parentClass(obj) != null)) { - _results.push(obj = Luca.parentClass(obj)); - } - return _results; - })(); - list = list.concat(classes); - return _.uniq(list); + metaData = typeof obj.componentMetaData === "function" ? obj.componentMetaData() : void 0; + metaData || (metaData = typeof (_base = obj.prototype).componentMetaData === "function" ? _base.componentMetaData() : void 0); + return list = (metaData != null ? metaData.classHierarchy() : void 0) || [obj.displayName || obj.prototype.displayName]; }; - Luca.parentClass = function(obj) { - var list, _base, _ref; - list = []; + Luca.parentClass = function(obj, resolve) { + var parent, _base, _ref, _ref2, _ref3; + if (resolve == null) resolve = true; if (_.isString(obj)) obj = Luca.util.resolve(obj); - if (Luca.isComponent(obj)) { - return obj.displayName; - } else if (Luca.isComponentPrototype(obj)) { - return typeof (_base = obj.prototype)._superClass === "function" ? (_ref = _base._superClass()) != null ? _ref.displayName : void 0 : void 0; + parent = typeof obj.componentMetaData === "function" ? (_ref = obj.componentMetaData()) != null ? _ref.meta["super class name"] : void 0 : void 0; + parent || (parent = typeof (_base = obj.prototype).componentMetaData === "function" ? (_ref2 = _base.componentMetaData()) != null ? _ref2.meta["super class name"] : void 0 : void 0); + parent || obj.displayName || ((_ref3 = obj.prototype) != null ? _ref3.displayName : void 0); + if (resolve) { + return Luca.util.resolve(parent); + } else { + return parent; } }; Luca.template = function(template_name, variables) { var jst, luca, needle, template, _ref; @@ -449,10 +450,29 @@ return _.string.capitalize(p); }); return fn = prefix + parts.join(''); }; + Luca.util.toCssClass = function() { + var componentName, exclusions, part, parts, transformed; + componentName = arguments[0], exclusions = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + parts = componentName.split('.'); + transformed = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = parts.length; _i < _len; _i++) { + part = parts[_i]; + if (!(_(exclusions).indexOf(part) === -1)) continue; + part = _.str.underscored(part); + part = part.replace(/_/g, '-'); + _results.push(part); + } + return _results; + })(); + return transformed.join('-'); + }; + Luca.util.isIE = function() { try { Object.defineProperty({}, '', {}); return false; } catch (e) { @@ -543,10 +563,52 @@ return Luca.util.make("span", { "class": cssClass }, contents); }; + Luca.util.setupHooks = function(set) { + var _this = this; + set || (set = this.hooks); + return _(set).each(function(eventId) { + var callback, fn; + fn = Luca.util.hook(eventId); + callback = function() { + var _ref; + return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0; + }; + if (eventId != null ? eventId.match(/once:/) : void 0) { + callback = _.once(callback); + } + return _this.on(eventId, callback, _this); + }); + }; + + Luca.util.setupHooksAdvanced = function(set) { + var _this = this; + set || (set = this.hooks); + return _(set).each(function(eventId) { + var callback, entry, fn, hookSetup, _i, _len, _results; + hookSetup = _this[Luca.util.hook(eventId)]; + if (!_.isArray(hookSetup)) hookSetup = [hookSetup]; + _results = []; + for (_i = 0, _len = hookSetup.length; _i < _len; _i++) { + entry = hookSetup[_i]; + fn = _.isString(entry) ? _this[entry] : void 0; + if (_.isFunction(entry)) fn = entry; + callback = function() { + var _ref; + return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0; + }; + if (eventId != null ? eventId.match(/once:/) : void 0) { + callback = _.once(callback); + } + _results.push(_this.on(eventId, callback, _this)); + } + return _results; + }); + }; + }).call(this); (function() { Luca.DevelopmentToolHelpers = { refreshCode: function() { @@ -701,35 +763,133 @@ } }; }).call(this); (function() { + + Luca.concern = function(mixinName) { + var namespace, resolved; + namespace = _(Luca.concern.namespaces).detect(function(space) { + var _ref; + return ((_ref = Luca.util.resolve(space)) != null ? _ref[mixinName] : void 0) != null; + }); + namespace || (namespace = "Luca.concerns"); + resolved = Luca.util.resolve(namespace)[mixinName]; + if (resolved == null) { + console.log("Could not find " + mixinName + " in ", Luca.concern.namespaces); + } + return resolved; + }; + + Luca.concern.namespaces = ["Luca.concerns"]; + + Luca.concern.namespace = function(namespace) { + Luca.concern.namespaces.push(namespace); + return Luca.concern.namespaces = _(Luca.concern.namespaces).uniq(); + }; + + Luca.concern.setup = function() { + var module, _i, _len, _ref, _ref2, _ref3, _ref4, _results; + if (((_ref = this.concerns) != null ? _ref.length : void 0) > 0) { + _ref2 = this.concerns; + _results = []; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + module = _ref2[_i]; + _results.push((_ref3 = Luca.concern(module)) != null ? (_ref4 = _ref3.__initializer) != null ? _ref4.call(this, this, module) : void 0 : void 0); + } + return _results; + } + }; + + Luca.decorate = function(target) { + var componentClass, componentName, componentPrototype; + try { + if (_.isString(target)) { + componentName = target; + componentClass = Luca.util.resolve(componentName); + } + if (_.isFunction(target)) componentClass = target; + componentPrototype = componentClass.prototype; + componentName = componentName || componentClass.displayName; + componentName || (componentName = componentPrototype.displayName); + } catch (e) { + console.log(e.message); + console.log(e.stack); + console.log("Error calling Luca.decorate on ", componentClass, componentPrototype, componentName); + throw e; + } + return { + "with": function(mixinName) { + var fn, method, mixinDefinition, mixinPrivates, sanitized, superclassMixins, _ref; + mixinDefinition = Luca.concern(mixinName); + mixinDefinition.__displayName || (mixinDefinition.__displayName = mixinName); + mixinPrivates = _(mixinDefinition).chain().keys().select(function(key) { + return ("" + key).match(/^__/) || key === "classMethods"; + }); + sanitized = _(mixinDefinition).omit(mixinPrivates.value()); + _.extend(componentPrototype, sanitized); + if (mixinDefinition.classMethods != null) { + _ref = mixinDefinition.classMethods; + for (method in _ref) { + fn = _ref[method]; + componentClass[method] = _.bind(fn, componentClass); + } + } + if (mixinDefinition != null) { + if (typeof mixinDefinition.__included === "function") { + mixinDefinition.__included(componentName, componentClass, mixinDefinition); + } + } + superclassMixins = componentPrototype._superClass().prototype.concerns; + componentPrototype.concerns || (componentPrototype.concerns = []); + componentPrototype.concerns.push(mixinName); + componentPrototype.concerns = componentPrototype.concerns.concat(superclassMixins); + componentPrototype.concerns = _(componentPrototype.concerns).chain().uniq().compact().value(); + return componentPrototype; + } + }; + }; + +}).call(this); +(function() { var DefineProxy, __slice = Array.prototype.slice; _.mixin({ def: Luca.component = Luca.define = Luca.register = function(componentName) { return new DefineProxy(componentName); - } + }, + register: Luca.register }); DefineProxy = (function() { function DefineProxy(componentName) { var parts; this.namespace = Luca.util.namespace(); this.componentId = this.componentName = componentName; this.superClassName = 'Luca.View'; + this.properties || (this.properties = {}); if (componentName.match(/\./)) { this.namespaced = true; parts = componentName.split('.'); this.componentId = parts.pop(); this.namespace = parts.join('.'); Luca.registry.addNamespace(parts.join('.')); } } + DefineProxy.prototype.meta = function(key, value) { + var data, metaKey; + metaKey = this.namespace + '.' + this.componentId; + metaKey = metaKey.replace(/^\./, ''); + data = Luca.registry.addMetaData(metaKey, key, value); + return this.properties.componentMetaData = function() { + return Luca.registry.getMetaDataFor(metaKey); + }; + }; + DefineProxy.prototype["in"] = function(namespace) { this.namespace = namespace; return this; }; @@ -757,10 +917,11 @@ for (_i = 0, _len = hooks.length; _i < _len; _i++) { hook = hooks[_i]; this.properties.hooks.push(hook); } this.properties.hooks = _.uniq(this.properties.hooks); + this.meta("hooks", this.properties.hooks); return this; }; DefineProxy.prototype.includes = function() { var include, includes, _i, _len; @@ -771,65 +932,96 @@ for (_i = 0, _len = includes.length; _i < _len; _i++) { include = includes[_i]; this.properties.include.push(include); } this.properties.include = _.uniq(this.properties.include); + this.meta("includes", this.properties.include); return this; }; DefineProxy.prototype.mixesIn = function() { - var mixin, mixins, _i, _len; - mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + var concern, concerns, _i, _len; + concerns = 1 <= arguments.length ? __slice.call(arguments, 0) : []; _.defaults(this.properties || (this.properties = {}), { - mixins: [] + concerns: [] }); - for (_i = 0, _len = mixins.length; _i < _len; _i++) { - mixin = mixins[_i]; - this.properties.mixins.push(mixin); + for (_i = 0, _len = concerns.length; _i < _len; _i++) { + concern = concerns[_i]; + this.properties.concerns.push(concern); } - this.properties.mixins = _.uniq(this.properties.mixins); + this.properties.concerns = _.uniq(this.properties.concerns); + this.meta("concerns", this.properties.concerns); return this; }; - DefineProxy.prototype.defaultProperties = function(properties) { - var at, componentType, _base; + DefineProxy.prototype.publicConfiguration = function(properties) { if (properties == null) properties = {}; + this.meta("public configuration", _.keys(properties)); + return _.defaults((this.properties || (this.properties = {})), properties); + }; + + DefineProxy.prototype.privateConfiguration = function(properties) { + if (properties == null) properties = {}; + this.meta("private configuration", _.keys(properties)); + return _.defaults((this.properties || (this.properties = {})), properties); + }; + + DefineProxy.prototype.publicInterface = function(properties) { + if (properties == null) properties = {}; + this.meta("public interface", _.keys(properties)); + return _.defaults((this.properties || (this.properties = {})), properties); + }; + + DefineProxy.prototype.privateInterface = function(properties) { + if (properties == null) properties = {}; + this.meta("private interface", _.keys(properties)); + return _.defaults((this.properties || (this.properties = {})), properties); + }; + + DefineProxy.prototype.definePrototype = function(properties) { + var at, componentType, definition, _base; + if (properties == null) properties = {}; _.defaults((this.properties || (this.properties = {})), properties); at = this.namespaced ? Luca.util.resolve(this.namespace, window || global) : window || global; if (this.namespaced && !(at != null)) { eval("(window||global)." + this.namespace + " = {}"); at = Luca.util.resolve(this.namespace, window || global); } - at[this.componentId] = Luca.extend(this.superClassName, this.componentName, this.properties); - if (Luca.autoRegister === true) { - if (Luca.isViewPrototype(at[this.componentId])) componentType = "view"; - if (Luca.isCollectionPrototype(at[this.componentId])) { + this.meta("super class name", this.superClassName); + this.meta("display name", this.componentName); + this.properties.displayName = this.componentName; + this.properties.componentMetaData = function() { + return Luca.registry.getMetaDataFor(this.displayName); + }; + definition = at[this.componentId] = Luca.extend(this.superClassName, this.componentName, this.properties); + if (Luca.config.autoRegister === true) { + if (Luca.isViewPrototype(definition)) componentType = "view"; + if (Luca.isCollectionPrototype(definition)) { (_base = Luca.Collection).namespaces || (_base.namespaces = []); Luca.Collection.namespaces.push(this.namespace); componentType = "collection"; } - if (Luca.isModelPrototype(at[this.componentId])) componentType = "model"; + if (Luca.isModelPrototype(definition)) componentType = "model"; Luca.registerComponent(_.string.underscored(this.componentId), this.componentName, componentType); } - return at[this.componentId]; + return definition; }; return DefineProxy; })(); - DefineProxy.prototype.behavesAs = DefineProxy.prototype.uses = DefineProxy.prototype.mixesIn; + DefineProxy.prototype.concerns = DefineProxy.prototype.behavesAs = DefineProxy.prototype.uses = DefineProxy.prototype.mixesIn; - DefineProxy.prototype.defines = DefineProxy.prototype.defaults = DefineProxy.prototype.exports = DefineProxy.prototype.defaultProperties; + DefineProxy.prototype.defines = DefineProxy.prototype.defaults = DefineProxy.prototype.exports = DefineProxy.prototype.defaultProperties = DefineProxy.prototype.definePrototype; - DefineProxy.prototype.defaultsTo = DefineProxy.prototype.enhance = DefineProxy.prototype["with"] = DefineProxy.prototype.defaultProperties; + DefineProxy.prototype.defaultsTo = DefineProxy.prototype.enhance = DefineProxy.prototype["with"] = DefineProxy.prototype.definePrototype; Luca.extend = function(superClassName, childName, properties) { var definition, include, superClass, _i, _len, _ref; if (properties == null) properties = {}; superClass = Luca.util.resolve(superClassName, window || global); - superClass.__initializers || (superClass.__initializers = []); if (!_.isFunction(superClass != null ? superClass.extend : void 0)) { throw "Error defining " + childName + ". " + superClassName + " is not a valid component to extend from"; } properties.displayName = childName; properties._superClass = function() { @@ -852,63 +1044,14 @@ } } return definition; }; - Luca.mixin = function(mixinName) { - var namespace, resolved; - namespace = _(Luca.mixin.namespaces).detect(function(space) { - var _ref; - return ((_ref = Luca.util.resolve(space)) != null ? _ref[mixinName] : void 0) != null; - }); - namespace || (namespace = "Luca.modules"); - resolved = Luca.util.resolve(namespace)[mixinName]; - if (resolved == null) { - console.log("Could not find " + mixinName + " in ", Luca.mixin.namespaces); - } - return resolved; - }; - - Luca.mixin.namespaces = ["Luca.modules"]; - - Luca.mixin.namespace = function(namespace) { - Luca.mixin.namespaces.push(namespace); - return Luca.mixin.namespaces = _(Luca.mixin.namespaces).uniq(); - }; - - Luca.decorate = function(componentPrototype) { - if (_.isString(componentPrototype)) { - componentPrototype = Luca.util.resolve(componentPrototype).prototype; - } - return { - "with": function(mixin) { - var mixinDefinition, mixinPrivates, sanitized, superclassMixins, _ref; - mixinDefinition = Luca.mixin(mixin); - mixinPrivates = _(mixinDefinition).chain().keys().select(function(key) { - return ("" + key).match(/^__/); - }); - sanitized = _(mixinDefinition).omit(mixinPrivates.value()); - _.extend(componentPrototype, sanitized); - if (mixinDefinition != null) { - if ((_ref = mixinDefinition.__included) != null) { - _ref.call(mixinDefinition, mixin); - } - } - superclassMixins = componentPrototype._superClass().prototype.mixins; - componentPrototype.mixins || (componentPrototype.mixins = []); - componentPrototype.mixins.push(mixin); - componentPrototype.mixins = componentPrototype.mixins.concat(superclassMixins); - componentPrototype.mixins = _(componentPrototype.mixins).chain().uniq().compact().value(); - return componentPrototype; - } - }; - }; - }).call(this); (function() { - Luca.modules.ApplicationEventBindings = { + Luca.concerns.ApplicationEventBindings = { __initializer: function() { var app, eventTrigger, handler, _len, _ref, _ref2, _results; if (_.isEmpty(this.applicationEvents)) return; app = this.app; if (_.isString(app) || _.isUndefined(app)) { @@ -932,11 +1075,11 @@ }; }).call(this); (function() { - Luca.modules.CollectionEventBindings = { + Luca.concerns.CollectionEventBindings = { __initializer: function() { var collection, eventTrigger, handler, key, manager, signature, _ref, _ref2, _results; if (_.isEmpty(this.collectionEvents)) return; manager = this.collectionManager || Luca.CollectionManager.get(); _ref = this.collectionEvents; @@ -960,11 +1103,11 @@ }; }).call(this); (function() { - Luca.modules.Deferrable = { + Luca.concerns.Deferrable = { configure_collection: function(setAsDeferrable) { var collectionManager, _ref, _ref2; if (setAsDeferrable == null) setAsDeferrable = true; if (!this.collection) return; if (_.isString(this.collection) && (collectionManager = (_ref = Luca.CollectionManager) != null ? _ref.get() : void 0)) { @@ -981,38 +1124,51 @@ }; }).call(this); (function() { - Luca.modules.DomHelpers = { + Luca.concerns.DomHelpers = { __initializer: function() { - var additional, additionalClasses, _i, _len, _results; + var additional, additionalClasses, classes, cssClass, _i, _j, _len, _len2, _ref, _results; additionalClasses = _(this.additionalClassNames || []).clone(); if (this.wrapperClass != null) this.$wrap(this.wrapperClass); if (_.isString(additionalClasses)) { additionalClasses = additionalClasses.split(" "); } if (this.gridSpan) additionalClasses.push("span" + this.gridSpan); if (this.gridOffset) additionalClasses.push("offset" + this.gridOffset); if (this.gridRowFluid) additionalClasses.push("row-fluid"); if (this.gridRow) additionalClasses.push("row"); if (additionalClasses == null) return; - _results = []; for (_i = 0, _len = additionalClasses.length; _i < _len; _i++) { additional = additionalClasses[_i]; - _results.push(this.$el.addClass(additional)); + this.$el.addClass(additional); } - return _results; + if (Luca.config.autoApplyClassHierarchyAsCssClasses === true) { + classes = (typeof this.componentMetaData === "function" ? (_ref = this.componentMetaData()) != null ? _ref.styleHierarchy() : void 0 : void 0) || []; + _results = []; + for (_j = 0, _len2 = classes.length; _j < _len2; _j++) { + cssClass = classes[_j]; + if (cssClass !== "luca-view" && cssClass !== "backbone-view") { + _results.push(this.$el.addClass(cssClass)); + } + } + return _results; + } }, $wrap: function(wrapper) { if (_.isString(wrapper) && !wrapper.match(/[<>]/)) { wrapper = this.make("div", { - "class": wrapper + "class": wrapper, + "data-wrapper": true }); } return this.$el.wrap(wrapper); }, + $wrapper: function() { + return this.$el.parent('[data-wrapper="true"]'); + }, $template: function(template, variables) { if (variables == null) variables = {}; return this.$el.html(Luca.template(template, variables)); }, $html: function(content) { @@ -1033,11 +1189,11 @@ }; }).call(this); (function() { - Luca.modules.EnhancedProperties = { + Luca.concerns.EnhancedProperties = { __initializer: function() { if (Luca.config.enhancedViewProperties !== true) return; if (_.isString(this.collection) && Luca.CollectionManager.get()) { this.collection = Luca.CollectionManager.get().getOrCreate(this.collection); } @@ -1052,76 +1208,78 @@ (function() { var FilterModel, __hasProp = Object.prototype.hasOwnProperty, __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; }; - Luca.modules.Filterable = { + Luca.concerns.Filterable = { __included: function(component, module) { return _.extend(Luca.Collection.prototype, { __filters: {} }); }, __initializer: function(component, module) { - var filter, + var filter, _base, _ref, _this = this; - if (this.filterable === false || !Luca.isBackboneCollection(this.collection)) { + if (this.filterable === false) return; + if (!Luca.isBackboneCollection(this.collection)) { + this.collection = typeof (_base = Luca.CollectionManager).get === "function" ? (_ref = _base.get()) != null ? _ref.getOrCreate(this.collection) : void 0 : void 0; + } + if (!Luca.isBackboneCollection(this.collection)) { + this.debug("Skipping Filterable due to no collection being present on " + (this.name || this.cid)); + this.debug("Collection", this.collection); return; } this.getCollection || (this.getCollection = function() { return this.collection; }); filter = this.getFilterState(); - filter.on("change", function(state) { - _this.trigger("collection:change:filter", state, _this.getCollection()); - return _this.trigger("refresh"); - }); - if (this.getQuery != null) { - this.getQuery = _.compose(this.getQuery, function(query) { - var obj; - if (query == null) query = {}; - obj = _.clone(query); - return _.extend(obj, filter.toQuery()); - }); - } else { - this.getQuery = function() { - return filter.toQuery(); - }; + this.querySources || (this.querySources = []); + this.optionsSources || (this.optionsSources = []); + this.query || (this.query = {}); + this.queryOptions || (this.queryOptions = {}); + this.querySources.push((function() { + return filter.toQuery(); + })); + this.optionsSources.push((function() { + return filter.toOptions(); + })); + if (this.debugMode === true) { + console.log("Filterable"); + console.log(this.querySources); + console.log(this.optionsSources); } - if (this.getQueryOptions != null) { - return this.getQueryOptions = _.compose(this.getQueryOptions, function(options) { - var obj; - if (options == null) options = {}; - obj = _.clone(options); - return _.extend(obj, filter.toOptions()); - }); - } else { - return this.getQueryOptions = function() { - return filter.toOptions(); - }; - } + filter.on("change", function() { + var merged; + if (_this.isRemote()) { + merged = _.extend(_this.getQuery(), _this.getQueryOptions()); + return _this.collection.applyFilter(merged, _this.getQueryOptions()); + } else { + return _this.trigger("refresh"); + } + }); + return module; }, + isRemote: function() { + return this.getQueryOptions().remote === true; + }, getFilterState: function() { var _base, _name; return (_base = this.collection.__filters)[_name = this.cid] || (_base[_name] = new FilterModel(this.filterable)); }, setSortBy: function(sortBy, options) { if (options == null) options = {}; return this.getFilterState().setOption('sortBy', sortBy, options); }, applyFilter: function(query, options) { - var silent; if (query == null) query = {}; if (options == null) options = {}; options = _.defaults(options, this.getQueryOptions()); query = _.defaults(query, this.getQuery()); - silent = _(options)["delete"]('silent') === true; return this.getFilterState().set({ query: query, options: options - }, { - silent: silent - }); + }, options); } }; FilterModel = (function(_super) { @@ -1129,10 +1287,15 @@ function FilterModel() { FilterModel.__super__.constructor.apply(this, arguments); } + FilterModel.prototype.defaults = { + options: {}, + query: {} + }; + FilterModel.prototype.setOption = function(option, value, options) { var payload; payload = {}; payload[option] = value; return this.set('options', _.extend(this.toOptions(), payload), options); @@ -1151,18 +1314,28 @@ FilterModel.prototype.toQuery = function() { return this.toJSON().query; }; + FilterModel.prototype.toRemote = function() { + var options; + options = this.toOptions(); + return _.extend(this.toQuery(), { + limit: options.limit, + page: options.page, + sortBy: options.sortBy + }); + }; + return FilterModel; })(Backbone.Model); }).call(this); (function() { - Luca.modules.GridLayout = { + Luca.concerns.GridLayout = { _initializer: function() { if (this.gridSpan) this.$el.addClass("span" + this.gridSpan); if (this.gridOffset) this.$el.addClass("offset" + this.gridOffset); if (this.gridRowFluid) this.$el.addClass("row-fluid"); if (this.gridRow) return this.$el.addClass("row"); @@ -1170,11 +1343,11 @@ }; }).call(this); (function() { - Luca.modules.LoadMaskable = { + Luca.concerns.LoadMaskable = { __initializer: function() { var _this = this; if (this.loadMask !== true) return; if (this.loadMask === true) { this.defer(function() { @@ -1317,11 +1490,11 @@ }).call(this); (function() { var applyModalConfig; - Luca.modules.ModalView = { + Luca.concerns.ModalView = { closeOnEscape: true, showOnInitialize: false, backdrop: false, __initializer: function() { this.$el.addClass("modal"); @@ -1355,52 +1528,99 @@ }; }).call(this); (function() { - Luca.modules.Paginatable = { + Luca.concerns.ModelPresenter = { + classMethods: { + getPresenter: function(format) { + var _ref; + return (_ref = this.presenters) != null ? _ref[format] : void 0; + }, + registerPresenter: function(format, config) { + this.presenters || (this.presenters = {}); + return this.presenters[format] = config; + } + }, + presentAs: function(format) { + var attributeList, + _this = this; + try { + attributeList = this.componentMetaData().componentDefinition().getPresenter(format); + if (attributeList == null) return this.toJSON(); + return _(attributeList).reduce(function(memo, attribute) { + memo[attribute] = _this.read(attribute); + return memo; + }, {}); + } catch (e) { + console.log("Error presentAs", e.stack, e.message); + return this.toJSON(); + } + } + }; + +}).call(this); +(function() { + + Luca.concerns.Paginatable = { paginatorViewClass: 'Luca.components.PaginationControl', paginationSelector: ".toolbar.bottom", __included: function() { return _.extend(Luca.Collection.prototype, { __paginators: {} }); }, __initializer: function() { - var collection, old, paginationState, + var collection, paginationState, _base, _ref, _this = this; - if (this.paginatable === false || !Luca.isBackboneCollection(this.collection)) { + if (this.paginatable === false) return; + if (!Luca.isBackboneCollection(this.collection)) { + this.collection = typeof (_base = Luca.CollectionManager).get === "function" ? (_ref = _base.get()) != null ? _ref.getOrCreate(this.collection) : void 0 : void 0; + } + if (!Luca.isBackboneCollection(this.collection)) { + this.debug("Skipping Paginatable due to no collection being present on " + (this.name || this.cid)); + this.debug("collection", this.collection); return; } - _.bindAll(this, "paginationControl"); + _.bindAll(this, "paginationControl", "pager"); this.getCollection || (this.getCollection = function() { return this.collection; }); collection = this.getCollection(); paginationState = this.getPaginationState(); - paginationState.on("change", function(state) { - _this.trigger("collection:change:pagination", state, collection); - return _this.trigger("refresh"); - }); - this.on("after:refresh", function(models, query, options) { - return _.defer(function() { - return _this.updatePagination.call(_this, models, query, options); + this.optionsSources || (this.optionsSources = []); + this.queryOptions || (this.queryOptions = {}); + this.optionsSources.push(function() { + var options; + options = _(paginationState.toJSON()).pick('limit', 'page', 'sortBy'); + return _.extend(options, { + pager: _this.pager }); }); - this.on("after:render", function() { - return _this.paginationControl().refresh(); + paginationState.on("change:page", function(state) { + var filter; + if (_this.isRemote()) { + filter = _.extend(_this.toQuery(), _this.toQueryOptions()); + return _this.collection.applyFilter(filter, { + remote: true + }); + } else { + return _this.trigger("refresh"); + } }); - if (old = this.getQueryOptions) { - return this.getQueryOptions = function() { - return _.extend(old(), paginationState.toJSON()); - }; - } else { - return this.getQueryOptions = function() { - return paginationState.toJSON(); - }; - } + return this.on("before:render", this.renderPaginationControl, this); }, + pager: function(numberOfPages, models) { + this.getPaginationState().set({ + numberOfPages: numberOfPages, + itemCount: models.length + }); + return this.paginationControl().updateWithPageCount(numberOfPages, models); + }, + isRemote: function() { + return this.getQueryOptions().remote === true; + }, getPaginationState: function() { var _base, _name; return (_base = this.collection.__paginators)[_name = this.cid] || (_base[_name] = this.paginationControl().state); }, paginationContainer: function() { @@ -1409,59 +1629,47 @@ setCurrentPage: function(page, options) { if (page == null) page = 1; if (options == null) options = {}; return this.getPaginationState().set('page', page, options); }, + setPage: function(page, options) { + if (page == null) page = 1; + if (options == null) options = {}; + return this.getPaginationState().set('page', page, options); + }, setLimit: function(limit, options) { if (limit == null) limit = 0; if (options == null) options = {}; return this.getPaginationState().set('limit', limit, options); }, - updatePagination: function(models, query, options) { - var itemCount, paginator, totalCount, _ref; - if (models == null) models = []; - if (query == null) query = {}; - if (options == null) options = {}; - _.defaults(options, this.getQueryOptions(), { - limit: 0 - }); - paginator = this.paginationControl(); - itemCount = (models != null ? models.length : void 0) || 0; - totalCount = (_ref = this.getCollection()) != null ? _ref.length : void 0; - if (itemCount === 0 || totalCount <= options.limit) { - paginator.$el.hide(); - } else { - paginator.$el.show(); - } - return paginator.state.set({ - page: options.page, - limit: options.limit - }); - }, paginationControl: function() { if (this.paginator != null) return this.paginator; _.defaults(this.paginatable || (this.paginatable = {}), { page: 1, limit: 20 }); this.paginator = Luca.util.lazyComponent({ type: "pagination_control", collection: this.getCollection(), - defaultState: this.paginatable + defaultState: this.paginatable, + parent: this.name || this.cid, + debugMode: this.debugMode }); return this.paginator; }, renderPaginationControl: function() { - this.paginationControl(); - return this.paginationContainer().append(this.paginationControl().render().$el); + var control; + control = this.paginationControl(); + this.paginationContainer().append(control.render().$el); + return control; } }; }).call(this); (function() { - Luca.modules.StateModel = { + Luca.concerns.StateModel = { __initializer: function() { var _this = this; if (this.stateful !== true) return; if ((this.state != null) && !Luca.isBackboneModel(this.state)) return; this.state = new Backbone.Model(this.defaultState || {}); @@ -1487,11 +1695,11 @@ }; }).call(this); (function() { - Luca.modules.Templating = { + Luca.concerns.Templating = { __initializer: function() { var template, templateContent, templateVars; templateVars = Luca.util.read.call(this, this.bodyTemplateVars) || {}; if (template = this.bodyTemplate) { this.$el.empty(); @@ -1640,10 +1848,65 @@ return componentCacheStore.cid_index[lookup_id]; }; }).call(this); (function() { + var MetaDataProxy; + + Luca.registry.componentMetaData = {}; + + Luca.registry.getMetaDataFor = function(componentName) { + return new MetaDataProxy(Luca.registry.componentMetaData[componentName]); + }; + + Luca.registry.addMetaData = function(componentName, key, value) { + var data, _base; + data = (_base = Luca.registry.componentMetaData)[componentName] || (_base[componentName] = {}); + data[key] = _(value).clone(); + return data; + }; + + MetaDataProxy = (function() { + + function MetaDataProxy(meta) { + this.meta = meta != null ? meta : {}; + this; + } + + MetaDataProxy.prototype.superClass = function() { + return Luca.util.resolve(this.meta["super class name"]); + }; + + MetaDataProxy.prototype.componentDefinition = function() { + return Luca.util.resolve(this.meta["display name"]); + }; + + MetaDataProxy.prototype.styleHierarchy = function() { + var list; + list = _(this.classHierarchy()).map(function(cls) { + return Luca.util.toCssClass(cls, 'views', 'components', 'core', 'fields', 'containers'); + }); + return _(list).without('backbone-view', 'luca-view'); + }; + + MetaDataProxy.prototype.classHierarchy = function() { + var list, proxy, _ref, _ref2, _ref3, _ref4; + list = [this.meta["display name"], this.meta["super class name"]]; + proxy = (_ref = this.superClass()) != null ? (_ref2 = _ref.prototype) != null ? typeof _ref2.componentMetaData === "function" ? _ref2.componentMetaData() : void 0 : void 0 : void 0; + while (!!proxy) { + list = list.concat(proxy != null ? proxy.classHierarchy() : void 0); + proxy = (_ref3 = proxy.superClass()) != null ? (_ref4 = _ref3.prototype) != null ? typeof _ref4.componentMetaData === "function" ? _ref4.componentMetaData() : void 0 : void 0 : void 0; + } + return _(list).uniq(); + }; + + return MetaDataProxy; + + })(); + +}).call(this); +(function() { var __slice = Array.prototype.slice; Luca.Observer = (function() { function Observer(options) { @@ -1681,65 +1944,40 @@ })); }; }).call(this); (function() { - var bindAllEventHandlers, bindEventHandlers, view; + var bindAllEventHandlers, bindEventHandlers, view, + __slice = Array.prototype.slice; view = Luca.register("Luca.View"); view["extends"]("Backbone.View"); - view.includes("Luca.Events", "Luca.modules.DomHelpers"); + view.includes("Luca.Events", "Luca.concerns.DomHelpers"); view.mixesIn("DomHelpers", "Templating", "EnhancedProperties", "CollectionEventBindings", "ApplicationEventBindings", "StateModel"); view.triggers("before:initialize", "after:initialize", "before:render", "after:render", "first:activation", "activation", "deactivation"); view.defines({ initialize: function(options) { - var module, _i, _len, _ref, _ref2, _ref3, _ref4; this.options = options != null ? options : {}; this.trigger("before:initialize", this, this.options); _.extend(this, this.options); if (this.autoBindEventHandlers === true || this.bindAllEvents === true) { bindAllEventHandlers.call(this); } if (this.name != null) this.cid = _.uniqueId(this.name); this.$el.attr("data-luca-id", this.name || this.cid); Luca.cacheInstance(this.cid, this); this.setupHooks(_(Luca.View.prototype.hooks.concat(this.hooks)).uniq()); - if (((_ref = this.mixins) != null ? _ref.length : void 0) > 0) { - _ref2 = this.mixins; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - module = _ref2[_i]; - if ((_ref3 = Luca.mixin(module)) != null) { - if ((_ref4 = _ref3.__initializer) != null) { - _ref4.call(this, this, module); - } - } - } - } + Luca.concern.setup.call(this); this.delegateEvents(); return this.trigger("after:initialize", this); }, - setupHooks: function(set) { - var _this = this; - set || (set = this.hooks); - return _(set).each(function(eventId) { - var callback, fn; - fn = Luca.util.hook(eventId); - callback = function() { - var _ref; - return (_ref = this[fn]) != null ? _ref.apply(this, arguments) : void 0; - }; - if (eventId != null ? eventId.match(/once:/) : void 0) { - callback = _.once(callback); - } - return _this.on(eventId, callback, _this); - }); - }, + setupHooks: Luca.util.setupHooks, registerEvent: function(selector, handler) { this.events || (this.events = {}); this.events[selector] = handler; return this.delegateEvents(); }, @@ -1755,18 +1993,14 @@ }, views: function() { return Luca.util.selectProperties(Luca.isBackboneView, this); }, debug: function() { - var message, _i, _len, _results; + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; if (!(this.debugMode || (window.LucaDebugMode != null))) return; - _results = []; - for (_i = 0, _len = arguments.length; _i < _len; _i++) { - message = arguments[_i]; - _results.push(console.log([this.name || this.cid, message])); - } - return _results; + return console.log([this.name || this.cid].concat(__slice.call(args))); }, trigger: function() { if (Luca.enableGlobalObserver) { if (Luca.developmentMode === true || this.observeEvents === true) { Luca.ViewObserver || (Luca.ViewObserver = new Luca.Observer({ @@ -1847,25 +2081,30 @@ } } return _results; }; + Luca.View.deferrableEvent = "reset"; + Luca.View.extend = function(definition) { - var module, _i, _len, _ref; + var componentClass, module, _i, _len, _ref; + if (definition == null) definition = {}; definition = Luca.View.renderWrapper(definition); - if ((definition.mixins != null) && _.isArray(definition.mixins)) { - _ref = definition.mixins; + if (definition.concerns != null) { + definition.concerns || (definition.concerns = definition.concerns); + } + componentClass = Luca.View._originalExtend.call(this, definition); + if ((definition.concerns != null) && _.isArray(definition.concerns)) { + _ref = definition.concerns; for (_i = 0, _len = _ref.length; _i < _len; _i++) { module = _ref[_i]; - Luca.decorate(definition)["with"](module); + Luca.decorate(componentClass)["with"](module); } } - return Luca.View._originalExtend.call(this, definition); + return componentClass; }; - Luca.View.deferrableEvent = "reset"; - }).call(this); (function() { var model, setupComputedProperties; model = Luca.define('Luca.Model'); @@ -1875,17 +2114,18 @@ model.includes('Luca.Events'); model.defines({ initialize: function() { Backbone.Model.prototype.initialize(this, arguments); - return setupComputedProperties.call(this); + setupComputedProperties.call(this); + return Luca.concern.setup.call(this); }, read: function(attr) { if (_.isFunction(this[attr])) { return this[attr].call(this); } else { - return this.get(attr); + return this.get(attr) || this[attr]; } }, get: function(attr) { var _ref; if ((_ref = this.computed) != null ? _ref.hasOwnProperty(attr) : void 0) { @@ -1917,10 +2157,29 @@ })); } return _results; }; + Luca.Model._originalExtend = Backbone.Model.extend; + + Luca.Model.extend = function(definition) { + var componentClass, module, _i, _len, _ref; + if (definition == null) definition = {}; + if (definition.concerns != null) { + definition.concerns || (definition.concerns = definition.concerns); + } + componentClass = Luca.Model._originalExtend.call(this, definition); + if ((definition.concerns != null) && _.isArray(definition.concerns)) { + _ref = definition.concerns; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + module = _ref[_i]; + Luca.decorate(componentClass)["with"](module); + } + } + return componentClass; + }; + }).call(this); (function() { var collection; collection = Luca.define('Luca.Collection'); @@ -1981,10 +2240,11 @@ this.reset(models, { silent: true, parse: options != null ? options.parse : void 0 }); } + Luca.concern.setup.call(this); return this.trigger("after:initialize"); }, __wrapUrl: function() { var params, url, _this = this; @@ -2076,11 +2336,13 @@ fetch: function(options) { var url; if (options == null) options = {}; this.trigger("before:fetch", this); if (this.memoryCollection === true) return this.reset(this.data); - if (this.cached_models().length && !options.refresh) return this.bootstrap(); + if (this.cached_models().length && !(options.refresh === true || options.remote === true)) { + return this.bootstrap(); + } url = _.isFunction(this.url) ? this.url() : this.url; if (!((url && url.length > 1) || this.localStorage)) return true; this.fetching = true; try { return Backbone.Collection.prototype.fetch.apply(this, arguments); @@ -2225,10 +2487,29 @@ } return Backbone.View.prototype.trigger.apply(this, arguments); } }); + Luca.Collection._originalExtend = Backbone.Collection.extend; + + Luca.Collection.extend = function(definition) { + var componentClass, module, _i, _len, _ref; + if (definition == null) definition = {}; + if (definition.concerns != null) { + definition.concerns || (definition.concerns = definition.concerns); + } + componentClass = Luca.Collection._originalExtend.call(this, definition); + if ((definition.concerns != null) && _.isArray(definition.concerns)) { + _ref = definition.concerns; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + module = _ref[_i]; + Luca.decorate(componentClass)["with"](module); + } + } + return componentClass; + }; + Luca.Collection.baseParams = function(obj) { if (obj) return Luca.Collection._baseParams = obj; if (_.isFunction(Luca.Collection._baseParams)) { return Luca.Collection._baseParams(); } @@ -2373,44 +2654,25 @@ } }); }).call(this); (function() { + var field; - _.def('Luca.core.Field')["extends"]('Luca.View')["with"]({ - className: 'luca-ui-text-field luca-ui-field', - isField: true, - template: 'fields/text_field', + field = Luca.register("Luca.core.Field"); + + field["extends"]("Luca.View"); + + field.triggers("before:validation", "after:validation", "on:change"); + + field.publicConfiguration({ labelAlign: 'top', - hooks: ["before:validation", "after:validation", "on:change"], - statuses: ["warning", "error", "success"], - initialize: function(options) { - var _ref; - this.options = options != null ? options : {}; - _.extend(this, this.options); - this.input_id || (this.input_id = _.uniqueId('field')); - this.input_name || (this.input_name = this.name); - this.input_class || (this.input_class = ""); - this.input_type || (this.input_type = ""); - this.helperText || (this.helperText = ""); - if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) { - this.label || (this.label = "*" + this.label); - } - this.inputStyles || (this.inputStyles = ""); - this.input_value || (this.input_value = this.value || ""); - if (this.disabled) this.disable(); - this.updateState(this.state); - this.placeHolder || (this.placeHolder = ""); - return Luca.View.prototype.initialize.apply(this, arguments); - }, - beforeRender: function() { - if (Luca.enableBootstrap) this.$el.addClass('control-group'); - if (this.required) return this.$el.addClass('required'); - }, - change_handler: function(e) { - return this.trigger("on:change", this, e); - }, + className: 'luca-ui-text-field luca-ui-field', + statuses: ["warning", "error", "success"] + }); + + field.publicInterface({ disable: function() { return this.getInputElement().attr('disabled', true); }, enable: function() { return this.getInputElement().attr('disabled', false); @@ -2432,22 +2694,57 @@ }, setValue: function(value) { var _ref; return (_ref = this.getInputElement()) != null ? _ref.attr('value', value) : void 0; }, - getInputElement: function() { - return this.input || (this.input = this.$('input').eq(0)); - }, updateState: function(state) { var _this = this; return _(this.statuses).each(function(cls) { _this.$el.removeClass(cls); return _this.$el.addClass(state); }); } }); + field.privateConfiguration({ + isField: true, + template: 'fields/text_field' + }); + + field.defines({ + initialize: function(options) { + var _ref; + this.options = options != null ? options : {}; + _.extend(this, this.options); + this.input_id || (this.input_id = _.uniqueId('field')); + this.input_name || (this.input_name = this.name); + this.input_class || (this.input_class = ""); + this.input_type || (this.input_type = ""); + this.helperText || (this.helperText = ""); + if (!(this.label != null) || this.label.length === 0) this.label = this.name; + if (this.required && !((_ref = this.label) != null ? _ref.match(/^\*/) : void 0)) { + this.label || (this.label = "*" + this.label); + } + this.inputStyles || (this.inputStyles = ""); + this.input_value || (this.input_value = this.value || ""); + if (this.disabled) this.disable(); + this.updateState(this.state); + this.placeHolder || (this.placeHolder = ""); + return Luca.View.prototype.initialize.apply(this, arguments); + }, + beforeRender: function() { + if (Luca.enableBootstrap) this.$el.addClass('control-group'); + if (this.required) return this.$el.addClass('required'); + }, + change_handler: function(e) { + return this.trigger("on:change", this, e); + }, + getInputElement: function() { + return this.input || (this.input = this.$('input').eq(0)); + } + }); + }).call(this); (function() { var applyDOMConfig, container, createGetterMethods, createMethodsToGetComponentsByRole, doComponents, doLayout, indexComponent, validateContainerConfiguration; container = Luca.register("Luca.core.Container"); @@ -2488,27 +2785,39 @@ }); }, prepareComponents: function() { var component, _i, _len, _ref, _this = this; + container = this; _ref = this.components; for (_i = 0, _len = _ref.length; _i < _len; _i++) { component = _ref[_i]; if (_.isString(component)) { component = { type: component }; } } return _(this.components).each(function(component, index) { - var ce, componentContainerElement, panel, _ref2; + var ce, componentContainerElement, componentExtension, panel, _ref2, _ref3; ce = componentContainerElement = (_ref2 = _this.componentContainers) != null ? _ref2[index] : void 0; ce["class"] = ce["class"] || ce.className || ce.classes; if (_this.generateComponentElements) { panel = _this.make(_this.componentTag, componentContainerElement, ''); _this.$append(panel); } + if (container.defaults != null) { + component = _.defaults(component, container.defaults || {}); + } + if (_.isArray(container.extensions) && _.isObject((_ref3 = container.extensions) != null ? _ref3[index] : void 0)) { + componentExtension = container.extensions[index]; + component = _.extend(component, componentExtension); + } + if ((component.role != null) && _.isObject(container.extensions) && _.isObject(container.extensions[component.role])) { + componentExtension = container.extensions[component.role]; + component = _.extend(component, componentExtension); + } if (component.container == null) { if (_this.generateComponentElements) { component.container = "#" + componentContainerElement.id; } return component.container || (component.container = _this.$bodyEl()); @@ -2524,15 +2833,19 @@ cid_index: {}, role_index: {} }; container = this; this.components = _(this.components).map(function(object, index) { - var component, created; - 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)); - if (!component.container && component.options.container) { + var component, created, _ref; + 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)); + if (!component.container && ((_ref = component.options) != null ? _ref.container : void 0)) { component.container = component.options.container; } + if (!(component.container != null)) { + console.log(component, index, _this); + console.error("could not assign container property to component on container " + (_this.name || _this.cid)); + } indexComponent(component).at(index)["in"](_this.componentIndex); return component; }); this.componentsCreated = true; return map; @@ -2544,11 +2857,11 @@ return _(this.components).each(function(component) { component.getParent = function() { return container; }; try { - $(component.container).append(component.el); + this.$(component.container).eq(0).append(component.el); return component.render(); } catch (e) { console.log("Error Rendering Component " + (component.name || component.cid), component); if (_.isObject(e)) { console.log(e.message); @@ -2592,15 +2905,15 @@ return this._().reject(fn); }, map: function(fn) { return this._().map(fn); }, - registerComponentEvents: function() { + registerComponentEvents: function(eventList) { var component, componentNameOrRole, eventId, handler, listener, _ref, _ref2, _results, _this = this; container = this; - _ref = this.componentEvents || {}; + _ref = eventList || this.componentEvents || {}; _results = []; for (listener in _ref) { handler = _ref[listener]; _ref2 = listener.split(' '), componentNameOrRole = _ref2[0], eventId = _ref2[1]; if (!_.isFunction(this[handler])) { @@ -2632,14 +2945,14 @@ }, allChildren: function() { var children, grandchildren; children = this.components; grandchildren = _(this.subContainers()).invoke('allChildren'); - return this._allChildren || (this._allChildren = _([children, grandchildren]).chain().compact().flatten().uniq().value()); + return _([children, grandchildren]).chain().compact().flatten().value(); }, findComponentForEventBinding: function(nameRoleOrGetter, deep) { - if (deep == null) deep = false; + if (deep == null) deep = true; return this.findComponentByName(nameRoleOrGetter, deep) || this.findComponentByGetter(nameRoleOrGetter, deep) || this.findComponentByRole(nameRoleOrGetter, deep); }, findComponentByGetter: function(getter, deep) { if (deep == null) deep = false; return _(this.allChildren()).detect(function(component) { @@ -2647,11 +2960,11 @@ }); }, findComponentByRole: function(role, deep) { if (deep == null) deep = false; return _(this.allChildren()).detect(function(component) { - return component.role === role; + return component.role === role || component.type === role || component.ctype === role; }); }, findComponentByName: function(name, deep) { if (deep == null) deep = false; return _(this.allChildren()).detect(function(component) { @@ -2777,11 +3090,10 @@ return component.getter != null; }); return _(childrenWithGetter).each(function(component) { var _name; return container[_name = component.getter] || (container[_name] = function() { - console.log("getter is being deprecated in favor of role"); console.log(component.getter, component, container); return component; }); }); }; @@ -2806,12 +3118,14 @@ this.prepareComponents(); this.createComponents(); this.trigger("before:render:components", this, this.components); this.renderComponents(); this.trigger("after:components", this, this.components); - createGetterMethods.call(this); - createMethodsToGetComponentsByRole.call(this); + if (this.skipGetterMethods !== true) { + createGetterMethods.call(this); + createMethodsToGetComponentsByRole.call(this); + } return this.registerComponentEvents(); }; validateContainerConfiguration = function() { return true; @@ -3490,20 +3804,31 @@ } }); }).call(this); (function() { + var tabView; - _.def('Luca.containers.TabView')["extends"]('Luca.containers.CardView')["with"]({ - hooks: ["before:select", "after:select"], - componentType: 'tab_view', - className: 'luca-ui-tab-view tabbable', + _.def('Luca.containers.TabView')["extends"]('Luca.containers.CardView')["with"]; + + tabView = Luca.register("Luca.containers.TabView"); + + tabView.triggers("before:select", "after:select"); + + tabView.publicConfiguration({ tab_position: 'top', - tabVerticalOffset: '50px', + tabVerticalOffset: '50px' + }); + + tabView.privateConfiguration({ + additionalClassNames: 'tabbable', navClass: "nav-tabs", bodyTemplate: "containers/tab_view", - bodyEl: "div.tab-content", + bodyEl: "div.tab-content" + }); + + tabView.defines({ initialize: function(options) { this.options = options != null ? options : {}; if (this.navStyle === "list") this.navClass = "nav-list"; Luca.containers.CardView.prototype.initialize.apply(this, arguments); _.bindAll(this, "select", "highlightSelectedTab"); @@ -3531,11 +3856,10 @@ this.tabContainerWrapper().addClass("span2"); return this.tabContentWrapper().addClass("span9"); } }, createTabSelectors: function() { - var tabView; tabView = this; return this.each(function(component, index) { var icon, link, selector, _ref; if (component.tabIcon) { icon = "<i class='icon-" + component.tabIcon + "'></i>"; @@ -3681,17 +4005,17 @@ } }); }).call(this); (function() { - var startHistory; + var application; - startHistory = function() { - return Backbone.history.start(); - }; + application = Luca.register("Luca.Application"); - _.def('Luca.Application')["extends"]('Luca.containers.Viewport')["with"]({ + application["extends"]("Luca.containers.Viewport"); + + application.defines({ name: "MyApp", defaultState: {}, autoBoot: false, autoStartHistory: "before:render", useCollectionManager: true, @@ -3885,11 +4209,11 @@ } if (this.router && this.autoStartHistory) { if (this.autoStartHistory === true) { this.autoStartHistory = "before:render"; } - return this.defer(startHistory, false).until(this, this.autoStartHistory); + return this.defer(Luca.util.startHistory, false).until(this, this.autoStartHistory); } }, setupKeyHandler: function() { var handler, keyEvent, _base, _i, _len, _ref, _results; if (!this.keyEvents) return; @@ -3906,35 +4230,48 @@ } return _results; } }); + Luca.util.startHistory = function() { + return Backbone.history.start(); + }; + }).call(this); (function() { + var toolbar; - _.def('Luca.components.Toolbar')["extends"]('Luca.core.Container')["with"]({ + _.def('Luca.components.Toolbar')["extends"]('Luca.core.Container')["with"]; + + toolbar = Luca.register("Luca.components.Toolbar"); + + toolbar["extends"]("Luca.core.Container"); + + toolbar.defines({ className: 'luca-ui-toolbar toolbar', position: 'bottom', - initialize: function(options) { - this.options = options != null ? options : {}; - return Luca.core.Container.prototype.initialize.apply(this, arguments); - }, prepareComponents: function() { var _this = this; return _(this.components).each(function(component) { return component.container = _this.$el; }); }, render: function() { - return $(this.container).append(this.el); + $(this.container).append(this.el); + return this; } }); }).call(this); (function() { + var loaderView; - _.def('Luca.components.CollectionLoaderView')["extends"]('Luca.components.Template')["with"]({ + loaderView = Luca.register("Luca.components.CollectionLoaderView"); + + loaderView["extends"]("Luca.View"); + + loaderView.defines({ className: 'luca-ui-collection-loader-view', template: "components/collection_loader_view", initialize: function(options) { this.options = options != null ? options : {}; Luca.components.Template.prototype.initialize.apply(this, arguments); @@ -3967,19 +4304,19 @@ }).call(this); (function() { var collectionView, make; - collectionView = Luca.define("Luca.components.CollectionView"); + collectionView = Luca.register("Luca.components.CollectionView"); collectionView["extends"]("Luca.components.Panel"); - collectionView.behavesAs("LoadMaskable", "Filterable", "Paginatable"); + collectionView.mixesIn("LoadMaskable", "Filterable", "Paginatable"); collectionView.triggers("before:refresh", "after:refresh", "refresh", "empty:results"); - collectionView.defaults({ + collectionView.defines({ tagName: "ol", className: "luca-ui-collection-view", bodyClassName: "collection-ui-panel", itemTemplate: void 0, itemRenderer: void 0, @@ -3995,15 +4332,19 @@ throw "Collection Views must specify a collection"; } if (!((this.itemTemplate != null) || (this.itemRenderer != null) || (this.itemProperty != null))) { throw "Collection Views must specify an item template or item renderer function"; } - Luca.components.Panel.prototype.initialize.apply(this, arguments); - if (_.isString(this.collection) && Luca.CollectionManager.get()) { - this.collection = Luca.CollectionManager.get().getOrCreate(this.collection); + if (_.isString(this.collection)) { + if (Luca.CollectionManager.get()) { + this.collection = Luca.CollectionManager.get().getOrCreate(this.collection); + } else { + console.log("String Collection but no collection manager"); + } } if (!Luca.isBackboneCollection(this.collection)) { + console.log("Missing Collection on " + (this.name || this.cid), this, this.collection); throw "Collection Views must have a valid backbone collection"; this.collection.on("before:fetch", function() { return _this.trigger("enable:loadmask"); }); this.collection.bind("reset", function() { @@ -4018,16 +4359,17 @@ }); if (this.observeChanges === true) { this.collection.on("change", this.refreshModel, this); } } + Luca.components.Panel.prototype.initialize.apply(this, arguments); if (this.autoRefreshOnModelsPresent !== false) { this.defer(function() { if (_this.collection.length > 0) return _this.refresh(); }).until("after:render"); } - return this.on("collection:change", this.refresh, this); + return this.on("refresh", this.refresh, this); }, attributesForItem: function(item, model) { return _.extend({}, { "class": this.itemClassName, "data-index": item.index, @@ -4063,15 +4405,43 @@ } }, getCollection: function() { return this.collection; }, + loadModels: function(models, options) { + var _ref; + if (models == null) models = []; + if (options == null) options = {}; + return (_ref = this.getCollection()) != null ? _ref.reset(models, options) : void 0; + }, + applyQuery: function(query, queryOptions) { + if (query == null) query = {}; + if (queryOptions == null) queryOptions = {}; + this.query = query; + this.queryOptions = queryOptions; + this.refresh(); + return this; + }, getQuery: function() { - return this.query || (this.query = {}); + var query, querySource, _i, _len, _ref; + query = this.query || (this.query = {}); + _ref = _(this.querySources || []).compact(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + querySource = _ref[_i]; + query = _.extend(query, querySource() || {}); + } + return query; }, getQueryOptions: function() { - return this.queryOptions || (this.queryOptions = {}); + var optionSource, options, _i, _len, _ref; + options = this.queryOptions || (this.queryOptions = {}); + _ref = _(this.optionsSources || []).compact(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + optionSource = _ref[_i]; + options = _.extend(options, optionSource() || {}); + } + return options; }, getModels: function(query, options) { var _ref; if ((_ref = this.collection) != null ? _ref.query : void 0) { query || (query = this.getQuery()); @@ -4091,16 +4461,16 @@ model: model, index: index }, model)); return this.trigger("model:refreshed", index, model); }, - refresh: function(query, options) { - var index, model, models, _i, _len; + refresh: function(query, options, models) { + var index, model, _i, _len; query || (query = this.getQuery()); options || (options = this.getQueryOptions()); + models || (models = this.getModels(query, options)); this.$bodyEl().empty(); - models = this.getModels(query, options); this.trigger("before:refresh", models, query, options); if (models.length === 0) this.trigger("empty:results"); index = 0; for (_i = 0, _len = models.length; _i < _len; _i++) { model = models[_i]; @@ -4127,12 +4497,17 @@ make = Luca.View.prototype.make; }).call(this); (function() { + var controller; - _.def('Luca.components.Controller')["extends"]('Luca.containers.CardView')["with"]({ + controller = Luca.register("Luca.components.Controller"); + + controller["extends"]("Luca.containers.CardView"); + + controller.defines({ additionalClassNames: ['luca-ui-controller'], activeAttribute: "active-section", initialize: function(options) { var _ref; this.options = options; @@ -4188,19 +4563,35 @@ } }); }).call(this); (function() { + var buttonField; - _.def('Luca.fields.ButtonField')["extends"]('Luca.core.Field')["with"]({ + buttonField = Luca.register("Luca.fields.ButtonField"); + + buttonField["extends"]("Luca.core.Field"); + + buttonField.triggers("button:click"); + + buttonField.publicConfiguration({ readOnly: true, + input_value: void 0, + input_type: "button", + icon_class: void 0, + input_name: void 0, + white: void 0 + }); + + buttonField.privateConfiguration({ + template: "fields/button_field", events: { "click input": "click_handler" - }, - hooks: ["button:click"], - className: 'luca-ui-field luca-ui-button-field', - template: 'fields/button_field', + } + }); + + buttonField.privateInterface({ click_handler: function(e) { var me, my; me = my = $(e.currentTarget); return this.trigger("button:click"); }, @@ -4216,11 +4607,10 @@ }, afterInitialize: function() { this.input_id || (this.input_id = _.uniqueId('button')); this.input_name || (this.input_name = this.name || (this.name = this.input_id)); this.input_value || (this.input_value = this.label || (this.label = this.text)); - this.input_type || (this.input_type = "button"); this.input_class || (this.input_class = this["class"]); this.icon_class || (this.icon_class = ""); if (this.icon_class.length && !this.icon_class.match(/^icon-/)) { this.icon_class = "icon-" + this.icon_class; } @@ -4229,28 +4619,36 @@ setValue: function() { return true; } }); + buttonField.defines({ + version: 1 + }); + }).call(this); (function() { - var make; + var checkboxArray, make; make = Luca.View.prototype.make; - _.def('Luca.fields.CheckboxArray')["extends"]('Luca.core.Field')["with"]({ + checkboxArray = Luca.register("Luca.fields.CheckboxArray"); + + checkboxArray["extends"]("Luca.core.Field"); + + checkboxArray.defines({ version: 2, template: "fields/checkbox_array", className: "luca-ui-checkbox-array", events: { "click input": "clickHandler" }, selectedItems: [], initialize: function(options) { this.options = options != null ? options : {}; _.extend(this, this.options); - _.extend(this, Luca.modules.Deferrable); + _.extend(this, Luca.concerns.Deferrable); _.bindAll(this, "renderCheckboxes", "clickHandler", "checkSelected"); Luca.core.Field.prototype.initialize.apply(this, arguments); this.input_id || (this.input_id = _.uniqueId('field')); this.input_name || (this.input_name = this.name); this.label || (this.label = this.name); @@ -4264,10 +4662,13 @@ this.configure_collection(); } catch (e) { console.log("Error Configuring Collection", this, e.message); } cbArray = this; + if (!Luca.isBackboneCollection(this.collection)) { + throw "Checkbox Array Fields must specify a @collection property"; + } if (this.collection.length > 0) { return this.renderCheckboxes(); } else { return this.defer("renderCheckboxes").until(this.collection, "reset"); } @@ -4359,19 +4760,31 @@ } }); }).call(this); (function() { + var checkboxField; - _.def('Luca.fields.CheckboxField')["extends"]('Luca.core.Field')["with"]({ + checkboxField = Luca.register("Luca.fields.CheckboxField"); + + checkboxField["extends"]("Luca.core.Field"); + + checkboxField.triggers("checked", "unchecked"); + + checkboxField.publicConfiguration({ + send_blanks: true, + input_value: 1 + }); + + checkboxField.privateConfiguration({ + template: 'fields/checkbox_field', events: { "change input": "change_handler" - }, - className: 'luca-ui-checkbox-field luca-ui-field', - template: 'fields/checkbox_field', - hooks: ["checked", "unchecked"], - send_blanks: true, + } + }); + + checkboxField.privateInterface({ change_handler: function(e) { var me, my; me = my = $(e.target); if (me.is(":checked")) { this.trigger("checked"); @@ -4382,30 +4795,40 @@ }, initialize: function(options) { this.options = options != null ? options : {}; _.extend(this, this.options); _.bindAll(this, "change_handler"); - return Luca.core.Field.prototype.initialize.apply(this, arguments); - }, - afterInitialize: function() { + Luca.core.Field.prototype.initialize.apply(this, arguments); this.input_id || (this.input_id = _.uniqueId('field')); this.input_name || (this.input_name = this.name); - this.input_value || (this.input_value = 1); return this.label || (this.label = this.name); - }, + } + }); + + checkboxField.publicInterface({ setValue: function(checked) { return this.getInputElement().attr('checked', checked); }, getValue: function() { return this.getInputElement().is(":checked"); } }); + checkboxField.defines({ + version: 1 + }); + }).call(this); (function() { + var fileUpload; - _.def('Luca.fields.FileUploadField')["extends"]('Luca.core.Field')["with"]({ + fileUpload = Luca.register("Luca.fields.FileUploadField"); + + fileUpload["extends"]("Luca.core.Field"); + + fileUpload.defines({ + version: 1, template: 'fields/file_upload_field', afterInitialize: function() { this.input_id || (this.input_id = _.uniqueId('field')); this.input_name || (this.input_name = this.name); this.label || (this.label = this.name); @@ -4413,12 +4836,17 @@ } }); }).call(this); (function() { + var hiddenField; - _.def('Luca.fields.HiddenField')["extends"]('Luca.core.Field')["with"]({ + hiddenField = Luca.register("Luca.fields.HiddenField"); + + hiddenField["extends"]("Luca.core.Field"); + + hiddenField.defines({ template: 'fields/hidden_field', afterInitialize: function() { this.input_id || (this.input_id = _.uniqueId('field')); this.input_name || (this.input_name = this.name); this.input_value || (this.input_value = this.value); @@ -4426,13 +4854,17 @@ } }); }).call(this); (function() { + var labelField; - _.def("Luca.components.LabelField")["extends"]("Luca.core.Field")["with"]({ - className: "luca-ui-field luca-ui-label-field", + labelField = Luca.register("Luca.components.LabelField"); + + labelField["extends"]("Luca.core.Field"); + + labelField.defines({ formatter: function(value) { value || (value = this.getValue()); return _.str.titleize(value); }, setValue: function(value) { @@ -4442,25 +4874,30 @@ } }); }).call(this); (function() { + var selectField; - _.def('Luca.fields.SelectField')["extends"]('Luca.core.Field')["with"]({ + selectField = Luca.register("Luca.fields.SelectField"); + + selectField["extends"]("Luca.core.Field"); + + selectField.triggers("after:select"); + + selectField.defines({ events: { "change select": "change_handler" }, - hooks: ["after:select"], - className: 'luca-ui-select-field luca-ui-field', template: "fields/select_field", includeBlank: true, blankValue: '', blankText: 'Select One', initialize: function(options) { this.options = options != null ? options : {}; _.extend(this, this.options); - _.extend(this, Luca.modules.Deferrable); + _.extend(this, Luca.concerns.Deferrable); _.bindAll(this, "change_handler", "populateOptions", "beforeFetch"); Luca.core.Field.prototype.initialize.apply(this, arguments); this.input_id || (this.input_id = _.uniqueId('field')); this.input_name || (this.input_name = this.name); this.label || (this.label = this.name); @@ -4584,12 +5021,17 @@ } }); }).call(this); (function() { + var textField; - _.def('Luca.fields.TextField')["extends"]('Luca.core.Field')["with"]({ + textField = Luca.register('Luca.fields.TextField'); + + textField["extends"]('Luca.core.Field'); + + textField.defines({ events: { "blur input": "blur_handler", "focus input": "focus_handler", "change input": "change_handler" }, @@ -4629,13 +5071,17 @@ } }); }).call(this); (function() { + var typeAheadField; - _.def('Luca.fields.TypeAheadField')["extends"]('Luca.fields.TextField')["with"]({ - className: 'luca-ui-field', + typeAheadField = Luca.register("Luca.fields.TypeAheadField"); + + typeAheadField["extends"]("Luca.fields.TextField"); + + typeAheadField.defines({ getSource: function() { return Luca.util.read(this.source) || []; }, matcher: function(item) { return true; @@ -4653,17 +5099,23 @@ } }); }).call(this); (function() { + var toolbar; - _.def('Luca.components.FormButtonToolbar')["extends"]('Luca.components.Toolbar')["with"]({ + toolbar = Luca.register("Luca.components.FormButtonToolbar"); + + toolbar["extends"]("Luca.components.Toolbar"); + + toolbar.defines({ className: 'luca-ui-form-toolbar form-actions', position: 'bottom', includeReset: false, render: function() { - return $(this.container).append(this.el); + $(this.container).append(this.el); + return this; }, initialize: function(options) { this.options = options != null ? options : {}; Luca.components.Toolbar.prototype.initialize.apply(this, arguments); this.components = [ @@ -4683,50 +5135,35 @@ } }); }).call(this); (function() { - var defaultToolbar; + var formView; - defaultToolbar = { - buttons: [ - { - icon: "remove-sign", - label: "Reset", - eventId: "click:reset", - className: "reset-button", - align: 'right' - }, { - icon: "ok-sign", - white: true, - label: "Save Changes", - eventId: "click:submit", - color: "success", - className: 'submit-button', - align: 'right' - } - ] - }; + formView = Luca.register("Luca.components.FormView"); - _.def("Luca.components.FormView")["extends"]('Luca.core.Container')["with"]({ + formView["extends"]("Luca.core.Container"); + + 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"); + + formView.defines({ tagName: 'form', className: 'luca-ui-form-view', - 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"], events: { "click .submit-button": "submitHandler", "click .reset-button": "resetHandler" }, toolbar: true, legend: "", bodyClassName: "form-view-body", - version: "0.9.33333333", + version: 1, initialize: function(options) { this.options = options != null ? options : {}; if (this.loadMask == null) this.loadMask = Luca.enableBootstrap; Luca.core.Container.prototype.initialize.apply(this, arguments); this.components || (this.components = this.fields); - _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars", "applyLoadMask"); + _.bindAll(this, "submitHandler", "resetHandler", "renderToolbars"); this.state || (this.state = new Backbone.Model); this.setupHooks(this.hooks); this.applyStyleClasses(); if (this.toolbar !== false && (!this.topToolbar && !this.bottomToolbar)) { if (this.toolbar === "both" || this.toolbar === "top") { @@ -4736,11 +5173,11 @@ return this.bottomToolbar = this.getDefaultToolbar(); } } }, getDefaultToolbar: function() { - return defaultToolbar; + return Luca.components.FormView.defaultFormViewToolbar; }, applyStyleClasses: function() { if (Luca.enableBootstrap) this.applyBootstrapStyleClasses(); if (this.labelAlign) this.$el.addClass("label-align-" + this.labelAlign); if (this.fieldLayoutClass) return this.$el.addClass(this.fieldLayoutClass); @@ -4950,10 +5387,30 @@ message: message })); } }); + Luca.components.FormView.defaultFormViewToolbar = { + buttons: [ + { + icon: "remove-sign", + label: "Reset", + eventId: "click:reset", + className: "reset-button", + align: 'right' + }, { + icon: "ok-sign", + white: true, + label: "Save Changes", + eventId: "click:submit", + color: "success", + className: 'submit-button', + align: 'right' + } + ] + }; + }).call(this); (function() { _.def('Luca.components.GridView').extend('Luca.components.Panel')["with"]({ bodyTemplate: "components/grid_view", @@ -4976,11 +5433,11 @@ hooks: ["before:grid:render", "before:render:header", "before:render:row", "after:grid:render", "row:double:click", "row:click", "after:collection:load"], initialize: function(options) { var _this = this; this.options = options != null ? options : {}; _.extend(this, this.options); - _.extend(this, Luca.modules.Deferrable); + _.extend(this, Luca.concerns.Deferrable); if (this.loadMask == null) this.loadMask = Luca.enableBootstrap; if (this.loadMask === true) { this.loadMaskEl || (this.loadMaskEl = ".luca-ui-g-view-body"); } Luca.components.Panel.prototype.initialize.apply(this, arguments); @@ -5202,17 +5659,17 @@ bodyTemplate: "components/load_mask" }); }).call(this); (function() { - var bubbleCollectionEvents, multiView, propagateCollectionComponents, validateComponent; + var multiView, propagateCollectionComponents, validateComponent; - multiView = Luca.define("Luca.components.MultiCollectionView"); + multiView = Luca.register("Luca.components.MultiCollectionView"); multiView["extends"]("Luca.containers.CardView"); - multiView.behavesAs("LoadMaskable", "Filterable", "Paginatable"); + multiView.mixesIn("LoadMaskable", "Filterable", "Paginatable"); multiView.triggers("before:refresh", "after:refresh", "refresh", "empty:results"); multiView.defaultsTo({ version: 1, @@ -5228,55 +5685,77 @@ _ref = this.components; for (_i = 0, _len = _ref.length; _i < _len; _i++) { view = _ref[_i]; validateComponent(view); } - this.on("collection:change", this.refresh, this); + this.on("refresh", this.refresh, this); this.on("after:card:switch", this.refresh, this); - this.on("before:components", propagateCollectionComponents, this); - this.on("after:components", bubbleCollectionEvents, this); + this.on("after:components", propagateCollectionComponents, this); + this.debug("multi collection , proto initialize"); return Luca.containers.CardView.prototype.initialize.apply(this, arguments); }, + relayAfterRefresh: function(models, query, options) { + return this.trigger("after:refresh", models, query, options); + }, refresh: function() { var _ref; return (_ref = this.activeComponent()) != null ? _ref.trigger("refresh") : void 0; }, - getQuery: Luca.components.CollectionView.prototype.getQuery, - getQueryOptions: Luca.components.CollectionView.prototype.getQueryOptions, - getCollection: Luca.components.CollectionView.prototype.getCollection - }); - - bubbleCollectionEvents = function() { - var container; - container = this; - return container.eachComponent(function(component) { - var eventId, _i, _len, _ref, _results; - _ref = ['refresh', 'before:refresh', 'after:refresh', 'empty:results']; - _results = []; + getCollection: function() { + return this.collection; + }, + applyQuery: function(query, queryOptions) { + if (query == null) query = {}; + if (queryOptions == null) queryOptions = {}; + this.query = query; + this.queryOptions = queryOptions; + return this; + }, + getQuery: function() { + var query, querySource, _i, _len, _ref; + this.debug("Get Query"); + query = this.query || (this.query = {}); + _ref = this.querySources; for (_i = 0, _len = _ref.length; _i < _len; _i++) { - eventId = _ref[_i]; - _results.push(component.on(eventId, function() { - if (component === container.activeComponent()) { - return container.trigger(eventId); - } - })); + querySource = _ref[_i]; + query = _.extend(query, querySource() || {}); } - return _results; - }); - }; + return query; + }, + getQueryOptions: function() { + var optionSource, options, _i, _len, _ref; + this.debug("Get Query Options"); + options = this.queryOptions || (this.queryOptions = {}); + _ref = this.optionsSources; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + optionSource = _ref[_i]; + options = _.extend(options, optionSource() || {}); + } + return options; + } + }); propagateCollectionComponents = function() { - var component, container, _i, _len, _ref, _results; + var component, container, _i, _len, _ref, _results, + _this = this; container = this; _ref = this.components; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { component = _ref[_i]; + component.on("after:refresh", function(models, query, options) { + _this.debug("collection member after refresh"); + return _this.trigger("after:refresh", models, query, options); + }); _results.push(_.extend(component, { - collection: (typeof container.getCollection === "function" ? container.getCollection() : void 0) || this.collection, - getQuery: container.getQuery, - getQueryOptions: container.getQueryOptions + collection: container.getCollection(), + getQuery: function() { + return container.getQuery.call(container); + }, + getQueryOptions: function() { + return container.getQueryOptions.call(container); + } })); } return _results; }; @@ -5339,12 +5818,16 @@ "click a[data-page-number]": "selectPage", "click a.next": "nextPage", "click a.prev": "previousPage" }, afterInitialize: function() { - _.bindAll(this, "refresh"); - return this.state.on("change", this.refresh, this); + var _ref, + _this = this; + _.bindAll(this, "updateWithPageCount"); + return (_ref = this.state) != null ? _ref.on("change", function(state, numberOfPages) { + return _this.updateWithPageCount(state.get('numberOfPages')); + }) : void 0; }, limit: function() { var _ref; return parseInt(this.state.get('limit') || ((_ref = this.collection) != null ? _ref.length : void 0)); }, @@ -5393,20 +5876,26 @@ return this.$('a.page.next'); }, pageButtons: function() { return this.$('a[data-page-number]', this.pageButtonContainer()); }, - refresh: function() { - var button, page, _ref; + updateWithPageCount: function(pageCount, models) { + var modelCount, + _this = this; + this.pageCount = pageCount; + if (models == null) models = []; + modelCount = models.length; this.pageButtonContainer().empty(); - for (page = 1, _ref = this.totalPages(); 1 <= _ref ? page <= _ref : page >= _ref; 1 <= _ref ? page++ : page--) { - button = this.make("a", { + _(this.pageCount).times(function(index) { + var button, page; + page = index + 1; + button = _this.make("a", { "data-page-number": page, "class": "page" }, page); - this.pageButtonContainer().append(button); - } + return _this.pageButtonContainer().append(button); + }); this.toggleNavigationButtons(); this.selectActivePageButton(); return this; }, toggleNavigationButtons: function() { @@ -5421,10 +5910,10 @@ }, activePageButton: function() { return this.pageButtons().filter("[data-page-number='" + (this.page()) + "']"); }, totalPages: function() { - return parseInt(Math.ceil(this.totalItems() / this.itemsPerPage())); + return this.pageCount; }, totalItems: function() { var _ref; return parseInt(((_ref = this.collection) != null ? _ref.length : void 0) || 0); },