d9cec545 by Adam Heath

First pass.

1 parent 155b7073
.*.sw?
/.grunt/
/node_modules/
/src/lib/bower/
/dist/
/* global module */
module.exports = function (grunt) {
/* global require */
'use strict';
var config = {};
config.base = 'src';
config.jshint = {
options: {
},
browserOptions: {
},
};
config.bower = {
directory: 'lib/bower',
};
config.jscs = {
options: {
validateIndentation: 4,
reporter: 'console',
maxErrors: -1,
},
};
config.jasmine = {
withCoverage: true,
};
var montyPython = require('grunt-monty-python')(grunt);
montyPython.createConfig(config);
};
{
"name": "rivets-bfeach-binder",
"version": "0.0.0",
"authors": [
"Adam Heath <doogie@brainfood.com>"
],
"main": [
"src/scripts/rivets-bfeach-binder.js"
],
"private": true,
"ignore": [
"**/.*",
"node_modules",
"src/lib"
],
"dependencies": {
"backbone": "",
"backbone-validation": "",
"rivets-backbone-adapter-brainfood": "git@gitlab.brainfood.com:brainfood/rivets-backbone-adapter-brainfood.git#iterate-branch",
"jquery": "",
"requirejs": "",
"rivets": "",
"underscore": ""
}
}
{
"name": "rivets-bfeach-binder",
"version": "0.0.0",
"main": [
"src/scripts/rivets-bfeach-binder.js"
],
"dependencies": {
"rivets": "",
"requirejs": ""
},
"devDependencies": {
"bower-requirejs": "~0.9.2",
"grunt": "~0",
"grunt-monty-python": "git+ssh://git@gitlab.brainfood.com:brainfood/grunt-monty-python.git"
},
"engines": {
"node": ">=0.8.0"
}
}
/* global require:true */
var require;
require = (function() {
'use strict';
var require = {
baseUrl: 'scripts',
config: {},
shim: {
rivets: {
deps: ['jquery'],
},
},
paths: {
backbone: '../lib/bower/backbone/backbone',
underscore: '../lib/bower/underscore/underscore',
sightglass: '../lib/bower/sightglass/index',
rivets: '../lib/bower/rivets/dist/rivets',
jquery: '../lib/bower/jquery/dist/jquery',
'rivets-backbone-adapter-brainfood': '../lib/bower/rivets-backbone-adapter-brainfood/src/scripts/rivets-backbone-adapter-brainfood',
},
};
return require;
})();
/* global require */
define(function() {
'use strict';
});
define(function(require) {
'use strict';
var Backbone = require('backbone');
var rivets = require('rivets');
var Sightglass = require('sightglass');
var setStack = (function(sightglassPrototype) {
var origSet = sightglassPrototype.set;
var setStack = [];
sightglassPrototype.set = function set(active, key, obj, callback) {
try {
setStack.push(arguments);
return origSet.apply(this, arguments);
} finally {
setSack.pop();
}
};
return setStack;
})(Sightglass.prototype);
var bfEachUtil = {
makeOverrideAdapters: function makeOverrideAdapters(parentAdapters, roData) {
function getStackPath() {
var currentStackPath = '';
_.each(setStack, function(stackFrame, stackFrameIndex) {
var key = stackFrame[1];
currentStackPath += key.i + key.path;
});
return currentStackPath;
currentStackPath += interfaceKey + leafKey;
if (currentStackPath in roData) {
givenObj = roData[currentStackPath];
}
return givenObj;
};
var subAdapters = {};
_.each(parentAdapters, function(adapterFunctions, interfaceKey) {
var subAdapter = {};
subAdapter.observe = function(obj, key, cb) {
var stackPath = getStackPath();
if (stackPath + interfaceKey + key in roData) {
return;
} else if (stackPath in roData) {
obj = roData[stackPath];
}
return adapterFunctions.observe(obj, key, cb);
};
subAdapter.unobserve = function(obj, key, cb) {
var stackPath = getStackPath();
if (stackPath in roData) {
obj = roData[stackPath];
}
if (stackPath + interfaceKey + key in roData) {
return;
} else if (stackPath in roData) {
obj = roData[stackPath];
}
return adapterFunctions.unobserve(obj, key, cb);
};
subAdapter.get = function(obj, key) {
var stackPath = getStackPath();
if (stackPath in roData) {
obj = roData[stackPath];
}
var fullKeyPath = stackPath + interfaceKey + key;
if (fullKeyPath in roData) {
return roData[fullKeyPath];
} else if (stackPath in roData) {
obj = roData[stackPath];
}
return adapterFunctions.get(obj, key);
};
subAdapter.set = function(obj, key, value) {
var stackPath = getStackPath();
if (stackPath in roData) {
obj = roData[stackPath];
}
var fullKeyPath = stackPath + interfaceKey + key;
if (fullKeyPath in roData) {
return roData[fullKeyPath];
} else if (stackPath in roData) {
obj = roData[stackPath];
}
return adapterFunctions.set(obj, key, value);
};
if (adapterFunctions.iterate) {
subAdapter.iterate = adapterFunctions.iterate;
}
subAdapters[interfaceKey] = subAdapter;
});
return subAdapters;
},
getIterator: function getIterator(adapter) {
return adapter.iterate || function iterate(obj, cb) {
obj = obj || [];
var i;
for (i = 0; i < obj.length; i++) {
cb(obj[i], i);
}
};
},
};
(function(rivetsBinders) {
rivetsBinders['bfeach-*'] = {
block: true,
bind: rivetsBinders['each-*'].bind,
unbind: rivetsBinders['each-*'].unbind,
routine: function(el, value) {
var parentView = this.view;
var observer = this.observer;
var adapters = observer.options.adapters;
var iterate = bfEachUtil.getIterator(adapters[observer.key.i]);
var rootInterface = observer.tokens.length ? observer.tokens[0].i : observer.key.i;
var modelName = this.args[0];
var iterationAlias = rivets.iterationAlias(modelName);
var iterated = this.iterated;
var previous = this.marker;
iterate(value, function(value, index) {
if (iterated[index] === undefined) {
var subData = {};
subData[rootInterface + 'index'] = index;
subData[rootInterface + modelName] = value;
subData[rootInterface + iterationAlias] = index;
var options = parentView.options();
options.preloadData = true;
options.adapters = bfEachUtil.makeOverrideAdapters(options.adapters, subData);
var template = el.cloneNode(true);
var childView = new rivets._.View(template, parentView.models, options);
childView.bind();
iterated.push(childView);
previous.parentNode.insertBefore(template, previous.nextSibling);
previous = template;
} else {
iterated[index].update(value);
}
});
},
};
})(rivets.binders);
return bfEachUtil;
});
define(function(require) {
'use strict';
var $ = require('jquery');
window.jQuery = $;
var RivetsBFEachUtil = require('rivets-bfeach-binder');
require('rivets-backbone-adapter-brainfood');
var _ = require('underscore');
var Backbone = require('backbone');
var rivets = require('rivets');
//rivets.config.rootInterface = ':';
/* global console:false */
describe('RivetsBFEachUtil', function() {
it('returns defined', function() {
expect(RivetsBFEachUtil).toBeDefined();
});
var rootScope, rootNode, rivetsView;
function makeTest(rootData, rootHtml, rootTests) {
beforeEach(function() {
rootScope = new Backbone.Model(rootData);
rootNode = $($.parseHTML(rootHtml));
rivetsView = rivets.bind(rootNode, rootScope);
});
rootTests();
}
makeTest({
sub: new Backbone.Model({
list: new Backbone.Collection([
{key: 'A'},
{key: 'B'},
{key: 'C'},
], {parse: true}),
}),
list: new Backbone.Collection([
{key: 'A'},
{key: 'B'},
{key: 'C'},
], {parse: true}),
constant: 'this-is-a-constant',
}, '<div>{:constant}<div rv-bfeach-item=":list">key:{:item:key} constant:{:constant}</div><div rv-bfeach-item=":sub:list">sub-key:{:item:key} constant:{:constant}</div</div>', function() {
it('foo', function() {
expect(rootNode.html()).toEqual(
'this-is-a-constant'
+ '<!-- rivets: bfeach-item -->'
+ '<div>key:A constant:this-is-a-constant</div>'
+ '<div>key:B constant:this-is-a-constant</div>'
+ '<div>key:C constant:this-is-a-constant</div>'
+ '<!-- rivets: bfeach-item -->'
+ '<div>sub-key:A constant:this-is-a-constant</div>'
+ '<div>sub-key:B constant:this-is-a-constant</div>'
+ '<div>sub-key:C constant:this-is-a-constant</div>'
);
});
describe('foo', function() {
beforeEach(function() {
//rootScope.set('constant', 'updated-constant');
rootScope.get('list').add({key: 'D'}, {at: -1, parse: true});
});
it('bar', function() {
expect(rootNode.html()).toEqual(
'updated-constant'
+ '<!-- rivets: bfeach-item -->'
+ '<div>key:A constant:updated-constant</div>'
+ '<div>key:B constant:updated-constant</div>'
+ '<div>key:C constant:updated-constant</div>'
+ '<!-- rivets: bfeach-item -->'
+ '<div>sub-key:A constant:updated-constant</div>'
+ '<div>sub-key:B constant:updated-constant</div>'
+ '<div>sub-key:C constant:updated-constant</div>'
);
});
});
});
});
});