mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-12 18:52:50 +00:00
77 lines
1.9 KiB
JavaScript
77 lines
1.9 KiB
JavaScript
var EventEmitter = require('events').EventEmitter
|
|
, racer = require('racer')
|
|
, View = require('./View')
|
|
, collection = require('./collection')
|
|
, isServer = racer.util.isServer
|
|
|
|
exports.create = createApp;
|
|
exports.treeMerge = treeMerge;
|
|
|
|
function createApp(derby, appModule) {
|
|
var app = racer.util.merge(appModule.exports, EventEmitter.prototype)
|
|
|
|
app.view = new View(derby._libraries, app, appModule.filename);
|
|
app.fn = appFn;
|
|
|
|
function appFn(value, fn) {
|
|
if (typeof value === 'string') {
|
|
pathMerge(app, value, fn, app);
|
|
} else {
|
|
treeMerge(app, value, app);
|
|
}
|
|
return app;
|
|
}
|
|
|
|
app._Collections = {};
|
|
app.Collection = collection.construct.bind(app);
|
|
|
|
return app;
|
|
}
|
|
|
|
function traverseNode(node, segments) {
|
|
var i, len, segment
|
|
for (i = 0, len = segments.length; i < len; i++) {
|
|
segment = segments[i];
|
|
node = node[segment] || (node[segment] = {});
|
|
}
|
|
return node;
|
|
}
|
|
|
|
// Recursively set nested objects based on a path
|
|
function pathMerge(node, path, value, app) {
|
|
var segments = path.split('.')
|
|
, last, i, len, segment
|
|
if (typeof value === 'object') {
|
|
node = traverseNode(node, segments);
|
|
treeMerge(node, value, app);
|
|
return;
|
|
}
|
|
last = segments.pop();
|
|
node = traverseNode(node, segments);
|
|
node[last] = bindPage(value, app);
|
|
}
|
|
|
|
// Recursively set objects such that the non-objects are
|
|
// merged with the corresponding structure of the base node
|
|
function treeMerge(node, tree, app) {
|
|
var key, child, value
|
|
for (key in tree) {
|
|
value = tree[key];
|
|
if (typeof value === 'object') {
|
|
child = node[key] || (node[key] = {});
|
|
treeMerge(child, value, app);
|
|
continue;
|
|
}
|
|
node[key] = bindPage(value, app);
|
|
}
|
|
}
|
|
|
|
function bindPage(fn, app) {
|
|
// Don't bind the function on the server, since each
|
|
// render gets passed a new model as part of the app
|
|
if (isServer) return fn;
|
|
return function() {
|
|
return fn.apply(app.page, arguments);
|
|
};
|
|
}
|