mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-12 18:52:50 +00:00
118 lines
2.8 KiB
JavaScript
118 lines
2.8 KiB
JavaScript
var EventEmitter = require('events').EventEmitter
|
|
, path = require('path')
|
|
, merge = require('racer').util.merge
|
|
, View = require('./View')
|
|
, arraySlice = Array.prototype.slice
|
|
|
|
module.exports = componentPlugin;
|
|
|
|
function componentPlugin(derby) {
|
|
derby._libraries = [];
|
|
derby._libraries.map = {};
|
|
derby.createLibrary = createLibrary;
|
|
}
|
|
componentPlugin.decorate = 'derby';
|
|
|
|
|
|
var componentProto = Object.create(EventEmitter.prototype);
|
|
|
|
componentProto.emitCancellable = function() {
|
|
var cancelled = false
|
|
, args = arraySlice.call(arguments)
|
|
|
|
function cancel() {
|
|
cancelled = true;
|
|
}
|
|
|
|
args.push(cancel);
|
|
this.emit.apply(this, args);
|
|
return cancelled;
|
|
};
|
|
|
|
componentProto.emitDelayable = function() {
|
|
var delayed = false
|
|
, args = arraySlice.call(arguments, 0, -1)
|
|
, callback = arguments[arguments.length - 1]
|
|
|
|
function delay() {
|
|
delayed = true;
|
|
}
|
|
|
|
args.push(delay, callback);
|
|
this.emit.apply(this, args);
|
|
if (!delayed) callback();
|
|
return delayed;
|
|
};
|
|
|
|
// Hack needed for model bundling
|
|
componentProto.toJSON = function() {}
|
|
|
|
function type(view) {
|
|
return view === this.view ? 'lib:' + this.id : this.ns + ':' + this.id;
|
|
}
|
|
|
|
function createLibrary(config, options) {
|
|
if (!config || !config.filename) {
|
|
throw new Error ('Configuration argument with a filename is required');
|
|
}
|
|
if (!options) options = {};
|
|
var root = path.dirname(config.filename)
|
|
, ns = options.ns || config.ns || path.basename(root)
|
|
, scripts = config.scripts || {}
|
|
, view = new View
|
|
, constructors = {}
|
|
, library = {
|
|
ns: ns
|
|
, root: root
|
|
, view: view
|
|
, constructors: constructors
|
|
, styles: config.styles
|
|
}
|
|
, Component, proto, id, script;
|
|
|
|
view._selfNs = 'lib';
|
|
view._selfLibrary = library;
|
|
|
|
for (id in scripts) {
|
|
script = scripts[id];
|
|
script.setup && script.setup(library);
|
|
|
|
Component = function(model, scope) {
|
|
this.view = view;
|
|
this.model = model;
|
|
this.scope = scope;
|
|
this.history = null;
|
|
this.dom = null;
|
|
|
|
// Don't limit the number of listeners
|
|
this.setMaxListeners(0);
|
|
|
|
var component = this;
|
|
model.__on = model._on;
|
|
model._on = function(name, listener) {
|
|
component.on('destroy', function() {
|
|
model.removeListener(name, listener);
|
|
})
|
|
return model.__on(name, listener);
|
|
};
|
|
component.on('destroy', function() {
|
|
model.silent().del();
|
|
});
|
|
}
|
|
proto = Component.prototype = Object.create(componentProto);
|
|
merge(proto, script);
|
|
|
|
Component.view = view;
|
|
Component.ns = ns;
|
|
Component.id = id;
|
|
Component.type = type;
|
|
|
|
// Note that component names are all lowercased
|
|
constructors[id.toLowerCase()] = Component;
|
|
}
|
|
|
|
this._libraries.push(library);
|
|
this._libraries.map[ns] = library;
|
|
return library;
|
|
}
|