Tags

, , , ,

For one of my internal projects, I do not wanted to rely any of the JavaScript frameworks out there and do all on my own. On Linux with Firefox and Firebug installed, I was writing some information to firebug console. When the application ran on another browser without Firebug, it simply did not work at all.I made it working by commenting out the logging calls for the moment but that was not the solution.

My first idea was to call window.console if it is not undefined. But that would not be something nice and would be a lot of code. The scene was clear. I had to write my own logger but what should it do? I thought it must check if window.console is available and emit message there and if not, should silently ignore.

I started to work on the idea and while working, I thought why not try to emit messages to an HTML div in case window.console is not available? So I worked on that. In first iteration you had to instantiate logger yourself. Then I made it already instantiated and you’d had to call the methods only. The whole idea heavily relies on JavaScritpt anonymous functions, inner functions and JavaScript closures.

Here’s the source code:

/*
 *The urdu tools base file
 */
if(typeof(URDUTOOLS) === 'undefined' || !URDUTOOLS){
    URDUTOOLS = {};
}

if(typeof(URDUTOOLS.util) === 'undefined' || !URDUTOOLS.util){
    URDUTOOLS.util = {};
}

if(typeof(URDUTOOLS.util.Logger) === 'undefined' || !URDUTOOLS.util.Logger){
    /**
     * Our own logging facility. It basically searches for a special DIV with
     * ID URDUTOOSL_logger_dock. If such a DIV is found, its used as logging 
     * area. If that is not found, window.console is used (which is available in
     * case of Fiebug installed) and even if that's not available, you can set
     * one of your own like this:
     * 
     * URDProblem at line 78 character 10: Missing semicolon.UTOOLS.util.Logger.setLoggingDock("my_logging_div_id");
     * 
     * Logger.info()
     * Logger.warn()
     * Logger.debug()
     * Logger.error()
     * Logger.clear()
     * Logger.setLoggingDock(element_id)
     * Logger.getLoggingDock()
     *
     * Heavily dependent on closures.
     *
     */
    
    // Create a new Logger object at the spot!
    URDUTOOLS.util.Logger = new (function(div_id){
    
        // Yet this is null
        var logging_dock = null;
        
        // Logger.info()
        this.info = function(msg){
            logging_dock = this.getLoggingDock();
            if(logging_dock){
                logging_dock.info(msg);
                }
        };
        
        // Logger.warn()
        this.warn = function(msg){
            logging_dock = this.getLoggingDock();
            if(logging_dock){
                logging_dock.warn(msg);
                }
        };
        
        // Logger.debug()
        this.debug = function(msg){
            logging_dock = this.getLoggingDock();
            if(logging_dock){
                logging_dock.debug(msg);
                }
        };
        
        // Logger.error()
        this.error = function(msg){
            logging_dock = this.getLoggingDock();
            if(logging_dock){
                logging_dock.error(msg);
                }
        };
        
        // Logger.clear()
        this.clear = function(){
            logging_dock = this.getLoggingDock();
            if(logging_dock){
                logging_dock.clear();
                }
        };
        
        // Logger.setLoggingDock()
        // We try to get the given DOM element and extent it with some 
        // of our own methods.
        this.setLoggingDock = function(el_id){
            var element = document.getElementById(el_id);
            
                // Inner function to build log message
            function logMsg(type, msg){
                return "<b>"+ type + "</b>: " + msg + "<br/>";
             }
                
            if(element){
                logging_dock = element;
                }
            
            if(logging_dock){
            
                logging_dock.info = function(msg){
                    this.innerHTML += logMsg("INFO", msg);
                };
            
                logging_dock.warn = function(msg){
                    this.innerHTML += logMsg("WARN", msg);
                };
            
                logging_dock.debug = function(msg){
                    this.innerHTML += logMsg("DEBG", msg);
                };
            
                logging_dock.error = function(msg){
                    this.innerHTML += logMsg("EROR", msg);
                };
                
                logging_dock.clear = function(){
                  this.innerHTML = "";  
                };
            }
        };
        
        // Logger.getLoggingDock()
        
        this.getLoggingDock = function(){
            // Get current div_id DIV if logging_dock not set
            // This is basically becasue when the new() logger is being 
            // execute for the first time, the DIV to be used for logger is not
            // available as yet. Each of the logging methos first always get
            // the logging dock by calling this method. If the DOM is ready,
            // and element is get once, its not get for the next times.
            // Read the code carefully to understand!
            if(!logging_dock){
              this.setLoggingDock(div_id);
              }
            if(!logging_dock){
              logging_dock = window.console;
              }
          return logging_dock;
        };
        
    })("URDUTOOLS_logger_dock");
}

After writing this, I ran it through JSLint and found no problems and it works well for me.

Advertisements