MDL-11082 Improved groups upgrade performance 1.8x -> 1.9; thanks Eloy for telling...
[moodle-pu.git] / lib / yui / logger / logger-debug.js
blob583eda200fde4326696ad4cc0790ed861e3e8c86
1 /*
2 Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
5 version: 2.3.0
6 */
7 /****************************************************************************/
8 /****************************************************************************/
9 /****************************************************************************/
11 /**
12  * The LogMsg class defines a single log message.
13  *
14  * @class LogMsg
15  * @constructor
16  * @param oConfigs {Object} Object literal of configuration params.
17  */
18  YAHOO.widget.LogMsg = function(oConfigs) {
19     // Parse configs
20     if (oConfigs && (oConfigs.constructor == Object)) {
21         for(var param in oConfigs) {
22             this[param] = oConfigs[param];
23         }
24     }
25  };
27 /////////////////////////////////////////////////////////////////////////////
29 // Public member variables
31 /////////////////////////////////////////////////////////////////////////////
33 /**
34  * Log message.
35  *
36  * @property msg
37  * @type String
38  */
39 YAHOO.widget.LogMsg.prototype.msg = null;
41 /**
42  * Log timestamp.
43  *
44  * @property time
45  * @type Date
46  */
47 YAHOO.widget.LogMsg.prototype.time = null;
49 /**
50  * Log category.
51  *
52  * @property category
53  * @type String
54  */
55 YAHOO.widget.LogMsg.prototype.category = null;
57 /**
58  * Log source. The first word passed in as the source argument.
59  *
60  * @property source
61  * @type String
62  */
63 YAHOO.widget.LogMsg.prototype.source = null;
65 /**
66  * Log source detail. The remainder of the string passed in as the source argument, not
67  * including the first word (if any).
68  *
69  * @property sourceDetail
70  * @type String
71  */
72 YAHOO.widget.LogMsg.prototype.sourceDetail = null;
75 /****************************************************************************/
76 /****************************************************************************/
77 /****************************************************************************/
79 /**
80  * The LogWriter class provides a mechanism to log messages through
81  * YAHOO.widget.Logger from a named source.
82  *
83  * @class LogWriter
84  * @constructor
85  * @param sSource {String} Source of LogWriter instance.
86  */
87 YAHOO.widget.LogWriter = function(sSource) {
88     if(!sSource) {
89         YAHOO.log("Could not instantiate LogWriter due to invalid source.",
90             "error", "LogWriter");
91         return;
92     }
93     this._source = sSource;
94  };
96 /////////////////////////////////////////////////////////////////////////////
98 // Public methods
100 /////////////////////////////////////////////////////////////////////////////
102  /**
103  * Public accessor to the unique name of the LogWriter instance.
105  * @method toString
106  * @return {String} Unique name of the LogWriter instance.
107  */
108 YAHOO.widget.LogWriter.prototype.toString = function() {
109     return "LogWriter " + this._sSource;
113  * Logs a message attached to the source of the LogWriter.
115  * @method log
116  * @param sMsg {String} The log message.
117  * @param sCategory {String} Category name.
118  */
119 YAHOO.widget.LogWriter.prototype.log = function(sMsg, sCategory) {
120     YAHOO.widget.Logger.log(sMsg, sCategory, this._source);
124  * Public accessor to get the source name.
126  * @method getSource
127  * @return {String} The LogWriter source.
128  */
129 YAHOO.widget.LogWriter.prototype.getSource = function() {
130     return this._sSource;
134  * Public accessor to set the source name.
136  * @method setSource
137  * @param sSource {String} Source of LogWriter instance.
138  */
139 YAHOO.widget.LogWriter.prototype.setSource = function(sSource) {
140     if(!sSource) {
141         YAHOO.log("Could not set source due to invalid source.", "error", this.toString());
142         return;
143     }
144     else {
145         this._sSource = sSource;
146     }
149 /////////////////////////////////////////////////////////////////////////////
151 // Private member variables
153 /////////////////////////////////////////////////////////////////////////////
156  * Source of the LogWriter instance.
158  * @property _source
159  * @type String
160  * @private
161  */
162 YAHOO.widget.LogWriter.prototype._source = null;
167 /****************************************************************************/
168 /****************************************************************************/
169 /****************************************************************************/
172  * The LogReader class provides UI to read messages logged to YAHOO.widget.Logger.
174  * @class LogReader
175  * @constructor
176  * @param elContainer {HTMLElement} (optional) DOM element reference of an existing DIV.
177  * @param elContainer {String} (optional) String ID of an existing DIV.
178  * @param oConfigs {Object} (optional) Object literal of configuration params.
179  */
180 YAHOO.widget.LogReader = function(elContainer, oConfigs) {
181     this._sName = YAHOO.widget.LogReader._index;
182     YAHOO.widget.LogReader._index++;
183     
184     // Internal vars
185     this._buffer = []; // output buffer
186     this._filterCheckboxes = {}; // pointers to checkboxes
187     this._lastTime = YAHOO.widget.Logger.getStartTime(); // timestamp of last log message to console
189     // Parse config vars here
190     if (oConfigs && (oConfigs.constructor == Object)) {
191         for(var param in oConfigs) {
192             this[param] = oConfigs[param];
193         }
194     }
196     this._initContainerEl(elContainer);
197     if(!this._elContainer) {
198         YAHOO.log("Could not instantiate LogReader due to an invalid container element " +
199                 elContainer, "error", this.toString());
200         return;
201     }
202     
203     this._initHeaderEl();
204     this._initConsoleEl();
205     this._initFooterEl();
207     this._initDragDrop();
209     this._initCategories();
210     this._initSources();
212     // Subscribe to Logger custom events
213     YAHOO.widget.Logger.newLogEvent.subscribe(this._onNewLog, this);
214     YAHOO.widget.Logger.logResetEvent.subscribe(this._onReset, this);
216     YAHOO.widget.Logger.categoryCreateEvent.subscribe(this._onCategoryCreate, this);
217     YAHOO.widget.Logger.sourceCreateEvent.subscribe(this._onSourceCreate, this);
219     this._filterLogs();
220     YAHOO.log("LogReader initialized", null, this.toString());
223 /////////////////////////////////////////////////////////////////////////////
225 // Public member variables
227 /////////////////////////////////////////////////////////////////////////////
230  * Whether or not LogReader is enabled to output log messages.
232  * @property logReaderEnabled
233  * @type Boolean
234  * @default true
235  */
236 YAHOO.widget.LogReader.prototype.logReaderEnabled = true;
239  * Public member to access CSS width of the LogReader container.
241  * @property width
242  * @type String
243  */
244 YAHOO.widget.LogReader.prototype.width = null;
247  * Public member to access CSS height of the LogReader container.
249  * @property height
250  * @type String
251  */
252 YAHOO.widget.LogReader.prototype.height = null;
255  * Public member to access CSS top position of the LogReader container.
257  * @property top
258  * @type String
259  */
260 YAHOO.widget.LogReader.prototype.top = null;
263  * Public member to access CSS left position of the LogReader container.
265  * @property left
266  * @type String
267  */
268 YAHOO.widget.LogReader.prototype.left = null;
271  * Public member to access CSS right position of the LogReader container.
273  * @property right
274  * @type String
275  */
276 YAHOO.widget.LogReader.prototype.right = null;
279  * Public member to access CSS bottom position of the LogReader container.
281  * @property bottom
282  * @type String
283  */
284 YAHOO.widget.LogReader.prototype.bottom = null;
287  * Public member to access CSS font size of the LogReader container.
289  * @property fontSize
290  * @type String
291  */
292 YAHOO.widget.LogReader.prototype.fontSize = null;
295  * Whether or not the footer UI is enabled for the LogReader.
297  * @property footerEnabled
298  * @type Boolean
299  * @default true
300  */
301 YAHOO.widget.LogReader.prototype.footerEnabled = true;
304  * Whether or not output is verbose (more readable). Setting to true will make
305  * output more compact (less readable).
307  * @property verboseOutput
308  * @type Boolean
309  * @default true
310  */
311 YAHOO.widget.LogReader.prototype.verboseOutput = true;
314  * Whether or not newest message is printed on top.
316  * @property newestOnTop
317  * @type Boolean
318  */
319 YAHOO.widget.LogReader.prototype.newestOnTop = true;
322  * Output timeout buffer in milliseconds.
324  * @property outputBuffer
325  * @type Number
326  * @default 100
327  */
328 YAHOO.widget.LogReader.prototype.outputBuffer = 100;
331  * Maximum number of messages a LogReader console will display.
333  * @property thresholdMax
334  * @type Number
335  * @default 500
336  */
337 YAHOO.widget.LogReader.prototype.thresholdMax = 500;
340  * When a LogReader console reaches its thresholdMax, it will clear out messages
341  * and print out the latest thresholdMin number of messages.
343  * @property thresholdMin
344  * @type Number
345  * @default 100
346  */
347 YAHOO.widget.LogReader.prototype.thresholdMin = 100;
350  * True when LogReader is in a collapsed state, false otherwise.
352  * @property isCollapsed
353  * @type Boolean
354  * @default false
355  */
356 YAHOO.widget.LogReader.prototype.isCollapsed = false;
359  * True when LogReader is in a paused state, false otherwise.
361  * @property isPaused
362  * @type Boolean
363  * @default false
364  */
365 YAHOO.widget.LogReader.prototype.isPaused = false;
368  * Enables draggable LogReader if DragDrop Utility is present.
370  * @property draggable
371  * @type Boolean
372  * @default true
373  */
374 YAHOO.widget.LogReader.prototype.draggable = true;
376 /////////////////////////////////////////////////////////////////////////////
378 // Public methods
380 /////////////////////////////////////////////////////////////////////////////
382  /**
383  * Public accessor to the unique name of the LogReader instance.
385  * @method toString
386  * @return {String} Unique name of the LogReader instance.
387  */
388 YAHOO.widget.LogReader.prototype.toString = function() {
389     return "LogReader instance" + this._sName;
392  * Pauses output of log messages. While paused, log messages are not lost, but
393  * get saved to a buffer and then output upon resume of LogReader.
395  * @method pause
396  */
397 YAHOO.widget.LogReader.prototype.pause = function() {
398     this.isPaused = true;
399     this._btnPause.value = "Resume";
400     this._timeout = null;
401     this.logReaderEnabled = false;
405  * Resumes output of log messages, including outputting any log messages that
406  * have been saved to buffer while paused.
408  * @method resume
409  */
410 YAHOO.widget.LogReader.prototype.resume = function() {
411     this.isPaused = false;
412     this._btnPause.value = "Pause";
413     this.logReaderEnabled = true;
414     this._printBuffer();
418  * Hides UI of LogReader. Logging functionality is not disrupted.
420  * @method hide
421  */
422 YAHOO.widget.LogReader.prototype.hide = function() {
423     this._elContainer.style.display = "none";
427  * Shows UI of LogReader. Logging functionality is not disrupted.
429  * @method show
430  */
431 YAHOO.widget.LogReader.prototype.show = function() {
432     this._elContainer.style.display = "block";
436  * Collapses UI of LogReader. Logging functionality is not disrupted.
438  * @method collapse
439  */
440 YAHOO.widget.LogReader.prototype.collapse = function() {
441     this._elConsole.style.display = "none";
442     if(this._elFt) {
443         this._elFt.style.display = "none";
444     }
445     this._btnCollapse.value = "Expand";
446     this.isCollapsed = true;
450  * Expands UI of LogReader. Logging functionality is not disrupted.
452  * @method expand
453  */
454 YAHOO.widget.LogReader.prototype.expand = function() {
455     this._elConsole.style.display = "block";
456     if(this._elFt) {
457         this._elFt.style.display = "block";
458     }
459     this._btnCollapse.value = "Collapse";
460     this.isCollapsed = false;
464  * Returns related checkbox element for given filter (i.e., category or source).
466  * @method getCheckbox
467  * @param {String} Category or source name.
468  * @return {Array} Array of all filter checkboxes.
469  */
470 YAHOO.widget.LogReader.prototype.getCheckbox = function(filter) {
471     return this._filterCheckboxes[filter];
475  * Returns array of enabled categories.
477  * @method getCategories
478  * @return {String[]} Array of enabled categories.
479  */
480 YAHOO.widget.LogReader.prototype.getCategories = function() {
481     return this._categoryFilters;
485  * Shows log messages associated with given category.
487  * @method showCategory
488  * @param {String} Category name.
489  */
490 YAHOO.widget.LogReader.prototype.showCategory = function(sCategory) {
491     var filtersArray = this._categoryFilters;
492     // Don't do anything if category is already enabled
493     // Use Array.indexOf if available...
494     if(filtersArray.indexOf) {
495          if(filtersArray.indexOf(sCategory) >  -1) {
496             return;
497         }
498     }
499     // ...or do it the old-fashioned way
500     else {
501         for(var i=0; i<filtersArray.length; i++) {
502            if(filtersArray[i] === sCategory){
503                 return;
504             }
505         }
506     }
508     this._categoryFilters.push(sCategory);
509     this._filterLogs();
510     var elCheckbox = this.getCheckbox(sCategory);
511     if(elCheckbox) {
512         elCheckbox.checked = true;
513     }
517  * Hides log messages associated with given category.
519  * @method hideCategory
520  * @param {String} Category name.
521  */
522 YAHOO.widget.LogReader.prototype.hideCategory = function(sCategory) {
523     var filtersArray = this._categoryFilters;
524     for(var i=0; i<filtersArray.length; i++) {
525         if(sCategory == filtersArray[i]) {
526             filtersArray.splice(i, 1);
527             break;
528         }
529     }
530     this._filterLogs();
531     var elCheckbox = this.getCheckbox(sCategory);
532     if(elCheckbox) {
533         elCheckbox.checked = false;
534     }
538  * Returns array of enabled sources.
540  * @method getSources
541  * @return {Array} Array of enabled sources.
542  */
543 YAHOO.widget.LogReader.prototype.getSources = function() {
544     return this._sourceFilters;
548  * Shows log messages associated with given source.
550  * @method showSource
551  * @param {String} Source name.
552  */
553 YAHOO.widget.LogReader.prototype.showSource = function(sSource) {
554     var filtersArray = this._sourceFilters;
555     // Don't do anything if category is already enabled
556     // Use Array.indexOf if available...
557     if(filtersArray.indexOf) {
558          if(filtersArray.indexOf(sSource) >  -1) {
559             return;
560         }
561     }
562     // ...or do it the old-fashioned way
563     else {
564         for(var i=0; i<filtersArray.length; i++) {
565            if(sSource == filtersArray[i]){
566                 return;
567             }
568         }
569     }
570     filtersArray.push(sSource);
571     this._filterLogs();
572     var elCheckbox = this.getCheckbox(sSource);
573     if(elCheckbox) {
574         elCheckbox.checked = true;
575     }
579  * Hides log messages associated with given source.
581  * @method hideSource
582  * @param {String} Source name.
583  */
584 YAHOO.widget.LogReader.prototype.hideSource = function(sSource) {
585     var filtersArray = this._sourceFilters;
586     for(var i=0; i<filtersArray.length; i++) {
587         if(sSource == filtersArray[i]) {
588             filtersArray.splice(i, 1);
589             break;
590         }
591     }
592     this._filterLogs();
593     var elCheckbox = this.getCheckbox(sSource);
594     if(elCheckbox) {
595         elCheckbox.checked = false;
596     }
600  * Does not delete any log messages, but clears all printed log messages from
601  * the console. Log messages will be printed out again if user re-filters. The
602  * static method YAHOO.widget.Logger.reset() should be called in order to
603  * actually delete log messages.
605  * @method clearConsole
606  */
607 YAHOO.widget.LogReader.prototype.clearConsole = function() {
608     // Clear the buffer of any pending messages
609     this._timeout = null;
610     this._buffer = [];
611     this._consoleMsgCount = 0;
613     var elConsole = this._elConsole;
614     while(elConsole.hasChildNodes()) {
615         elConsole.removeChild(elConsole.firstChild);
616     }
620  * Updates title to given string.
622  * @method setTitle
623  * @param sTitle {String} New title.
624  */
625 YAHOO.widget.LogReader.prototype.setTitle = function(sTitle) {
626     this._title.innerHTML = this.html2Text(sTitle);
630  * Gets timestamp of the last log.
632  * @method getLastTime
633  * @return {Date} Timestamp of the last log.
634  */
635 YAHOO.widget.LogReader.prototype.getLastTime = function() {
636     return this._lastTime;
640  * Formats message string to HTML for output to console.
642  * @method formatMsg
643  * @param oLogMsg {Object} Log message object.
644  * @return {String} HTML-formatted message for output to console.
645  */
646 YAHOO.widget.LogReader.prototype.formatMsg = function(oLogMsg) {
647     var category = oLogMsg.category;
648     
649     // Label for color-coded display
650     var label = category.substring(0,4).toUpperCase();
652     // Calculate the elapsed time to be from the last item that passed through the filter,
653     // not the absolute previous item in the stack
655     var time = oLogMsg.time;
656     if (time.toLocaleTimeString) {
657         var localTime  = time.toLocaleTimeString();
658     }
659     else {
660         localTime = time.toString();
661     }
663     var msecs = time.getTime();
664     var startTime = YAHOO.widget.Logger.getStartTime();
665     var totalTime = msecs - startTime;
666     var elapsedTime = msecs - this.getLastTime();
668     var source = oLogMsg.source;
669     var sourceDetail = oLogMsg.sourceDetail;
670     var sourceAndDetail = (sourceDetail) ?
671         source + " " + sourceDetail : source;
672         
673     
674     // Escape HTML entities in the log message itself for output to console
675     //var msg = this.html2Text(oLogMsg.msg); //TODO: delete
676     var msg = this.html2Text(YAHOO.lang.dump(oLogMsg.msg));
678     // Verbose output includes extra line breaks
679     var output =  (this.verboseOutput) ?
680         ["<pre class=\"yui-log-verbose\"><p><span class='", category, "'>", label, "</span> ",
681         totalTime, "ms (+", elapsedTime, ") ",
682         localTime, ": ",
683         "</p><p>",
684         sourceAndDetail,
685         ": </p><p>",
686         msg,
687         "</p></pre>"] :
689         ["<pre><p><span class='", category, "'>", label, "</span> ",
690         totalTime, "ms (+", elapsedTime, ") ",
691         localTime, ": ",
692         sourceAndDetail, ": ",
693         msg, "</p></pre>"];
695     return output.join("");
699  * Converts input chars "<", ">", and "&" to HTML entities.
701  * @method html2Text
702  * @param sHtml {String} String to convert.
703  * @private
704  */
705 YAHOO.widget.LogReader.prototype.html2Text = function(sHtml) {
706     if(sHtml) {
707         sHtml += "";
708         return sHtml.replace(/&/g, "&#38;").replace(/</g, "&#60;").replace(/>/g, "&#62;");
709     }
710     return "";
713 /////////////////////////////////////////////////////////////////////////////
715 // Private member variables
717 /////////////////////////////////////////////////////////////////////////////
720  * Internal class member to index multiple LogReader instances.
722  * @property _memberName
723  * @static
724  * @type Number
725  * @default 0
726  * @private
727  */
728 YAHOO.widget.LogReader._index = 0;
731  * Name of LogReader instance.
733  * @property _sName
734  * @type String
735  * @private
736  */
737 YAHOO.widget.LogReader.prototype._sName = null;
739 //TODO: remove
741  * A class member shared by all LogReaders if a container needs to be
742  * created during instantiation. Will be null if a container element never needs to
743  * be created on the fly, such as when the implementer passes in their own element.
745  * @property _elDefaultContainer
746  * @type HTMLElement
747  * @private
748  */
749 //YAHOO.widget.LogReader._elDefaultContainer = null;
752  * Buffer of log message objects for batch output.
754  * @property _buffer
755  * @type Object[]
756  * @private
757  */
758 YAHOO.widget.LogReader.prototype._buffer = null;
761  * Number of log messages output to console.
763  * @property _consoleMsgCount
764  * @type Number
765  * @default 0
766  * @private
767  */
768 YAHOO.widget.LogReader.prototype._consoleMsgCount = 0;
771  * Date of last output log message.
773  * @property _lastTime
774  * @type Date
775  * @private
776  */
777 YAHOO.widget.LogReader.prototype._lastTime = null;
780  * Batched output timeout ID.
782  * @property _timeout
783  * @type Number
784  * @private
785  */
786 YAHOO.widget.LogReader.prototype._timeout = null;
789  * Hash of filters and their related checkbox elements.
791  * @property _filterCheckboxes
792  * @type Object
793  * @private
794  */
795 YAHOO.widget.LogReader.prototype._filterCheckboxes = null;
798  * Array of filters for log message categories.
800  * @property _categoryFilters
801  * @type String[]
802  * @private
803  */
804 YAHOO.widget.LogReader.prototype._categoryFilters = null;
807  * Array of filters for log message sources.
809  * @property _sourceFilters
810  * @type String[]
811  * @private
812  */
813 YAHOO.widget.LogReader.prototype._sourceFilters = null;
816  * LogReader container element.
818  * @property _elContainer
819  * @type HTMLElement
820  * @private
821  */
822 YAHOO.widget.LogReader.prototype._elContainer = null;
825  * LogReader header element.
827  * @property _elHd
828  * @type HTMLElement
829  * @private
830  */
831 YAHOO.widget.LogReader.prototype._elHd = null;
834  * LogReader collapse element.
836  * @property _elCollapse
837  * @type HTMLElement
838  * @private
839  */
840 YAHOO.widget.LogReader.prototype._elCollapse = null;
843  * LogReader collapse button element.
845  * @property _btnCollapse
846  * @type HTMLElement
847  * @private
848  */
849 YAHOO.widget.LogReader.prototype._btnCollapse = null;
852  * LogReader title header element.
854  * @property _title
855  * @type HTMLElement
856  * @private
857  */
858 YAHOO.widget.LogReader.prototype._title = null;
861  * LogReader console element.
863  * @property _elConsole
864  * @type HTMLElement
865  * @private
866  */
867 YAHOO.widget.LogReader.prototype._elConsole = null;
870  * LogReader footer element.
872  * @property _elFt
873  * @type HTMLElement
874  * @private
875  */
876 YAHOO.widget.LogReader.prototype._elFt = null;
879  * LogReader buttons container element.
881  * @property _elBtns
882  * @type HTMLElement
883  * @private
884  */
885 YAHOO.widget.LogReader.prototype._elBtns = null;
888  * Container element for LogReader category filter checkboxes.
890  * @property _elCategoryFilters
891  * @type HTMLElement
892  * @private
893  */
894 YAHOO.widget.LogReader.prototype._elCategoryFilters = null;
897  * Container element for LogReader source filter checkboxes.
899  * @property _elSourceFilters
900  * @type HTMLElement
901  * @private
902  */
903 YAHOO.widget.LogReader.prototype._elSourceFilters = null;
906  * LogReader pause button element.
908  * @property _btnPause
909  * @type HTMLElement
910  * @private
911  */
912 YAHOO.widget.LogReader.prototype._btnPause = null;
915  * Clear button element.
917  * @property _btnClear
918  * @type HTMLElement
919  * @private
920  */
921 YAHOO.widget.LogReader.prototype._btnClear = null;
923 /////////////////////////////////////////////////////////////////////////////
925 // Private methods
927 /////////////////////////////////////////////////////////////////////////////
930  * Initializes the primary container element.
932  * @method _initContainerEl
933  * @param elContainer {HTMLElement} Container element by reference or string ID.
934  * @private
935  */
936 YAHOO.widget.LogReader.prototype._initContainerEl = function(elContainer) {
937     // Validate container
938     elContainer = YAHOO.util.Dom.get(elContainer);
939     // Attach to existing container...
940     if(elContainer && elContainer.tagName && (elContainer.tagName.toLowerCase() == "div")) {
941         this._elContainer = elContainer;
942         YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
943     }
944     // ...or create container from scratch
945     else {
946         this._elContainer = document.body.appendChild(document.createElement("div"));
947         //this._elContainer.id = "yui-log" + this._sName;
948         YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
949         YAHOO.util.Dom.addClass(this._elContainer,"yui-log-container");
951         //YAHOO.widget.LogReader._elDefaultContainer = this._elContainer;
953         // If implementer has provided container values, trust and set those
954         var containerStyle = this._elContainer.style;
955         if(this.width) {
956             containerStyle.width = this.width;
957         }
958         if(this.right) {
959             containerStyle.right = this.right;
960         }
961         if(this.top) {
962             containerStyle.top = this.top;
963         }
964          if(this.left) {
965             containerStyle.left = this.left;
966             containerStyle.right = "auto";
967         }
968         if(this.bottom) {
969             containerStyle.bottom = this.bottom;
970             containerStyle.top = "auto";
971         }
972        if(this.fontSize) {
973             containerStyle.fontSize = this.fontSize;
974         }
975         // For Opera
976         if(navigator.userAgent.toLowerCase().indexOf("opera") != -1) {
977             document.body.style += '';
978         }
979     }
983  * Initializes the header element.
985  * @method _initHeaderEl
986  * @private
987  */
988 YAHOO.widget.LogReader.prototype._initHeaderEl = function() {
989     var oSelf = this;
991     // Destroy header
992     if(this._elHd) {
993         // Unhook DOM events
994         YAHOO.util.Event.purgeElement(this._elHd, true);
996         // Remove DOM elements
997         this._elHd.innerHTML = "";
998     }
999     
1000     // Create header
1001     this._elHd = this._elContainer.appendChild(document.createElement("div"));
1002     this._elHd.id = "yui-log-hd" + this._sName;
1003     this._elHd.className = "yui-log-hd";
1005     this._elCollapse = this._elHd.appendChild(document.createElement("div"));
1006     this._elCollapse.className = "yui-log-btns";
1008     this._btnCollapse = document.createElement("input");
1009     this._btnCollapse.type = "button";
1010     //this._btnCollapse.style.fontSize =
1011     //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
1012     this._btnCollapse.className = "yui-log-button";
1013     this._btnCollapse.value = "Collapse";
1014     this._btnCollapse = this._elCollapse.appendChild(this._btnCollapse);
1015     YAHOO.util.Event.addListener(
1016         oSelf._btnCollapse,'click',oSelf._onClickCollapseBtn,oSelf);
1018     this._title = this._elHd.appendChild(document.createElement("h4"));
1019     this._title.innerHTML = "Logger Console";
1023  * Initializes the console element.
1025  * @method _initConsoleEl
1026  * @private
1027  */
1028 YAHOO.widget.LogReader.prototype._initConsoleEl = function() {
1029     // Destroy console
1030     if(this._elConsole) {
1031         // Unhook DOM events
1032         YAHOO.util.Event.purgeElement(this._elConsole, true);
1034         // Remove DOM elements
1035         this._elConsole.innerHTML = "";
1036     }
1038     // Ceate console
1039     this._elConsole = this._elContainer.appendChild(document.createElement("div"));
1040     this._elConsole.className = "yui-log-bd";
1042     // If implementer has provided console, trust and set those
1043     if(this.height) {
1044         this._elConsole.style.height = this.height;
1045     }
1049  * Initializes the footer element.
1051  * @method _initFooterEl
1052  * @private
1053  */
1054 YAHOO.widget.LogReader.prototype._initFooterEl = function() {
1055     var oSelf = this;
1057     // Don't create footer elements if footer is disabled
1058     if(this.footerEnabled) {
1059         // Destroy console
1060         if(this._elFt) {
1061             // Unhook DOM events
1062             YAHOO.util.Event.purgeElement(this._elFt, true);
1064             // Remove DOM elements
1065             this._elFt.innerHTML = "";
1066         }
1068         this._elFt = this._elContainer.appendChild(document.createElement("div"));
1069         this._elFt.className = "yui-log-ft";
1071         this._elBtns = this._elFt.appendChild(document.createElement("div"));
1072         this._elBtns.className = "yui-log-btns";
1074         this._btnPause = document.createElement("input");
1075         this._btnPause.type = "button";
1076         //this._btnPause.style.fontSize =
1077         //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
1078         this._btnPause.className = "yui-log-button";
1079         this._btnPause.value = "Pause";
1080         this._btnPause = this._elBtns.appendChild(this._btnPause);
1081         YAHOO.util.Event.addListener(
1082             oSelf._btnPause,'click',oSelf._onClickPauseBtn,oSelf);
1084         this._btnClear = document.createElement("input");
1085         this._btnClear.type = "button";
1086         //this._btnClear.style.fontSize =
1087         //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
1088         this._btnClear.className = "yui-log-button";
1089         this._btnClear.value = "Clear";
1090         this._btnClear = this._elBtns.appendChild(this._btnClear);
1091         YAHOO.util.Event.addListener(
1092             oSelf._btnClear,'click',oSelf._onClickClearBtn,oSelf);
1094         this._elCategoryFilters = this._elFt.appendChild(document.createElement("div"));
1095         this._elCategoryFilters.className = "yui-log-categoryfilters";
1096         this._elSourceFilters = this._elFt.appendChild(document.createElement("div"));
1097         this._elSourceFilters.className = "yui-log-sourcefilters";
1098     }
1102  * Initializes Drag and Drop on the header element.
1104  * @method _initDragDrop
1105  * @private
1106  */
1107 YAHOO.widget.LogReader.prototype._initDragDrop = function() {
1108     // If Drag and Drop utility is available...
1109     // ...and draggable is true...
1110     // ...then make the header draggable
1111     if(YAHOO.util.DD && this.draggable && this._elHd) {
1112         var ylog_dd = new YAHOO.util.DD(this._elContainer);
1113         ylog_dd.setHandleElId(this._elHd.id);
1114         //TODO: use class name
1115         this._elHd.style.cursor = "move";
1116     }
1120  * Initializes category filters.
1122  * @method _initCategories
1123  * @private
1124  */
1125 YAHOO.widget.LogReader.prototype._initCategories = function() {
1126     // Initialize category filters
1127     this._categoryFilters = [];
1128     var aInitialCategories = YAHOO.widget.Logger.categories;
1130     for(var j=0; j < aInitialCategories.length; j++) {
1131         var sCategory = aInitialCategories[j];
1133         // Add category to the internal array of filters
1134         this._categoryFilters.push(sCategory);
1136         // Add checkbox element if UI is enabled
1137         if(this._elCategoryFilters) {
1138             this._createCategoryCheckbox(sCategory);
1139         }
1140     }
1144  * Initializes source filters.
1146  * @method _initSources
1147  * @private
1148  */
1149 YAHOO.widget.LogReader.prototype._initSources = function() {
1150     // Initialize source filters
1151     this._sourceFilters = [];
1152     var aInitialSources = YAHOO.widget.Logger.sources;
1154     for(var j=0; j < aInitialSources.length; j++) {
1155         var sSource = aInitialSources[j];
1157         // Add source to the internal array of filters
1158         this._sourceFilters.push(sSource);
1160         // Add checkbox element if UI is enabled
1161         if(this._elSourceFilters) {
1162             this._createSourceCheckbox(sSource);
1163         }
1164     }}
1168  * Creates the UI for a category filter in the LogReader footer element.
1170  * @method _createCategoryCheckbox
1171  * @param sCategory {String} Category name.
1172  * @private
1173  */
1174 YAHOO.widget.LogReader.prototype._createCategoryCheckbox = function(sCategory) {
1175     var oSelf = this;
1177     if(this._elFt) {
1178         var elParent = this._elCategoryFilters;
1179         var elFilter = elParent.appendChild(document.createElement("span"));
1180         elFilter.className = "yui-log-filtergrp";
1181         
1182         // Append el at the end so IE 5.5 can set "type" attribute
1183         // and THEN set checked property
1184         var chkCategory = document.createElement("input");
1185         chkCategory.id = "yui-log-filter-" + sCategory + this._sName;
1186         chkCategory.className = "yui-log-filter-" + sCategory;
1187         chkCategory.type = "checkbox";
1188         chkCategory.category = sCategory;
1189         chkCategory = elFilter.appendChild(chkCategory);
1190         chkCategory.checked = true;
1192         // Subscribe to the click event
1193         YAHOO.util.Event.addListener(chkCategory,'click',oSelf._onCheckCategory,oSelf);
1195         // Create and class the text label
1196         var lblCategory = elFilter.appendChild(document.createElement("label"));
1197         lblCategory.htmlFor = chkCategory.id;
1198         lblCategory.className = sCategory;
1199         lblCategory.innerHTML = sCategory;
1200         
1201         this._filterCheckboxes[sCategory] = chkCategory;
1202     }
1206  * Creates a checkbox in the LogReader footer element to filter by source.
1208  * @method _createSourceCheckbox
1209  * @param sSource {String} Source name.
1210  * @private
1211  */
1212 YAHOO.widget.LogReader.prototype._createSourceCheckbox = function(sSource) {
1213     var oSelf = this;
1215     if(this._elFt) {
1216         var elParent = this._elSourceFilters;
1217         var elFilter = elParent.appendChild(document.createElement("span"));
1218         elFilter.className = "yui-log-filtergrp";
1220         // Append el at the end so IE 5.5 can set "type" attribute
1221         // and THEN set checked property
1222         var chkSource = document.createElement("input");
1223         chkSource.id = "yui-log-filter" + sSource + this._sName;
1224         chkSource.className = "yui-log-filter" + sSource;
1225         chkSource.type = "checkbox";
1226         chkSource.source = sSource;
1227         chkSource = elFilter.appendChild(chkSource);
1228         chkSource.checked = true;
1230         // Subscribe to the click event
1231         YAHOO.util.Event.addListener(chkSource,'click',oSelf._onCheckSource,oSelf);
1233         // Create and class the text label
1234         var lblSource = elFilter.appendChild(document.createElement("label"));
1235         lblSource.htmlFor = chkSource.id;
1236         lblSource.className = sSource;
1237         lblSource.innerHTML = sSource;
1238         
1239         this._filterCheckboxes[sSource] = chkSource;
1240     }
1244  * Reprints all log messages in the stack through filters.
1246  * @method _filterLogs
1247  * @private
1248  */
1249 YAHOO.widget.LogReader.prototype._filterLogs = function() {
1250     // Reprint stack with new filters
1251     if (this._elConsole !== null) {
1252         this.clearConsole();
1253         this._printToConsole(YAHOO.widget.Logger.getStack());
1254     }
1258  * Sends buffer of log messages to output and clears buffer.
1260  * @method _printBuffer
1261  * @private
1262  */
1263 YAHOO.widget.LogReader.prototype._printBuffer = function() {
1264     this._timeout = null;
1266     if(this._elConsole !== null) {
1267         var thresholdMax = this.thresholdMax;
1268         thresholdMax = (thresholdMax && !isNaN(thresholdMax)) ? thresholdMax : 500;
1269         if(this._consoleMsgCount < thresholdMax) {
1270             var entries = [];
1271             for (var i=0; i<this._buffer.length; i++) {
1272                 entries[i] = this._buffer[i];
1273             }
1274             this._buffer = [];
1275             this._printToConsole(entries);
1276         }
1277         else {
1278             this._filterLogs();
1279         }
1280         
1281         if(!this.newestOnTop) {
1282             this._elConsole.scrollTop = this._elConsole.scrollHeight;
1283         }
1284     }
1288  * Cycles through an array of log messages, and outputs each one to the console
1289  * if its category has not been filtered out.
1291  * @method _printToConsole
1292  * @param aEntries {Object[]} Array of LogMsg objects to output to console.
1293  * @private
1294  */
1295 YAHOO.widget.LogReader.prototype._printToConsole = function(aEntries) {
1296     // Manage the number of messages displayed in the console
1297     var entriesLen = aEntries.length;
1298     var thresholdMin = this.thresholdMin;
1299     if(isNaN(thresholdMin) || (thresholdMin > this.thresholdMax)) {
1300         thresholdMin = 0;
1301     }
1302     var entriesStartIndex = (entriesLen > thresholdMin) ? (entriesLen - thresholdMin) : 0;
1303     
1304     // Iterate through all log entries 
1305     var sourceFiltersLen = this._sourceFilters.length;
1306     var categoryFiltersLen = this._categoryFilters.length;
1307     for(var i=entriesStartIndex; i<entriesLen; i++) {
1308         // Print only the ones that filter through
1309         var okToPrint = false;
1310         var okToFilterCats = false;
1312         // Get log message details
1313         var entry = aEntries[i];
1314         var source = entry.source;
1315         var category = entry.category;
1317         for(var j=0; j<sourceFiltersLen; j++) {
1318             if(source == this._sourceFilters[j]) {
1319                 okToFilterCats = true;
1320                 break;
1321             }
1322         }
1323         if(okToFilterCats) {
1324             for(var k=0; k<categoryFiltersLen; k++) {
1325                 if(category == this._categoryFilters[k]) {
1326                     okToPrint = true;
1327                     break;
1328                 }
1329             }
1330         }
1331         if(okToPrint) {
1332             var output = this.formatMsg(entry);
1333             if(this.newestOnTop) {
1334                 this._elConsole.innerHTML = output + this._elConsole.innerHTML;
1335             }
1336             else {
1337                 this._elConsole.innerHTML += output;
1338             }
1339             this._consoleMsgCount++;
1340             this._lastTime = entry.time.getTime();
1341         }
1342     }
1345 /////////////////////////////////////////////////////////////////////////////
1347 // Private event handlers
1349 /////////////////////////////////////////////////////////////////////////////
1352  * Handles Logger's categoryCreateEvent.
1354  * @method _onCategoryCreate
1355  * @param sType {String} The event.
1356  * @param aArgs {Object[]} Data passed from event firer.
1357  * @param oSelf {Object} The LogReader instance.
1358  * @private
1359  */
1360 YAHOO.widget.LogReader.prototype._onCategoryCreate = function(sType, aArgs, oSelf) {
1361     var category = aArgs[0];
1362     
1363     // Add category to the internal array of filters
1364     oSelf._categoryFilters.push(category);
1366     if(oSelf._elFt) {
1367         oSelf._createCategoryCheckbox(category);
1368     }
1372  * Handles Logger's sourceCreateEvent.
1374  * @method _onSourceCreate
1375  * @param sType {String} The event.
1376  * @param aArgs {Object[]} Data passed from event firer.
1377  * @param oSelf {Object} The LogReader instance.
1378  * @private
1379  */
1380 YAHOO.widget.LogReader.prototype._onSourceCreate = function(sType, aArgs, oSelf) {
1381     var source = aArgs[0];
1382     
1383     // Add source to the internal array of filters
1384     oSelf._sourceFilters.push(source);
1386     if(oSelf._elFt) {
1387         oSelf._createSourceCheckbox(source);
1388     }
1392  * Handles check events on the category filter checkboxes.
1394  * @method _onCheckCategory
1395  * @param v {HTMLEvent} The click event.
1396  * @param oSelf {Object} The LogReader instance.
1397  * @private
1398  */
1399 YAHOO.widget.LogReader.prototype._onCheckCategory = function(v, oSelf) {
1400     var category = this.category;
1401     if(!this.checked) {
1402         oSelf.hideCategory(category);
1403     }
1404     else {
1405         oSelf.showCategory(category);
1406     }
1410  * Handles check events on the category filter checkboxes.
1412  * @method _onCheckSource
1413  * @param v {HTMLEvent} The click event.
1414  * @param oSelf {Object} The LogReader instance.
1415  * @private
1416  */
1417 YAHOO.widget.LogReader.prototype._onCheckSource = function(v, oSelf) {
1418     var source = this.source;
1419     if(!this.checked) {
1420         oSelf.hideSource(source);
1421     }
1422     else {
1423         oSelf.showSource(source);
1424     }
1428  * Handles click events on the collapse button.
1430  * @method _onClickCollapseBtn
1431  * @param v {HTMLEvent} The click event.
1432  * @param oSelf {Object} The LogReader instance
1433  * @private
1434  */
1435 YAHOO.widget.LogReader.prototype._onClickCollapseBtn = function(v, oSelf) {
1436     if(!oSelf.isCollapsed) {
1437         oSelf.collapse();
1438     }
1439     else {
1440         oSelf.expand();
1441     }
1445  * Handles click events on the pause button.
1447  * @method _onClickPauseBtn
1448  * @param v {HTMLEvent} The click event.
1449  * @param oSelf {Object} The LogReader instance.
1450  * @private
1451  */
1452 YAHOO.widget.LogReader.prototype._onClickPauseBtn = function(v, oSelf) {
1453     if(!oSelf.isPaused) {
1454         oSelf.pause();
1455     }
1456     else {
1457         oSelf.resume();
1458     }
1462  * Handles click events on the clear button.
1464  * @method _onClickClearBtn
1465  * @param v {HTMLEvent} The click event.
1466  * @param oSelf {Object} The LogReader instance.
1467  * @private
1468  */
1469 YAHOO.widget.LogReader.prototype._onClickClearBtn = function(v, oSelf) {
1470     oSelf.clearConsole();
1474  * Handles Logger's newLogEvent.
1476  * @method _onNewLog
1477  * @param sType {String} The event.
1478  * @param aArgs {Object[]} Data passed from event firer.
1479  * @param oSelf {Object} The LogReader instance.
1480  * @private
1481  */
1482 YAHOO.widget.LogReader.prototype._onNewLog = function(sType, aArgs, oSelf) {
1483     var logEntry = aArgs[0];
1484     oSelf._buffer.push(logEntry);
1486     if (oSelf.logReaderEnabled === true && oSelf._timeout === null) {
1487         oSelf._timeout = setTimeout(function(){oSelf._printBuffer();}, oSelf.outputBuffer);
1488     }
1492  * Handles Logger's resetEvent.
1494  * @method _onReset
1495  * @param sType {String} The event.
1496  * @param aArgs {Object[]} Data passed from event firer.
1497  * @param oSelf {Object} The LogReader instance.
1498  * @private
1499  */
1500 YAHOO.widget.LogReader.prototype._onReset = function(sType, aArgs, oSelf) {
1501     oSelf._filterLogs();
1504  /**
1505  * The Logger widget provides a simple way to read or write log messages in
1506  * JavaScript code. Integration with the YUI Library's debug builds allow
1507  * implementers to access under-the-hood events, errors, and debugging messages.
1508  * Output may be read through a LogReader console and/or output to a browser
1509  * console.
1511  * @module logger
1512  * @requires yahoo, event, dom
1513  * @optional dragdrop
1514  * @namespace YAHOO.widget
1515  * @title Logger Widget
1516  */
1518 /****************************************************************************/
1519 /****************************************************************************/
1520 /****************************************************************************/
1522 // Define once
1523 if(!YAHOO.widget.Logger) {
1524     /**
1525      * The singleton Logger class provides core log management functionality. Saves
1526      * logs written through the global YAHOO.log function or written by a LogWriter
1527      * instance. Provides access to logs for reading by a LogReader instance or
1528      * native browser console such as the Firebug extension to Firefox or Safari's
1529      * JavaScript console through integration with the console.log() method.
1530      *
1531      * @class Logger
1532      * @static
1533      */
1534     YAHOO.widget.Logger = {
1535         // Initialize properties
1536         loggerEnabled: true,
1537         _browserConsoleEnabled: false,
1538         categories: ["info","warn","error","time","window"],
1539         sources: ["global"],
1540         _stack: [], // holds all log msgs
1541         maxStackEntries: 2500,
1542         _startTime: new Date().getTime(), // static start timestamp
1543         _lastTime: null // timestamp of last logged message
1544     };
1546     /////////////////////////////////////////////////////////////////////////////
1547     //
1548     // Public properties
1549     //
1550     /////////////////////////////////////////////////////////////////////////////
1551     /**
1552      * True if Logger is enabled, false otherwise.
1553      *
1554      * @property loggerEnabled
1555      * @type Boolean
1556      * @static
1557      * @default true
1558      */
1560     /**
1561      * Array of categories.
1562      *
1563      * @property categories
1564      * @type String[]
1565      * @static
1566      * @default ["info","warn","error","time","window"]
1567      */
1569     /**
1570      * Array of sources.
1571      *
1572      * @property sources
1573      * @type String[]
1574      * @static
1575      * @default ["global"]
1576      */
1578     /**
1579      * Upper limit on size of internal stack.
1580      *
1581      * @property maxStackEntries
1582      * @type Number
1583      * @static
1584      * @default 2500
1585      */
1587     /////////////////////////////////////////////////////////////////////////////
1588     //
1589     // Private properties
1590     //
1591     /////////////////////////////////////////////////////////////////////////////
1592     /**
1593      * Internal property to track whether output to browser console is enabled.
1594      *
1595      * @property _browserConsoleEnabled
1596      * @type Boolean
1597      * @static
1598      * @default false
1599      * @private
1600      */
1602     /**
1603      * Array to hold all log messages.
1604      *
1605      * @property _stack
1606      * @type Array
1607      * @static
1608      * @private
1609      */
1610     /**
1611      * Static timestamp of Logger initialization.
1612      *
1613      * @property _startTime
1614      * @type Date
1615      * @static
1616      * @private
1617      */
1618     /**
1619      * Timestamp of last logged message.
1620      *
1621      * @property _lastTime
1622      * @type Date
1623      * @static
1624      * @private
1625      */
1626     /////////////////////////////////////////////////////////////////////////////
1627     //
1628     // Public methods
1629     //
1630     /////////////////////////////////////////////////////////////////////////////
1631     /**
1632      * Saves a log message to the stack and fires newLogEvent. If the log message is
1633      * assigned to an unknown category, creates a new category. If the log message is
1634      * from an unknown source, creates a new source.  If browser console is enabled,
1635      * outputs the log message to browser console.
1636      *
1637      * @method log
1638      * @param sMsg {String} The log message.
1639      * @param sCategory {String} Category of log message, or null.
1640      * @param sSource {String} Source of LogWriter, or null if global.
1641      */
1642     YAHOO.widget.Logger.log = function(sMsg, sCategory, sSource) {
1643         if(this.loggerEnabled) {
1644             if(!sCategory) {
1645                 sCategory = "info"; // default category
1646             }
1647             else {
1648                 sCategory = sCategory.toLocaleLowerCase();
1649                 if(this._isNewCategory(sCategory)) {
1650                     this._createNewCategory(sCategory);
1651                 }
1652             }
1653             var sClass = "global"; // default source
1654             var sDetail = null;
1655             if(sSource) {
1656                 var spaceIndex = sSource.indexOf(" ");
1657                 if(spaceIndex > 0) {
1658                     // Substring until first space
1659                     sClass = sSource.substring(0,spaceIndex);
1660                     // The rest of the source
1661                     sDetail = sSource.substring(spaceIndex,sSource.length);
1662                 }
1663                 else {
1664                     sClass = sSource;
1665                 }
1666                 if(this._isNewSource(sClass)) {
1667                     this._createNewSource(sClass);
1668                 }
1669             }
1671             var timestamp = new Date();
1672             var logEntry = new YAHOO.widget.LogMsg({
1673                 msg: sMsg,
1674                 time: timestamp,
1675                 category: sCategory,
1676                 source: sClass,
1677                 sourceDetail: sDetail
1678             });
1680             var stack = this._stack;
1681             var maxStackEntries = this.maxStackEntries;
1682             if(maxStackEntries && !isNaN(maxStackEntries) &&
1683                 (stack.length >= maxStackEntries)) {
1684                 stack.shift();
1685             }
1686             stack.push(logEntry);
1687             this.newLogEvent.fire(logEntry);
1689             if(this._browserConsoleEnabled) {
1690                 this._printToBrowserConsole(logEntry);
1691             }
1692             return true;
1693         }
1694         else {
1695             return false;
1696         }
1697     };
1699     /**
1700      * Resets internal stack and startTime, enables Logger, and fires logResetEvent.
1701      *
1702      * @method reset
1703      */
1704     YAHOO.widget.Logger.reset = function() {
1705         this._stack = [];
1706         this._startTime = new Date().getTime();
1707         this.loggerEnabled = true;
1708         this.log("Logger reset");
1709         this.logResetEvent.fire();
1710     };
1712     /**
1713      * Public accessor to internal stack of log message objects.
1714      *
1715      * @method getStack
1716      * @return {Object[]} Array of log message objects.
1717      */
1718     YAHOO.widget.Logger.getStack = function() {
1719         return this._stack;
1720     };
1722     /**
1723      * Public accessor to internal start time.
1724      *
1725      * @method getStartTime
1726      * @return {Date} Internal date of when Logger singleton was initialized.
1727      */
1728     YAHOO.widget.Logger.getStartTime = function() {
1729         return this._startTime;
1730     };
1732     /**
1733      * Disables output to the browser's global console.log() function, which is used
1734      * by the Firebug extension to Firefox as well as Safari.
1735      *
1736      * @method disableBrowserConsole
1737      */
1738     YAHOO.widget.Logger.disableBrowserConsole = function() {
1739         YAHOO.log("Logger output to the function console.log() has been disabled.");
1740         this._browserConsoleEnabled = false;
1741     };
1743     /**
1744      * Enables output to the browser's global console.log() function, which is used
1745      * by the Firebug extension to Firefox as well as Safari.
1746      *
1747      * @method enableBrowserConsole
1748      */
1749     YAHOO.widget.Logger.enableBrowserConsole = function() {
1750         this._browserConsoleEnabled = true;
1751         YAHOO.log("Logger output to the function console.log() has been enabled.");
1752     };
1754     /////////////////////////////////////////////////////////////////////////////
1755     //
1756     // Public events
1757     //
1758     /////////////////////////////////////////////////////////////////////////////
1760      /**
1761      * Fired when a new category has been created.
1762      *
1763      * @event categoryCreateEvent
1764      * @param sCategory {String} Category name.
1765      */
1766     YAHOO.widget.Logger.categoryCreateEvent =
1767         new YAHOO.util.CustomEvent("categoryCreate", this, true);
1769      /**
1770      * Fired when a new source has been named.
1771      *
1772      * @event sourceCreateEvent
1773      * @param sSource {String} Source name.
1774      */
1775     YAHOO.widget.Logger.sourceCreateEvent =
1776         new YAHOO.util.CustomEvent("sourceCreate", this, true);
1778      /**
1779      * Fired when a new log message has been created.
1780      *
1781      * @event newLogEvent
1782      * @param sMsg {String} Log message.
1783      */
1784     YAHOO.widget.Logger.newLogEvent = new YAHOO.util.CustomEvent("newLog", this, true);
1786     /**
1787      * Fired when the Logger has been reset has been created.
1788      *
1789      * @event logResetEvent
1790      */
1791     YAHOO.widget.Logger.logResetEvent = new YAHOO.util.CustomEvent("logReset", this, true);
1793     /////////////////////////////////////////////////////////////////////////////
1794     //
1795     // Private methods
1796     //
1797     /////////////////////////////////////////////////////////////////////////////
1799     /**
1800      * Creates a new category of log messages and fires categoryCreateEvent.
1801      *
1802      * @method _createNewCategory
1803      * @param sCategory {String} Category name.
1804      * @private
1805      */
1806     YAHOO.widget.Logger._createNewCategory = function(sCategory) {
1807         this.categories.push(sCategory);
1808         this.categoryCreateEvent.fire(sCategory);
1809     };
1811     /**
1812      * Checks to see if a category has already been created.
1813      *
1814      * @method _isNewCategory
1815      * @param sCategory {String} Category name.
1816      * @return {Boolean} Returns true if category is unknown, else returns false.
1817      * @private
1818      */
1819     YAHOO.widget.Logger._isNewCategory = function(sCategory) {
1820         for(var i=0; i < this.categories.length; i++) {
1821             if(sCategory == this.categories[i]) {
1822                 return false;
1823             }
1824         }
1825         return true;
1826     };
1828     /**
1829      * Creates a new source of log messages and fires sourceCreateEvent.
1830      *
1831      * @method _createNewSource
1832      * @param sSource {String} Source name.
1833      * @private
1834      */
1835     YAHOO.widget.Logger._createNewSource = function(sSource) {
1836         this.sources.push(sSource);
1837         this.sourceCreateEvent.fire(sSource);
1838     };
1840     /**
1841      * Checks to see if a source already exists.
1842      *
1843      * @method _isNewSource
1844      * @param sSource {String} Source name.
1845      * @return {Boolean} Returns true if source is unknown, else returns false.
1846      * @private
1847      */
1848     YAHOO.widget.Logger._isNewSource = function(sSource) {
1849         if(sSource) {
1850             for(var i=0; i < this.sources.length; i++) {
1851                 if(sSource == this.sources[i]) {
1852                     return false;
1853                 }
1854             }
1855             return true;
1856         }
1857     };
1859     /**
1860      * Outputs a log message to global console.log() function.
1861      *
1862      * @method _printToBrowserConsole
1863      * @param oEntry {Object} Log entry object.
1864      * @private
1865      */
1866     YAHOO.widget.Logger._printToBrowserConsole = function(oEntry) {
1867         if(window.console && console.log) {
1868             var category = oEntry.category;
1869             var label = oEntry.category.substring(0,4).toUpperCase();
1871             var time = oEntry.time;
1872             if (time.toLocaleTimeString) {
1873                 var localTime  = time.toLocaleTimeString();
1874             }
1875             else {
1876                 localTime = time.toString();
1877             }
1879             var msecs = time.getTime();
1880             var elapsedTime = (YAHOO.widget.Logger._lastTime) ?
1881                 (msecs - YAHOO.widget.Logger._lastTime) : 0;
1882             YAHOO.widget.Logger._lastTime = msecs;
1884             var output =
1885                 localTime + " (" +
1886                 elapsedTime + "ms): " +
1887                 oEntry.source + ": " +
1888                 oEntry.msg;
1890             console.log(output);
1891         }
1892     };
1894     /////////////////////////////////////////////////////////////////////////////
1895     //
1896     // Private event handlers
1897     //
1898     /////////////////////////////////////////////////////////////////////////////
1900     /**
1901      * Handles logging of messages due to window error events.
1902      *
1903      * @method _onWindowError
1904      * @param sMsg {String} The error message.
1905      * @param sUrl {String} URL of the error.
1906      * @param sLine {String} Line number of the error.
1907      * @private
1908      */
1909     YAHOO.widget.Logger._onWindowError = function(sMsg,sUrl,sLine) {
1910         // Logger is not in scope of this event handler
1911         try {
1912             YAHOO.widget.Logger.log(sMsg+' ('+sUrl+', line '+sLine+')', "window");
1913             if(YAHOO.widget.Logger._origOnWindowError) {
1914                 YAHOO.widget.Logger._origOnWindowError();
1915             }
1916         }
1917         catch(e) {
1918             return false;
1919         }
1920     };
1922     /////////////////////////////////////////////////////////////////////////////
1923     //
1924     // Enable handling of native JavaScript errors
1925     // NB: Not all browsers support the window.onerror event
1926     //
1927     /////////////////////////////////////////////////////////////////////////////
1929     if(window.onerror) {
1930         // Save any previously defined handler to call
1931         YAHOO.widget.Logger._origOnWindowError = window.onerror;
1932     }
1933     window.onerror = YAHOO.widget.Logger._onWindowError;
1935     /////////////////////////////////////////////////////////////////////////////
1936     //
1937     // First log
1938     //
1939     /////////////////////////////////////////////////////////////////////////////
1941     YAHOO.widget.Logger.log("Logger initialized");
1945 YAHOO.register("logger", YAHOO.widget.Logger, {version: "2.3.0", build: "442"});