Permalink
Browse files

Merge branch 'original' (Updating to 0.9.1)

Conflicts:
	backbone.js
	package.json
  • Loading branch information...
2 parents 2c6c1e0 + 65fa4f4 commit 4861fd7f6e9f24f841734eb2203f213c84317d6a Claudio Cicali committed Feb 3, 2012
Showing with 594 additions and 344 deletions.
  1. +33 −31 backbone-min.js
  2. +68 −36 backbone.js
  3. +183 −156 docs/backbone.html
  4. BIN docs/images/trajectory.png
  5. BIN docs/images/wunderkit.png
  6. +98 −30 index.html
  7. +1 −1 package.json
  8. +29 −47 test/collection.js
  9. +134 −36 test/model.js
  10. +31 −0 test/setdomlibrary.js
  11. +16 −7 test/sync.js
  12. +1 −0 test/test.html
View

Large diffs are not rendered by default.

Oops, something went wrong.
View
@@ -1,4 +1,5 @@
-// Backbone.js 0.9.0
+// Backbone.js 0.9.1
+
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
@@ -31,7 +32,7 @@
}
// Current version of the library. Keep in sync with `package.json`.
- Backbone.VERSION = '0.9.0-SP';
+ Backbone.VERSION = '0.9.1-SP';
// Require Underscore, if we're on the server, and it's not already present.
var _ = root._;
@@ -41,6 +42,15 @@
// var $ = root.jQuery || root.Zepto || root.ender;
var $ = (root.Sponsorpay && root.Sponsorpay.jQuery) ? root.Sponsorpay.jQuery : root.jQuery;
+ // Set the JavaScript library that will be used for DOM manipulation and
+ // Ajax calls (a.k.a. the `$` variable). By default Backbone will use: jQuery,
+ // Zepto, or Ender; but the `setDomLibrary()` method lets you inject an
+ // alternate JavaScript library (or a mock library for testing your views
+ // outside of a browser).
+ Backbone.setDomLibrary = function(lib) {
+ $ = lib;
+ };
+
// Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
// to its previous owner. Returns a reference to this Backbone object.
Backbone.noConflict = function() {
@@ -164,11 +174,8 @@
this.attributes = {};
this._escapedAttributes = {};
this.cid = _.uniqueId('c');
- this._changed = {};
- if (!this.set(attributes, {silent: true})) {
- throw new Error("Can't create an invalid model");
- }
- this._changed = {};
+ this.set(attributes, {silent: true});
+ delete this._changed;
this._previousAttributes = _.clone(this.attributes);
this.initialize.apply(this, arguments);
};
@@ -227,32 +234,37 @@
if (options.unset) for (attr in attrs) attrs[attr] = void 0;
// Run validation.
- if (this.validate && !this._performValidation(attrs, options)) return false;
+ if (!this._validate(attrs, options)) return false;
// Check for changes of `id`.
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
var now = this.attributes;
var escaped = this._escapedAttributes;
var prev = this._previousAttributes || {};
- var alreadyChanging = this._changing;
- this._changing = true;
+ var alreadySetting = this._setting;
+ this._changed || (this._changed = {});
+ this._setting = true;
// Update attributes.
for (attr in attrs) {
val = attrs[attr];
if (!_.isEqual(now[attr], val)) delete escaped[attr];
options.unset ? delete now[attr] : now[attr] = val;
+ if (this._changing && !_.isEqual(this._changed[attr], val)) {
+ this.trigger('change:' + attr, this, val, options);
+ this._moreChanges = true;
+ }
delete this._changed[attr];
if (!_.isEqual(prev[attr], val) || (_.has(now, attr) != _.has(prev, attr))) {
this._changed[attr] = val;
}
}
// Fire the `"change"` events, if the model has been changed.
- if (!alreadyChanging) {
+ if (!alreadySetting) {
if (!options.silent && this.hasChanged()) this.change(options);
- this._changing = false;
+ this._setting = false;
}
return this;
},
@@ -290,7 +302,7 @@
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save: function(key, value, options) {
- var attrs;
+ var attrs, current;
if (_.isObject(key) || key == null) {
attrs = key;
options = value;
@@ -300,7 +312,11 @@
}
options = options ? _.clone(options) : {};
- if (attrs && !this[options.wait ? '_performValidation' : 'set'](attrs, options)) return false;
+ if (options.wait) current = _.clone(this.attributes);
+ var silentOptions = _.extend({}, options, {silent: true});
+ if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
+ return false;
+ }
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
@@ -315,7 +331,9 @@
};
options.error = Backbone.wrapError(options.error, model, options);
var method = this.isNew() ? 'create' : 'update';
- return (this.sync || Backbone.sync).call(this, method, this, options);
+ var xhr = (this.sync || Backbone.sync).call(this, method, this, options);
+ if (options.wait) this.set(current, silentOptions);
+ return xhr;
},
// Destroy this model on the server if it was already persisted.
@@ -374,19 +392,27 @@
// a `"change:attribute"` event for each changed attribute.
// Calling this will cause all objects observing the model to update.
change: function(options) {
+ if (this._changing || !this.hasChanged()) return this;
+ this._changing = true;
+ this._moreChanges = true;
for (var attr in this._changed) {
this.trigger('change:' + attr, this, this._changed[attr], options);
}
- this.trigger('change', this, options);
+ while (this._moreChanges) {
+ this._moreChanges = false;
+ this.trigger('change', this, options);
+ }
this._previousAttributes = _.clone(this.attributes);
- this._changed = {};
+ delete this._changed;
+ this._changing = false;
+ return this;
},
// Determine if the model has changed since the last `"change"` event.
// If you specify an attribute name, determine if that attribute has changed.
hasChanged: function(attr) {
- if (attr) return _.has(this._changed, attr);
- return !_.isEmpty(this._changed);
+ if (!arguments.length) return !_.isEmpty(this._changed);
+ return this._changed && _.has(this._changed, attr);
},
// Return an object containing all the attributes that have changed, or
@@ -408,7 +434,7 @@
// Get the previous value of an attribute, recorded at the time the last
// `"change"` event was fired.
previous: function(attr) {
- if (!attr || !this._previousAttributes) return null;
+ if (!arguments.length || !this._previousAttributes) return null;
return this._previousAttributes[attr];
},
@@ -418,21 +444,26 @@
return _.clone(this._previousAttributes);
},
+ // Check if the model is currently in a valid state. It's only possible to
+ // get into an *invalid* state if you're using silent changes.
+ isValid: function() {
+ return !this.validate(this.attributes);
+ },
+
// Run validation against a set of incoming attributes, returning `true`
// if all is well. If a specific `error` callback has been passed,
// call that instead of firing the general `"error"` event.
- _performValidation: function(attrs, options) {
- var newAttrs = _.extend({}, this.attributes, attrs);
- var error = this.validate(newAttrs, options);
- if (error) {
- if (options.error) {
- options.error(this, error, options);
- } else {
- this.trigger('error', this, error, options);
- }
- return false;
+ _validate: function(attrs, options) {
+ if (options.silent || !this.validate) return true;
+ attrs = _.extend({}, this.attributes, attrs);
+ var error = this.validate(attrs, options);
+ if (!error) return true;
+ if (options && options.error) {
+ options.error(this, error, options);
+ } else {
+ this.trigger('error', this, error, options);
}
- return true;
+ return false;
}
});
@@ -651,7 +682,7 @@
var attrs = model;
options.collection = this;
model = new this.model(attrs, options);
- if (model.validate && !model._performValidation(model.attributes, options)) model = false;
+ if (!model._validate(model.attributes, options)) model = false;
} else if (!model.collection) {
model.collection = this;
}
@@ -816,9 +847,9 @@
fragment = window.location.hash;
}
}
- fragment = decodeURIComponent(fragment.replace(routeStripper, ''));
+ fragment = decodeURIComponent(fragment);
if (!fragment.indexOf(this.options.root)) fragment = fragment.substr(this.options.root.length);
- return fragment;
+ return fragment.replace(routeStripper, '');
},
// Start the hash change handling, returning `true` if the current URL matches
@@ -1032,6 +1063,7 @@
this.$el = $(element);
this.el = this.$el[0];
if (delegate !== false) this.delegateEvents();
+ return this;
},
// Set callbacks, where `this.events` is a hash of
@@ -1190,9 +1222,9 @@
return function(model, resp) {
resp = model === originalModel ? resp : model;
if (onError) {
- onError(model, resp, options);
+ onError(originalModel, resp, options);
} else {
- originalModel.trigger('error', model, resp, options);
+ originalModel.trigger('error', originalModel, resp, options);
}
};
};
Oops, something went wrong.

0 comments on commit 4861fd7

Please sign in to comment.