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.

Revisions

  1. dustinmartin revised this gist Jun 15, 2010. 2 changed files with 67 additions and 0 deletions.
    67 changes: 67 additions & 0 deletions ApplicationCode.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    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();

    });
    File renamed without changes.
  2. dustinmartin created this gist Jun 15, 2010.
    278 changes: 278 additions & 0 deletions Framework
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,278 @@
    (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;
    })();