app/assets/javascripts/spine.js in spine-rails-0.0.9 vs app/assets/javascripts/spine.js in spine-rails-0.1.0

- old
+ new

@@ -1,20 +1,13 @@ (function() { - var $, Controller, Events, Log, Model, Module, Spine, guid, isArray, isBlank, makeArray, moduleKeywords; - var __slice = Array.prototype.slice, __indexOf = Array.prototype.indexOf || function(item) { - for (var i = 0, l = this.length; i < l; i++) { - if (this[i] === item) return i; - } - return -1; - }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __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; - }; + var $, Controller, Events, Log, Model, Module, Spine, isArray, isBlank, makeArray, moduleKeywords, + __slice = Array.prototype.slice, + __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + __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; }, + __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + Events = { bind: function(ev, callback) { var calls, evs, name, _i, _len; evs = ev.split(' '); calls = this.hasOwnProperty('_callbacks') && this._callbacks || (this._callbacks = {}); @@ -34,291 +27,298 @@ trigger: function() { var args, callback, ev, list, _i, _len, _ref; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; ev = args.shift(); list = this.hasOwnProperty('_callbacks') && ((_ref = this._callbacks) != null ? _ref[ev] : void 0); - if (!list) { - return false; - } + if (!list) return; for (_i = 0, _len = list.length; _i < _len; _i++) { callback = list[_i]; - if (callback.apply(this, args) === false) { - break; - } + if (callback.apply(this, args) === false) break; } return true; }, unbind: function(ev, callback) { var cb, i, list, _len, _ref; if (!ev) { this._callbacks = {}; return this; } list = (_ref = this._callbacks) != null ? _ref[ev] : void 0; - if (!list) { - return this; - } + if (!list) return this; if (!callback) { delete this._callbacks[ev]; return this; } for (i = 0, _len = list.length; i < _len; i++) { cb = list[i]; - if (cb === callback) { - list = list.slice(); - list.splice(i, 1); - this._callbacks[ev] = list; - break; - } + if (!(cb === callback)) continue; + list = list.slice(); + list.splice(i, 1); + this._callbacks[ev] = list; + break; } return this; } }; + Log = { trace: true, logPrefix: '(App)', log: function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - if (!this.trace) { - return; + 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); } - if (typeof console === 'undefined') { - return; - } - if (this.logPrefix) { - args.unshift(this.logPrefix); - } - console.log.apply(console, args); return this; } }; + moduleKeywords = ['included', 'extended']; + Module = (function() { + Module.include = function(obj) { - var included, key, value; - if (!obj) { - throw 'include(obj) requires obj'; - } + var key, value, _ref; + if (!obj) throw 'include(obj) requires obj'; for (key in obj) { value = obj[key]; - if (__indexOf.call(moduleKeywords, key) < 0) { - this.prototype[key] = value; - } + if (__indexOf.call(moduleKeywords, key) < 0) this.prototype[key] = value; } - included = obj.included; - if (included) { - included.apply(this); - } + if ((_ref = obj.included) != null) _ref.apply(this); return this; }; + Module.extend = function(obj) { - var extended, key, value; - if (!obj) { - throw 'extend(obj) requires obj'; - } + var key, value, _ref; + if (!obj) throw 'extend(obj) requires obj'; for (key in obj) { value = obj[key]; - if (__indexOf.call(moduleKeywords, key) < 0) { - this[key] = value; - } + if (__indexOf.call(moduleKeywords, key) < 0) this[key] = value; } - extended = obj.extended; - if (extended) { - extended.apply(this); - } + if ((_ref = obj.extended) != null) _ref.apply(this); return this; }; + Module.proxy = function(func) { - return __bind(function() { - return func.apply(this, arguments); - }, this); + var _this = this; + return function() { + return func.apply(_this, arguments); + }; }; + Module.prototype.proxy = function(func) { - return __bind(function() { - return func.apply(this, arguments); - }, this); + var _this = this; + return function() { + return func.apply(_this, arguments); + }; }; + function Module() { - if (typeof this.init === "function") { - this.init.apply(this, arguments); - } + if (typeof this.init === "function") this.init.apply(this, arguments); } + return Module; + })(); - Model = (function() { - __extends(Model, Module); + + Model = (function(_super) { + + __extends(Model, _super); + Model.extend(Events); + Model.records = {}; + + Model.crecords = {}; + Model.attributes = []; + Model.configure = function() { var attributes, name; name = arguments[0], attributes = 2 <= arguments.length ? __slice.call(arguments, 1) : []; this.className = name; this.records = {}; - if (attributes.length) { - this.attributes = attributes; - } + this.crecords = {}; + 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) { var record; record = this.records[id]; - if (!record) { - throw 'Unknown record'; - } + if (!record && ("" + id).match(/c-\d+/)) return this.findCID(id); + if (!record) throw 'Unknown record'; return record.clone(); }; + + Model.findCID = function(cid) { + var record; + record = this.crecords[cid]; + if (!record) throw 'Unknown record'; + return record.clone(); + }; + Model.exists = function(id) { try { return this.find(id); } catch (e) { return false; } }; + Model.refresh = function(values, options) { var record, records, _i, _len; - if (options == null) { - options = {}; - } + if (options == null) options = {}; if (options.clear) { this.records = {}; + this.crecords = {}; } records = this.fromJSON(values); - if (!isArray(records)) { - records = [records]; - } + if (!isArray(records)) records = [records]; for (_i = 0, _len = records.length; _i < _len; _i++) { record = records[_i]; - record.newRecord = false; - record.id || (record.id = guid()); + record.id || (record.id = record.cid); this.records[record.id] = record; + this.crecords[record.cid] = record; } - this.trigger('refresh', !options.clear && records); + this.trigger('refresh', !options.clear && this.cloneArray(records)); return this; }; + Model.select = function(callback) { var id, record, result; result = (function() { var _ref, _results; _ref = this.records; _results = []; for (id in _ref) { record = _ref[id]; - if (callback(record)) { - _results.push(record); - } + if (callback(record)) _results.push(record); } return _results; }).call(this); return this.cloneArray(result); }; + Model.findByAttribute = function(name, value) { var id, record, _ref; _ref = this.records; for (id in _ref) { record = _ref[id]; - if (record[name] === value) { - return record.clone(); - } + 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 key, value, _ref, _results; _ref = this.records; _results = []; for (key in _ref) { value = _ref[key]; _results.push(callback(value.clone())); } return _results; }; + Model.all = function() { return this.cloneArray(this.recordsValues()); }; + Model.first = function() { var record; record = this.recordsValues()[0]; return record != null ? record.clone() : void 0; }; + Model.last = function() { var record, values; values = this.recordsValues(); record = values[values.length - 1]; return record != null ? record.clone() : void 0; }; + Model.count = function() { return this.recordsValues().length; }; + Model.deleteAll = function() { var key, value, _ref, _results; _ref = this.records; _results = []; for (key in _ref) { value = _ref[key]; _results.push(delete this.records[key]); } return _results; }; + Model.destroyAll = function() { var key, value, _ref, _results; _ref = this.records; _results = []; for (key in _ref) { value = _ref[key]; _results.push(this.records[key].destroy()); } return _results; }; - Model.update = function(id, atts) { - return this.find(id).updateAttributes(atts); + + Model.update = function(id, atts, options) { + return this.find(id).updateAttributes(atts, options); }; - Model.create = function(atts) { + + Model.create = function(atts, options) { var record; record = new this(atts); - return record.save(); + return record.save(options); }; - Model.destroy = function(id) { - return this.find(id).destroy(); + + Model.destroy = function(id, options) { + return this.find(id).destroy(options); }; + Model.change = function(callbackOrParams) { if (typeof callbackOrParams === 'function') { return this.bind('change', callbackOrParams); } else { return this.trigger('change', callbackOrParams); } }; + Model.fetch = function(callbackOrParams) { if (typeof callbackOrParams === 'function') { return this.bind('fetch', callbackOrParams); } else { return this.trigger('fetch', callbackOrParams); } }; + Model.toJSON = function() { return this.recordsValues(); }; + Model.fromJSON = function(objects) { var value, _i, _len, _results; - if (!objects) { - return; - } - if (typeof objects === 'string') { - objects = JSON.parse(objects); - } + if (!objects) return; + if (typeof objects === 'string') objects = JSON.parse(objects); if (isArray(objects)) { _results = []; for (_i = 0, _len = objects.length; _i < _len; _i++) { value = objects[_i]; _results.push(new this(value)); @@ -326,48 +326,59 @@ return _results; } else { return new this(objects); } }; + Model.fromForm = function() { var _ref; return (_ref = new this).fromForm.apply(_ref, arguments); }; + Model.recordsValues = function() { var key, result, value, _ref; result = []; _ref = this.records; for (key in _ref) { value = _ref[key]; result.push(value); } return result; }; + Model.cloneArray = function(array) { var value, _i, _len, _results; _results = []; for (_i = 0, _len = array.length; _i < _len; _i++) { value = array[_i]; _results.push(value.clone()); } return _results; }; - Model.prototype.newRecord = true; + + Model.idCounter = 0; + + Model.uid = function() { + return this.idCounter++; + }; + function Model(atts) { Model.__super__.constructor.apply(this, arguments); - this.ids = []; - if (atts) { - this.load(atts); - } + if (atts) this.load(atts); + this.cid || (this.cid = 'c-' + this.constructor.uid()); } + Model.prototype.isNew = function() { - return this.newRecord; + return !this.exists(); }; + Model.prototype.isValid = function() { return !this.validate(); }; + Model.prototype.validate = function() {}; + Model.prototype.load = function(atts) { var key, value; for (key in atts) { value = atts[key]; if (typeof this[key] === 'function') { @@ -376,10 +387,11 @@ this[key] = value; } } return this; }; + Model.prototype.attributes = function() { var key, result, _i, _len, _ref; result = {}; _ref = this.constructor.attributes; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -390,231 +402,261 @@ } else { result[key] = this[key]; } } } - if (this.id) { - result.id = this.id; - } + if (this.id) result.id = this.id; return result; }; + Model.prototype.eql = function(rec) { - var _ref, _ref2; - return rec && rec.constructor === this.constructor && (rec.id === this.id || (_ref = this.id, __indexOf.call(rec.ids, _ref) >= 0) || (_ref2 = rec.id, __indexOf.call(this.ids, _ref2) >= 0)); + return !!(rec && rec.constructor === this.constructor && (rec.id === this.id || rec.cid === this.cid)); }; - Model.prototype.save = function() { + + Model.prototype.save = function(options) { var error, record; - error = this.validate(); - if (error) { - this.trigger('error', error); - return false; + if (options == null) options = {}; + if (options.validate !== false) { + error = this.validate(); + if (error) { + this.trigger('error', error); + return false; + } } - this.trigger('beforeSave'); - record = this.newRecord ? this.create() : this.update(); - this.trigger('save'); + this.trigger('beforeSave', options); + record = this.isNew() ? this.create(options) : this.update(options); + this.trigger('save', options); return record; }; + Model.prototype.updateAttribute = function(name, value) { this[name] = value; return this.save(); }; - Model.prototype.updateAttributes = function(atts) { + + Model.prototype.updateAttributes = function(atts, options) { this.load(atts); - return this.save(); + return this.save(options); }; + Model.prototype.changeID = function(id) { var records; - this.ids.push(this.id); records = this.constructor.records; records[id] = records[this.id]; delete records[this.id]; this.id = id; return this.save(); }; - Model.prototype.destroy = function() { - this.trigger('beforeDestroy'); + + Model.prototype.destroy = function(options) { + if (options == null) options = {}; + this.trigger('beforeDestroy', options); delete this.constructor.records[this.id]; + delete this.constructor.crecords[this.cid]; this.destroyed = true; - this.trigger('destroy'); - this.trigger('change', 'destroy'); + this.trigger('destroy', options); + this.trigger('change', 'destroy', options); this.unbind(); return this; }; + Model.prototype.dup = function(newRecord) { var result; result = new this.constructor(this.attributes()); if (newRecord === false) { - result.newRecord = this.newRecord; + result.cid = this.cid; } else { delete result.id; } return result; }; + Model.prototype.clone = function() { return Object.create(this); }; + Model.prototype.reload = function() { var original; - if (this.newRecord) { - return this; - } + if (this.isNew()) return this; original = this.constructor.find(this.id); this.load(original.attributes()); return original; }; + Model.prototype.toJSON = function() { return this.attributes(); }; + Model.prototype.toString = function() { return "<" + this.constructor.className + " (" + (JSON.stringify(this)) + ")>"; }; + Model.prototype.fromForm = function(form) { var key, result, _i, _len, _ref; result = {}; _ref = $(form).serializeArray(); for (_i = 0, _len = _ref.length; _i < _len; _i++) { key = _ref[_i]; result[key.name] = key.value; } return this.load(result); }; + Model.prototype.exists = function() { return this.id && this.id in this.constructor.records; }; - Model.prototype.update = function() { + + Model.prototype.update = function(options) { var clone, records; - this.trigger('beforeUpdate'); + this.trigger('beforeUpdate', options); records = this.constructor.records; records[this.id].load(this.attributes()); clone = records[this.id].clone(); - clone.trigger('update'); - clone.trigger('change', 'update'); + clone.trigger('update', options); + clone.trigger('change', 'update', options); return clone; }; - Model.prototype.create = function() { - var clone, records; - this.trigger('beforeCreate'); - if (!this.id) { - this.id = guid(); - } - this.newRecord = false; - records = this.constructor.records; - records[this.id] = this.dup(false); - clone = records[this.id].clone(); - clone.trigger('create'); - clone.trigger('change', 'create'); + + Model.prototype.create = function(options) { + var clone, record; + this.trigger('beforeCreate', options); + if (!this.id) this.id = this.cid; + record = this.dup(false); + this.constructor.records[this.id] = record; + this.constructor.crecords[this.cid] = record; + clone = record.clone(); + clone.trigger('create', options); + clone.trigger('change', 'create', options); return clone; }; + Model.prototype.bind = function(events, callback) { - var binder, unbinder; - this.constructor.bind(events, binder = __bind(function(record) { - if (record && this.eql(record)) { - return callback.apply(this, arguments); + var binder, unbinder, + _this = this; + this.constructor.bind(events, binder = function(record) { + if (record && _this.eql(record)) return callback.apply(_this, arguments); + }); + this.constructor.bind('unbind', unbinder = function(record) { + if (record && _this.eql(record)) { + _this.constructor.unbind(events, binder); + return _this.constructor.unbind('unbind', unbinder); } - }, this)); - this.constructor.bind('unbind', unbinder = __bind(function(record) { - if (record && this.eql(record)) { - this.constructor.unbind(events, binder); - return this.constructor.unbind('unbind', unbinder); - } - }, this)); + }); return binder; }; + + Model.prototype.one = function(events, callback) { + var binder, + _this = this; + return binder = this.bind(events, function() { + _this.constructor.unbind(events, binder); + return callback.apply(_this); + }); + }; + Model.prototype.trigger = function() { var args, _ref; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; args.splice(1, 0, this); return (_ref = this.constructor).trigger.apply(_ref, args); }; + Model.prototype.unbind = function() { return this.trigger('unbind'); }; + return Model; - })(); - Controller = (function() { - __extends(Controller, Module); + + })(Module); + + Controller = (function(_super) { + + __extends(Controller, _super); + 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 key, value, _ref; 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); - } + if (!this.el) this.el = document.createElement(this.tag); this.el = $(this.el); - if (this.className) { - this.el.addClass(this.className); - } + if (this.className) this.el.addClass(this.className); + if (this.attributes) this.el.attr(this.attributes); this.release(function() { return this.el.remove(); }); - if (!this.events) { - this.events = this.constructor.events; - } - if (!this.elements) { - this.elements = this.constructor.elements; - } - if (this.events) { - this.delegateEvents(); - } - if (this.elements) { - this.refreshElements(); - } + if (!this.events) this.events = this.constructor.events; + if (!this.elements) this.elements = this.constructor.elements; + if (this.events) this.delegateEvents(); + if (this.elements) this.refreshElements(); Controller.__super__.constructor.apply(this, arguments); } + Controller.prototype.release = function(callback) { if (typeof callback === 'function') { return this.bind('release', callback); } else { return this.trigger('release'); } }; + Controller.prototype.$ = function(selector) { return $(selector, this.el); }; + Controller.prototype.delegateEvents = function() { var eventName, key, match, method, selector, _ref, _results; _ref = this.events; _results = []; for (key in _ref) { method = _ref[key]; - if (typeof method !== 'function') { - method = this.proxy(this[method]); - } + if (typeof method !== 'function') method = this.proxy(this[method]); match = key.match(this.eventSplitter); eventName = match[1]; selector = match[2]; - _results.push(selector === '' ? this.el.bind(eventName, method) : this.el.delegate(selector, eventName, method)); + if (selector === '') { + _results.push(this.el.bind(eventName, method)); + } else { + _results.push(this.el.delegate(selector, eventName, method)); + } } return _results; }; + Controller.prototype.refreshElements = function() { var key, value, _ref, _results; _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 _i, _len, _results; @@ -627,15 +669,17 @@ })(); (_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 _i, _len, _results; @@ -648,104 +692,117 @@ })(); (_ref = this.el).prepend.apply(_ref, elements); this.refreshElements(); return this.el; }; + Controller.prototype.replace = function(element) { var previous, _ref; - _ref = [this.el, element.el || element], previous = _ref[0], this.el = _ref[1]; + _ref = [this.el, $(element.el || element)], previous = _ref[0], this.el = _ref[1]; previous.replaceWith(this.el); this.delegateEvents(); this.refreshElements(); return this.el; }; + return Controller; - })(); - $ = this.jQuery || this.Zepto || function(element) { + + })(Module); + + $ = (typeof window !== "undefined" && window !== null ? window.jQuery : void 0) || (typeof window !== "undefined" && window !== null ? window.Zepto : void 0) || function(element) { return element; }; + if (typeof Object.create !== 'function') { Object.create = function(o) { var Func; Func = function() {}; Func.prototype = o; return new Func(); }; } + isArray = function(value) { return Object.prototype.toString.call(value) === '[object Array]'; }; + isBlank = function(value) { var key; - if (!value) { - return true; - } + if (!value) return true; for (key in value) { return false; } return true; }; + makeArray = function(args) { return Array.prototype.slice.call(args, 0); }; - guid = function() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r, v; - r = Math.random() * 16 | 0; - v = c === 'x' ? r : r & 3 | 8; - return v.toString(16); - }).toUpperCase(); - }; + Spine = this.Spine = {}; - if (typeof module !== "undefined" && module !== null) { - module.exports = Spine; - } - Spine.version = '1.0.3'; + + if (typeof module !== "undefined" && module !== null) module.exports = Spine; + + Spine.version = '1.0.5'; + Spine.isArray = isArray; + Spine.isBlank = isBlank; + 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() { - __extends(result, this); + result = (function(_super) { + + __extends(result, _super); + function result() { result.__super__.constructor.apply(this, arguments); } + return result; - }).call(this); - if (instances) { - result.include(instances); - } - if (statics) { - result.extend(statics); - } - if (typeof result.unbind === "function") { - result.unbind(); - } + + })(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() { - __extends(Instance, this); + if (attributes == null) attributes = []; + Instance = (function(_super) { + + __extends(Instance, _super); + function Instance() { Instance.__super__.constructor.apply(this, arguments); } + return Instance; - }).call(this); + + })(this); Instance.configure.apply(Instance, [name].concat(__slice.call(attributes))); return Instance; }; + Module.init = Controller.init = Model.init = function(a1, a2, a3, a4, a5) { return new this(a1, a2, a3, a4, a5); }; + Spine.Class = Module; + }).call(this);