External Libraries: Update Backbone to version 1.3.3.
Changelog: https://cdn.rawgit.com/jashkenas/backbone/1.3.3/index.html#changelog Diff: https://github.com/jashkenas/backbone/compare/1.2.3...1.3.3 Includes a unit test to ensure that the minified version doesn't include `sourceMappingURL`. Props adamsilverstein. Fixes #37099. git-svn-id: https://develop.svn.wordpress.org/trunk@37723 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
70afec2875
commit
62bd8ecdd7
|
@ -1,6 +1,6 @@
|
||||||
// Backbone.js 1.2.3
|
// Backbone.js 1.3.3
|
||||||
|
|
||||||
// (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
// (c) 2010-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||||
// Backbone may be freely distributed under the MIT license.
|
// Backbone may be freely distributed under the MIT license.
|
||||||
// For all details and documentation:
|
// For all details and documentation:
|
||||||
// http://backbonejs.org
|
// http://backbonejs.org
|
||||||
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
// Establish the root object, `window` (`self`) in the browser, or `global` on the server.
|
// Establish the root object, `window` (`self`) in the browser, or `global` on the server.
|
||||||
// We use `self` instead of `window` for `WebWorker` support.
|
// We use `self` instead of `window` for `WebWorker` support.
|
||||||
var root = (typeof self == 'object' && self.self == self && self) ||
|
var root = (typeof self == 'object' && self.self === self && self) ||
|
||||||
(typeof global == 'object' && global.global == global && global);
|
(typeof global == 'object' && global.global === global && global);
|
||||||
|
|
||||||
// Set up Backbone appropriately for the environment. Start with AMD.
|
// Set up Backbone appropriately for the environment. Start with AMD.
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
|
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
|
||||||
} else if (typeof exports !== 'undefined') {
|
} else if (typeof exports !== 'undefined') {
|
||||||
var _ = require('underscore'), $;
|
var _ = require('underscore'), $;
|
||||||
try { $ = require('jquery'); } catch(e) {}
|
try { $ = require('jquery'); } catch (e) {}
|
||||||
factory(root, exports, _, $);
|
factory(root, exports, _, $);
|
||||||
|
|
||||||
// Finally, as a browser global.
|
// Finally, as a browser global.
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
|
root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
|
||||||
}
|
}
|
||||||
|
|
||||||
}(function(root, Backbone, _, $) {
|
})(function(root, Backbone, _, $) {
|
||||||
|
|
||||||
// Initial Setup
|
// Initial Setup
|
||||||
// -------------
|
// -------------
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
var slice = Array.prototype.slice;
|
var slice = Array.prototype.slice;
|
||||||
|
|
||||||
// Current version of the library. Keep in sync with `package.json`.
|
// Current version of the library. Keep in sync with `package.json`.
|
||||||
Backbone.VERSION = '1.2.3';
|
Backbone.VERSION = '1.3.3';
|
||||||
|
|
||||||
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
|
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
|
||||||
// the `$` variable.
|
// the `$` variable.
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
|
events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
|
||||||
}
|
}
|
||||||
} else if (name && eventSplitter.test(name)) {
|
} else if (name && eventSplitter.test(name)) {
|
||||||
// Handle space separated event names by delegating them individually.
|
// Handle space-separated event names by delegating them individually.
|
||||||
for (names = name.split(eventSplitter); i < names.length; i++) {
|
for (names = name.split(eventSplitter); i < names.length; i++) {
|
||||||
events = iteratee(events, names[i], callback, opts);
|
events = iteratee(events, names[i], callback, opts);
|
||||||
}
|
}
|
||||||
|
@ -166,9 +166,9 @@
|
||||||
// Guard the `listening` argument from the public API.
|
// Guard the `listening` argument from the public API.
|
||||||
var internalOn = function(obj, name, callback, context, listening) {
|
var internalOn = function(obj, name, callback, context, listening) {
|
||||||
obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
|
obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
|
||||||
context: context,
|
context: context,
|
||||||
ctx: obj,
|
ctx: obj,
|
||||||
listening: listening
|
listening: listening
|
||||||
});
|
});
|
||||||
|
|
||||||
if (listening) {
|
if (listening) {
|
||||||
|
@ -182,7 +182,7 @@
|
||||||
// Inversion-of-control versions of `on`. Tell *this* object to listen to
|
// Inversion-of-control versions of `on`. Tell *this* object to listen to
|
||||||
// an event in another object... keeping track of what it's listening to
|
// an event in another object... keeping track of what it's listening to
|
||||||
// for easier unbinding later.
|
// for easier unbinding later.
|
||||||
Events.listenTo = function(obj, name, callback) {
|
Events.listenTo = function(obj, name, callback) {
|
||||||
if (!obj) return this;
|
if (!obj) return this;
|
||||||
var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
|
var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
|
||||||
var listeningTo = this._listeningTo || (this._listeningTo = {});
|
var listeningTo = this._listeningTo || (this._listeningTo = {});
|
||||||
|
@ -207,7 +207,7 @@
|
||||||
var context = options.context, ctx = options.ctx, listening = options.listening;
|
var context = options.context, ctx = options.ctx, listening = options.listening;
|
||||||
if (listening) listening.count++;
|
if (listening) listening.count++;
|
||||||
|
|
||||||
handlers.push({ callback: callback, context: context, ctx: context || ctx, listening: listening });
|
handlers.push({callback: callback, context: context, ctx: context || ctx, listening: listening});
|
||||||
}
|
}
|
||||||
return events;
|
return events;
|
||||||
};
|
};
|
||||||
|
@ -216,18 +216,18 @@
|
||||||
// callbacks with that function. If `callback` is null, removes all
|
// callbacks with that function. If `callback` is null, removes all
|
||||||
// callbacks for the event. If `name` is null, removes all bound
|
// callbacks for the event. If `name` is null, removes all bound
|
||||||
// callbacks for all events.
|
// callbacks for all events.
|
||||||
Events.off = function(name, callback, context) {
|
Events.off = function(name, callback, context) {
|
||||||
if (!this._events) return this;
|
if (!this._events) return this;
|
||||||
this._events = eventsApi(offApi, this._events, name, callback, {
|
this._events = eventsApi(offApi, this._events, name, callback, {
|
||||||
context: context,
|
context: context,
|
||||||
listeners: this._listeners
|
listeners: this._listeners
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tell this object to stop listening to either specific events ... or
|
// Tell this object to stop listening to either specific events ... or
|
||||||
// to every object it's currently listening to.
|
// to every object it's currently listening to.
|
||||||
Events.stopListening = function(obj, name, callback) {
|
Events.stopListening = function(obj, name, callback) {
|
||||||
var listeningTo = this._listeningTo;
|
var listeningTo = this._listeningTo;
|
||||||
if (!listeningTo) return this;
|
if (!listeningTo) return this;
|
||||||
|
|
||||||
|
@ -242,7 +242,6 @@
|
||||||
|
|
||||||
listening.obj.off(name, callback, this);
|
listening.obj.off(name, callback, this);
|
||||||
}
|
}
|
||||||
if (_.isEmpty(listeningTo)) this._listeningTo = void 0;
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
@ -299,21 +298,22 @@
|
||||||
delete events[name];
|
delete events[name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_.size(events)) return events;
|
return events;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bind an event to only be triggered a single time. After the first time
|
// Bind an event to only be triggered a single time. After the first time
|
||||||
// the callback is invoked, its listener will be removed. If multiple events
|
// the callback is invoked, its listener will be removed. If multiple events
|
||||||
// are passed in using the space-separated syntax, the handler will fire
|
// are passed in using the space-separated syntax, the handler will fire
|
||||||
// once for each event, not once for a combination of all events.
|
// once for each event, not once for a combination of all events.
|
||||||
Events.once = function(name, callback, context) {
|
Events.once = function(name, callback, context) {
|
||||||
// Map the event into a `{event: once}` object.
|
// Map the event into a `{event: once}` object.
|
||||||
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
|
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
|
||||||
return this.on(events, void 0, context);
|
if (typeof name === 'string' && context == null) callback = void 0;
|
||||||
|
return this.on(events, callback, context);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Inversion-of-control versions of `once`.
|
// Inversion-of-control versions of `once`.
|
||||||
Events.listenToOnce = function(obj, name, callback) {
|
Events.listenToOnce = function(obj, name, callback) {
|
||||||
// Map the event into a `{event: once}` object.
|
// Map the event into a `{event: once}` object.
|
||||||
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
|
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
|
||||||
return this.listenTo(obj, events);
|
return this.listenTo(obj, events);
|
||||||
|
@ -336,7 +336,7 @@
|
||||||
// passed the same arguments as `trigger` is, apart from the event name
|
// passed the same arguments as `trigger` is, apart from the event name
|
||||||
// (unless you're listening on `"all"`, which will cause your callback to
|
// (unless you're listening on `"all"`, which will cause your callback to
|
||||||
// receive the true name of the event as the first argument).
|
// receive the true name of the event as the first argument).
|
||||||
Events.trigger = function(name) {
|
Events.trigger = function(name) {
|
||||||
if (!this._events) return this;
|
if (!this._events) return this;
|
||||||
|
|
||||||
var length = Math.max(0, arguments.length - 1);
|
var length = Math.max(0, arguments.length - 1);
|
||||||
|
@ -348,7 +348,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handles triggering the appropriate event callbacks.
|
// Handles triggering the appropriate event callbacks.
|
||||||
var triggerApi = function(objEvents, name, cb, args) {
|
var triggerApi = function(objEvents, name, callback, args) {
|
||||||
if (objEvents) {
|
if (objEvents) {
|
||||||
var events = objEvents[name];
|
var events = objEvents[name];
|
||||||
var allEvents = objEvents.all;
|
var allEvents = objEvents.all;
|
||||||
|
@ -398,7 +398,8 @@
|
||||||
this.attributes = {};
|
this.attributes = {};
|
||||||
if (options.collection) this.collection = options.collection;
|
if (options.collection) this.collection = options.collection;
|
||||||
if (options.parse) attrs = this.parse(attrs, options) || {};
|
if (options.parse) attrs = this.parse(attrs, options) || {};
|
||||||
attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
|
var defaults = _.result(this, 'defaults');
|
||||||
|
attrs = _.defaults(_.extend({}, defaults, attrs), defaults);
|
||||||
this.set(attrs, options);
|
this.set(attrs, options);
|
||||||
this.changed = {};
|
this.changed = {};
|
||||||
this.initialize.apply(this, arguments);
|
this.initialize.apply(this, arguments);
|
||||||
|
@ -506,7 +507,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the `id`.
|
// Update the `id`.
|
||||||
this.id = this.get(this.idAttribute);
|
if (this.idAttribute in attrs) this.id = this.get(this.idAttribute);
|
||||||
|
|
||||||
// Trigger all relevant attribute changes.
|
// Trigger all relevant attribute changes.
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
|
@ -619,8 +620,8 @@
|
||||||
// the model will be valid when the attributes, if any, are set.
|
// the model will be valid when the attributes, if any, are set.
|
||||||
if (attrs && !wait) {
|
if (attrs && !wait) {
|
||||||
if (!this.set(attrs, options)) return false;
|
if (!this.set(attrs, options)) return false;
|
||||||
} else {
|
} else if (!this._validate(attrs, options)) {
|
||||||
if (!this._validate(attrs, options)) return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// After a successful server-side save, the client is (optionally)
|
// After a successful server-side save, the client is (optionally)
|
||||||
|
@ -714,7 +715,7 @@
|
||||||
|
|
||||||
// Check if the model is currently in a valid state.
|
// Check if the model is currently in a valid state.
|
||||||
isValid: function(options) {
|
isValid: function(options) {
|
||||||
return this._validate({}, _.defaults({validate: true}, options));
|
return this._validate({}, _.extend({}, options, {validate: true}));
|
||||||
},
|
},
|
||||||
|
|
||||||
// Run validation against the next complete set of model attributes,
|
// Run validation against the next complete set of model attributes,
|
||||||
|
@ -732,8 +733,8 @@
|
||||||
|
|
||||||
// Underscore methods that we want to implement on the Model, mapped to the
|
// Underscore methods that we want to implement on the Model, mapped to the
|
||||||
// number of arguments they take.
|
// number of arguments they take.
|
||||||
var modelMethods = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
|
var modelMethods = {keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
|
||||||
omit: 0, chain: 1, isEmpty: 1 };
|
omit: 0, chain: 1, isEmpty: 1};
|
||||||
|
|
||||||
// Mix in each Underscore method as a proxy to `Model#attributes`.
|
// Mix in each Underscore method as a proxy to `Model#attributes`.
|
||||||
addUnderscoreMethods(Model, modelMethods, 'attributes');
|
addUnderscoreMethods(Model, modelMethods, 'attributes');
|
||||||
|
@ -769,7 +770,8 @@
|
||||||
at = Math.min(Math.max(at, 0), array.length);
|
at = Math.min(Math.max(at, 0), array.length);
|
||||||
var tail = Array(array.length - at);
|
var tail = Array(array.length - at);
|
||||||
var length = insert.length;
|
var length = insert.length;
|
||||||
for (var i = 0; i < tail.length; i++) tail[i] = array[i + at];
|
var i;
|
||||||
|
for (i = 0; i < tail.length; i++) tail[i] = array[i + at];
|
||||||
for (i = 0; i < length; i++) array[i + at] = insert[i];
|
for (i = 0; i < length; i++) array[i + at] = insert[i];
|
||||||
for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
|
for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
|
||||||
};
|
};
|
||||||
|
@ -807,9 +809,12 @@
|
||||||
remove: function(models, options) {
|
remove: function(models, options) {
|
||||||
options = _.extend({}, options);
|
options = _.extend({}, options);
|
||||||
var singular = !_.isArray(models);
|
var singular = !_.isArray(models);
|
||||||
models = singular ? [models] : _.clone(models);
|
models = singular ? [models] : models.slice();
|
||||||
var removed = this._removeModels(models, options);
|
var removed = this._removeModels(models, options);
|
||||||
if (!options.silent && removed) this.trigger('update', this, options);
|
if (!options.silent && removed.length) {
|
||||||
|
options.changes = {added: [], merged: [], removed: removed};
|
||||||
|
this.trigger('update', this, options);
|
||||||
|
}
|
||||||
return singular ? removed[0] : removed;
|
return singular ? removed[0] : removed;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -820,18 +825,22 @@
|
||||||
set: function(models, options) {
|
set: function(models, options) {
|
||||||
if (models == null) return;
|
if (models == null) return;
|
||||||
|
|
||||||
options = _.defaults({}, options, setOptions);
|
options = _.extend({}, setOptions, options);
|
||||||
if (options.parse && !this._isModel(models)) models = this.parse(models, options);
|
if (options.parse && !this._isModel(models)) {
|
||||||
|
models = this.parse(models, options) || [];
|
||||||
|
}
|
||||||
|
|
||||||
var singular = !_.isArray(models);
|
var singular = !_.isArray(models);
|
||||||
models = singular ? [models] : models.slice();
|
models = singular ? [models] : models.slice();
|
||||||
|
|
||||||
var at = options.at;
|
var at = options.at;
|
||||||
if (at != null) at = +at;
|
if (at != null) at = +at;
|
||||||
|
if (at > this.length) at = this.length;
|
||||||
if (at < 0) at += this.length + 1;
|
if (at < 0) at += this.length + 1;
|
||||||
|
|
||||||
var set = [];
|
var set = [];
|
||||||
var toAdd = [];
|
var toAdd = [];
|
||||||
|
var toMerge = [];
|
||||||
var toRemove = [];
|
var toRemove = [];
|
||||||
var modelMap = {};
|
var modelMap = {};
|
||||||
|
|
||||||
|
@ -840,13 +849,13 @@
|
||||||
var remove = options.remove;
|
var remove = options.remove;
|
||||||
|
|
||||||
var sort = false;
|
var sort = false;
|
||||||
var sortable = this.comparator && (at == null) && options.sort !== false;
|
var sortable = this.comparator && at == null && options.sort !== false;
|
||||||
var sortAttr = _.isString(this.comparator) ? this.comparator : null;
|
var sortAttr = _.isString(this.comparator) ? this.comparator : null;
|
||||||
|
|
||||||
// Turn bare objects into model references, and prevent invalid models
|
// Turn bare objects into model references, and prevent invalid models
|
||||||
// from being added.
|
// from being added.
|
||||||
var model;
|
var model, i;
|
||||||
for (var i = 0; i < models.length; i++) {
|
for (i = 0; i < models.length; i++) {
|
||||||
model = models[i];
|
model = models[i];
|
||||||
|
|
||||||
// If a duplicate is found, prevent it from being added and
|
// If a duplicate is found, prevent it from being added and
|
||||||
|
@ -857,6 +866,7 @@
|
||||||
var attrs = this._isModel(model) ? model.attributes : model;
|
var attrs = this._isModel(model) ? model.attributes : model;
|
||||||
if (options.parse) attrs = existing.parse(attrs, options);
|
if (options.parse) attrs = existing.parse(attrs, options);
|
||||||
existing.set(attrs, options);
|
existing.set(attrs, options);
|
||||||
|
toMerge.push(existing);
|
||||||
if (sortable && !sort) sort = existing.hasChanged(sortAttr);
|
if (sortable && !sort) sort = existing.hasChanged(sortAttr);
|
||||||
}
|
}
|
||||||
if (!modelMap[existing.cid]) {
|
if (!modelMap[existing.cid]) {
|
||||||
|
@ -890,8 +900,8 @@
|
||||||
var orderChanged = false;
|
var orderChanged = false;
|
||||||
var replace = !sortable && add && remove;
|
var replace = !sortable && add && remove;
|
||||||
if (set.length && replace) {
|
if (set.length && replace) {
|
||||||
orderChanged = this.length != set.length || _.some(this.models, function(model, index) {
|
orderChanged = this.length !== set.length || _.some(this.models, function(m, index) {
|
||||||
return model !== set[index];
|
return m !== set[index];
|
||||||
});
|
});
|
||||||
this.models.length = 0;
|
this.models.length = 0;
|
||||||
splice(this.models, set, 0);
|
splice(this.models, set, 0);
|
||||||
|
@ -905,7 +915,7 @@
|
||||||
// Silently sort the collection if appropriate.
|
// Silently sort the collection if appropriate.
|
||||||
if (sort) this.sort({silent: true});
|
if (sort) this.sort({silent: true});
|
||||||
|
|
||||||
// Unless silenced, it's time to fire all appropriate add/sort events.
|
// Unless silenced, it's time to fire all appropriate add/sort/update events.
|
||||||
if (!options.silent) {
|
if (!options.silent) {
|
||||||
for (i = 0; i < toAdd.length; i++) {
|
for (i = 0; i < toAdd.length; i++) {
|
||||||
if (at != null) options.index = at + i;
|
if (at != null) options.index = at + i;
|
||||||
|
@ -913,7 +923,14 @@
|
||||||
model.trigger('add', model, this, options);
|
model.trigger('add', model, this, options);
|
||||||
}
|
}
|
||||||
if (sort || orderChanged) this.trigger('sort', this, options);
|
if (sort || orderChanged) this.trigger('sort', this, options);
|
||||||
if (toAdd.length || toRemove.length) this.trigger('update', this, options);
|
if (toAdd.length || toRemove.length || toMerge.length) {
|
||||||
|
options.changes = {
|
||||||
|
added: toAdd,
|
||||||
|
removed: toRemove,
|
||||||
|
merged: toMerge
|
||||||
|
};
|
||||||
|
this.trigger('update', this, options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the added (or merged) model (or models).
|
// Return the added (or merged) model (or models).
|
||||||
|
@ -963,11 +980,18 @@
|
||||||
return slice.apply(this.models, arguments);
|
return slice.apply(this.models, arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get a model from the set by id.
|
// Get a model from the set by id, cid, model object with id or cid
|
||||||
|
// properties, or an attributes object that is transformed through modelId.
|
||||||
get: function(obj) {
|
get: function(obj) {
|
||||||
if (obj == null) return void 0;
|
if (obj == null) return void 0;
|
||||||
var id = this.modelId(this._isModel(obj) ? obj.attributes : obj);
|
return this._byId[obj] ||
|
||||||
return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
|
this._byId[this.modelId(obj.attributes || obj)] ||
|
||||||
|
obj.cid && this._byId[obj.cid];
|
||||||
|
},
|
||||||
|
|
||||||
|
// Returns `true` if the model is in the collection.
|
||||||
|
has: function(obj) {
|
||||||
|
return this.get(obj) != null;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get the model at the given index.
|
// Get the model at the given index.
|
||||||
|
@ -1011,7 +1035,7 @@
|
||||||
|
|
||||||
// Pluck an attribute from each model in the collection.
|
// Pluck an attribute from each model in the collection.
|
||||||
pluck: function(attr) {
|
pluck: function(attr) {
|
||||||
return _.invoke(this.models, 'get', attr);
|
return this.map(attr + '');
|
||||||
},
|
},
|
||||||
|
|
||||||
// Fetch the default set of models for this collection, resetting the
|
// Fetch the default set of models for this collection, resetting the
|
||||||
|
@ -1042,9 +1066,9 @@
|
||||||
if (!wait) this.add(model, options);
|
if (!wait) this.add(model, options);
|
||||||
var collection = this;
|
var collection = this;
|
||||||
var success = options.success;
|
var success = options.success;
|
||||||
options.success = function(model, resp, callbackOpts) {
|
options.success = function(m, resp, callbackOpts) {
|
||||||
if (wait) collection.add(model, callbackOpts);
|
if (wait) collection.add(m, callbackOpts);
|
||||||
if (success) success.call(callbackOpts.context, model, resp, callbackOpts);
|
if (success) success.call(callbackOpts.context, m, resp, callbackOpts);
|
||||||
};
|
};
|
||||||
model.save(null, options);
|
model.save(null, options);
|
||||||
return model;
|
return model;
|
||||||
|
@ -1065,7 +1089,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
// Define how to uniquely identify models in the collection.
|
// Define how to uniquely identify models in the collection.
|
||||||
modelId: function (attrs) {
|
modelId: function(attrs) {
|
||||||
return attrs[this.model.prototype.idAttribute || 'id'];
|
return attrs[this.model.prototype.idAttribute || 'id'];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1103,6 +1127,12 @@
|
||||||
this.models.splice(index, 1);
|
this.models.splice(index, 1);
|
||||||
this.length--;
|
this.length--;
|
||||||
|
|
||||||
|
// Remove references before triggering 'remove' event to prevent an
|
||||||
|
// infinite loop. #3693
|
||||||
|
delete this._byId[model.cid];
|
||||||
|
var id = this.modelId(model.attributes);
|
||||||
|
if (id != null) delete this._byId[id];
|
||||||
|
|
||||||
if (!options.silent) {
|
if (!options.silent) {
|
||||||
options.index = index;
|
options.index = index;
|
||||||
model.trigger('remove', model, this, options);
|
model.trigger('remove', model, this, options);
|
||||||
|
@ -1111,12 +1141,12 @@
|
||||||
removed.push(model);
|
removed.push(model);
|
||||||
this._removeReference(model, options);
|
this._removeReference(model, options);
|
||||||
}
|
}
|
||||||
return removed.length ? removed : false;
|
return removed;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Method for checking whether an object should be considered a model for
|
// Method for checking whether an object should be considered a model for
|
||||||
// the purposes of adding to the collection.
|
// the purposes of adding to the collection.
|
||||||
_isModel: function (model) {
|
_isModel: function(model) {
|
||||||
return model instanceof Model;
|
return model instanceof Model;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1142,14 +1172,16 @@
|
||||||
// events simply proxy through. "add" and "remove" events that originate
|
// events simply proxy through. "add" and "remove" events that originate
|
||||||
// in other collections are ignored.
|
// in other collections are ignored.
|
||||||
_onModelEvent: function(event, model, collection, options) {
|
_onModelEvent: function(event, model, collection, options) {
|
||||||
if ((event === 'add' || event === 'remove') && collection !== this) return;
|
if (model) {
|
||||||
if (event === 'destroy') this.remove(model, options);
|
if ((event === 'add' || event === 'remove') && collection !== this) return;
|
||||||
if (event === 'change') {
|
if (event === 'destroy') this.remove(model, options);
|
||||||
var prevId = this.modelId(model.previousAttributes());
|
if (event === 'change') {
|
||||||
var id = this.modelId(model.attributes);
|
var prevId = this.modelId(model.previousAttributes());
|
||||||
if (prevId !== id) {
|
var id = this.modelId(model.attributes);
|
||||||
if (prevId != null) delete this._byId[prevId];
|
if (prevId !== id) {
|
||||||
if (id != null) this._byId[id] = model;
|
if (prevId != null) delete this._byId[prevId];
|
||||||
|
if (id != null) this._byId[id] = model;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.trigger.apply(this, arguments);
|
this.trigger.apply(this, arguments);
|
||||||
|
@ -1160,14 +1192,14 @@
|
||||||
// Underscore methods that we want to implement on the Collection.
|
// Underscore methods that we want to implement on the Collection.
|
||||||
// 90% of the core usefulness of Backbone Collections is actually implemented
|
// 90% of the core usefulness of Backbone Collections is actually implemented
|
||||||
// right here:
|
// right here:
|
||||||
var collectionMethods = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 4,
|
var collectionMethods = {forEach: 3, each: 3, map: 3, collect: 3, reduce: 0,
|
||||||
foldl: 4, inject: 4, reduceRight: 4, foldr: 4, find: 3, detect: 3, filter: 3,
|
foldl: 0, inject: 0, reduceRight: 0, foldr: 0, find: 3, detect: 3, filter: 3,
|
||||||
select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
|
select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
|
||||||
contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
|
contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
|
||||||
head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
|
head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
|
||||||
without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
|
without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
|
||||||
isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
|
isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
|
||||||
sortBy: 3, indexBy: 3};
|
sortBy: 3, indexBy: 3, findIndex: 3, findLastIndex: 3};
|
||||||
|
|
||||||
// Mix in each Underscore method as a proxy to `Collection#models`.
|
// Mix in each Underscore method as a proxy to `Collection#models`.
|
||||||
addUnderscoreMethods(Collection, collectionMethods, 'models');
|
addUnderscoreMethods(Collection, collectionMethods, 'models');
|
||||||
|
@ -1417,9 +1449,9 @@
|
||||||
var methodMap = {
|
var methodMap = {
|
||||||
'create': 'POST',
|
'create': 'POST',
|
||||||
'update': 'PUT',
|
'update': 'PUT',
|
||||||
'patch': 'PATCH',
|
'patch': 'PATCH',
|
||||||
'delete': 'DELETE',
|
'delete': 'DELETE',
|
||||||
'read': 'GET'
|
'read': 'GET'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set the default implementation of `Backbone.ajax` to proxy through to `$`.
|
// Set the default implementation of `Backbone.ajax` to proxy through to `$`.
|
||||||
|
@ -1576,8 +1608,8 @@
|
||||||
// Does the pathname match the root?
|
// Does the pathname match the root?
|
||||||
matchRoot: function() {
|
matchRoot: function() {
|
||||||
var path = this.decodeFragment(this.location.pathname);
|
var path = this.decodeFragment(this.location.pathname);
|
||||||
var root = path.slice(0, this.root.length - 1) + '/';
|
var rootPath = path.slice(0, this.root.length - 1) + '/';
|
||||||
return root === this.root;
|
return rootPath === this.root;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Unicode characters in `location.pathname` are percent encoded so they're
|
// Unicode characters in `location.pathname` are percent encoded so they're
|
||||||
|
@ -1649,8 +1681,8 @@
|
||||||
// If we've started off with a route from a `pushState`-enabled
|
// If we've started off with a route from a `pushState`-enabled
|
||||||
// browser, but we're currently in a browser that doesn't support it...
|
// browser, but we're currently in a browser that doesn't support it...
|
||||||
if (!this._hasPushState && !this.atRoot()) {
|
if (!this._hasPushState && !this.atRoot()) {
|
||||||
var root = this.root.slice(0, -1) || '/';
|
var rootPath = this.root.slice(0, -1) || '/';
|
||||||
this.location.replace(root + '#' + this.getPath());
|
this.location.replace(rootPath + '#' + this.getPath());
|
||||||
// Return immediately as browser will do redirect to new url
|
// Return immediately as browser will do redirect to new url
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1679,7 +1711,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a cross-platform `addEventListener` shim for older browsers.
|
// Add a cross-platform `addEventListener` shim for older browsers.
|
||||||
var addEventListener = window.addEventListener || function (eventName, listener) {
|
var addEventListener = window.addEventListener || function(eventName, listener) {
|
||||||
return attachEvent('on' + eventName, listener);
|
return attachEvent('on' + eventName, listener);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1700,7 +1732,7 @@
|
||||||
// but possibly useful for unit testing Routers.
|
// but possibly useful for unit testing Routers.
|
||||||
stop: function() {
|
stop: function() {
|
||||||
// Add a cross-platform `removeEventListener` shim for older browsers.
|
// Add a cross-platform `removeEventListener` shim for older browsers.
|
||||||
var removeEventListener = window.removeEventListener || function (eventName, listener) {
|
var removeEventListener = window.removeEventListener || function(eventName, listener) {
|
||||||
return detachEvent('on' + eventName, listener);
|
return detachEvent('on' + eventName, listener);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1774,11 +1806,11 @@
|
||||||
fragment = this.getFragment(fragment || '');
|
fragment = this.getFragment(fragment || '');
|
||||||
|
|
||||||
// Don't include a trailing slash on the root.
|
// Don't include a trailing slash on the root.
|
||||||
var root = this.root;
|
var rootPath = this.root;
|
||||||
if (fragment === '' || fragment.charAt(0) === '?') {
|
if (fragment === '' || fragment.charAt(0) === '?') {
|
||||||
root = root.slice(0, -1) || '/';
|
rootPath = rootPath.slice(0, -1) || '/';
|
||||||
}
|
}
|
||||||
var url = root + fragment;
|
var url = rootPath + fragment;
|
||||||
|
|
||||||
// Strip the hash and decode for matching.
|
// Strip the hash and decode for matching.
|
||||||
fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
|
fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
|
||||||
|
@ -1794,7 +1826,7 @@
|
||||||
// fragment to store history.
|
// fragment to store history.
|
||||||
} else if (this._wantsHashChange) {
|
} else if (this._wantsHashChange) {
|
||||||
this._updateHash(this.location, fragment, options.replace);
|
this._updateHash(this.location, fragment, options.replace);
|
||||||
if (this.iframe && (fragment !== this.getHash(this.iframe.contentWindow))) {
|
if (this.iframe && fragment !== this.getHash(this.iframe.contentWindow)) {
|
||||||
var iWindow = this.iframe.contentWindow;
|
var iWindow = this.iframe.contentWindow;
|
||||||
|
|
||||||
// Opening and closing the iframe tricks IE7 and earlier to push a
|
// Opening and closing the iframe tricks IE7 and earlier to push a
|
||||||
|
@ -1856,14 +1888,9 @@
|
||||||
_.extend(child, parent, staticProps);
|
_.extend(child, parent, staticProps);
|
||||||
|
|
||||||
// Set the prototype chain to inherit from `parent`, without calling
|
// Set the prototype chain to inherit from `parent`, without calling
|
||||||
// `parent` constructor function.
|
// `parent`'s constructor function and add the prototype properties.
|
||||||
var Surrogate = function(){ this.constructor = child; };
|
child.prototype = _.create(parent.prototype, protoProps);
|
||||||
Surrogate.prototype = parent.prototype;
|
child.prototype.constructor = child;
|
||||||
child.prototype = new Surrogate;
|
|
||||||
|
|
||||||
// Add prototype properties (instance properties) to the subclass,
|
|
||||||
// if supplied.
|
|
||||||
if (protoProps) _.extend(child.prototype, protoProps);
|
|
||||||
|
|
||||||
// Set a convenience property in case the parent's prototype is needed
|
// Set a convenience property in case the parent's prototype is needed
|
||||||
// later.
|
// later.
|
||||||
|
@ -1890,5 +1917,4 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
return Backbone;
|
return Backbone;
|
||||||
|
});
|
||||||
}));
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group dependencies
|
||||||
|
* @group scripts
|
||||||
|
*/
|
||||||
|
class Tests_Dependencies_Backbonejs extends WP_UnitTestCase {
|
||||||
|
|
||||||
|
function test_exclusion_of_sourcemaps() {
|
||||||
|
$file = ABSPATH . WPINC . '/js/backbone.min.js';
|
||||||
|
$this->assertTrue( file_exists( $file ) );
|
||||||
|
$contents = trim( file_get_contents( $file ) );
|
||||||
|
$this->assertFalse( strpos( $contents, 'sourceMappingURL' ), 'Presence of sourceMappingURL' );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue