wp/wp-includes/js/backbone.js
changeset 19 3d72ae0968f4
parent 16 a86126ab1dd4
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
     1 //     Backbone.js 1.4.0
     1 //     Backbone.js 1.4.1
     2 
     2 
     3 //     (c) 2010-2019 Jeremy Ashkenas and DocumentCloud
     3 //     (c) 2010-2022 Jeremy Ashkenas and DocumentCloud
     4 //     Backbone may be freely distributed under the MIT license.
     4 //     Backbone may be freely distributed under the MIT license.
     5 //     For all details and documentation:
     5 //     For all details and documentation:
     6 //     http://backbonejs.org
     6 //     http://backbonejs.org
     7 
     7 
     8 (function(factory) {
     8 (function(factory) {
    42 
    42 
    43   // Create a local reference to a common array method we'll want to use later.
    43   // Create a local reference to a common array method we'll want to use later.
    44   var slice = Array.prototype.slice;
    44   var slice = Array.prototype.slice;
    45 
    45 
    46   // Current version of the library. Keep in sync with `package.json`.
    46   // Current version of the library. Keep in sync with `package.json`.
    47   Backbone.VERSION = '1.4.0';
    47   Backbone.VERSION = '1.4.1';
    48 
    48 
    49   // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
    49   // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
    50   // the `$` variable.
    50   // the `$` variable.
    51   Backbone.$ = $;
    51   Backbone.$ = $;
    52 
    52 
   514         }
   514         }
   515         unset ? delete current[attr] : current[attr] = val;
   515         unset ? delete current[attr] : current[attr] = val;
   516       }
   516       }
   517 
   517 
   518       // Update the `id`.
   518       // Update the `id`.
   519       if (this.idAttribute in attrs) this.id = this.get(this.idAttribute);
   519       if (this.idAttribute in attrs) {
       
   520         var prevId = this.id;
       
   521         this.id = this.get(this.idAttribute);
       
   522         this.trigger('changeId', this, prevId, options);
       
   523       }
   520 
   524 
   521       // Trigger all relevant attribute changes.
   525       // Trigger all relevant attribute changes.
   522       if (!silent) {
   526       if (!silent) {
   523         if (changes.length) this._pending = options;
   527         if (changes.length) this._pending = options;
   524         for (var i = 0; i < changes.length; i++) {
   528         for (var i = 0; i < changes.length; i++) {
   992     // Get a model from the set by id, cid, model object with id or cid
   996     // Get a model from the set by id, cid, model object with id or cid
   993     // properties, or an attributes object that is transformed through modelId.
   997     // properties, or an attributes object that is transformed through modelId.
   994     get: function(obj) {
   998     get: function(obj) {
   995       if (obj == null) return void 0;
   999       if (obj == null) return void 0;
   996       return this._byId[obj] ||
  1000       return this._byId[obj] ||
   997         this._byId[this.modelId(this._isModel(obj) ? obj.attributes : obj)] ||
  1001         this._byId[this.modelId(this._isModel(obj) ? obj.attributes : obj, obj.idAttribute)] ||
   998         obj.cid && this._byId[obj.cid];
  1002         obj.cid && this._byId[obj.cid];
   999     },
  1003     },
  1000 
  1004 
  1001     // Returns `true` if the model is in the collection.
  1005     // Returns `true` if the model is in the collection.
  1002     has: function(obj) {
  1006     has: function(obj) {
  1096         comparator: this.comparator
  1100         comparator: this.comparator
  1097       });
  1101       });
  1098     },
  1102     },
  1099 
  1103 
  1100     // Define how to uniquely identify models in the collection.
  1104     // Define how to uniquely identify models in the collection.
  1101     modelId: function(attrs) {
  1105     modelId: function(attrs, idAttribute) {
  1102       return attrs[this.model.prototype.idAttribute || 'id'];
  1106       return attrs[idAttribute || this.model.prototype.idAttribute || 'id'];
  1103     },
  1107     },
  1104 
  1108 
  1105     // Get an iterator of all models in this collection.
  1109     // Get an iterator of all models in this collection.
  1106     values: function() {
  1110     values: function() {
  1107       return new CollectionIterator(this, ITERATOR_VALUES);
  1111       return new CollectionIterator(this, ITERATOR_VALUES);
  1132         if (!attrs.collection) attrs.collection = this;
  1136         if (!attrs.collection) attrs.collection = this;
  1133         return attrs;
  1137         return attrs;
  1134       }
  1138       }
  1135       options = options ? _.clone(options) : {};
  1139       options = options ? _.clone(options) : {};
  1136       options.collection = this;
  1140       options.collection = this;
  1137       var model = new this.model(attrs, options);
  1141 
       
  1142       var model;
       
  1143       if (this.model.prototype) {
       
  1144         model = new this.model(attrs, options);
       
  1145       } else {
       
  1146         // ES class methods didn't have prototype
       
  1147         model = this.model(attrs, options);
       
  1148       }
       
  1149 
  1138       if (!model.validationError) return model;
  1150       if (!model.validationError) return model;
  1139       this.trigger('invalid', this, model.validationError, options);
  1151       this.trigger('invalid', this, model.validationError, options);
  1140       return false;
  1152       return false;
  1141     },
  1153     },
  1142 
  1154 
  1152         this.length--;
  1164         this.length--;
  1153 
  1165 
  1154         // Remove references before triggering 'remove' event to prevent an
  1166         // Remove references before triggering 'remove' event to prevent an
  1155         // infinite loop. #3693
  1167         // infinite loop. #3693
  1156         delete this._byId[model.cid];
  1168         delete this._byId[model.cid];
  1157         var id = this.modelId(model.attributes);
  1169         var id = this.modelId(model.attributes, model.idAttribute);
  1158         if (id != null) delete this._byId[id];
  1170         if (id != null) delete this._byId[id];
  1159 
  1171 
  1160         if (!options.silent) {
  1172         if (!options.silent) {
  1161           options.index = index;
  1173           options.index = index;
  1162           model.trigger('remove', model, this, options);
  1174           model.trigger('remove', model, this, options);
  1175     },
  1187     },
  1176 
  1188 
  1177     // Internal method to create a model's ties to a collection.
  1189     // Internal method to create a model's ties to a collection.
  1178     _addReference: function(model, options) {
  1190     _addReference: function(model, options) {
  1179       this._byId[model.cid] = model;
  1191       this._byId[model.cid] = model;
  1180       var id = this.modelId(model.attributes);
  1192       var id = this.modelId(model.attributes, model.idAttribute);
  1181       if (id != null) this._byId[id] = model;
  1193       if (id != null) this._byId[id] = model;
  1182       model.on('all', this._onModelEvent, this);
  1194       model.on('all', this._onModelEvent, this);
  1183     },
  1195     },
  1184 
  1196 
  1185     // Internal method to sever a model's ties to a collection.
  1197     // Internal method to sever a model's ties to a collection.
  1186     _removeReference: function(model, options) {
  1198     _removeReference: function(model, options) {
  1187       delete this._byId[model.cid];
  1199       delete this._byId[model.cid];
  1188       var id = this.modelId(model.attributes);
  1200       var id = this.modelId(model.attributes, model.idAttribute);
  1189       if (id != null) delete this._byId[id];
  1201       if (id != null) delete this._byId[id];
  1190       if (this === model.collection) delete model.collection;
  1202       if (this === model.collection) delete model.collection;
  1191       model.off('all', this._onModelEvent, this);
  1203       model.off('all', this._onModelEvent, this);
  1192     },
  1204     },
  1193 
  1205 
  1197     // in other collections are ignored.
  1209     // in other collections are ignored.
  1198     _onModelEvent: function(event, model, collection, options) {
  1210     _onModelEvent: function(event, model, collection, options) {
  1199       if (model) {
  1211       if (model) {
  1200         if ((event === 'add' || event === 'remove') && collection !== this) return;
  1212         if ((event === 'add' || event === 'remove') && collection !== this) return;
  1201         if (event === 'destroy') this.remove(model, options);
  1213         if (event === 'destroy') this.remove(model, options);
  1202         if (event === 'change') {
  1214         if (event === 'changeId') {
  1203           var prevId = this.modelId(model.previousAttributes());
  1215           var prevId = this.modelId(model.previousAttributes(), model.idAttribute);
  1204           var id = this.modelId(model.attributes);
  1216           var id = this.modelId(model.attributes, model.idAttribute);
  1205           if (prevId !== id) {
  1217           if (prevId != null) delete this._byId[prevId];
  1206             if (prevId != null) delete this._byId[prevId];
  1218           if (id != null) this._byId[id] = model;
  1207             if (id != null) this._byId[id] = model;
       
  1208           }
       
  1209         }
  1219         }
  1210       }
  1220       }
  1211       this.trigger.apply(this, arguments);
  1221       this.trigger.apply(this, arguments);
  1212     }
  1222     }
  1213 
  1223 
  1259         // Construct a value depending on what kind of values should be iterated.
  1269         // Construct a value depending on what kind of values should be iterated.
  1260         var value;
  1270         var value;
  1261         if (this._kind === ITERATOR_VALUES) {
  1271         if (this._kind === ITERATOR_VALUES) {
  1262           value = model;
  1272           value = model;
  1263         } else {
  1273         } else {
  1264           var id = this._collection.modelId(model.attributes);
  1274           var id = this._collection.modelId(model.attributes, model.idAttribute);
  1265           if (this._kind === ITERATOR_KEYS) {
  1275           if (this._kind === ITERATOR_KEYS) {
  1266             value = id;
  1276             value = id;
  1267           } else { // ITERATOR_KEYSVALUES
  1277           } else { // ITERATOR_KEYSVALUES
  1268             value = [id, model];
  1278             value = [id, model];
  1269           }
  1279           }
  1613     return xhr;
  1623     return xhr;
  1614   };
  1624   };
  1615 
  1625 
  1616   // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
  1626   // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
  1617   var methodMap = {
  1627   var methodMap = {
  1618     create: 'POST',
  1628     'create': 'POST',
  1619     update: 'PUT',
  1629     'update': 'PUT',
  1620     patch: 'PATCH',
  1630     'patch': 'PATCH',
  1621     delete: 'DELETE',
  1631     'delete': 'DELETE',
  1622     read: 'GET'
  1632     'read': 'GET'
  1623   };
  1633   };
  1624 
  1634 
  1625   // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
  1635   // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
  1626   // Override this if you'd like to use a different library.
  1636   // Override this if you'd like to use a different library.
  1627   Backbone.ajax = function() {
  1637   Backbone.ajax = function() {
  1710 
  1720 
  1711     // Convert a route string into a regular expression, suitable for matching
  1721     // Convert a route string into a regular expression, suitable for matching
  1712     // against the current location hash.
  1722     // against the current location hash.
  1713     _routeToRegExp: function(route) {
  1723     _routeToRegExp: function(route) {
  1714       route = route.replace(escapeRegExp, '\\$&')
  1724       route = route.replace(escapeRegExp, '\\$&')
  1715         .replace(optionalParam, '(?:$1)?')
  1725       .replace(optionalParam, '(?:$1)?')
  1716         .replace(namedParam, function(match, optional) {
  1726       .replace(namedParam, function(match, optional) {
  1717           return optional ? match : '([^/?]+)';
  1727         return optional ? match : '([^/?]+)';
  1718         })
  1728       })
  1719         .replace(splatParam, '([^?]*?)');
  1729       .replace(splatParam, '([^?]*?)');
  1720       return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
  1730       return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
  1721     },
  1731     },
  1722 
  1732 
  1723     // Given a route, and a URL fragment that it matches, return the array of
  1733     // Given a route, and a URL fragment that it matches, return the array of
  1724     // extracted decoded parameters. Empty or unmatched parameters will be
  1734     // extracted decoded parameters. Empty or unmatched parameters will be