Permalink
Browse files

Merge branch 'master' into local-helpers

Conflicts:
	test/src/thorax.js
  • Loading branch information...
2 parents 4726b7e + 34ca9a9 commit 2e0065e61ff70cb9ec498154ed5cd7cba5f045ea Ryan Eastridge committed Dec 26, 2012
View
@@ -0,0 +1,9 @@
+var build = require('phoenix-build');
+
+build.lumbarFile = 'build.json';
+build.projectDir = __dirname;
+build.mochaTests = true;
+build.testPlatforms = [
+ {platform: 'jquery'},
+ {platform: 'zepto'}
+];
View
@@ -1,16 +0,0 @@
-// Shamelessly pulled from Modernizr
-// https://github.com/Modernizr/Modernizr/blob/master/test/js/server.js
-var express = require('express'),
- path = require('path'),
- fs = require('fs'),
- args = process.argv.slice(2),
- root = path.join(__dirname, '..'),
- folder = path.join(root, 'build'),
- port = args[1] || '80';
-
-var server = express.createServer();
-server.use(express.static(folder));
-
-server.listen(port);
-
-console.log("Server started on port %s in %s", port, folder);
View
@@ -40,33 +40,24 @@
},
"test": {
+ "mixins": [
+ "test",
+ "loaded-test-runner"
+ ],
"scripts": [
- {"src": "test/lib/mocha.js", "global": true},
- {"src": "test/lib/chai.js", "global": true},
- {"src": "test/lib/sinon-chai.js", "global": true},
- {"src": "test/lib/sinon.js", "global": true},
- {"src": "test/lib/sinon-backbone.js", "global": true},
- "test/lib/runner.js",
-
"test/src/"
],
- "styles": [
- "test/lib/mocha.css"
- ],
"static": [
- {"src": "test/jquery.html", "dest": "jquery.html"},
- {"src": "test/zepto.html", "dest": "zepto.html"}
+ {"src": "test/jquery.html", "dest": "jquery/test.html"},
+ {"src": "test/zepto.html", "dest": "zepto/test.html"}
]
}
},
"mixins": [
+ "node_modules/phoenix-build/mixin",
"."
],
"scope": {
"template": "src/fragments/scope.handlebars"
- },
-
- "test": {
- "auto-include": "test/src/test."
}
}
View
@@ -1,4 +1,6 @@
{
+ "name": "thorax",
+
"mixins": {
"thorax-dep-jquery": {
"scripts": [
View
@@ -0,0 +1,5 @@
+{
+ "build-targets": [
+ {"name": "Test", "path": "build/dev"}
+ ]
+}
View
@@ -15,21 +15,14 @@
"node": ">=0.4.7"
},
"dependencies": {
- "fs-watch-tree": "0.2.0",
- "handlebars": "1.0.x"
+ "fs-watch-tree": "0.2.0"
},
"devDependencies": {
- "express": "2.5.11",
- "lumbar": "~2",
- "mocha-phantomjs": "~1.1"
+ "jake": "~0.5",
+ "phoenix-build": "~1"
},
"scripts": {
- "watch": "./node_modules/.bin/lumbar watch ./build.json ./build",
-
- "start": "node bin/test-server.js . 8083",
-
- "pretest": "./node_modules/.bin/lumbar build ./build.json ./build",
- "test": "./node_modules/.bin/mocha-phantomjs 'http://localhost:8083/zepto.html' && ./node_modules/.bin/mocha-phantomjs 'http://localhost:8083/jquery.html'"
+ "test": "./node_modules/.bin/jake test"
},
"bin": {
"thorax": "bin/thorax"
View
@@ -38,15 +38,15 @@ Thorax.Collections = {};
createRegistryWrapper(Thorax.Collection, Thorax.Collections);
dataObject('collection', {
- name: '_collectionEvents',
- array: '_collections',
- hash: '_collectionOptionsByCid',
set: 'setCollection',
setCallback: afterSetCollection,
- bind: 'bindCollection',
- unbind: 'unbindCollection',
- options: '_setCollectionOptions',
- change: '_onCollectionReset',
+ defaultOptions: {
+ render: true,
+ fetch: true,
+ success: false,
+ errors: true
+ },
+ change: onCollectionReset,
$el: 'getCollectionElement',
cidAttrName: collectionCidAttributeName
});
@@ -188,15 +188,10 @@ _.extend(Thorax.View.prototype, {
var element = this.$(this._collectionSelector);
return element.length === 0 ? this.$el : element;
},
- _onCollectionReset: function(collection) {
- if (collection === this.collection && this._collectionOptionsByCid[this.collection.cid].render) {
- this.renderCollection();
- }
- },
// Events that will only be bound to "this.collection"
_collectionRenderingEvents: {
- reset: '_onCollectionReset',
- sort: '_onCollectionReset',
+ reset: onCollectionReset,
+ sort: onCollectionReset,
filter: function() {
applyVisibilityFilter.call(this);
},
@@ -233,13 +228,19 @@ _.extend(Thorax.View.prototype, {
Thorax.View.on({
collection: {
error: function(collection, message) {
- if (this._collectionOptionsByCid[collection.cid].errors) {
+ if (this._objectOptionsByCid[collection.cid].errors) {
this.trigger('error', message, collection);
}
}
}
});
+function onCollectionReset(collection) {
+ if (collection === this.collection && this._objectOptionsByCid[this.collection.cid].render) {
+ this.renderCollection();
+ }
+}
+
function afterSetCollection(collection) {
if (!collectionHelperPresentForPrimaryCollection.call(this) && collection) {
_.each(this._collectionRenderingEvents, function(callback, eventName) {
View
@@ -1,6 +1,10 @@
/*global getValue, inheritVars, walkInheritTree */
+
function dataObject(type, spec) {
- spec = inheritVars[type] = _.defaults({event: true}, spec);
+ spec = inheritVars[type] = _.defaults({
+ name: '_' + type + 'Events',
+ event: true
+ }, spec);
// Add a callback in the view constructor
spec.ctor = function() {
@@ -13,110 +17,117 @@ function dataObject(type, spec) {
}
};
- function bindEvents(target, source) {
- var context = this;
- walkInheritTree(source, spec.name, true, function(event) {
- // getEventCallback will resolve if it is a string or a method
- // and return a method
- context.listenTo(target, event[0], _.bind(getEventCallback(event[1], context), event[2] || context));
- });
- }
+ function setObject(dataObject, options) {
+ var old = this[type],
+ $el = getValue(this, spec.$el);
+
+ if (dataObject === old) {
+ return this;
+ }
+ if (old) {
+ this.unbindDataObject(old);
+ }
+
+ if (dataObject) {
+ this[type] = dataObject;
+
+ if (spec.loading) {
+ spec.loading.call(this);
+ }
- function loadObject(dataObject, options) {
- if (dataObject.load) {
- dataObject.load(function() {
- options && options.success && options.success(dataObject);
- }, options);
+ this.bindDataObject(dataObject, _.extend({}, this.options, options));
+ $el.attr(spec.cidAttrName, dataObject.cid);
+ dataObject.trigger('set', dataObject, old);
} else {
- dataObject.fetch(options);
+ this[type] = false;
+ if (spec.change) {
+ spec.change.call(this, false);
+ }
+ $el.removeAttr(spec.cidAttrName);
}
+ spec.setCallback && spec.setCallback.call(this, dataObject, options);
+ return this;
}
- function bindObject(dataObject, options) {
- if (this[spec.array].indexOf(dataObject) !== -1) {
+ Thorax.View.prototype[spec.set] = setObject;
+}
+
+_.extend(Thorax.View.prototype, {
+ bindDataObject: function(dataObject, options) {
+ var type = getDataObjectType(dataObject);
+ if (this._boundDataObjects.indexOf(dataObject) !== -1) {
return false;
}
// Collections do not have a cid attribute by default
ensureDataObjectCid(type, dataObject);
- this[spec.array].push(dataObject);
+ this._boundDataObjects.push(dataObject);
- var options = this[spec.options](dataObject, options);
+ var options = this._modifyDataObjectOptions(dataObject, _.extend({}, inheritVars[type].defaultOptions, options));
+ this._objectOptionsByCid[dataObject.cid] = options;
- bindEvents.call(this, dataObject, this.constructor);
- bindEvents.call(this, dataObject, this);
+ bindEvents.call(this, type, dataObject, this.constructor);
+ bindEvents.call(this, type, dataObject, this);
if (Thorax.Util.shouldFetch(dataObject, options)) {
loadObject(dataObject, options);
- } else {
+ } else if (inheritVars[type].change) {
// want to trigger built in rendering without triggering event on model
- this[spec.change](dataObject, options);
+ inheritVars[type].change.call(this, dataObject, options);
}
return true;
- }
+ },
- function unbindObject(dataObject) {
- if (this[spec.array].indexOf(dataObject) === -1) {
+ unbindDataObject: function (dataObject) {
+ if (this._boundDataObjects.indexOf(dataObject) === -1) {
return false;
}
- this[spec.array] = _.without(this[spec.array], dataObject);
+ this._boundDataObjects = _.without(this._boundDataObjects, dataObject);
dataObject.trigger('freeze');
this.stopListening(dataObject);
- delete this[spec.hash][dataObject.cid];
+ delete this._objectOptionsByCid[dataObject.cid];
return true;
- }
+ },
- function objectOptions(dataObject, options) {
- if (!this[spec.hash][dataObject.cid]) {
- this[spec.hash][dataObject.cid] = {
- render: true,
- fetch: true,
- success: false,
- errors: true
- };
- }
- _.extend(this[spec.hash][dataObject.cid], options || {});
- return this[spec.hash][dataObject.cid];
+ _modifyDataObjectOptions: function(dataObject, options) {
+ return options;
}
+});
- function setObject(dataObject, options) {
- var old = this[type],
- $el = getValue(this, spec.$el);
+function getDataObjectType(dataObject) {
+ if (isModel(dataObject)) {
+ return 'model';
+ } else if (isCollection(dataObject)) {
+ return 'collection';
+ } else {
+ throw new Error('Unknown data object bound: ' + (typeof dataObject));
+ }
+}
- if (dataObject === old) {
- return this;
- }
- if (old) {
- this[spec.unbind](old);
- }
+function isModel(model) {
+ return model && model.attributes && model.set;
+}
- if (dataObject) {
- this[type] = dataObject;
+function isCollection(collection) {
+ return collection && collection.indexOf && collection.models;
+}
- if (spec.loading) {
- spec.loading.call(this);
- }
+function bindEvents(type, target, source) {
+ var context = this;
+ walkInheritTree(source, '_' + type + 'Events', true, function(event) {
+ // getEventCallback will resolve if it is a string or a method
+ // and return a method
+ context.listenTo(target, event[0], _.bind(getEventCallback(event[1], context), event[2] || context));
+ });
+}
- this[spec.bind](dataObject, _.extend({}, this.options, options));
- $el.attr(spec.cidAttrName, dataObject.cid);
- dataObject.trigger('set', dataObject, old);
- } else {
- this[type] = false;
- if (spec.change) {
- this[spec.change](false);
- }
- $el.removeAttr(spec.cidAttrName);
- }
- spec.setCallback && spec.setCallback.call(this, dataObject, options);
- return this;
+function loadObject(dataObject, options) {
+ if (dataObject.load) {
+ dataObject.load(function() {
+ options && options.success && options.success(dataObject);
+ }, options);
+ } else {
+ dataObject.fetch(options);
}
-
- var extend = {};
- extend[spec.bind] = bindObject;
- extend[spec.unbind] = unbindObject;
- extend[spec.set] = setObject;
- extend[spec.options] = objectOptions;
-
- _.extend(Thorax.View.prototype, extend);
}
function getEventCallback(callback, context) {
View
@@ -46,11 +46,7 @@ _.extend(Thorax.View, {
_.extend(Thorax.View.prototype, {
freeze: function(options) {
- _.each(inheritVars, function(obj) {
- if (obj.unbind) {
- _.each(this[obj.array], this[obj.unbind], this);
- }
- }, this);
+ _.each(this._boundDataObjects, this.unbindDataObject, this);
options = _.defaults(options || {}, {
dom: true,
children: true
Oops, something went wrong.

0 comments on commit 2e0065e

Please sign in to comment.