Index: openacs-4/packages/ajaxhelper/www/resources/yui/logger/logger.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ajaxhelper/www/resources/yui/logger/logger.js,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ajaxhelper/www/resources/yui/logger/logger.js 21 Oct 2006 06:14:58 -0000 1.1 +++ openacs-4/packages/ajaxhelper/www/resources/yui/logger/logger.js 25 Dec 2006 16:40:02 -0000 1.2 @@ -6,7 +6,7 @@ http://developer.yahoo.com/yui/license.txt -version: 0.11.3 +version: 0.12.1 */ @@ -18,626 +18,166 @@ /****************************************************************************/ -/** - - * Singleton providing core logging functionality. Saves logs written through the - - * global YAHOO.log function or written by LogWriter. Provides access to logs - - * for reading by LogReader. Log messages can be automatically output to browser - - * console such as the Firebug extension to Firefox or Safari's JavaScript - - * console, if present. - - * - - * requires YAHOO.util.Event Event utility - - */ - -YAHOO.widget.Logger = { - - // Initialize members - - loggerEnabled: true, - - _browserConsoleEnabled: false, - - categories: ["info","warn","error","time","window"], - - sources: ["global"], - - _stack: [], // holds all log msgs - - maxStackEntries: 5, - - _startTime: new Date().getTime(), // static start timestamp - - _lastTime: null // timestamp of last logged message - -}; - -/*************************************************************************** - - * Events - - ***************************************************************************/ - /** - * Fired when a new category has been created. Subscribers receive the following + * The LogMsg class defines a single log message. - * array:
- - * - args[0] The category name - - */ - -YAHOO.widget.Logger.categoryCreateEvent = new YAHOO.util.CustomEvent("categoryCreate", this, true); - - - -/** - - * Fired when a new source has been named. Subscribers receive the following - - * array:
- - * - args[0] The source name - - */ - -YAHOO.widget.Logger.sourceCreateEvent = new YAHOO.util.CustomEvent("sourceCreate", this, true); - - - -/** - - * Fired when a new log message has been created. Subscribers receive the - - * following array:
- - * - args[0] The log message - - */ - -YAHOO.widget.Logger.newLogEvent = new YAHOO.util.CustomEvent("newLog", this, true); - - - -/** - - * Fired when the Logger has been reset has been created. - - */ - -YAHOO.widget.Logger.logResetEvent = new YAHOO.util.CustomEvent("logReset", this, true); - - - -/*************************************************************************** - - * Public methods - - ***************************************************************************/ - -/** - - * Saves a log message to the stack and fires newLogEvent. If the log message is - - * assigned to an unknown category, creates a new category. If the log message is - - * from an unknown source, creates a new source. If browser console is enabled, - - * outputs the log message to browser console. - * - * @param {string} sMsg The log message + * @class LogMsg - * @param {string} sCategory Category of log message, or null + * @constructor - * @param {string} sSource Source of LogWriter, or null if global + * @param oConfigs {Object} Object literal of configuration params. */ -YAHOO.widget.Logger.log = function(sMsg, sCategory, sSource) { + YAHOO.widget.LogMsg = function(oConfigs) { - if(this.loggerEnabled) { + // Parse configs - if(!sCategory) { + if (typeof oConfigs == "object") { - sCategory = "info"; // default category + for(var param in oConfigs) { - } + this[param] = oConfigs[param]; - else { - - sCategory = sCategory.toLocaleLowerCase(); - - if(this._isNewCategory(sCategory)) { - - this._createNewCategory(sCategory); - - } - } - var sClass = "global"; // default source - - var sDetail = null; - - if(sSource) { - - var spaceIndex = sSource.indexOf(" "); - - if(spaceIndex > 0) { - - sClass = sSource.substring(0,spaceIndex);// substring until first space - - sDetail = sSource.substring(spaceIndex,sSource.length);// the rest of the source - - } - - else { - - sClass = sSource; - - } - - if(this._isNewSource(sClass)) { - - this._createNewSource(sClass); - - } - - } - - - - var timestamp = new Date(); - - var logEntry = { - - time: timestamp, - - category: sCategory, - - source: sClass, - - sourceDetail: sDetail, - - msg: sMsg - - }; - - - - var stack = this._stack; - - var maxStackEntries = this.maxStackEntries; - - if(maxStackEntries && !isNaN(maxStackEntries) && (stack.length >= maxStackEntries)) { - - stack.shift(); - - } - - stack.push(logEntry); - - this.newLogEvent.fire(logEntry); - - - - if(this._browserConsoleEnabled) { - - this._printToBrowserConsole(logEntry); - - } - - return true; - } - else { + }; - return false; - - } - -}; - -/** +///////////////////////////////////////////////////////////////////////////// - * Resets internal stack and startTime, enables Logger, and fires logResetEvent. +// - * +// Public member variables - */ +// -YAHOO.widget.Logger.reset = function() { +///////////////////////////////////////////////////////////////////////////// - this._stack = []; - - this._startTime = new Date().getTime(); - - this.loggerEnabled = true; - - this.log("Logger reset"); - - this.logResetEvent.fire(); - -}; - /** - * Public accessor to internal stack of log messages. + * Log message. * - * @return {array} Array of log messages. + * @property msg - */ + * @type String -YAHOO.widget.Logger.getStack = function() { - - return this._stack; - -}; - - - -/** - - * Public accessor to internal start time. - - * - - * @return {date} Internal date of when Logger singleton was initialized. - */ -YAHOO.widget.Logger.getStartTime = function() { +YAHOO.widget.LogMsg.prototype.msg = null; - return this._startTime; - -}; - /** - * Disables output to the browser's global console.log() function, which is used + * Log timestamp. - * by the Firebug extension to Firefox as well as Safari. - - */ - -YAHOO.widget.Logger.disableBrowserConsole = function() { - - YAHOO.log("Logger output to the function console.log() has been disabled."); - - this._browserConsoleEnabled = false; - -}; - - - -/** - - * Enables output to the browser's global console.log() function, which is used - - * by the Firebug extension to Firefox as well as Safari. - - */ - -YAHOO.widget.Logger.enableBrowserConsole = function() { - - this._browserConsoleEnabled = true; - - YAHOO.log("Logger output to the function console.log() has been enabled."); - -}; - - - -/*************************************************************************** - - * Private methods - - ***************************************************************************/ - -/** - - * Creates a new category of log messages and fires categoryCreateEvent. - * - * @param {string} category Category name + * @property time - * @private + * @type Date */ -YAHOO.widget.Logger._createNewCategory = function(category) { +YAHOO.widget.LogMsg.prototype.time = null; - this.categories.push(category); - - this.categoryCreateEvent.fire(category); - -}; - /** - * Checks to see if a category has already been created. + * Log category. * - * @param {string} category Category name + * @property category - * @return {boolean} Returns true if category is unknown, else returns false + * @type String - * @private - */ -YAHOO.widget.Logger._isNewCategory = function(category) { +YAHOO.widget.LogMsg.prototype.category = null; - for(var i=0; i < this.categories.length; i++) { - - if(category == this.categories[i]) { - - return false; - - } - - } - - return true; - -}; - /** - * Creates a new source of log messages and fires sourceCreateEvent. + * Log source. The first word passed in as the source argument. * - * @param {string} source Source name + * @property source - * @private + * @type String */ -YAHOO.widget.Logger._createNewSource = function(source) { +YAHOO.widget.LogMsg.prototype.source = null; - this.sources.push(source); - - this.sourceCreateEvent.fire(source); - -}; - /** - * Checks to see if a source has already been created. + * Log source detail. The remainder of the string passed in as the source argument, not - * + * including the first word (if any). - * @param {string} source Source name - - * @return {boolean} Returns true if source is unknown, else returns false - - * @private - - */ - -YAHOO.widget.Logger._isNewSource = function(source) { - - if(source) { - - for(var i=0; i < this.sources.length; i++) { - - if(source == this.sources[i]) { - - return false; - - } - - } - - return true; - - } - -}; - - - -/** - - * Outputs a log message to global console.log() function. - * - * @param {object} entry Log entry object + * @property sourceDetail - * @private + * @type String */ -YAHOO.widget.Logger._printToBrowserConsole = function(entry) { +YAHOO.widget.LogMsg.prototype.sourceDetail = null; - if(window.console && console.log) { - - var category = entry.category; - - var label = entry.category.substring(0,4).toUpperCase(); - - var time = entry.time; - - if (time.toLocaleTimeString) { - - var localTime = time.toLocaleTimeString(); - - } - - else { - - localTime = time.toString(); - - } - - - - var msecs = time.getTime(); - - var elapsedTime = (YAHOO.widget.Logger._lastTime) ? - - (msecs - YAHOO.widget.Logger._lastTime) : 0; - - YAHOO.widget.Logger._lastTime = msecs; - - - - var output = - - localTime + " (" + - - elapsedTime + "ms): " + - - entry.source + ": " + - - entry.msg; - - - - console.log(output); - - } - -}; - - - -/*************************************************************************** - - * Private event handlers - - ***************************************************************************/ - -/** - - * Handles logging of messages due to window error events. - - * - - * @param {string} msg The error message - - * @param {string} url URL of the error - - * @param {string} line Line number of the error - - * @private - - */ - -YAHOO.widget.Logger._onWindowError = function(msg,url,line) { - - // Logger is not in scope of this event handler - - try { - - YAHOO.widget.Logger.log(msg+' ('+url+', line '+line+')', "window"); - - if(YAHOO.widget.Logger._origOnWindowError) { - - YAHOO.widget.Logger._origOnWindowError(); - - } - - } - - catch(e) { - - return false; - - } - -}; - - - -/** - - * Handle native JavaScript errors - - */ - -//NB: Not all browsers support the window.onerror event - -if(window.onerror) { - - // Save any previously defined handler to call - - YAHOO.widget.Logger._origOnWindowError = window.onerror; - -} - -window.onerror = YAHOO.widget.Logger._onWindowError; - - - -/** - - * First log - - */ - -YAHOO.widget.Logger.log("Logger initialized"); - - - /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ + + /** - * Class providing ability to log messages through YAHOO.widget.Logger from a + * The LogWriter class provides a mechanism to log messages through - * named source. + * YAHOO.widget.Logger from a named source. * + * @class LogWriter + * @constructor - * @param {string} sSource Source of LogWriter instance + * @param sSource {String} Source of LogWriter instance. */ YAHOO.widget.LogWriter = function(sSource) { if(!sSource) { - YAHOO.log("Could not instantiate LogWriter due to invalid source.", "error", "LogWriter"); + YAHOO.log("Could not instantiate LogWriter due to invalid source.", + "error", "LogWriter"); + return; } @@ -648,20 +188,28 @@ -/*************************************************************************** +///////////////////////////////////////////////////////////////////////////// - * Public methods +// - ***************************************************************************/ +// Public methods +// + +///////////////////////////////////////////////////////////////////////////// + + + /** * Public accessor to the unique name of the LogWriter instance. * - * @return {string} Unique name of the LogWriter instance + * @method toString + * @return {String} Unique name of the LogWriter instance. + */ YAHOO.widget.LogWriter.prototype.toString = function() { @@ -678,10 +226,12 @@ * - * @param {string} sMsg The log message + * @method log - * @param {string} sCategory Category name + * @param sMsg {String} The log message. + * @param sCategory {String} Category name. + */ YAHOO.widget.LogWriter.prototype.log = function(sMsg, sCategory) { @@ -698,8 +248,10 @@ * - * @return {string} The LogWriter source + * @method getSource + * @return {String} The LogWriter source. + */ YAHOO.widget.LogWriter.prototype.getSource = function() { @@ -716,8 +268,10 @@ * - * @param {string} sSource Source of LogWriter instance + * @method setSource + * @param sSource {String} Source of LogWriter instance. + */ YAHOO.widget.LogWriter.prototype.setSource = function(sSource) { @@ -738,20 +292,30 @@ }; -/*************************************************************************** + - * Private members +///////////////////////////////////////////////////////////////////////////// - ***************************************************************************/ +// +// Private member variables + +// + +///////////////////////////////////////////////////////////////////////////// + + + /** - * Source of the log writer instance. + * Source of the LogWriter instance. * - * @type string + * @property _source + * @type String + * @private */ @@ -774,27 +338,23 @@ /** - * Class providing UI to read messages logged to YAHOO.widget.Logger. + * The LogReader class provides UI to read messages logged to YAHOO.widget.Logger. * - * requires YAHOO.util.Dom DOM utility + * @class LogReader - * requires YAHOO.util.Event Event utility - - * optional YAHOO.util.DragDrop Drag and drop utility - - * - * @constructor - * @param {el or ID} containerEl DOM element object or ID of container to wrap reader UI + * @param elContainer {HTMLElement} (optional) DOM element reference of an existing DIV. - * @param {object} oConfig Optional object literal of configuration params + * @param elContainer {String} (optional) String ID of an existing DIV. + * @param oConfigs {Object} (optional) Object literal of configuration params. + */ -YAHOO.widget.LogReader = function(containerEl, oConfig) { +YAHOO.widget.LogReader = function(elContainer, oConfigs) { var oSelf = this; @@ -806,11 +366,11 @@ // Parse config vars here - if (typeof oConfig == "object") { + if (typeof oConfigs == "object") { - for(var param in oConfig) { + for(var param in oConfigs) { - this[param] = oConfig[param]; + this[param] = oConfigs[param]; } @@ -820,131 +380,145 @@ // Attach container... - if(containerEl) { + if(elContainer) { - if(typeof containerEl == "string") { + if(typeof elContainer == "string") { - this._containerEl = document.getElementById(containerEl); + this._elContainer = document.getElementById(elContainer); } - else if(containerEl.tagName) { + else if(elContainer.tagName) { - this._containerEl = containerEl; + this._elContainer = elContainer; } - this._containerEl.className = "yui-log"; + this._elContainer.className = "yui-log"; } // ...or create container from scratch - if(!this._containerEl) { + if(!this._elContainer) { - if(YAHOO.widget.LogReader._defaultContainerEl) { + if(YAHOO.widget.LogReader._elDefaultContainer) { - this._containerEl = YAHOO.widget.LogReader._defaultContainerEl; + this._elContainer = YAHOO.widget.LogReader._elDefaultContainer; } else { - this._containerEl = document.body.appendChild(document.createElement("div")); + this._elContainer = document.body.appendChild(document.createElement("div")); - this._containerEl.id = "yui-log"; + this._elContainer.id = "yui-log"; - this._containerEl.className = "yui-log"; + this._elContainer.className = "yui-log"; - YAHOO.widget.LogReader._defaultContainerEl = this._containerEl; + YAHOO.widget.LogReader._elDefaultContainer = this._elContainer; } // If implementer has provided container values, trust and set those - var containerStyle = this._containerEl.style; + var containerStyle = this._elContainer.style; if(this.width) { containerStyle.width = this.width; } - if(this.left) { + if(this.right) { - containerStyle.left = this.left; + containerStyle.right = this.right; } - if(this.right) { + if(this.top) { - containerStyle.right = this.right; + containerStyle.top = this.top; } + if(this.left) { + + containerStyle.left = this.left; + + containerStyle.right = "auto"; + + } + if(this.bottom) { containerStyle.bottom = this.bottom; + containerStyle.top = "auto"; + } - if(this.top) { + if(this.fontSize) { - containerStyle.top = this.top; + containerStyle.fontSize = this.fontSize; } - if(this.fontSize) { + if(window.opera) { - containerStyle.fontSize = this.fontSize; + document.body.style += ''; } } - if(this._containerEl) { + if(this._elContainer) { // Create header - if(!this._hdEl) { + if(!this._elHd) { - this._hdEl = this._containerEl.appendChild(document.createElement("div")); + this._elHd = this._elContainer.appendChild(document.createElement("div")); - this._hdEl.id = "yui-log-hd" + this._sName; + this._elHd.id = "yui-log-hd" + this._sName; - this._hdEl.className = "yui-log-hd"; + this._elHd.className = "yui-log-hd"; - this._collapseEl = this._hdEl.appendChild(document.createElement("div")); + this._elCollapse = this._elHd.appendChild(document.createElement("div")); - this._collapseEl.className = "yui-log-btns"; + this._elCollapse.className = "yui-log-btns"; - this._collapseBtn = document.createElement("input"); + this._btnCollapse = document.createElement("input"); - this._collapseBtn.type = "button"; + this._btnCollapse.type = "button"; - this._collapseBtn.style.fontSize = YAHOO.util.Dom.getStyle(this._containerEl,"fontSize"); + this._btnCollapse.style.fontSize = - this._collapseBtn.className = "yui-log-button"; + YAHOO.util.Dom.getStyle(this._elContainer,"fontSize"); - this._collapseBtn.value = "Collapse"; + this._btnCollapse.className = "yui-log-button"; - this._collapseBtn = this._collapseEl.appendChild(this._collapseBtn); + this._btnCollapse.value = "Collapse"; - YAHOO.util.Event.addListener(oSelf._collapseBtn,'click',oSelf._onClickCollapseBtn,oSelf); + this._btnCollapse = this._elCollapse.appendChild(this._btnCollapse); + YAHOO.util.Event.addListener( + + oSelf._btnCollapse,'click',oSelf._onClickCollapseBtn,oSelf); + - this._title = this._hdEl.appendChild(document.createElement("h4")); + this._title = this._elHd.appendChild(document.createElement("h4")); this._title.innerHTML = "Logger Console"; @@ -958,93 +532,103 @@ if(YAHOO.util.DD && - (YAHOO.widget.LogReader._defaultContainerEl == this._containerEl)) { + (YAHOO.widget.LogReader._elDefaultContainer == this._elContainer)) { - var ylog_dd = new YAHOO.util.DD(this._containerEl.id); + var ylog_dd = new YAHOO.util.DD(this._elContainer.id); - ylog_dd.setHandleElId(this._hdEl.id); + ylog_dd.setHandleElId(this._elHd.id); - this._hdEl.style.cursor = "move"; + this._elHd.style.cursor = "move"; } } // Ceate console - if(!this._consoleEl) { + if(!this._elConsole) { - this._consoleEl = this._containerEl.appendChild(document.createElement("div")); + this._elConsole = - this._consoleEl.className = "yui-log-bd"; + this._elContainer.appendChild(document.createElement("div")); + this._elConsole.className = "yui-log-bd"; + // If implementer has provided console, trust and set those if(this.height) { - this._consoleEl.style.height = this.height; + this._elConsole.style.height = this.height; } } // Don't create footer if disabled - if(!this._ftEl && this.footerEnabled) { + if(!this._elFt && this.footerEnabled) { - this._ftEl = this._containerEl.appendChild(document.createElement("div")); + this._elFt = this._elContainer.appendChild(document.createElement("div")); - this._ftEl.className = "yui-log-ft"; + this._elFt.className = "yui-log-ft"; - this._btnsEl = this._ftEl.appendChild(document.createElement("div")); + this._elBtns = this._elFt.appendChild(document.createElement("div")); - this._btnsEl.className = "yui-log-btns"; + this._elBtns.className = "yui-log-btns"; - this._pauseBtn = document.createElement("input"); + this._btnPause = document.createElement("input"); - this._pauseBtn.type = "button"; + this._btnPause.type = "button"; - this._pauseBtn.style.fontSize = YAHOO.util.Dom.getStyle(this._containerEl,"fontSize"); + this._btnPause.style.fontSize = - this._pauseBtn.className = "yui-log-button"; + YAHOO.util.Dom.getStyle(this._elContainer,"fontSize"); - this._pauseBtn.value = "Pause"; + this._btnPause.className = "yui-log-button"; - this._pauseBtn = this._btnsEl.appendChild(this._pauseBtn); + this._btnPause.value = "Pause"; - YAHOO.util.Event.addListener(oSelf._pauseBtn,'click',oSelf._onClickPauseBtn,oSelf); + this._btnPause = this._elBtns.appendChild(this._btnPause); + YAHOO.util.Event.addListener( + + oSelf._btnPause,'click',oSelf._onClickPauseBtn,oSelf); + - this._clearBtn = document.createElement("input"); + this._btnClear = document.createElement("input"); - this._clearBtn.type = "button"; + this._btnClear.type = "button"; - this._clearBtn.style.fontSize = YAHOO.util.Dom.getStyle(this._containerEl,"fontSize"); + this._btnClear.style.fontSize = - this._clearBtn.className = "yui-log-button"; + YAHOO.util.Dom.getStyle(this._elContainer,"fontSize"); - this._clearBtn.value = "Clear"; + this._btnClear.className = "yui-log-button"; - this._clearBtn = this._btnsEl.appendChild(this._clearBtn); + this._btnClear.value = "Clear"; - YAHOO.util.Event.addListener(oSelf._clearBtn,'click',oSelf._onClickClearBtn,oSelf); + this._btnClear = this._elBtns.appendChild(this._btnClear); + YAHOO.util.Event.addListener( + + oSelf._btnClear,'click',oSelf._onClickClearBtn,oSelf); + - this._categoryFiltersEl = this._ftEl.appendChild(document.createElement("div")); + this._elCategoryFilters = this._elFt.appendChild(document.createElement("div")); - this._categoryFiltersEl.className = "yui-log-categoryfilters"; + this._elCategoryFilters.className = "yui-log-categoryfilters"; - this._sourceFiltersEl = this._ftEl.appendChild(document.createElement("div")); + this._elSourceFilters = this._elFt.appendChild(document.createElement("div")); - this._sourceFiltersEl.className = "yui-log-sourcefilters"; + this._elSourceFilters.className = "yui-log-sourcefilters"; } @@ -1060,10 +644,12 @@ } - this._lastTime = YAHOO.widget.Logger.getStartTime(); // timestamp of last log message to console + // Timestamp of last log message to console - + this._lastTime = YAHOO.widget.Logger.getStartTime(); + + // Subscribe to Logger custom events YAHOO.widget.Logger.newLogEvent.subscribe(this._onNewLog, this); @@ -1078,7 +664,7 @@ var catsLen = YAHOO.widget.Logger.categories.length; - if(this._categoryFiltersEl) { + if(this._elCategoryFilters) { for(var i=0; i < catsLen; i++) { @@ -1094,7 +680,7 @@ var sourcesLen = YAHOO.widget.Logger.sources.length; - if(this._sourceFiltersEl) { + if(this._elSourceFilters) { for(var j=0; j < sourcesLen; j++) { @@ -1118,22 +704,30 @@ -/*************************************************************************** +///////////////////////////////////////////////////////////////////////////// - * Public members +// - ***************************************************************************/ +// Public member variables -/** +// - * Whether or not the log reader is enabled to output log messages. Default: +///////////////////////////////////////////////////////////////////////////// - * true. + +/** + + * Whether or not the log reader is enabled to output log messages. + * - * @type boolean + * @property logReaderEnabled + * @type Boolean + + * @default true + */ YAHOO.widget.LogReader.prototype.logReaderEnabled = true; @@ -1146,8 +740,10 @@ * - * @type string + * @property width + * @type String + */ YAHOO.widget.LogReader.prototype.width = null; @@ -1160,8 +756,10 @@ * - * @type string + * @property height + * @type String + */ YAHOO.widget.LogReader.prototype.height = null; @@ -1174,8 +772,10 @@ * - * @type string + * @property top + * @type String + */ YAHOO.widget.LogReader.prototype.top = null; @@ -1188,8 +788,10 @@ * - * @type string + * @property left + * @type String + */ YAHOO.widget.LogReader.prototype.left = null; @@ -1202,8 +804,10 @@ * - * @type string + * @property right + * @type String + */ YAHOO.widget.LogReader.prototype.right = null; @@ -1216,8 +820,10 @@ * - * @type string + * @property bottom + * @type String + */ YAHOO.widget.LogReader.prototype.bottom = null; @@ -1230,8 +836,10 @@ * - * @type string + * @property fontSize + * @type String + */ YAHOO.widget.LogReader.prototype.fontSize = null; @@ -1240,12 +848,16 @@ /** - * Whether or not the footer UI is enabled for the log reader. Default: true. + * Whether or not the footer UI is enabled for the log reader. * - * @type boolean + * @property footerEnabled + * @type Boolean + + * @default true + */ YAHOO.widget.LogReader.prototype.footerEnabled = true; @@ -1256,12 +868,16 @@ * Whether or not output is verbose (more readable). Setting to true will make - * output more compact (less readable). Default: true. + * output more compact (less readable). * - * @type boolean + * @property verboseOutput + * @type Boolean + + * @default true + */ YAHOO.widget.LogReader.prototype.verboseOutput = true; @@ -1270,12 +886,14 @@ /** - * Whether or not newest message is printed on top. Default: true. + * Whether or not newest message is printed on top. * - * @type boolean + * @property newestOnTop + * @type Boolean + */ YAHOO.widget.LogReader.prototype.newestOnTop = true; @@ -1284,12 +902,16 @@ /** - * Maximum number of messages a LogReader console will display. Default: 500; + * Maximum number of messages a LogReader console will display. * - * @type number + * @property thresholdMax + * @type Number + + * @default 500 + */ YAHOO.widget.LogReader.prototype.thresholdMax = 500; @@ -1300,32 +922,44 @@ * When a LogReader console reaches its thresholdMax, it will clear out messages - * and print out the latest thresholdMin number of messages. Default: 100; + * and print out the latest thresholdMin number of messages. * - * @type number + * @property thresholdMin + * @type Number + + * @default 100 + */ YAHOO.widget.LogReader.prototype.thresholdMin = 100; -/*************************************************************************** +///////////////////////////////////////////////////////////////////////////// - * Public methods +// - ***************************************************************************/ +// Public methods +// + +///////////////////////////////////////////////////////////////////////////// + + + /** * Public accessor to the unique name of the LogReader instance. * - * @return {string} Unique name of the LogReader instance + * @method toString + * @return {String} Unique name of the LogReader instance. + */ YAHOO.widget.LogReader.prototype.toString = function() { @@ -1340,6 +974,10 @@ * get saved to a buffer and then output upon resume of log reader. + * + + * @method pause + */ YAHOO.widget.LogReader.prototype.pause = function() { @@ -1358,6 +996,10 @@ * have been saved to buffer while paused. + * + + * @method resume + */ YAHOO.widget.LogReader.prototype.resume = function() { @@ -1374,11 +1016,15 @@ * Hides UI of log reader. Logging functionality is not disrupted. + * + + * @method hide + */ YAHOO.widget.LogReader.prototype.hide = function() { - this._containerEl.style.display = "none"; + this._elContainer.style.display = "none"; }; @@ -1388,11 +1034,15 @@ * Shows UI of log reader. Logging functionality is not disrupted. + * + + * @method show + */ YAHOO.widget.LogReader.prototype.show = function() { - this._containerEl.style.display = "block"; + this._elContainer.style.display = "block"; }; @@ -1404,30 +1054,210 @@ * - * @param {string} sTitle String to display in log reader's title bar. + * @method setTitle + * @param sTitle {String} New title. + */ YAHOO.widget.LogReader.prototype.setTitle = function(sTitle) { - this._title.innerHTML = this._HTML2Text(sTitle); + this._title.innerHTML = this.html2Text(sTitle); }; - /*************************************************************************** + - * Private members +/** - ***************************************************************************/ + * Gets timestamp of the last log. + * + + * @method getLastTime + + * @return {Date} Timestamp of the last log. + + */ + +YAHOO.widget.LogReader.prototype.getLastTime = function() { + + return this._lastTime; + +}; + + + /** + * Formats message string to HTML for output to console. + + * + + * @method formatMsg + + * @param oLogMsg {Object} Log message object. + + * @return {String} HTML-formatted message for output to console. + + */ + +YAHOO.widget.LogReader.prototype.formatMsg = function(oLogMsg) { + + var category = oLogMsg.category; + + + + // Label for color-coded display + + var label = category.substring(0,4).toUpperCase(); + + + + // Calculate the elapsed time to be from the last item that passed through the filter, + + // not the absolute previous item in the stack + + + + var time = oLogMsg.time; + + if (time.toLocaleTimeString) { + + var localTime = time.toLocaleTimeString(); + + } + + else { + + localTime = time.toString(); + + } + + + + var msecs = time.getTime(); + + var startTime = YAHOO.widget.Logger.getStartTime(); + + var totalTime = msecs - startTime; + + var elapsedTime = msecs - this.getLastTime(); + + + + var source = oLogMsg.source; + + var sourceDetail = oLogMsg.sourceDetail; + + var sourceAndDetail = (sourceDetail) ? + + source + " " + sourceDetail : source; + + + + // Escape HTML entities in the log message itself for output to console + + var msg = this.html2Text(oLogMsg.msg); + + + + // Verbose output includes extra line breaks + + var output = (this.verboseOutput) ? + + ["

", label, " ", + + totalTime, "ms (+", elapsedTime, ") ", + + localTime, ": ", + + "

", + + sourceAndDetail, + + ":

", + + msg, + + "

"] : + + + + ["

", label, " ", + + totalTime, "ms (+", elapsedTime, ") ", + + localTime, ": ", + + sourceAndDetail, ": ", + + msg,"

"]; + + + + return output.join(""); + +}; + + + +/** + + * Converts input chars "<", ">", and "&" to HTML entities. + + * + + * @method html2Text + + * @param sHtml {String} String to convert. + + * @private + + */ + +YAHOO.widget.LogReader.prototype.html2Text = function(sHtml) { + + if(sHtml) { + + sHtml += ""; + + return sHtml.replace(/&/g, "&").replace(//g, ">"); + + } + + return ""; + +}; + + + +///////////////////////////////////////////////////////////////////////////// + +// + +// Private member variables + +// + +///////////////////////////////////////////////////////////////////////////// + + + +/** + * Internal class member to index multiple log reader instances. * - * @type number + * @property _memberName + * @static + + * @type Number + + * @default 0 + * @private */ @@ -1442,8 +1272,10 @@ * - * @type string + * @property _sName + * @type String + * @private */ @@ -1462,24 +1294,28 @@ * + * @property _elDefaultContainer + * @type HTMLElement * @private */ -YAHOO.widget.LogReader._defaultContainerEl = null; +YAHOO.widget.LogReader._elDefaultContainer = null; /** - * Buffer of log messages for batch output. + * Buffer of log message objects for batch output. * - * @type array + * @property _buffer + * @type Object[] + * @private */ @@ -1494,8 +1330,12 @@ * - * @type number + * @property _consoleMsgCount + * @type Number + + * @default 0 + * @private */ @@ -1510,8 +1350,10 @@ * - * @type date + * @property _lastTime + * @type Date + * @private */ @@ -1526,8 +1368,10 @@ * - * @type number + * @property _timeout + * @type Number + * @private */ @@ -1542,8 +1386,10 @@ * - * @type array + * @property _categoryFilters + * @type String[] + * @private */ @@ -1558,8 +1404,10 @@ * - * @type array + * @property _sourceFilters + * @type String[] + * @private */ @@ -1574,13 +1422,15 @@ * + * @property _elContainer + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._containerEl = null; +YAHOO.widget.LogReader.prototype._elContainer = null; @@ -1590,13 +1440,15 @@ * + * @property _elHd + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._hdEl = null; +YAHOO.widget.LogReader.prototype._elHd = null; @@ -1606,13 +1458,15 @@ * + * @property _elCollapse + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._collapseEl = null; +YAHOO.widget.LogReader.prototype._elCollapse = null; @@ -1622,13 +1476,15 @@ * + * @property _btnCollapse + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._collapseBtn = null; +YAHOO.widget.LogReader.prototype._btnCollapse = null; @@ -1638,6 +1494,8 @@ * + * @property _title + * @type HTMLElement * @private @@ -1654,13 +1512,15 @@ * + * @property _elConsole + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._consoleEl = null; +YAHOO.widget.LogReader.prototype._elConsole = null; @@ -1670,13 +1530,15 @@ * + * @property _elFt + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._ftEl = null; +YAHOO.widget.LogReader.prototype._elFt = null; @@ -1686,13 +1548,15 @@ * + * @property _elBtns + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._btnsEl = null; +YAHOO.widget.LogReader.prototype._elBtns = null; @@ -1702,13 +1566,15 @@ * + * @property _elCategoryFilters + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._categoryFiltersEl = null; +YAHOO.widget.LogReader.prototype._elCategoryFilters = null; @@ -1718,13 +1584,15 @@ * + * @property _elSourceFilters + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._sourceFiltersEl = null; +YAHOO.widget.LogReader.prototype._elSourceFilters = null; @@ -1734,13 +1602,15 @@ * + * @property _btnPause + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._pauseBtn = null; +YAHOO.widget.LogReader.prototype._btnPause = null; @@ -1750,155 +1620,181 @@ * + * @property _btnClear + * @type HTMLElement * @private */ -YAHOO.widget.LogReader.prototype._clearBtn = null; +YAHOO.widget.LogReader.prototype._btnClear = null; -/*************************************************************************** + - * Private methods +///////////////////////////////////////////////////////////////////////////// - ***************************************************************************/ +// +// Private methods + +// + +///////////////////////////////////////////////////////////////////////////// + + + /** * Creates the UI for a category filter in the log reader footer element. * - * @param {string} category Category name + * @method _createCategoryCheckbox + * @param sCategory {String} Category name. + * @private */ -YAHOO.widget.LogReader.prototype._createCategoryCheckbox = function(category) { +YAHOO.widget.LogReader.prototype._createCategoryCheckbox = function(sCategory) { var oSelf = this; - if(this._ftEl) { + if(this._elFt) { - var parentEl = this._categoryFiltersEl; + var elParent = this._elCategoryFilters; var filters = this._categoryFilters; - var filterEl = parentEl.appendChild(document.createElement("span")); + var elFilter = elParent.appendChild(document.createElement("span")); - filterEl.className = "yui-log-filtergrp"; + elFilter.className = "yui-log-filtergrp"; // Append el at the end so IE 5.5 can set "type" attribute // and THEN set checked property - var categoryChk = document.createElement("input"); + var chkCategory = document.createElement("input"); - categoryChk.id = "yui-log-filter-" + category + this._sName; + chkCategory.id = "yui-log-filter-" + sCategory + this._sName; - categoryChk.className = "yui-log-filter-" + category; + chkCategory.className = "yui-log-filter-" + sCategory; - categoryChk.type = "checkbox"; + chkCategory.type = "checkbox"; - categoryChk.category = category; + chkCategory.category = sCategory; - categoryChk = filterEl.appendChild(categoryChk); + chkCategory = elFilter.appendChild(chkCategory); - categoryChk.checked = true; + chkCategory.checked = true; // Add this checked filter to the internal array of filters - filters.push(category); + filters.push(sCategory); // Subscribe to the click event - YAHOO.util.Event.addListener(categoryChk,'click',oSelf._onCheckCategory,oSelf); + YAHOO.util.Event.addListener(chkCategory,'click',oSelf._onCheckCategory,oSelf); // Create and class the text label - var categoryChkLbl = filterEl.appendChild(document.createElement("label")); + var lblCategory = elFilter.appendChild(document.createElement("label")); - categoryChkLbl.htmlFor = categoryChk.id; + lblCategory.htmlFor = chkCategory.id; - categoryChkLbl.className = category; + lblCategory.className = sCategory; - categoryChkLbl.innerHTML = category; + lblCategory.innerHTML = sCategory; } }; -YAHOO.widget.LogReader.prototype._createSourceCheckbox = function(source) { +/** + * Creates a checkbox in the log reader footer element to filter by source. + + * + + * @method _createSourceCheckbox + + * @param sSource {String} Source name. + + * @private + + */ + +YAHOO.widget.LogReader.prototype._createSourceCheckbox = function(sSource) { + var oSelf = this; - if(this._ftEl) { + if(this._elFt) { - var parentEl = this._sourceFiltersEl; + var elParent = this._elSourceFilters; var filters = this._sourceFilters; - var filterEl = parentEl.appendChild(document.createElement("span")); + var elFilter = elParent.appendChild(document.createElement("span")); - filterEl.className = "yui-log-filtergrp"; + elFilter.className = "yui-log-filtergrp"; // Append el at the end so IE 5.5 can set "type" attribute // and THEN set checked property - var sourceChk = document.createElement("input"); + var chkSource = document.createElement("input"); - sourceChk.id = "yui-log-filter" + source + this._sName; + chkSource.id = "yui-log-filter" + sSource + this._sName; - sourceChk.className = "yui-log-filter" + source; + chkSource.className = "yui-log-filter" + sSource; - sourceChk.type = "checkbox"; + chkSource.type = "checkbox"; - sourceChk.source = source; + chkSource.source = sSource; - sourceChk = filterEl.appendChild(sourceChk); + chkSource = elFilter.appendChild(chkSource); - sourceChk.checked = true; + chkSource.checked = true; // Add this checked filter to the internal array of filters - filters.push(source); + filters.push(sSource); // Subscribe to the click event - YAHOO.util.Event.addListener(sourceChk,'click',oSelf._onCheckSource,oSelf); + YAHOO.util.Event.addListener(chkSource,'click',oSelf._onCheckSource,oSelf); // Create and class the text label - var sourceChkLbl = filterEl.appendChild(document.createElement("label")); + var lblSource = elFilter.appendChild(document.createElement("label")); - sourceChkLbl.htmlFor = sourceChk.id; + lblSource.htmlFor = chkSource.id; - sourceChkLbl.className = source; + lblSource.className = sSource; - sourceChkLbl.innerHTML = source; + lblSource.innerHTML = sSource; } @@ -1912,6 +1808,8 @@ * + * @method _filterLogs + * @private */ @@ -1920,7 +1818,7 @@ // Reprint stack with new filters - if (this._consoleEl !== null) { + if (this._elConsole !== null) { this._clearConsole(); @@ -1940,6 +1838,8 @@ * + * @method _clearConsole + * @private */ @@ -1962,11 +1862,11 @@ - var consoleEl = this._consoleEl; + var elConsole = this._elConsole; - while(consoleEl.hasChildNodes()) { + while(elConsole.hasChildNodes()) { - consoleEl.removeChild(consoleEl.firstChild); + elConsole.removeChild(elConsole.firstChild); } @@ -1980,6 +1880,8 @@ * + * @method _printBuffer + * @private */ @@ -1990,7 +1892,7 @@ - if(this._consoleEl !== null) { + if(this._elConsole !== null) { var thresholdMax = this.thresholdMax; @@ -2018,11 +1920,11 @@ } - + if(!this.newestOnTop) { - this._consoleEl.scrollTop = this._consoleEl.scrollHeight; + this._elConsole.scrollTop = this._elConsole.scrollHeight; } @@ -2040,8 +1942,10 @@ * - * @param {array} aEntries + * @method _printToConsole + * @param aEntries {Object[]} Array of LogMsg objects to output to console. + * @private */ @@ -2062,28 +1966,32 @@ var entriesStartIndex = (entriesLen > thresholdMin) ? (entriesLen - thresholdMin) : 0; - + - // Iterate through all log entries to print the ones that filter through + // Iterate through all log entries var sourceFiltersLen = this._sourceFilters.length; var categoryFiltersLen = this._categoryFilters.length; for(var i=entriesStartIndex; i tag instead of
 tag (for wrapping)
 
-            if (time.toLocaleTimeString) {
+            var container = (this.verboseOutput) ? "CODE" : "PRE";
 
-                var localTime  = time.toLocaleTimeString();
+            var oNewElement = (this.newestOnTop) ?
 
-            }
+                this._elConsole.insertBefore(
 
-            else {
+                    document.createElement(container),this._elConsole.firstChild):
 
-                localTime = time.toString();
+                this._elConsole.appendChild(document.createElement(container));
 
-            }
-
 
 
-            var msecs = time.getTime();
+            oNewElement.innerHTML = output;
 
-            var startTime = YAHOO.widget.Logger.getStartTime();
-
-            var totalTime = msecs - startTime;
-
-            var elapsedTime = msecs - this._lastTime;
-
-            this._lastTime = msecs;
-
-
-
-            var verboseOutput = (this.verboseOutput);
-
-            var container = (verboseOutput) ? "CODE" : "PRE";
-
-            var sourceAndDetail = (sourceDetail) ?
-
-                source + " " + sourceDetail : source;
-
-
-
-            // Verbose uses code tag instead of pre tag (for wrapping)
-
-            // and includes extra line breaks
-
-            var output =  (verboseOutput) ?
-
-                ["

", label, " ", - - totalTime, "ms (+", elapsedTime, ") ", - - localTime, ": ", - - "

", - - sourceAndDetail, - - ":

", - - this._HTML2Text(entry.msg), - - "

"] : - - - - ["

", label, " ", - - totalTime, "ms (+", elapsedTime, ") ", - - localTime, ": ", - - sourceAndDetail, ": ", - - this._HTML2Text(entry.msg),"

"]; - - - - var oNewElement = (this.newestOnTop) ? - - this._consoleEl.insertBefore(document.createElement(container),this._consoleEl.firstChild): - - this._consoleEl.appendChild(document.createElement(container)); - - - - oNewElement.innerHTML = output.join(""); - this._consoleMsgCount++; + this._lastTime = entry.time.getTime(); + } } @@ -2220,57 +2056,41 @@ -/** +///////////////////////////////////////////////////////////////////////////// - * Converts input chars "<", ">", and "&" to HTML entities. +// - * +// Private event handlers - * @private +// - */ +///////////////////////////////////////////////////////////////////////////// -YAHOO.widget.LogReader.prototype._HTML2Text = function(html) { - - if(html) { - - return html.replace(/&/g, "&").replace(//g, ">"); - - } - - else return ""; - -}; - -/*************************************************************************** - - * Private event handlers - - ***************************************************************************/ - /** * Handles Logger's categoryCreateEvent. * - * @param {string} type The event + * @method _onCategoryCreate - * @param {array} args Data passed from event firer + * @param sType {String} The event. - * @param {object} oSelf The log reader instance + * @param aArgs {Object[]} Data passed from event firer. + * @param oSelf {Object} The LogReader instance. + * @private */ -YAHOO.widget.LogReader.prototype._onCategoryCreate = function(type, args, oSelf) { +YAHOO.widget.LogReader.prototype._onCategoryCreate = function(sType, aArgs, oSelf) { - var category = args[0]; + var category = aArgs[0]; - if(oSelf._ftEl) { + if(oSelf._elFt) { oSelf._createCategoryCheckbox(category); @@ -2286,21 +2106,23 @@ * - * @param {string} type The event + * @method _onSourceCreate - * @param {array} args Data passed from event firer + * @param sType {String} The event. - * @param {object} oSelf The log reader instance + * @param aArgs {Object[]} Data passed from event firer. + * @param oSelf {Object} The LogReader instance. + * @private */ -YAHOO.widget.LogReader.prototype._onSourceCreate = function(type, args, oSelf) { +YAHOO.widget.LogReader.prototype._onSourceCreate = function(sType, aArgs, oSelf) { - var source = args[0]; + var source = aArgs[0]; - if(oSelf._ftEl) { + if(oSelf._elFt) { oSelf._createSourceCheckbox(source); @@ -2316,10 +2138,12 @@ * - * @param {event} v The click event + * @method _onCheckCategory - * @param {object} oSelf The log reader instance + * @param v {HTMLEvent} The click event. + * @param oSelf {Object} The LogReader instance. + * @private */ @@ -2366,10 +2190,12 @@ * - * @param {event} v The click event + * @method _onCheckSource - * @param {object} oSelf The log reader instance + * @param v {HTMLEvent} The click event. + * @param oSelf {Object} The log reader instance. + * @private */ @@ -2416,25 +2242,27 @@ * - * @param {event} v The click event + * @method _onClickCollapseBtn - * @param {object} oSelf The log reader instance + * @param v {HTMLEvent} The click event. + * @param oSelf {Object} The LogReader instance + * @private */ YAHOO.widget.LogReader.prototype._onClickCollapseBtn = function(v, oSelf) { - var btn = oSelf._collapseBtn; + var btn = oSelf._btnCollapse; if(btn.value == "Expand") { - oSelf._consoleEl.style.display = "block"; + oSelf._elConsole.style.display = "block"; - if(oSelf._ftEl) { + if(oSelf._elFt) { - oSelf._ftEl.style.display = "block"; + oSelf._elFt.style.display = "block"; } @@ -2444,11 +2272,11 @@ else { - oSelf._consoleEl.style.display = "none"; + oSelf._elConsole.style.display = "none"; - if(oSelf._ftEl) { + if(oSelf._elFt) { - oSelf._ftEl.style.display = "none"; + oSelf._elFt.style.display = "none"; } @@ -2466,17 +2294,19 @@ * - * @param {event} v The click event + * @method _onClickPauseBtn - * @param {object} oSelf The log reader instance + * @param v {HTMLEvent} The click event. + * @param oSelf {Object} The LogReader instance. + * @private */ YAHOO.widget.LogReader.prototype._onClickPauseBtn = function(v, oSelf) { - var btn = oSelf._pauseBtn; + var btn = oSelf._btnPause; if(btn.value == "Resume") { @@ -2504,10 +2334,12 @@ * - * @param {event} v The click event + * @method _onClickClearBtn - * @param {object} oSelf The log reader instance + * @param v {HTMLEvent} The click event. + * @param oSelf {Object} The LogReader instance. + * @private */ @@ -2526,19 +2358,21 @@ * - * @param {string} type The newLog event + * @method _onNewLog - * @param {array} args Data passed from event firer + * @param sType {String} The event. - * @param {object} oSelf The log reader instance + * @param aArgs {Object[]} Data passed from event firer. + * @param oSelf {Object} The LogReader instance. + * @private */ -YAHOO.widget.LogReader.prototype._onNewLog = function(type, args, oSelf) { +YAHOO.widget.LogReader.prototype._onNewLog = function(sType, aArgs, oSelf) { - var logEntry = args[0]; + var logEntry = aArgs[0]; oSelf._buffer.push(logEntry); @@ -2560,21 +2394,735 @@ * - * @param {string} type The click event + * @method _onReset - * @param {array} args Data passed from event firer + * @param sType {String} The event. - * @param {object} oSelf The log reader instance + * @param aArgs {Object[]} Data passed from event firer. + * @param oSelf {Object} The LogReader instance. + * @private */ -YAHOO.widget.LogReader.prototype._onReset = function(type, args, oSelf) { +YAHOO.widget.LogReader.prototype._onReset = function(sType, aArgs, oSelf) { oSelf._filterLogs(); }; + /** + + * The Logger widget provides a simple way to read or write log messages in + + * JavaScript code. Integration with the YUI Library's debug builds allow + + * implementers to access under-the-hood events, errors, and debugging messages. + + * Output may be read through a LogReader console and/or output to a browser + + * console. + + * + + * @module logger + + * @requires yahoo, event, dom + + * @optional dragdrop + + * @namespace YAHOO.widget + + * @title Logger Widget + + */ + +/****************************************************************************/ + +/****************************************************************************/ + +/****************************************************************************/ + + + +/** + + * The singleton Logger class provides core log management functionality. Saves + + * logs written through the global YAHOO.log function or written by a LogWriter + + * instance. Provides access to logs for reading by a LogReader instance or + + * native browser console such as the Firebug extension to Firefox or Safari's + + * JavaScript console through integration with the console.log() method. + + * + + * @class Logger + + * @static + + */ + +YAHOO.widget.Logger = { + + // Initialize members + + loggerEnabled: true, + + _browserConsoleEnabled: false, + + categories: ["info","warn","error","time","window"], + + sources: ["global"], + + _stack: [], // holds all log msgs + + maxStackEntries: 2500, + + _startTime: new Date().getTime(), // static start timestamp + + _lastTime: null // timestamp of last logged message + +}; + + + +///////////////////////////////////////////////////////////////////////////// + +// + +// Public methods + +// + +///////////////////////////////////////////////////////////////////////////// + +/** + + * Saves a log message to the stack and fires newLogEvent. If the log message is + + * assigned to an unknown category, creates a new category. If the log message is + + * from an unknown source, creates a new source. If browser console is enabled, + + * outputs the log message to browser console. + + * + + * @method log + + * @param sMsg {String} The log message. + + * @param sCategory {String} Category of log message, or null. + + * @param sSource {String} Source of LogWriter, or null if global. + + */ + +YAHOO.widget.Logger.log = function(sMsg, sCategory, sSource) { + + if(this.loggerEnabled) { + + if(!sCategory) { + + sCategory = "info"; // default category + + } + + else { + + sCategory = sCategory.toLocaleLowerCase(); + + if(this._isNewCategory(sCategory)) { + + this._createNewCategory(sCategory); + + } + + } + + var sClass = "global"; // default source + + var sDetail = null; + + if(sSource) { + + var spaceIndex = sSource.indexOf(" "); + + if(spaceIndex > 0) { + + // Substring until first space + + sClass = sSource.substring(0,spaceIndex); + + // The rest of the source + + sDetail = sSource.substring(spaceIndex,sSource.length); + + } + + else { + + sClass = sSource; + + } + + if(this._isNewSource(sClass)) { + + this._createNewSource(sClass); + + } + + } + + + + var timestamp = new Date(); + + var logEntry = new YAHOO.widget.LogMsg({ + + msg: sMsg, + + time: timestamp, + + category: sCategory, + + source: sClass, + + sourceDetail: sDetail + + }); + + + + var stack = this._stack; + + var maxStackEntries = this.maxStackEntries; + + if(maxStackEntries && !isNaN(maxStackEntries) && + + (stack.length >= maxStackEntries)) { + + stack.shift(); + + } + + stack.push(logEntry); + + this.newLogEvent.fire(logEntry); + + + + if(this._browserConsoleEnabled) { + + this._printToBrowserConsole(logEntry); + + } + + return true; + + } + + else { + + return false; + + } + +}; + + + +/** + + * Resets internal stack and startTime, enables Logger, and fires logResetEvent. + + * + + * @method reset + + */ + +YAHOO.widget.Logger.reset = function() { + + this._stack = []; + + this._startTime = new Date().getTime(); + + this.loggerEnabled = true; + + this.log("Logger reset"); + + this.logResetEvent.fire(); + +}; + + + +/** + + * Public accessor to internal stack of log message objects. + + * + + * @method getStack + + * @return {Object[]} Array of log message objects. + + */ + +YAHOO.widget.Logger.getStack = function() { + + return this._stack; + +}; + + + +/** + + * Public accessor to internal start time. + + * + + * @method getStartTime + + * @return {Date} Internal date of when Logger singleton was initialized. + + */ + +YAHOO.widget.Logger.getStartTime = function() { + + return this._startTime; + +}; + + + +/** + + * Disables output to the browser's global console.log() function, which is used + + * by the Firebug extension to Firefox as well as Safari. + + * + + * @method disableBrowserConsole + + */ + +YAHOO.widget.Logger.disableBrowserConsole = function() { + + YAHOO.log("Logger output to the function console.log() has been disabled."); + + this._browserConsoleEnabled = false; + +}; + + + +/** + + * Enables output to the browser's global console.log() function, which is used + + * by the Firebug extension to Firefox as well as Safari. + + * + + * @method enableBrowserConsole + + */ + +YAHOO.widget.Logger.enableBrowserConsole = function() { + + this._browserConsoleEnabled = true; + + YAHOO.log("Logger output to the function console.log() has been enabled."); + +}; + + + +///////////////////////////////////////////////////////////////////////////// + +// + +// Public events + +// + +///////////////////////////////////////////////////////////////////////////// + + + + /** + + * Fired when a new category has been created. + + * + + * @event categoryCreateEvent + + * @param sCategory {String} Category name. + + */ + +YAHOO.widget.Logger.categoryCreateEvent = + + new YAHOO.util.CustomEvent("categoryCreate", this, true); + + + + /** + + * Fired when a new source has been named. + + * + + * @event sourceCreateEvent + + * @param sSource {String} Source name. + + */ + +YAHOO.widget.Logger.sourceCreateEvent = + + new YAHOO.util.CustomEvent("sourceCreate", this, true); + + + + /** + + * Fired when a new log message has been created. + + * + + * @event newLogEvent + + * @param sMsg {String} Log message. + + */ + +YAHOO.widget.Logger.newLogEvent = new YAHOO.util.CustomEvent("newLog", this, true); + + + +/** + + * Fired when the Logger has been reset has been created. + + * + + * @event logResetEvent + + */ + +YAHOO.widget.Logger.logResetEvent = new YAHOO.util.CustomEvent("logReset", this, true); + + + +///////////////////////////////////////////////////////////////////////////// + +// + +// Private methods + +// + +///////////////////////////////////////////////////////////////////////////// + + + +/** + + * Creates a new category of log messages and fires categoryCreateEvent. + + * + + * @method _createNewCategory + + * @param sCategory {String} Category name. + + * @private + + */ + +YAHOO.widget.Logger._createNewCategory = function(sCategory) { + + this.categories.push(sCategory); + + this.categoryCreateEvent.fire(sCategory); + +}; + + + +/** + + * Checks to see if a category has already been created. + + * + + * @method _isNewCategory + + * @param sCategory {String} Category name. + + * @return {Boolean} Returns true if category is unknown, else returns false. + + * @private + + */ + +YAHOO.widget.Logger._isNewCategory = function(sCategory) { + + for(var i=0; i < this.categories.length; i++) { + + if(sCategory == this.categories[i]) { + + return false; + + } + + } + + return true; + +}; + + + +/** + + * Creates a new source of log messages and fires sourceCreateEvent. + + * + + * @method _createNewSource + + * @param sSource {String} Source name. + + * @private + + */ + +YAHOO.widget.Logger._createNewSource = function(sSource) { + + this.sources.push(sSource); + + this.sourceCreateEvent.fire(sSource); + +}; + + + +/** + + * Checks to see if a source already exists. + + * + + * @method _isNewSource + + * @param sSource {String} Source name. + + * @return {Boolean} Returns true if source is unknown, else returns false. + + * @private + + */ + +YAHOO.widget.Logger._isNewSource = function(sSource) { + + if(sSource) { + + for(var i=0; i < this.sources.length; i++) { + + if(sSource == this.sources[i]) { + + return false; + + } + + } + + return true; + + } + +}; + + + +/** + + * Outputs a log message to global console.log() function. + + * + + * @method _printToBrowserConsole + + * @param oEntry {Object} Log entry object. + + * @private + + */ + +YAHOO.widget.Logger._printToBrowserConsole = function(oEntry) { + + if(window.console && console.log) { + + var category = oEntry.category; + + var label = oEntry.category.substring(0,4).toUpperCase(); + + + + var time = oEntry.time; + + if (time.toLocaleTimeString) { + + var localTime = time.toLocaleTimeString(); + + } + + else { + + localTime = time.toString(); + + } + + + + var msecs = time.getTime(); + + var elapsedTime = (YAHOO.widget.Logger._lastTime) ? + + (msecs - YAHOO.widget.Logger._lastTime) : 0; + + YAHOO.widget.Logger._lastTime = msecs; + + + + var output = + + localTime + " (" + + + elapsedTime + "ms): " + + + oEntry.source + ": " + + + oEntry.msg; + + + + console.log(output); + + } + +}; + + + +///////////////////////////////////////////////////////////////////////////// + +// + +// Private event handlers + +// + +///////////////////////////////////////////////////////////////////////////// + + + +/** + + * Handles logging of messages due to window error events. + + * + + * @method _onWindowError + + * @param sMsg {String} The error message. + + * @param sUrl {String} URL of the error. + + * @param sLine {String} Line number of the error. + + * @private + + */ + +YAHOO.widget.Logger._onWindowError = function(sMsg,sUrl,sLine) { + + // Logger is not in scope of this event handler + + try { + + YAHOO.widget.Logger.log(sMsg+' ('+sUrl+', line '+sLine+')', "window"); + + if(YAHOO.widget.Logger._origOnWindowError) { + + YAHOO.widget.Logger._origOnWindowError(); + + } + + } + + catch(e) { + + return false; + + } + +}; + + + +///////////////////////////////////////////////////////////////////////////// + +// + +// Enable handling of native JavaScript errors + +// NB: Not all browsers support the window.onerror event + +// + +///////////////////////////////////////////////////////////////////////////// + + + +if(window.onerror) { + + // Save any previously defined handler to call + + YAHOO.widget.Logger._origOnWindowError = window.onerror; + +} + +window.onerror = YAHOO.widget.Logger._onWindowError; + + + +///////////////////////////////////////////////////////////////////////////// + +// + +// First log + +// + +///////////////////////////////////////////////////////////////////////////// + + + +YAHOO.widget.Logger.log("Logger initialized"); + + +