backbone-rails 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
- // Backbone.js 0.9.0
1
+ // Backbone.js 0.9.1
2
+
2
3
  // (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
3
4
  // Backbone may be freely distributed under the MIT license.
4
5
  // For all details and documentation:
@@ -31,7 +32,7 @@
31
32
  }
32
33
 
33
34
  // Current version of the library. Keep in sync with `package.json`.
34
- Backbone.VERSION = '0.9.0';
35
+ Backbone.VERSION = '0.9.1';
35
36
 
36
37
  // Require Underscore, if we're on the server, and it's not already present.
37
38
  var _ = root._;
@@ -40,6 +41,15 @@
40
41
  // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable.
41
42
  var $ = root.jQuery || root.Zepto || root.ender;
42
43
 
44
+ // Set the JavaScript library that will be used for DOM manipulation and
45
+ // Ajax calls (a.k.a. the `$` variable). By default Backbone will use: jQuery,
46
+ // Zepto, or Ender; but the `setDomLibrary()` method lets you inject an
47
+ // alternate JavaScript library (or a mock library for testing your views
48
+ // outside of a browser).
49
+ Backbone.setDomLibrary = function(lib) {
50
+ $ = lib;
51
+ };
52
+
43
53
  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
44
54
  // to its previous owner. Returns a reference to this Backbone object.
45
55
  Backbone.noConflict = function() {
@@ -163,11 +173,10 @@
163
173
  this.attributes = {};
164
174
  this._escapedAttributes = {};
165
175
  this.cid = _.uniqueId('c');
166
- this._changed = {};
167
176
  if (!this.set(attributes, {silent: true})) {
168
177
  throw new Error("Can't create an invalid model");
169
178
  }
170
- this._changed = {};
179
+ delete this._changed;
171
180
  this._previousAttributes = _.clone(this.attributes);
172
181
  this.initialize.apply(this, arguments);
173
182
  };
@@ -223,10 +232,10 @@
223
232
  options || (options = {});
224
233
  if (!attrs) return this;
225
234
  if (attrs instanceof Backbone.Model) attrs = attrs.attributes;
226
- if (options.unset) for (var attr in attrs) attrs[attr] = void 0;
235
+ if (options.unset) for (attr in attrs) attrs[attr] = void 0;
227
236
 
228
237
  // Run validation.
229
- if (this.validate && !this._performValidation(attrs, options)) return false;
238
+ if (!this._validate(attrs, options)) return false;
230
239
 
231
240
  // Check for changes of `id`.
232
241
  if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
@@ -234,14 +243,19 @@
234
243
  var now = this.attributes;
235
244
  var escaped = this._escapedAttributes;
236
245
  var prev = this._previousAttributes || {};
237
- var alreadyChanging = this._changing;
238
- this._changing = true;
246
+ var alreadySetting = this._setting;
247
+ this._changed || (this._changed = {});
248
+ this._setting = true;
239
249
 
240
250
  // Update attributes.
241
251
  for (attr in attrs) {
242
252
  val = attrs[attr];
243
253
  if (!_.isEqual(now[attr], val)) delete escaped[attr];
244
254
  options.unset ? delete now[attr] : now[attr] = val;
255
+ if (this._changing && !_.isEqual(this._changed[attr], val)) {
256
+ this.trigger('change:' + attr, this, val, options);
257
+ this._moreChanges = true;
258
+ }
245
259
  delete this._changed[attr];
246
260
  if (!_.isEqual(prev[attr], val) || (_.has(now, attr) != _.has(prev, attr))) {
247
261
  this._changed[attr] = val;
@@ -249,9 +263,9 @@
249
263
  }
250
264
 
251
265
  // Fire the `"change"` events, if the model has been changed.
252
- if (!alreadyChanging) {
266
+ if (!alreadySetting) {
253
267
  if (!options.silent && this.hasChanged()) this.change(options);
254
- this._changing = false;
268
+ this._setting = false;
255
269
  }
256
270
  return this;
257
271
  },
@@ -289,7 +303,7 @@
289
303
  // If the server returns an attributes hash that differs, the model's
290
304
  // state will be `set` again.
291
305
  save: function(key, value, options) {
292
- var attrs;
306
+ var attrs, current;
293
307
  if (_.isObject(key) || key == null) {
294
308
  attrs = key;
295
309
  options = value;
@@ -299,7 +313,11 @@
299
313
  }
300
314
 
301
315
  options = options ? _.clone(options) : {};
302
- if (attrs && !this[options.wait ? '_performValidation' : 'set'](attrs, options)) return false;
316
+ if (options.wait) current = _.clone(this.attributes);
317
+ var silentOptions = _.extend({}, options, {silent: true});
318
+ if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
319
+ return false;
320
+ }
303
321
  var model = this;
304
322
  var success = options.success;
305
323
  options.success = function(resp, status, xhr) {
@@ -314,7 +332,9 @@
314
332
  };
315
333
  options.error = Backbone.wrapError(options.error, model, options);
316
334
  var method = this.isNew() ? 'create' : 'update';
317
- return (this.sync || Backbone.sync).call(this, method, this, options);
335
+ var xhr = (this.sync || Backbone.sync).call(this, method, this, options);
336
+ if (options.wait) this.set(current, silentOptions);
337
+ return xhr;
318
338
  },
319
339
 
320
340
  // Destroy this model on the server if it was already persisted.
@@ -373,19 +393,27 @@
373
393
  // a `"change:attribute"` event for each changed attribute.
374
394
  // Calling this will cause all objects observing the model to update.
375
395
  change: function(options) {
396
+ if (this._changing || !this.hasChanged()) return this;
397
+ this._changing = true;
398
+ this._moreChanges = true;
376
399
  for (var attr in this._changed) {
377
400
  this.trigger('change:' + attr, this, this._changed[attr], options);
378
401
  }
379
- this.trigger('change', this, options);
402
+ while (this._moreChanges) {
403
+ this._moreChanges = false;
404
+ this.trigger('change', this, options);
405
+ }
380
406
  this._previousAttributes = _.clone(this.attributes);
381
- this._changed = {};
407
+ delete this._changed;
408
+ this._changing = false;
409
+ return this;
382
410
  },
383
411
 
384
412
  // Determine if the model has changed since the last `"change"` event.
385
413
  // If you specify an attribute name, determine if that attribute has changed.
386
414
  hasChanged: function(attr) {
387
- if (attr) return _.has(this._changed, attr);
388
- return !_.isEmpty(this._changed);
415
+ if (!arguments.length) return !_.isEmpty(this._changed);
416
+ return this._changed && _.has(this._changed, attr);
389
417
  },
390
418
 
391
419
  // Return an object containing all the attributes that have changed, or
@@ -407,7 +435,7 @@
407
435
  // Get the previous value of an attribute, recorded at the time the last
408
436
  // `"change"` event was fired.
409
437
  previous: function(attr) {
410
- if (!attr || !this._previousAttributes) return null;
438
+ if (!arguments.length || !this._previousAttributes) return null;
411
439
  return this._previousAttributes[attr];
412
440
  },
413
441
 
@@ -417,21 +445,26 @@
417
445
  return _.clone(this._previousAttributes);
418
446
  },
419
447
 
448
+ // Check if the model is currently in a valid state. It's only possible to
449
+ // get into an *invalid* state if you're using silent changes.
450
+ isValid: function() {
451
+ return !this.validate(this.attributes);
452
+ },
453
+
420
454
  // Run validation against a set of incoming attributes, returning `true`
421
455
  // if all is well. If a specific `error` callback has been passed,
422
456
  // call that instead of firing the general `"error"` event.
423
- _performValidation: function(attrs, options) {
424
- var newAttrs = _.extend({}, this.attributes, attrs);
425
- var error = this.validate(newAttrs, options);
426
- if (error) {
427
- if (options.error) {
428
- options.error(this, error, options);
429
- } else {
430
- this.trigger('error', this, error, options);
431
- }
432
- return false;
457
+ _validate: function(attrs, options) {
458
+ if (options.silent || !this.validate) return true;
459
+ attrs = _.extend({}, this.attributes, attrs);
460
+ var error = this.validate(attrs, options);
461
+ if (!error) return true;
462
+ if (options && options.error) {
463
+ options.error(this, error, options);
464
+ } else {
465
+ this.trigger('error', this, error, options);
433
466
  }
434
- return true;
467
+ return false;
435
468
  }
436
469
 
437
470
  });
@@ -650,7 +683,7 @@
650
683
  var attrs = model;
651
684
  options.collection = this;
652
685
  model = new this.model(attrs, options);
653
- if (model.validate && !model._performValidation(model.attributes, options)) model = false;
686
+ if (!model._validate(model.attributes, options)) model = false;
654
687
  } else if (!model.collection) {
655
688
  model.collection = this;
656
689
  }
@@ -815,9 +848,9 @@
815
848
  fragment = window.location.hash;
816
849
  }
817
850
  }
818
- fragment = decodeURIComponent(fragment.replace(routeStripper, ''));
851
+ fragment = decodeURIComponent(fragment);
819
852
  if (!fragment.indexOf(this.options.root)) fragment = fragment.substr(this.options.root.length);
820
- return fragment;
853
+ return fragment.replace(routeStripper, '');
821
854
  },
822
855
 
823
856
  // Start the hash change handling, returning `true` if the current URL matches
@@ -1031,6 +1064,7 @@
1031
1064
  this.$el = $(element);
1032
1065
  this.el = this.$el[0];
1033
1066
  if (delegate !== false) this.delegateEvents();
1067
+ return this;
1034
1068
  },
1035
1069
 
1036
1070
  // Set callbacks, where `this.events` is a hash of
@@ -1187,11 +1221,11 @@
1187
1221
  // Wrap an optional error callback with a fallback error event.
1188
1222
  Backbone.wrapError = function(onError, originalModel, options) {
1189
1223
  return function(model, resp) {
1190
- var resp = model === originalModel ? resp : model;
1224
+ resp = model === originalModel ? resp : model;
1191
1225
  if (onError) {
1192
- onError(model, resp, options);
1226
+ onError(originalModel, resp, options);
1193
1227
  } else {
1194
- originalModel.trigger('error', model, resp, options);
1228
+ originalModel.trigger('error', originalModel, resp, options);
1195
1229
  }
1196
1230
  };
1197
1231
  };
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backbone-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-06 00:00:00.000000000Z
12
+ date: 2012-03-13 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &2157255900 !ruby/object:Gem::Requirement
16
+ requirement: &2156951720 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: 3.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2157255900
24
+ version_requirements: *2156951720
25
25
  description: Ships backbone and underscore to your Rails 3.1 application through the
26
26
  new asset pipeline. Rails 3.0 is supported via generators.
27
27
  email:
@@ -65,3 +65,4 @@ signing_key:
65
65
  specification_version: 3
66
66
  summary: backbone and underscore for Rails
67
67
  test_files: []
68
+ has_rdoc: