Skip to content

Instantly share code, notes, and snippets.

@dustinmartin
Created June 15, 2010 02:21
Show Gist options
  • Save dustinmartin/438615 to your computer and use it in GitHub Desktop.
Save dustinmartin/438615 to your computer and use it in GitHub Desktop.
Application.init("MyApplication", function(Core){
Core.loadConfig({
enableLogging: true,
handleErrors: true
});
Core.sandbox.addExtension("sayHello",function(){
alert("Hey there!");
);
Core.sandbox.addExtension("get",jQuery);
Core.modules.register("MyFirstModule", function(Sandbox){
// Called automatically on module start. Use the init function to initialize all values, load
// HTML to page, register the module to listen for certain events, etc.
function init(){
Sandbox.sayHello(); // alerts "Hey there!" - This is a sandbox extension
Sandbox.get(".Selector").show(); // This is another sandbox extension but is pointing to jquery.
Sandbox.listen(["some-event-just-happened"],self.myFunction,self);
}
function myFunction(eventName,data){
alert(eventName); // should alert "some-event-just-happened"
alert(data.foo); // should alert "bar"
}
// Called when the module is stopped. Could be used to remove the module's HTML (if any exists) from the page
function destroy(){
}
// The following represents "public" functions. Events cannot be called unless the function is in "self"
var self;
return self = {
init: init,
destroy: destroy,
myFunction: myFunction
}
});
Core.modules.register("MySecondModule", function(Sandbox){
function init(){
doSomething();
}
function doSomething(){
Sandbox.broadcast("some-event-just-happened",{ foo: "bar" });
}
function destroy(){
}
var self;
return self = {
init: init,
destroy: destroy
}
});
// Start all modules
Core.modules.startAll();
});
(function(){
var Application = (function(){
// With this framework, multiple applications can be created on the same page. Because of this,
// each application has its own "Core". The Core contains all the functionality, registered events,
// etc. for the application.
var ApplicationCores = {};
// Check if the console exist and create a dummy console if not
if (!window.console || !console.firebug){
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
"group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i) {
window.console[names[i]] = function(){}
}
}
// This function creates a new application core
function createApplication(){
// All modules get saved into this object. Every object must be uniquely named
var modules = {};
// All registered events are stored in this object with associated handlers
var eventRegistry = {};
// The function to execute to create a new sandbox instance for each module
var sandboxConstructor;
// Each extension the user adds to the sanbox get stored here. Once a new instance is
// created, the array is looped through and the extensions are copied to the sandbox.
// When I say "extension" I basically mean just function.
var sandboxExtensions = [];
// Stores the Logger object and ErrorHandler if one is present
var utils = {};
// The default configuration values
var config = {
enableLogging: false,
handleErrors: false
};
// Simply loads any new configuration values into the application
function loadConfig(configuration){
if(configuration.enableLogging){
config.enableLogging = true;
}
if(configuration.handleErrors){
config.handleErrors = true;
}
}
function start(moduleName,args){
var instance = modules[moduleName].module(getSandbox());
var name;
var method;
var eventRegistry = {};
if (config.enableLogging || config.handleErrors){
for (name in instance) {
method = instance[name];
if (typeof method == "function"){
instance[name] = (function(name, method){
return function(){
try {
if(config.enableLogging){
if (getLogger()) {
getLogger().log("Method Executed: " + moduleName + "." + name + "()", {args: arguments});
}
else {
console.log("Method Executed: " + moduleName + "." + name + "()", {args: arguments});
}
}
return method.apply(this, arguments);
}
catch (e) {
if (config.handleErrors && getErrorHandler()) {
getErrorHandler().handleError(e);
}
else {
throw e;
}
}
};
})(name, method);
}
}
}
modules[moduleName].instance = instance;
if (instance.init) {
instance.init(args);
}
}
function stop(moduleName){
if (modules[moduleName].instance !== null){
if (modules[moduleName].instance["destroy"]) {
modules[moduleName].instance.destroy();
}
modules[moduleName].instance = null;
}
}
function startAll(){
var name;
for (name in modules){
start(name);
}
}
function stopAll(){
var name;
for (name in modules){
stop(name);
}
}
function listen(events,method,object){
var i = 0;
for(i=0; i<=events.length-1; i++){
if (!eventRegistry[events[i]]) {
eventRegistry[events[i]] = [];
}
eventRegistry[events[i]].push({subscriber: object, handler: method});
}
}
function broadcast(event,data){
var i = 0;
var subscriber;
var handler;
var key;
if (getLogger()) {
getLogger().log("Event Broadcast: " + event,data);
}
if(!eventRegistry[event]){
return;
}
for(key in eventRegistry[event]){
subscriber = eventRegistry[event][key].subscriber;
handler = eventRegistry[event][key].handler;
handler.apply(subscriber,arguments);
}
}
function registerModule(name,module){
var definition = {};
definition.name = name;
definition.module = module;
definition.instance = null;
if (!modules[name]) {
modules[name] = definition;
}
else {
throw new Error("The module " + name + " already exists.")
}
}
function registerSandbox(constructor){
sandboxConstructor = constructor;
};
function addSandboxExtension(name,fn){
if(!name || !fn){
throw new Error("An extension must have both a name and function defined.");
}
sandboxExtensions.push({name: name, fn: fn});
};
function getSandbox(){
var i = 0;
var sandbox = sandboxConstructor(self);
for(i=0; i<=sandboxExtensions.length-1; i++){
sandbox[sandboxExtensions[i].name] = sandboxExtensions[i].fn;
}
return sandbox;
}
function registerLogger(logger){
if(!logger.log){
throw new Error("The Logger must have a 'log' method defined.");
}
if(!logger.error){
throw new Error("The Logger must have a 'error' method defined.");
}
utils.logger = logger;
}
function getLogger(){
return utils.logger;
}
function registerErrorHandler(errorHandler){
if(!errorHandler.handleError){
throw new Error("The ErrorHandler must have a 'handleError' method defined.");
}
utils.errorHandler = errorHandler;
}
function getErrorHandler(){
return utils.errorHandler;
}
// Register a default sandbox
registerSandbox(function(application){
return {
listen: function(events,method,object){
application.events.listen(events,method,object);
},
broadcast: function(event,data){
application.events.broadcast(event,data);
}
}
});
var self;
return self = {
loadConfig: loadConfig,
events: {
listen: listen,
broadcast: broadcast
},
modules: {
register: registerModule,
start: start,
stop: stop,
startAll: startAll,
stopAll: stopAll
},
sandbox: {
register: registerSandbox,
addExtension: addSandboxExtension
},
util: {
registerLogger: registerLogger,
registerErrorHandler: registerErrorHandler
}
}
}
return {
init: function(name,fn){
if(ApplicationCores[name]){
throw new Error("Application " + name + " already exists.");
}
else{
ApplicationCores[name] = createApplication();
fn(ApplicationCores[name]);
}
},
get: function(name){
return ApplicationCores[name];
}
};
})();
window.Application = Application;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment