Update vendors.

Former-commit-id: 6ab66f9ea6fd881e8c5ed18e84b9a24656496e10
This commit is contained in:
John-David Dalton
2013-02-17 16:38:23 -08:00
parent 25e4231d7b
commit 8183740c04
6 changed files with 129 additions and 237 deletions

View File

@@ -1,6 +1,6 @@
// Backbone.js 0.9.10
// (c) 2010-2013 Jeremy Ashkenas, DocumentCloud Inc.
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
// http://backbonejs.org
@@ -89,15 +89,15 @@
// Optimized internal dispatch function for triggering events. Tries to
// keep the usual cases speedy (most Backbone events have 3 arguments).
var triggerEvents = function(events, args) {
var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
var ev, i = -1, l = events.length;
switch (args.length) {
case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx);
return;
case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1);
case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0]);
return;
case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2);
case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1]);
return;
case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3);
case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1], args[2]);
return;
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
}
@@ -119,24 +119,25 @@
// to a `callback` function. Passing `"all"` will bind the callback to
// all events fired.
on: function(name, callback, context) {
if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
if (!(eventsApi(this, 'on', name, [callback, context]) && callback)) return this;
this._events || (this._events = {});
var events = this._events[name] || (this._events[name] = []);
events.push({callback: callback, context: context, ctx: context || this});
var list = this._events[name] || (this._events[name] = []);
list.push({callback: callback, context: context, ctx: context || this});
return this;
},
// Bind events to only be triggered a single time. After the first time
// the callback is invoked, it will be removed.
once: function(name, callback, context) {
if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
if (!(eventsApi(this, 'once', name, [callback, context]) && callback)) return this;
var self = this;
var once = _.once(function() {
self.off(name, once);
callback.apply(this, arguments);
});
once._callback = callback;
return this.on(name, once, context);
this.on(name, once, context);
return this;
},
// Remove one or many callbacks. If `context` is null, removes all
@@ -144,7 +145,7 @@
// callbacks for the event. If `name` is null, removes all bound
// callbacks for all events.
off: function(name, callback, context) {
var retain, ev, events, names, i, l, j, k;
var list, ev, events, names, i, l, j, k;
if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
if (!name && !callback && !context) {
this._events = {};
@@ -154,19 +155,19 @@
names = name ? [name] : _.keys(this._events);
for (i = 0, l = names.length; i < l; i++) {
name = names[i];
if (events = this._events[name]) {
this._events[name] = retain = [];
if (list = this._events[name]) {
events = [];
if (callback || context) {
for (j = 0, k = events.length; j < k; j++) {
ev = events[j];
for (j = 0, k = list.length; j < k; j++) {
ev = list[j];
if ((callback && callback !== ev.callback &&
callback !== ev.callback._callback) ||
(context && context !== ev.context)) {
retain.push(ev);
events.push(ev);
}
}
}
if (!retain.length) delete this._events[name];
this._events[name] = events;
}
}
@@ -188,37 +189,35 @@
return this;
},
// An inversion-of-control version of `on`. Tell *this* object to listen to
// an event in another object ... keeping track of what it's listening to.
listenTo: function(obj, name, callback) {
var listeners = this._listeners || (this._listeners = {});
var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
listeners[id] = obj;
obj.on(name, typeof name === 'object' ? this : callback, this);
return this;
},
// Tell this object to stop listening to either specific events ... or
// to every object it's currently listening to.
stopListening: function(obj, name, callback) {
var listeners = this._listeners;
if (!listeners) return this;
var deleteListener = !name && !callback;
if (typeof name === 'object') callback = this;
if (obj) (listeners = {})[obj._listenerId] = obj;
for (var id in listeners) {
listeners[id].off(name, callback, this);
if (deleteListener) delete this._listeners[id];
if (!listeners) return;
if (obj) {
obj.off(name, typeof name === 'object' ? this : callback, this);
if (!name && !callback) delete listeners[obj._listenerId];
} else {
if (typeof name === 'object') callback = this;
for (var id in listeners) {
listeners[id].off(name, callback, this);
}
this._listeners = {};
}
return this;
}
};
var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
// An inversion-of-control versions of `on` and `once`. Tell *this* object to listen to
// an event in another object ... keeping track of what it's listening to.
_.each(listenMethods, function(implementation, method) {
Events[method] = function(obj, name, callback) {
var listeners = this._listeners || (this._listeners = {});
var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
listeners[id] = obj;
if (typeof name === 'object') callback = this;
obj[implementation](name, callback, this);
return this;
};
});
// Aliases for backwards compatibility.
Events.bind = Events.on;
Events.unbind = Events.off;
@@ -253,9 +252,6 @@
// A hash of attributes whose current and previous value differ.
changed: null,
// The value returned during the last failed validation.
validationError: null,
// The default name for the JSON `id` attribute is `"id"`. MongoDB and
// CouchDB users may want to set this to `"_id"`.
idAttribute: 'id',
@@ -418,14 +414,11 @@
fetch: function(options) {
options = options ? _.clone(options) : {};
if (options.parse === void 0) options.parse = true;
var model = this;
var success = options.success;
options.success = function(resp) {
options.success = function(model, resp, options) {
if (!model.set(model.parse(resp, options), options)) return false;
if (success) success(model, resp, options);
model.trigger('sync', model, resp, options);
};
wrapError(this, options);
return this.sync('read', this, options);
},
@@ -433,7 +426,7 @@
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save: function(key, val, options) {
var attrs, method, xhr, attributes = this.attributes;
var attrs, success, method, xhr, attributes = this.attributes;
// Handle both `"key", value` and `{key: value}` -style arguments.
if (key == null || typeof key === 'object') {
@@ -459,9 +452,8 @@
// After a successful server-side save, the client is (optionally)
// updated with the server-side state.
if (options.parse === void 0) options.parse = true;
var model = this;
var success = options.success;
options.success = function(resp) {
success = options.success;
options.success = function(model, resp, options) {
// Ensure attributes are restored during synchronous saves.
model.attributes = attributes;
var serverAttrs = model.parse(resp, options);
@@ -470,10 +462,9 @@
return false;
}
if (success) success(model, resp, options);
model.trigger('sync', model, resp, options);
};
wrapError(this, options);
// Finish configuring and sending the Ajax request.
method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
if (method === 'patch') options.attrs = attrs;
xhr = this.sync(method, this, options);
@@ -496,17 +487,15 @@
model.trigger('destroy', model, model.collection, options);
};
options.success = function(resp) {
options.success = function(model, resp, options) {
if (options.wait || model.isNew()) destroy();
if (success) success(model, resp, options);
if (!model.isNew()) model.trigger('sync', model, resp, options);
};
if (this.isNew()) {
options.success();
options.success(this, null, options);
return false;
}
wrapError(this, options);
var xhr = this.sync('delete', this, options);
if (!options.wait) destroy();
@@ -544,8 +533,8 @@
},
// Run validation against the next complete set of model attributes,
// returning `true` if all is well. Otherwise, fire an
// `"invalid"` event and call the invalid callback, if specified.
// returning `true` if all is well. Otherwise, fire a general
// `"error"` event and call the error callback, if specified.
_validate: function(attrs, options) {
if (!options.validate || !this.validate) return true;
attrs = _.extend({}, this.attributes, attrs);
@@ -567,6 +556,7 @@
options || (options = {});
if (options.model) this.model = options.model;
if (options.comparator !== void 0) this.comparator = options.comparator;
this.models = [];
this._reset();
this.initialize.apply(this, arguments);
if (models) this.reset(models, _.extend({silent: true}, options));
@@ -601,13 +591,16 @@
var i, l, model, attrs, existing, doSort, add, at, sort, sortAttr;
add = [];
at = options.at;
sort = this.comparator && (at == null) && options.sort !== false;
sort = this.comparator && (at == null) && options.sort != false;
sortAttr = _.isString(this.comparator) ? this.comparator : null;
// Turn bare objects into model references, and prevent invalid models
// from being added.
for (i = 0, l = models.length; i < l; i++) {
if (!(model = this._prepareModel(attrs = models[i], options))) continue;
if (!(model = this._prepareModel(attrs = models[i], options))) {
this.trigger('invalid', this, attrs, options);
continue;
}
// If a duplicate is found, prevent it from being added and
// optionally merge it into the existing model.
@@ -714,7 +707,8 @@
// Get a model from the set by id.
get: function(obj) {
if (obj == null) return void 0;
return this._byId[obj.id || obj.cid || obj];
this._idAttr || (this._idAttr = this.model.prototype.idAttribute);
return this._byId[obj.id || obj.cid || obj[this._idAttr] || obj];
},
// Get the model at the given index.
@@ -722,11 +716,10 @@
return this.models[index];
},
// Return models with matching attributes. Useful for simple cases of
// `filter`.
where: function(attrs, first) {
if (_.isEmpty(attrs)) return first ? void 0 : [];
return this[first ? 'find' : 'filter'](function(model) {
// Return models with matching attributes. Useful for simple cases of `filter`.
where: function(attrs) {
if (_.isEmpty(attrs)) return [];
return this.filter(function(model) {
for (var key in attrs) {
if (attrs[key] !== model.get(key)) return false;
}
@@ -734,12 +727,6 @@
});
},
// Return the first model with matching attributes. Useful for simple cases
// of `find`.
findWhere: function(attrs) {
return this.where(attrs, true);
},
// Force the collection to re-sort itself. You don't need to call this under
// normal circumstances, as the set will maintain sort order as each item
// is added.
@@ -770,7 +757,7 @@
update: function(models, options) {
options = _.extend({add: true, merge: true, remove: true}, options);
if (options.parse) models = this.parse(models, options);
var attrs, model, i, l, existing;
var model, i, l, existing;
var add = [], remove = [], modelMap = {};
// Allow a single model (or no argument) to be passed.
@@ -781,12 +768,11 @@
// Determine which models to add and merge, and which to remove.
for (i = 0, l = models.length; i < l; i++) {
if (!((attrs = models[i]) instanceof Model)) attrs = _.clone(attrs);
if (!(model = this._prepareModel(attrs, options))) continue;
model = models[i];
existing = this.get(model);
if (options.remove && existing) modelMap[existing.cid] = true;
if ((options.add && !existing) || (options.merge && existing)) {
add.push(models[i]);
add.push(model);
}
}
if (options.remove) {
@@ -811,7 +797,7 @@
for (var i = 0, l = this.models.length; i < l; i++) {
this._removeReference(this.models[i]);
}
options.previousModels = this.models;
options.previousModels = this.models.slice();
this._reset();
if (models) this.add(models, _.extend({silent: true}, options));
if (!options.silent) this.trigger('reset', this, options);
@@ -825,14 +811,11 @@
options = options ? _.clone(options) : {};
if (options.parse === void 0) options.parse = true;
var success = options.success;
var collection = this;
options.success = function(resp) {
options.success = function(collection, resp, options) {
var method = options.update ? 'update' : 'reset';
collection[method](resp, options);
if (success) success(collection, resp, options);
collection.trigger('sync', collection, resp, options);
};
wrapError(this, options);
return this.sync('read', this, options);
},
@@ -845,7 +828,7 @@
if (!options.wait) this.add(model, options);
var collection = this;
var success = options.success;
options.success = function(resp) {
options.success = function(model, resp, options) {
if (options.wait) collection.add(model, options);
if (success) success(model, resp, options);
};
@@ -867,7 +850,7 @@
// Reset all internal state. Called when the collection is reset.
_reset: function() {
this.length = 0;
this.models = [];
this.models.length = 0;
this._byId = {};
},
@@ -880,10 +863,7 @@
options || (options = {});
options.collection = this;
var model = new this.model(attrs, options);
if (!model._validate(attrs, options)) {
this.trigger('invalid', this, attrs, options);
return false;
}
if (!model._validate(attrs, options)) return false;
return model;
},
@@ -1320,7 +1300,7 @@
// This only works for delegate-able events: not `focus`, `blur`, and
// not `change`, `submit`, and `reset` in Internet Explorer.
delegateEvents: function(events) {
if (!(events || (events = _.result(this, 'events')))) return this;
if (!(events || (events = _.result(this, 'events')))) return;
this.undelegateEvents();
for (var key in events) {
var method = events[key];
@@ -1336,7 +1316,6 @@
this.$el.on(eventName, selector, method);
}
}
return this;
},
// Clears all callbacks previously bound to the view with `delegateEvents`.
@@ -1344,7 +1323,6 @@
// Backbone views attached to the same DOM element.
undelegateEvents: function() {
this.$el.off('.delegateEvents' + this.cid);
return this;
},
// Performs the initial configuration of a View with a set of options.
@@ -1447,6 +1425,18 @@
params.processData = false;
}
var success = options.success;
options.success = function(resp) {
if (success) success(model, resp, options);
model.trigger('sync', model, resp, options);
};
var error = options.error;
options.error = function(xhr) {
if (error) error(model, xhr, options);
model.trigger('error', model, xhr, options);
};
// Make the request, allowing the user to override any Ajax options.
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
model.trigger('request', model, xhr, options);
@@ -1505,13 +1495,4 @@
throw new Error('A "url" property or function must be specified');
};
// Wrap an optional error callback with a fallback error event.
var wrapError = function (model, options) {
var error = options.error;
options.error = function(resp) {
if (error) error(model, resp, options);
model.trigger('error', model, resp, options);
};
};
}).call(this);