// Generated by CoffeeScript 1.10.0 /* Spine.js MVC library Released under the MIT License */ (function() { var $, Controller, Events, Log, Model, Module, Spine, createObject, makeArray, moduleKeywords, slice = [].slice, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, extend = 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; }, hasProp = {}.hasOwnProperty, bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; Events = { bind: function(ev, callback) { var base, evs, j, len, name; evs = ev.split(' '); if (!this.hasOwnProperty('_callbacks')) { this._callbacks || (this._callbacks = {}); } for (j = 0, len = evs.length; j < len; j++) { name = evs[j]; (base = this._callbacks)[name] || (base[name] = []); this._callbacks[name].push(callback); } return this; }, one: function(ev, callback) { var handler; return this.bind(ev, handler = function() { this.unbind(ev, handler); return callback.apply(this, arguments); }); }, trigger: function() { var args, callback, ev, j, len, list, ref; args = 1 <= arguments.length ? slice.call(arguments, 0) : []; ev = args.shift(); list = (ref = this._callbacks) != null ? ref[ev] : void 0; if (!list) { return; } for (j = 0, len = list.length; j < len; j++) { callback = list[j]; if (callback.apply(this, args) === false) { break; } } return true; }, listenTo: function(obj, ev, callback) { obj.bind(ev, callback); this.listeningTo || (this.listeningTo = []); this.listeningTo.push({ obj: obj, ev: ev, callback: callback }); return this; }, listenToOnce: function(obj, ev, callback) { var handler, listeningToOnce; listeningToOnce = this.listeningToOnce || (this.listeningToOnce = []); obj.bind(ev, handler = function() { var i, idx, j, len, lt; idx = -1; for (i = j = 0, len = listeningToOnce.length; j < len; i = ++j) { lt = listeningToOnce[i]; if (lt.obj === obj) { if (lt.ev === ev && lt.callback === handler) { idx = i; } } } obj.unbind(ev, handler); if (idx !== -1) { listeningToOnce.splice(idx, 1); } return callback.apply(this, arguments); }); listeningToOnce.push({ obj: obj, ev: ev, callback: handler }); return this; }, stopListening: function(obj, events, callback) { var e, ev, evts, idx, j, k, l, len, len1, len2, len3, listeningTo, lt, m, n, ref, ref1, ref2; if (arguments.length === 0) { ref = [this.listeningTo, this.listeningToOnce]; for (j = 0, len = ref.length; j < len; j++) { listeningTo = ref[j]; if (!(listeningTo != null ? listeningTo.length : void 0)) { continue; } for (k = 0, len1 = listeningTo.length; k < len1; k++) { lt = listeningTo[k]; lt.obj.unbind(lt.ev, lt.callback); } } this.listeningTo = void 0; this.listeningToOnce = void 0; } else if (obj) { events = events ? events.split(' ') : [void 0]; ref1 = [this.listeningTo, this.listeningToOnce]; for (l = 0, len2 = ref1.length; l < len2; l++) { listeningTo = ref1[l]; if (!listeningTo) { continue; } for (m = 0, len3 = events.length; m < len3; m++) { ev = events[m]; for (idx = n = ref2 = listeningTo.length - 1; ref2 <= 0 ? n <= 0 : n >= 0; idx = ref2 <= 0 ? ++n : --n) { lt = listeningTo[idx]; if (lt.obj !== obj) { continue; } if (callback && lt.callback !== callback) { continue; } if ((!ev) || (ev === lt.ev)) { lt.obj.unbind(lt.ev, lt.callback); if (idx !== -1) { listeningTo.splice(idx, 1); } } else if (ev) { evts = lt.ev.split(' '); if (indexOf.call(evts, ev) >= 0) { evts = (function() { var len4, p, results; results = []; for (p = 0, len4 = evts.length; p < len4; p++) { e = evts[p]; if (e !== ev) { results.push(e); } } return results; })(); lt.ev = $.trim(evts.join(' ')); lt.obj.unbind(ev, lt.callback); } } } } } } return this; }, unbind: function(ev, callback) { var cb, evs, i, j, k, len, len1, list, name, ref; if (arguments.length === 0) { this._callbacks = {}; return this; } if (!ev) { return this; } evs = ev.split(' '); for (j = 0, len = evs.length; j < len; j++) { name = evs[j]; list = (ref = this._callbacks) != null ? ref[name] : void 0; if (!list) { continue; } if (!callback) { delete this._callbacks[name]; continue; } for (i = k = 0, len1 = list.length; k < len1; i = ++k) { cb = list[i]; if (!(cb === callback)) { continue; } list = list.slice(); list.splice(i, 1); this._callbacks[name] = list; break; } } return this; } }; Events.on = Events.bind; Events.off = Events.unbind; Log = { trace: true, logPrefix: '(App)', log: function() { var args; args = 1 <= arguments.length ? slice.call(arguments, 0) : []; if (!this.trace) { return; } if (this.logPrefix) { args.unshift(this.logPrefix); } if (typeof console !== "undefined" && console !== null) { if (typeof console.log === "function") { console.log.apply(console, args); } } return this; } }; moduleKeywords = ['included', 'extended']; Module = (function() { Module.include = function(obj) { var key, ref, value; if (!obj) { throw new Error('include(obj) requires obj'); } for (key in obj) { value = obj[key]; if (indexOf.call(moduleKeywords, key) < 0) { this.prototype[key] = value; } } if ((ref = obj.included) != null) { ref.apply(this); } return this; }; Module.extend = function(obj) { var key, ref, value; if (!obj) { throw new Error('extend(obj) requires obj'); } for (key in obj) { value = obj[key]; if (indexOf.call(moduleKeywords, key) < 0) { this[key] = value; } } if ((ref = obj.extended) != null) { ref.apply(this); } return this; }; Module.proxy = function(func) { return (function(_this) { return function() { return func.apply(_this, arguments); }; })(this); }; Module.prototype.proxy = function(func) { return (function(_this) { return function() { return func.apply(_this, arguments); }; })(this); }; function Module() { if (typeof this.init === "function") { this.init.apply(this, arguments); } } return Module; })(); Model = (function(superClass) { extend(Model, superClass); Model.extend(Events); Model.include(Events); Model.records = []; Model.irecords = {}; Model.attributes = []; Model.configure = function() { var attributes, name; name = arguments[0], attributes = 2 <= arguments.length ? slice.call(arguments, 1) : []; this.className = name; this.deleteAll(); if (attributes.length) { this.attributes = attributes; } this.attributes && (this.attributes = makeArray(this.attributes)); this.attributes || (this.attributes = []); this.unbind(); return this; }; Model.toString = function() { return this.className + "(" + (this.attributes.join(", ")) + ")"; }; Model.find = function(id, notFound) { var ref; if (notFound == null) { notFound = this.notFound; } return ((ref = this.irecords[id]) != null ? ref.clone() : void 0) || (typeof notFound === "function" ? notFound(id) : void 0); }; Model.findAll = function(ids, notFound) { var id, j, len, results; results = []; for (j = 0, len = ids.length; j < len; j++) { id = ids[j]; if (this.find(id, notFound)) { results.push(this.find(id)); } } return results; }; Model.notFound = function(id) { return null; }; Model.exists = function(id) { return Boolean(this.irecords[id]); }; Model.addRecord = function(record, idx) { var root; if (root = this.irecords[record.id || record.cid]) { root.refresh(record); } else { record.id || (record.id = record.cid); this.irecords[record.id] = this.irecords[record.cid] = record; if (idx !== void 0) { this.records.splice(idx, 0, record); } else { this.records.push(record); } } return record; }; Model.refresh = function(values, options) { var j, len, record, records, result; if (options == null) { options = {}; } if (options.clear) { this.deleteAll(); } records = this.fromJSON(values); if (!Array.isArray(records)) { records = [records]; } for (j = 0, len = records.length; j < len; j++) { record = records[j]; this.addRecord(record); } this.sort(); result = this.cloneArray(records); this.trigger('refresh', result, options); return result; }; Model.select = function(callback) { var j, len, record, ref, results; ref = this.records; results = []; for (j = 0, len = ref.length; j < len; j++) { record = ref[j]; if (callback(record)) { results.push(record.clone()); } } return results; }; Model.findByAttribute = function(name, value) { var j, len, record, ref; ref = this.records; for (j = 0, len = ref.length; j < len; j++) { record = ref[j]; if (record[name] === value) { return record.clone(); } } return null; }; Model.findAllByAttribute = function(name, value) { return this.select(function(item) { return item[name] === value; }); }; Model.each = function(callback) { var j, len, record, ref, results; ref = this.records; results = []; for (j = 0, len = ref.length; j < len; j++) { record = ref[j]; results.push(callback(record.clone())); } return results; }; Model.all = function() { return this.cloneArray(this.records); }; Model.slice = function(begin, end) { if (begin == null) { begin = 0; } return this.cloneArray(this.records.slice(begin, end)); }; Model.first = function(end) { var ref; if (end == null) { end = 1; } if (end > 1) { return this.cloneArray(this.records.slice(0, end)); } else { return (ref = this.records[0]) != null ? ref.clone() : void 0; } }; Model.last = function(begin) { var ref; if (typeof begin === 'number') { return this.cloneArray(this.records.slice(-begin)); } else { return (ref = this.records[this.records.length - 1]) != null ? ref.clone() : void 0; } }; Model.count = function() { return this.records.length; }; Model.deleteAll = function() { this.records = []; return this.irecords = {}; }; Model.destroyAll = function(options) { var j, len, record, ref, results; ref = this.records; results = []; for (j = 0, len = ref.length; j < len; j++) { record = ref[j]; results.push(record.destroy(options)); } return results; }; Model.update = function(id, atts, options) { return this.find(id).updateAttributes(atts, options); }; Model.create = function(atts, options) { var record; record = new this(atts); return record.save(options); }; Model.destroy = function(id, options) { var ref; return (ref = this.find(id)) != null ? ref.destroy(options) : void 0; }; Model.change = function(callbackOrParams) { if (typeof callbackOrParams === 'function') { return this.bind('change', callbackOrParams); } else { return this.trigger.apply(this, ['change'].concat(slice.call(arguments))); } }; Model.fetch = function(callbackOrParams) { if (typeof callbackOrParams === 'function') { return this.bind('fetch', callbackOrParams); } else { return this.trigger.apply(this, ['fetch'].concat(slice.call(arguments))); } }; Model.toJSON = function() { return this.records; }; Model.beforeFromJSON = function(objects) { return objects; }; Model.fromJSON = function(objects) { var j, len, results, value; if (!objects) { return; } if (typeof objects === 'string') { objects = JSON.parse(objects); } objects = this.beforeFromJSON(objects); if (Array.isArray(objects)) { results = []; for (j = 0, len = objects.length; j < len; j++) { value = objects[j]; if (value instanceof this) { results.push(value); } else { results.push(new this(value)); } } return results; } else { if (objects instanceof this) { return objects; } return new this(objects); } }; Model.fromForm = function() { var ref; return (ref = new this).fromForm.apply(ref, arguments); }; Model.sort = function() { if (this.comparator) { this.records.sort(this.comparator); } return this; }; Model.cloneArray = function(array) { var j, len, results, value; results = []; for (j = 0, len = array.length; j < len; j++) { value = array[j]; results.push(value.clone()); } return results; }; Model.idCounter = 0; Model.uid = function(prefix) { var uid; if (prefix == null) { prefix = ''; } uid = prefix + this.idCounter++; if (this.exists(uid)) { uid = this.uid(prefix); } return uid; }; function Model(atts) { Model.__super__.constructor.apply(this, arguments); if ((this.constructor.uuid != null) && typeof this.constructor.uuid === 'function') { this.cid = this.constructor.uuid(); if (!this.id) { this.id = this.cid; } } else { this.cid = (atts != null ? atts.cid : void 0) || this.constructor.uid('c-'); } if (atts) { this.load(atts); } } Model.prototype.isNew = function() { return !this.exists(); }; Model.prototype.isValid = function() { return !this.validate(); }; Model.prototype.validate = function() {}; Model.prototype.load = function(atts) { var key, value; if (atts.id) { this.id = atts.id; } for (key in atts) { value = atts[key]; if (key === '_callbacks') { continue; } if (typeof this[key] === 'function') { if (typeof value === 'function') { continue; } this[key](value); } else { this[key] = value; } } return this; }; Model.prototype.attributes = function() { var j, key, len, ref, result; result = {}; ref = this.constructor.attributes; for (j = 0, len = ref.length; j < len; j++) { key = ref[j]; if (key in this) { if (typeof this[key] === 'function') { result[key] = this[key](); } else { result[key] = this[key]; } } } if (this.id) { result.id = this.id; } return result; }; Model.prototype.eql = function(rec) { return rec && rec.constructor === this.constructor && ((rec.cid === this.cid) || (rec.id && rec.id === this.id)); }; Model.prototype.save = function(options) { var error, record; if (options == null) { options = {}; } if (options.validate !== false) { error = this.validate(); if (error) { this.trigger('error', this, error); return false; } } this.trigger('beforeSave', this, options); record = this.isNew() ? this.create(options) : this.update(options); this.stripCloneAttrs(); this.trigger('save', record, options); return record; }; Model.prototype.stripCloneAttrs = function() { var key, value; if (this.hasOwnProperty('cid')) { return; } for (key in this) { if (!hasProp.call(this, key)) continue; value = this[key]; if (indexOf.call(this.constructor.attributes, key) >= 0) { delete this[key]; } } return this; }; Model.prototype.updateAttribute = function(name, value, options) { var atts; atts = {}; atts[name] = value; return this.updateAttributes(atts, options); }; Model.prototype.updateAttributes = function(atts, options) { this.load(atts); return this.save(options); }; Model.prototype.changeID = function(id) { var records; if (id === this.id) { return; } records = this.constructor.irecords; records[id] = records[this.id]; if (this.cid !== this.id) { delete records[this.id]; } return this.id = id; }; Model.prototype.remove = function(options) { var i, j, len, record, records; if (options == null) { options = {}; } records = this.constructor.records.slice(0); for (i = j = 0, len = records.length; j < len; i = ++j) { record = records[i]; if (!(this.eql(record))) { continue; } records.splice(i, 1); break; } this.constructor.records = records; if (options.clear) { delete this.constructor.irecords[this.id]; return delete this.constructor.irecords[this.cid]; } }; Model.prototype.destroy = function(options) { if (options == null) { options = {}; } if (options.clear == null) { options.clear = true; } this.trigger('beforeDestroy', this, options); this.remove(options); this.destroyed = true; this.trigger('destroy', this, options); this.trigger('change', this, 'destroy', options); if (this.listeningTo) { this.stopListening(); } this.unbind(); return this; }; Model.prototype.dup = function(newRecord) { var atts, record; if (newRecord == null) { newRecord = true; } atts = this.attributes(); if (newRecord) { delete atts.id; } else { atts.cid = this.cid; } record = new this.constructor(atts); if (!newRecord) { this._callbacks && (record._callbacks = this._callbacks); } return record; }; Model.prototype.clone = function() { return createObject(this); }; Model.prototype.reload = function() { var original; if (this.isNew()) { return this; } original = this.constructor.find(this.id); this.load(original.attributes()); return original; }; Model.prototype.refresh = function(atts) { atts = this.constructor.fromJSON(atts); if (atts.id && this.id !== atts.id) { this.changeID(atts.id); } this.constructor.irecords[this.id].load(atts); this.trigger('refresh', this); this.trigger('change', this, 'refresh'); return this; }; Model.prototype.toJSON = function() { return this.attributes(); }; Model.prototype.toString = function() { return "<" + this.constructor.className + " (" + (JSON.stringify(this)) + ")>"; }; Model.prototype.fromForm = function(form) { var checkbox, j, k, key, l, len, len1, len2, name, name1, ref, ref1, ref2, result; result = {}; ref = $(form).find('[type=checkbox]:not([value])'); for (j = 0, len = ref.length; j < len; j++) { checkbox = ref[j]; result[checkbox.name] = $(checkbox).prop('checked'); } ref1 = $(form).find('[type=checkbox][name$="[]"]'); for (k = 0, len1 = ref1.length; k < len1; k++) { checkbox = ref1[k]; name = checkbox.name.replace(/\[\]$/, ''); result[name] || (result[name] = []); if ($(checkbox).prop('checked')) { result[name].push(checkbox.value); } } ref2 = $(form).serializeArray(); for (l = 0, len2 = ref2.length; l < len2; l++) { key = ref2[l]; result[name1 = key.name] || (result[name1] = key.value); } return this.load(result); }; Model.prototype.exists = function() { return this.constructor.exists(this.id); }; Model.prototype.update = function(options) { var clone, records; this.trigger('beforeUpdate', this, options); records = this.constructor.irecords; records[this.id].load(this.attributes()); this.constructor.sort(); clone = records[this.id].clone(); clone.trigger('update', clone, options); clone.trigger('change', clone, 'update', options); return clone; }; Model.prototype.create = function(options) { var clone, record; this.trigger('beforeCreate', this, options); this.id || (this.id = this.cid); record = this.dup(false); this.constructor.addRecord(record, options.idx); this.constructor.sort(); clone = record.clone(); clone.trigger('create', clone, options); clone.trigger('change', clone, 'create', options); return clone; }; Model.prototype.bind = function() { var record; record = this.constructor.irecords[this.id] || this; return Events.bind.apply(record, arguments); }; Model.prototype.one = function() { var record; record = this.constructor.irecords[this.id] || this; return Events.one.apply(record, arguments); }; Model.prototype.unbind = function() { var record; record = this.constructor.irecords[this.id] || this; return Events.unbind.apply(record, arguments); }; Model.prototype.trigger = function() { var ref; Events.trigger.apply(this, arguments); if (arguments[0] === 'refresh') { return true; } return (ref = this.constructor).trigger.apply(ref, arguments); }; return Model; })(Module); Model.prototype.on = Model.prototype.bind; Model.prototype.off = Model.prototype.unbind; Controller = (function(superClass) { extend(Controller, superClass); Controller.include(Events); Controller.include(Log); Controller.prototype.eventSplitter = /^(\S+)\s*(.*)$/; Controller.prototype.tag = 'div'; function Controller(options) { this.release = bind(this.release, this); var context, key, parent_prototype, ref, value; this.options = options; ref = this.options; for (key in ref) { value = ref[key]; this[key] = value; } if (!this.el) { this.el = document.createElement(this.tag); } this.el = $(this.el); if (this.className) { this.el.addClass(this.className); } if (this.attributes) { this.el.attr(this.attributes); } if (!this.events) { this.events = this.constructor.events; } if (!this.elements) { this.elements = this.constructor.elements; } context = this; while (parent_prototype = context.constructor.__super__) { if (parent_prototype.events) { this.events = $.extend({}, parent_prototype.events, this.events); } if (parent_prototype.elements) { this.elements = $.extend({}, parent_prototype.elements, this.elements); } context = parent_prototype; } if (this.events) { this.delegateEvents(this.events); } if (this.elements) { this.refreshElements(); } Controller.__super__.constructor.apply(this, arguments); } Controller.prototype.release = function() { this.trigger('release', this); this.el.remove(); this.unbind(); return this.stopListening(); }; Controller.prototype.$ = function(selector) { return this.el.find(selector); }; Controller.prototype.delegateEvents = function(events) { var eventName, key, match, method, results, selector; results = []; for (key in events) { method = events[key]; if (typeof method === 'function') { method = (function(_this) { return function(method) { return function() { method.apply(_this, arguments); return true; }; }; })(this)(method); } else { if (!this[method]) { throw new Error(method + " doesn't exist"); } method = (function(_this) { return function(method) { return function() { _this[method].apply(_this, arguments); return true; }; }; })(this)(method); } match = key.match(this.eventSplitter); eventName = match[1]; selector = match[2]; if (selector === '') { results.push(this.el.bind(eventName, method)); } else { results.push(this.el.on(eventName, selector, method)); } } return results; }; Controller.prototype.refreshElements = function() { var key, ref, results, value; ref = this.elements; results = []; for (key in ref) { value = ref[key]; results.push(this[value] = this.$(key)); } return results; }; Controller.prototype.delay = function(func, timeout) { return setTimeout(this.proxy(func), timeout || 0); }; Controller.prototype.html = function(element) { this.el.html(element.el || element); this.refreshElements(); return this.el; }; Controller.prototype.append = function() { var e, elements, ref; elements = 1 <= arguments.length ? slice.call(arguments, 0) : []; elements = (function() { var j, len, results; results = []; for (j = 0, len = elements.length; j < len; j++) { e = elements[j]; results.push(e.el || e); } return results; })(); (ref = this.el).append.apply(ref, elements); this.refreshElements(); return this.el; }; Controller.prototype.appendTo = function(element) { this.el.appendTo(element.el || element); this.refreshElements(); return this.el; }; Controller.prototype.prepend = function() { var e, elements, ref; elements = 1 <= arguments.length ? slice.call(arguments, 0) : []; elements = (function() { var j, len, results; results = []; for (j = 0, len = elements.length; j < len; j++) { e = elements[j]; results.push(e.el || e); } return results; })(); (ref = this.el).prepend.apply(ref, elements); this.refreshElements(); return this.el; }; Controller.prototype.replace = function(element) { var previous, ref, ref1; element = element.el || element; if (typeof element === "string") { element = $.trim(element); } ref1 = [this.el, $(((ref = $.parseHTML(element)) != null ? ref[0] : void 0) || element)], previous = ref1[0], this.el = ref1[1]; previous.replaceWith(this.el); this.delegateEvents(this.events); this.refreshElements(); return this.el; }; return Controller; })(Module); $ = (typeof window !== "undefined" && window !== null ? window.jQuery : void 0) || (typeof window !== "undefined" && window !== null ? window.Zepto : void 0) || function(element) { return element; }; createObject = Object.create || function(o) { var Func; Func = function() {}; Func.prototype = o; return new Func(); }; makeArray = function(args) { return Array.prototype.slice.call(args, 0); }; Spine = this.Spine = {}; if (typeof module !== "undefined" && module !== null) { module.exports = Spine; } Spine.version = '1.6.2'; Spine.$ = $; Spine.Events = Events; Spine.Log = Log; Spine.Module = Module; Spine.Controller = Controller; Spine.Model = Model; Module.extend.call(Spine, Events); Module.create = Module.sub = Controller.create = Controller.sub = Model.sub = function(instances, statics) { var Result; Result = (function(superClass) { extend(Result, superClass); function Result() { return Result.__super__.constructor.apply(this, arguments); } return Result; })(this); if (instances) { Result.include(instances); } if (statics) { Result.extend(statics); } if (typeof Result.unbind === "function") { Result.unbind(); } return Result; }; Model.setup = function(name, attributes) { var Instance; if (attributes == null) { attributes = []; } Instance = (function(superClass) { extend(Instance, superClass); function Instance() { return Instance.__super__.constructor.apply(this, arguments); } return Instance; })(this); Instance.configure.apply(Instance, [name].concat(slice.call(attributes))); return Instance; }; Spine.Class = Module; }).call(this); //# sourceMappingURL=spine.js.map