Upgrade to spine 1.0.9.

This commit is contained in:
Martin Edenhofer 2013-03-06 18:36:38 +01:00
parent f85adab5f1
commit 4c35f73e0f
7 changed files with 182 additions and 136 deletions

View file

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.3.3 // Generated by CoffeeScript 1.4.0
(function() { (function() {
var $, Ajax, Base, Collection, Extend, Include, Model, Singleton, Spine, var $, Ajax, Base, Collection, Extend, Include, Model, Queue, Singleton, Spine,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty, __hasProp = {}.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; }, __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; },
@ -12,13 +12,13 @@
Model = Spine.Model; Model = Spine.Model;
Queue = $({});
Ajax = { Ajax = {
getURL: function(object) { getURL: function(object) {
return object && (typeof object.url === "function" ? object.url() : void 0) || object.url; return object && (typeof object.url === "function" ? object.url() : void 0) || object.url;
}, },
enabled: true, enabled: true,
pending: false,
requests: [],
disable: function(callback) { disable: function(callback) {
if (this.enabled) { if (this.enabled) {
this.enabled = false; this.enabled = false;
@ -33,32 +33,15 @@
return callback(); return callback();
} }
}, },
requestNext: function() { queue: function(request) {
var next; if (request) {
next = this.requests.shift(); return Queue.queue(request);
if (next) {
return this.request(next);
} else { } else {
return this.pending = false; return Queue.queue();
} }
}, },
request: function(callback) { clearQueue: function() {
var _this = this; return this.queue([]);
return (callback()).complete(function() {
return _this.requestNext();
});
},
queue: function(callback) {
if (!this.enabled) {
return;
}
if (this.pending) {
this.requests.push(callback);
} else {
this.pending = true;
this.request(callback);
}
return callback;
} }
}; };
@ -75,12 +58,42 @@
} }
}; };
Base.prototype.queue = Ajax.queue;
Base.prototype.ajax = function(params, defaults) { Base.prototype.ajax = function(params, defaults) {
return $.ajax($.extend({}, this.defaults, defaults, params)); return $.ajax(this.ajaxSettings(params, defaults));
}; };
Base.prototype.queue = function(callback) { Base.prototype.ajaxQueue = function(params, defaults) {
return Ajax.queue(callback); var deferred, jqXHR, promise, request, settings;
jqXHR = null;
deferred = $.Deferred();
promise = deferred.promise();
if (!Ajax.enabled) {
return promise;
}
settings = this.ajaxSettings(params, defaults);
request = function(next) {
return jqXHR = $.ajax(settings).done(deferred.resolve).fail(deferred.reject).then(next, next);
};
promise.abort = function(statusText) {
var index;
if (jqXHR) {
return jqXHR.abort(statusText);
}
index = $.inArray(request, this.queue());
if (index > -1) {
this.queue().splice(index, 1);
}
deferred.rejectWith(settings.context || settings, [promise, statusText, '']);
return promise;
};
this.queue(request);
return promise;
};
Base.prototype.ajaxSettings = function(params, defaults) {
return $.extend({}, this.defaults, defaults, params);
}; };
return Base; return Base;
@ -93,7 +106,7 @@
function Collection(model) { function Collection(model) {
this.model = model; this.model = model;
this.errorResponse = __bind(this.errorResponse, this); this.failResponse = __bind(this.failResponse, this);
this.recordsResponse = __bind(this.recordsResponse, this); this.recordsResponse = __bind(this.recordsResponse, this);
@ -104,17 +117,17 @@
record = new this.model({ record = new this.model({
id: id id: id
}); });
return this.ajax(params, { return this.ajaxQueue(params, {
type: 'GET', type: 'GET',
url: Ajax.getURL(record) url: Ajax.getURL(record)
}).success(this.recordsResponse).error(this.errorResponse); }).done(this.recordsResponse).fail(this.failResponse);
}; };
Collection.prototype.all = function(params) { Collection.prototype.all = function(params) {
return this.ajax(params, { return this.ajaxQueue(params, {
type: 'GET', type: 'GET',
url: Ajax.getURL(this.model) url: Ajax.getURL(this.model)
}).success(this.recordsResponse).error(this.errorResponse); }).done(this.recordsResponse).fail(this.failResponse);
}; };
Collection.prototype.fetch = function(params, options) { Collection.prototype.fetch = function(params, options) {
@ -128,11 +141,11 @@
} }
if (id = params.id) { if (id = params.id) {
delete params.id; delete params.id;
return this.find(id, params).success(function(record) { return this.find(id, params).done(function(record) {
return _this.model.refresh(record, options); return _this.model.refresh(record, options);
}); });
} else { } else {
return this.all(params).success(function(records) { return this.all(params).done(function(records) {
return _this.model.refresh(records, options); return _this.model.refresh(records, options);
}); });
} }
@ -142,7 +155,7 @@
return this.model.trigger('ajaxSuccess', null, status, xhr); return this.model.trigger('ajaxSuccess', null, status, xhr);
}; };
Collection.prototype.errorResponse = function(xhr, statusText, error) { Collection.prototype.failResponse = function(xhr, statusText, error) {
return this.model.trigger('ajaxError', null, xhr, statusText, error); return this.model.trigger('ajaxError', null, xhr, statusText, error);
}; };
@ -156,7 +169,7 @@
function Singleton(record) { function Singleton(record) {
this.record = record; this.record = record;
this.errorResponse = __bind(this.errorResponse, this); this.failResponse = __bind(this.failResponse, this);
this.recordResponse = __bind(this.recordResponse, this); this.recordResponse = __bind(this.recordResponse, this);
@ -164,45 +177,33 @@
} }
Singleton.prototype.reload = function(params, options) { Singleton.prototype.reload = function(params, options) {
var _this = this; return this.ajaxQueue(params, {
return this.queue(function() {
return _this.ajax(params, {
type: 'GET', type: 'GET',
url: Ajax.getURL(_this.record) url: Ajax.getURL(this.record)
}).success(_this.recordResponse(options)).error(_this.errorResponse(options)); }).done(this.recordResponse(options)).fail(this.failResponse(options));
});
}; };
Singleton.prototype.create = function(params, options) { Singleton.prototype.create = function(params, options) {
var _this = this; return this.ajaxQueue(params, {
return this.queue(function() {
return _this.ajax(params, {
type: 'POST', type: 'POST',
data: JSON.stringify(_this.record), data: JSON.stringify(this.record),
url: Ajax.getURL(_this.model) url: Ajax.getURL(this.model)
}).success(_this.recordResponse(options)).error(_this.errorResponse(options)); }).done(this.recordResponse(options)).fail(this.failResponse(options));
});
}; };
Singleton.prototype.update = function(params, options) { Singleton.prototype.update = function(params, options) {
var _this = this; return this.ajaxQueue(params, {
return this.queue(function() {
return _this.ajax(params, {
type: 'PUT', type: 'PUT',
data: JSON.stringify(_this.record), data: JSON.stringify(this.record),
url: Ajax.getURL(_this.record) url: Ajax.getURL(this.record)
}).success(_this.recordResponse(options)).error(_this.errorResponse(options)); }).done(this.recordResponse(options)).fail(this.failResponse(options));
});
}; };
Singleton.prototype.destroy = function(params, options) { Singleton.prototype.destroy = function(params, options) {
var _this = this; return this.ajaxQueue(params, {
return this.queue(function() {
return _this.ajax(params, {
type: 'DELETE', type: 'DELETE',
url: Ajax.getURL(_this.record) url: Ajax.getURL(this.record)
}).success(_this.recordResponse(options)).error(_this.errorResponse(options)); }).done(this.recordResponse(options)).fail(this.failResponse(options));
});
}; };
Singleton.prototype.recordResponse = function(options) { Singleton.prototype.recordResponse = function(options) {
@ -211,8 +212,8 @@
options = {}; options = {};
} }
return function(data, status, xhr) { return function(data, status, xhr) {
var _ref; var _ref, _ref1;
if (Spine.isBlank(data)) { if (Spine.isBlank(data) || _this.record.destroyed) {
data = false; data = false;
} else { } else {
data = _this.model.fromJSON(data); data = _this.model.fromJSON(data);
@ -226,19 +227,25 @@
} }
}); });
_this.record.trigger('ajaxSuccess', data, status, xhr); _this.record.trigger('ajaxSuccess', data, status, xhr);
return (_ref = options.success) != null ? _ref.apply(_this.record) : void 0; if ((_ref = options.success) != null) {
_ref.apply(_this.record);
}
return (_ref1 = options.done) != null ? _ref1.apply(_this.record) : void 0;
}; };
}; };
Singleton.prototype.errorResponse = function(options) { Singleton.prototype.failResponse = function(options) {
var _this = this; var _this = this;
if (options == null) { if (options == null) {
options = {}; options = {};
} }
return function(xhr, statusText, error) { return function(xhr, statusText, error) {
var _ref; var _ref, _ref1;
_this.record.trigger('ajaxError', xhr, statusText, error); _this.record.trigger('ajaxError', xhr, statusText, error);
return (_ref = options.error) != null ? _ref.apply(_this.record) : void 0; if ((_ref = options.error) != null) {
_ref.apply(_this.record);
}
return (_ref1 = options.fail) != null ? _ref1.apply(_this.record) : void 0;
}; };
}; };

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3 // Generated by CoffeeScript 1.4.0
(function() { (function() {
var $, Spine, var $, Spine,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3 // Generated by CoffeeScript 1.4.0
(function() { (function() {
var Spine; var Spine;

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3 // Generated by CoffeeScript 1.4.0
(function() { (function() {
var $, Spine, var $, Spine,
__hasProp = {}.hasOwnProperty, __hasProp = {}.hasOwnProperty,
@ -112,6 +112,9 @@
_ref = this.controllers; _ref = this.controllers;
for (key in _ref) { for (key in _ref) {
value = _ref[key]; value = _ref[key];
if (this[key] != null) {
throw Error("'@" + key + "' already assigned - choose a different name");
}
this[key] = new value({ this[key] = new value({
stack: this stack: this
}); });

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3 // Generated by CoffeeScript 1.4.0
(function() { (function() {
var Collection, Instance, Singleton, Spine, isArray, require, singularize, underscore, var Collection, Instance, Singleton, Spine, isArray, require, singularize, underscore,
__hasProp = {}.hasOwnProperty, __hasProp = {}.hasOwnProperty,
@ -48,10 +48,10 @@
var records, var records,
_this = this; _this = this;
records = this.select(function(rec) { records = this.select(function(rec) {
return rec.id + '' === id + ''; return ("" + rec.id) === ("" + id);
}); });
if (!records[0]) { if (!records[0]) {
throw 'Unknown record'; throw new Error("\"" + this.model.className + "\" model could not find a record for the ID \"" + id + "\"");
} }
return records[0]; return records[0];
}; };
@ -252,4 +252,10 @@
} }
}); });
Spine.Collection = Collection;
Spine.Singleton = Singleton;
Spine.Instance = Instance;
}).call(this); }).call(this);

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3 // Generated by CoffeeScript 1.4.0
(function() { (function() {
var $, Spine, escapeRegExp, hashStrip, namedParam, splatParam, var $, Spine, escapeRegExp, hashStrip, namedParam, splatParam,
__hasProp = {}.hasOwnProperty, __hasProp = {}.hasOwnProperty,
@ -31,7 +31,8 @@
Route.options = { Route.options = {
trigger: true, trigger: true,
history: false, history: false,
shim: false shim: false,
replace: false
}; };
Route.add = function(path, callback) { Route.add = function(path, callback) {
@ -68,6 +69,9 @@
}; };
Route.unbind = function() { Route.unbind = function() {
if (this.options.shim) {
return;
}
if (this.history) { if (this.history) {
return $(window).unbind('popstate', this.change); return $(window).unbind('popstate', this.change);
} else { } else {
@ -98,7 +102,9 @@
if (options.shim) { if (options.shim) {
return; return;
} }
if (this.history) { if (this.history && options.replace) {
return history.replaceState({}, document.title, this.path);
} else if (this.history) {
return history.pushState({}, document.title, this.path); return history.pushState({}, document.title, this.path);
} else { } else {
return window.location.hash = this.path; return window.location.hash = this.path;
@ -107,28 +113,25 @@
Route.getPath = function() { Route.getPath = function() {
var path; var path;
if (this.history) {
path = window.location.pathname; path = window.location.pathname;
if (path.substr(0, 1) !== '/') { if (path.substr(0, 1) !== '/') {
path = '/' + path; path = '/' + path;
} }
} else {
path = window.location.hash;
path = path.replace(hashStrip, '');
}
return path; return path;
}; };
Route.getHash = function() {
return window.location.hash;
};
Route.getFragment = function() {
return this.getHash().replace(hashStrip, '');
};
Route.getHost = function() { Route.getHost = function() {
return (document.location + '').replace(this.getPath() + this.getHash(), ''); return "" + window.location.protocol + "//" + window.location.host;
}; };
Route.change = function() { Route.change = function() {
var path; var path;
path = this.getFragment() !== '' ? this.getFragment() : this.getPath(); path = this.getPath();
if (path === this.path) { if (path === this.path) {
return; return;
} }
@ -141,11 +144,12 @@
_ref1 = this.routes; _ref1 = this.routes;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
route = _ref1[_i]; route = _ref1[_i];
if (route.match(path, options)) { if (!(route.match(path, options))) {
continue;
}
this.trigger('change', route, path); this.trigger('change', route, path);
return route; return route;
} }
}
}; };
function Route(path, callback) { function Route(path, callback) {
@ -163,7 +167,7 @@
this.names.push(match[1]); this.names.push(match[1]);
} }
path = path.replace(escapeRegExp, '\\$&').replace(namedParam, '([^\/]*)').replace(splatParam, '(.*?)'); path = path.replace(escapeRegExp, '\\$&').replace(namedParam, '([^\/]*)').replace(splatParam, '(.*?)');
this.route = new RegExp('^' + path + '$'); this.route = new RegExp("^" + path + "$");
} else { } else {
this.route = path; this.route = path;
} }

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3 // Generated by CoffeeScript 1.4.0
(function() { (function() {
var $, Controller, Events, Log, Model, Module, Spine, createObject, isArray, isBlank, makeArray, moduleKeywords, var $, Controller, Events, Log, Model, Module, Spine, createObject, isArray, isBlank, makeArray, moduleKeywords,
__slice = [].slice, __slice = [].slice,
@ -42,33 +42,41 @@
return true; return true;
}, },
unbind: function(ev, callback) { unbind: function(ev, callback) {
var cb, i, list, _i, _len, _ref; var cb, evs, i, list, name, _i, _j, _len, _len1, _ref;
if (!ev) { if (!ev) {
this._callbacks = {}; this._callbacks = {};
return this; return this;
} }
list = (_ref = this._callbacks) != null ? _ref[ev] : void 0; evs = ev.split(' ');
for (_i = 0, _len = evs.length; _i < _len; _i++) {
name = evs[_i];
list = (_ref = this._callbacks) != null ? _ref[name] : void 0;
if (!list) { if (!list) {
return this; continue;
} }
if (!callback) { if (!callback) {
delete this._callbacks[ev]; delete this._callbacks[name];
return this; continue;
} }
for (i = _i = 0, _len = list.length; _i < _len; i = ++_i) { for (i = _j = 0, _len1 = list.length; _j < _len1; i = ++_j) {
cb = list[i]; cb = list[i];
if (!(cb === callback)) { if (!(cb === callback)) {
continue; continue;
} }
list = list.slice(); list = list.slice();
list.splice(i, 1); list.splice(i, 1);
this._callbacks[ev] = list; this._callbacks[name] = list;
break; break;
} }
}
return this; return this;
} }
}; };
Events.on = Events.bind;
Events.off = Events.unbind;
Log = { Log = {
trace: true, trace: true,
logPrefix: '(App)', logPrefix: '(App)',
@ -190,7 +198,7 @@
return this.findCID(id); return this.findCID(id);
} }
if (!record) { if (!record) {
throw new Error('Unknown record'); throw new Error("\"" + this.className + "\" model could not find a record for the ID \"" + id + "\"");
} }
return record.clone(); return record.clone();
}; };
@ -199,7 +207,7 @@
var record; var record;
record = this.crecords[cid]; record = this.crecords[cid];
if (!record) { if (!record) {
throw new Error('Unknown record'); throw new Error("\"" + this.className + "\" model could not find a record for the ID \"" + id + "\"");
} }
return record.clone(); return record.clone();
}; };
@ -313,13 +321,13 @@
return _results; return _results;
}; };
Model.destroyAll = function() { Model.destroyAll = function(options) {
var key, value, _ref, _results; var key, value, _ref, _results;
_ref = this.records; _ref = this.records;
_results = []; _results = [];
for (key in _ref) { for (key in _ref) {
value = _ref[key]; value = _ref[key];
_results.push(this.records[key].destroy()); _results.push(this.records[key].destroy(options));
} }
return _results; return _results;
}; };
@ -487,13 +495,31 @@
} }
this.trigger('beforeSave', options); this.trigger('beforeSave', options);
record = this.isNew() ? this.create(options) : this.update(options); record = this.isNew() ? this.create(options) : this.update(options);
this.stripCloneAttrs();
this.trigger('save', options); this.trigger('save', options);
return record; 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 (this.constructor.attributes.indexOf(key) > -1) {
delete this[key];
}
}
return this;
};
Model.prototype.updateAttribute = function(name, value, options) { Model.prototype.updateAttribute = function(name, value, options) {
this[name] = value; var atts;
return this.save(options); atts = {};
atts[name] = value;
return this.updateAttributes(atts, options);
}; };
Model.prototype.updateAttributes = function(atts, options) { Model.prototype.updateAttributes = function(atts, options) {
@ -843,7 +869,7 @@
module.exports = Spine; module.exports = Spine;
} }
Spine.version = '1.0.8'; Spine.version = '1.0.9';
Spine.isArray = isArray; Spine.isArray = isArray;
@ -864,28 +890,28 @@
Module.extend.call(Spine, Events); Module.extend.call(Spine, Events);
Module.create = Module.sub = Controller.create = Controller.sub = Model.sub = function(instances, statics) { Module.create = Module.sub = Controller.create = Controller.sub = Model.sub = function(instances, statics) {
var result; var Result;
result = (function(_super) { Result = (function(_super) {
__extends(result, _super); __extends(Result, _super);
function result() { function Result() {
return result.__super__.constructor.apply(this, arguments); return Result.__super__.constructor.apply(this, arguments);
} }
return result; return Result;
})(this); })(this);
if (instances) { if (instances) {
result.include(instances); Result.include(instances);
} }
if (statics) { if (statics) {
result.extend(statics); Result.extend(statics);
} }
if (typeof result.unbind === "function") { if (typeof Result.unbind === "function") {
result.unbind(); Result.unbind();
} }
return result; return Result;
}; };
Model.setup = function(name, attributes) { Model.setup = function(name, attributes) {