2 Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
7 /****************************************************************************/
8 /****************************************************************************/
9 /****************************************************************************/
12 * The LogMsg class defines a single log message.
16 * @param oConfigs {Object} Object literal of configuration params.
18 YAHOO.widget.LogMsg = function(oConfigs) {
20 if (oConfigs && (oConfigs.constructor == Object)) {
21 for(var param in oConfigs) {
22 this[param] = oConfigs[param];
27 /////////////////////////////////////////////////////////////////////////////
29 // Public member variables
31 /////////////////////////////////////////////////////////////////////////////
39 YAHOO.widget.LogMsg.prototype.msg = null;
47 YAHOO.widget.LogMsg.prototype.time = null;
55 YAHOO.widget.LogMsg.prototype.category = null;
58 * Log source. The first word passed in as the source argument.
63 YAHOO.widget.LogMsg.prototype.source = null;
66 * Log source detail. The remainder of the string passed in as the source argument, not
67 * including the first word (if any).
69 * @property sourceDetail
72 YAHOO.widget.LogMsg.prototype.sourceDetail = null;
75 /****************************************************************************/
76 /****************************************************************************/
77 /****************************************************************************/
80 * The LogWriter class provides a mechanism to log messages through
81 * YAHOO.widget.Logger from a named source.
85 * @param sSource {String} Source of LogWriter instance.
87 YAHOO.widget.LogWriter = function(sSource) {
89 YAHOO.log("Could not instantiate LogWriter due to invalid source.",
90 "error", "LogWriter");
93 this._source = sSource;
96 /////////////////////////////////////////////////////////////////////////////
100 /////////////////////////////////////////////////////////////////////////////
103 * Public accessor to the unique name of the LogWriter instance.
106 * @return {String} Unique name of the LogWriter instance.
108 YAHOO.widget.LogWriter.prototype.toString = function() {
109 return "LogWriter " + this._sSource;
113 * Logs a message attached to the source of the LogWriter.
116 * @param sMsg {String} The log message.
117 * @param sCategory {String} Category name.
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.
127 * @return {String} The LogWriter source.
129 YAHOO.widget.LogWriter.prototype.getSource = function() {
130 return this._sSource;
134 * Public accessor to set the source name.
137 * @param sSource {String} Source of LogWriter instance.
139 YAHOO.widget.LogWriter.prototype.setSource = function(sSource) {
141 YAHOO.log("Could not set source due to invalid source.", "error", this.toString());
145 this._sSource = sSource;
149 /////////////////////////////////////////////////////////////////////////////
151 // Private member variables
153 /////////////////////////////////////////////////////////////////////////////
156 * Source of the LogWriter instance.
162 YAHOO.widget.LogWriter.prototype._source = null;
167 /****************************************************************************/
168 /****************************************************************************/
169 /****************************************************************************/
172 * The LogReader class provides UI to read messages logged to YAHOO.widget.Logger.
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.
180 YAHOO.widget.LogReader = function(elContainer, oConfigs) {
181 this._sName = YAHOO.widget.LogReader._index;
182 YAHOO.widget.LogReader._index++;
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];
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());
203 this._initHeaderEl();
204 this._initConsoleEl();
205 this._initFooterEl();
207 this._initDragDrop();
209 this._initCategories();
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);
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
236 YAHOO.widget.LogReader.prototype.logReaderEnabled = true;
239 * Public member to access CSS width of the LogReader container.
244 YAHOO.widget.LogReader.prototype.width = null;
247 * Public member to access CSS height of the LogReader container.
252 YAHOO.widget.LogReader.prototype.height = null;
255 * Public member to access CSS top position of the LogReader container.
260 YAHOO.widget.LogReader.prototype.top = null;
263 * Public member to access CSS left position of the LogReader container.
268 YAHOO.widget.LogReader.prototype.left = null;
271 * Public member to access CSS right position of the LogReader container.
276 YAHOO.widget.LogReader.prototype.right = null;
279 * Public member to access CSS bottom position of the LogReader container.
284 YAHOO.widget.LogReader.prototype.bottom = null;
287 * Public member to access CSS font size of the LogReader container.
292 YAHOO.widget.LogReader.prototype.fontSize = null;
295 * Whether or not the footer UI is enabled for the LogReader.
297 * @property footerEnabled
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
311 YAHOO.widget.LogReader.prototype.verboseOutput = true;
314 * Whether or not newest message is printed on top.
316 * @property newestOnTop
319 YAHOO.widget.LogReader.prototype.newestOnTop = true;
322 * Output timeout buffer in milliseconds.
324 * @property outputBuffer
328 YAHOO.widget.LogReader.prototype.outputBuffer = 100;
331 * Maximum number of messages a LogReader console will display.
333 * @property thresholdMax
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
347 YAHOO.widget.LogReader.prototype.thresholdMin = 100;
350 * True when LogReader is in a collapsed state, false otherwise.
352 * @property isCollapsed
356 YAHOO.widget.LogReader.prototype.isCollapsed = false;
359 * True when LogReader is in a paused state, false otherwise.
365 YAHOO.widget.LogReader.prototype.isPaused = false;
368 * Enables draggable LogReader if DragDrop Utility is present.
370 * @property draggable
374 YAHOO.widget.LogReader.prototype.draggable = true;
376 /////////////////////////////////////////////////////////////////////////////
380 /////////////////////////////////////////////////////////////////////////////
383 * Public accessor to the unique name of the LogReader instance.
386 * @return {String} Unique name of the LogReader instance.
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.
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.
410 YAHOO.widget.LogReader.prototype.resume = function() {
411 this.isPaused = false;
412 this._btnPause.value = "Pause";
413 this.logReaderEnabled = true;
418 * Hides UI of LogReader. Logging functionality is not disrupted.
422 YAHOO.widget.LogReader.prototype.hide = function() {
423 this._elContainer.style.display = "none";
427 * Shows UI of LogReader. Logging functionality is not disrupted.
431 YAHOO.widget.LogReader.prototype.show = function() {
432 this._elContainer.style.display = "block";
436 * Collapses UI of LogReader. Logging functionality is not disrupted.
440 YAHOO.widget.LogReader.prototype.collapse = function() {
441 this._elConsole.style.display = "none";
443 this._elFt.style.display = "none";
445 this._btnCollapse.value = "Expand";
446 this.isCollapsed = true;
450 * Expands UI of LogReader. Logging functionality is not disrupted.
454 YAHOO.widget.LogReader.prototype.expand = function() {
455 this._elConsole.style.display = "block";
457 this._elFt.style.display = "block";
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.
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.
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.
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) {
499 // ...or do it the old-fashioned way
501 for(var i=0; i<filtersArray.length; i++) {
502 if(filtersArray[i] === sCategory){
508 this._categoryFilters.push(sCategory);
510 var elCheckbox = this.getCheckbox(sCategory);
512 elCheckbox.checked = true;
517 * Hides log messages associated with given category.
519 * @method hideCategory
520 * @param {String} Category name.
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);
531 var elCheckbox = this.getCheckbox(sCategory);
533 elCheckbox.checked = false;
538 * Returns array of enabled sources.
541 * @return {Array} Array of enabled sources.
543 YAHOO.widget.LogReader.prototype.getSources = function() {
544 return this._sourceFilters;
548 * Shows log messages associated with given source.
551 * @param {String} Source name.
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) {
562 // ...or do it the old-fashioned way
564 for(var i=0; i<filtersArray.length; i++) {
565 if(sSource == filtersArray[i]){
570 filtersArray.push(sSource);
572 var elCheckbox = this.getCheckbox(sSource);
574 elCheckbox.checked = true;
579 * Hides log messages associated with given source.
582 * @param {String} Source name.
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);
593 var elCheckbox = this.getCheckbox(sSource);
595 elCheckbox.checked = false;
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
607 YAHOO.widget.LogReader.prototype.clearConsole = function() {
608 // Clear the buffer of any pending messages
609 this._timeout = null;
611 this._consoleMsgCount = 0;
613 var elConsole = this._elConsole;
614 while(elConsole.hasChildNodes()) {
615 elConsole.removeChild(elConsole.firstChild);
620 * Updates title to given string.
623 * @param sTitle {String} New title.
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.
635 YAHOO.widget.LogReader.prototype.getLastTime = function() {
636 return this._lastTime;
640 * Formats message string to HTML for output to console.
643 * @param oLogMsg {Object} Log message object.
644 * @return {String} HTML-formatted message for output to console.
646 YAHOO.widget.LogReader.prototype.formatMsg = function(oLogMsg) {
647 var category = oLogMsg.category;
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();
660 localTime = time.toString();
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;
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, ") ",
689 ["<pre><p><span class='", category, "'>", label, "</span> ",
690 totalTime, "ms (+", elapsedTime, ") ",
692 sourceAndDetail, ": ",
695 return output.join("");
699 * Converts input chars "<", ">", and "&" to HTML entities.
702 * @param sHtml {String} String to convert.
705 YAHOO.widget.LogReader.prototype.html2Text = function(sHtml) {
708 return sHtml.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
713 /////////////////////////////////////////////////////////////////////////////
715 // Private member variables
717 /////////////////////////////////////////////////////////////////////////////
720 * Internal class member to index multiple LogReader instances.
722 * @property _memberName
728 YAHOO.widget.LogReader._index = 0;
731 * Name of LogReader instance.
737 YAHOO.widget.LogReader.prototype._sName = null;
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
749 //YAHOO.widget.LogReader._elDefaultContainer = null;
752 * Buffer of log message objects for batch output.
758 YAHOO.widget.LogReader.prototype._buffer = null;
761 * Number of log messages output to console.
763 * @property _consoleMsgCount
768 YAHOO.widget.LogReader.prototype._consoleMsgCount = 0;
771 * Date of last output log message.
773 * @property _lastTime
777 YAHOO.widget.LogReader.prototype._lastTime = null;
780 * Batched output timeout ID.
786 YAHOO.widget.LogReader.prototype._timeout = null;
789 * Hash of filters and their related checkbox elements.
791 * @property _filterCheckboxes
795 YAHOO.widget.LogReader.prototype._filterCheckboxes = null;
798 * Array of filters for log message categories.
800 * @property _categoryFilters
804 YAHOO.widget.LogReader.prototype._categoryFilters = null;
807 * Array of filters for log message sources.
809 * @property _sourceFilters
813 YAHOO.widget.LogReader.prototype._sourceFilters = null;
816 * LogReader container element.
818 * @property _elContainer
822 YAHOO.widget.LogReader.prototype._elContainer = null;
825 * LogReader header element.
831 YAHOO.widget.LogReader.prototype._elHd = null;
834 * LogReader collapse element.
836 * @property _elCollapse
840 YAHOO.widget.LogReader.prototype._elCollapse = null;
843 * LogReader collapse button element.
845 * @property _btnCollapse
849 YAHOO.widget.LogReader.prototype._btnCollapse = null;
852 * LogReader title header element.
858 YAHOO.widget.LogReader.prototype._title = null;
861 * LogReader console element.
863 * @property _elConsole
867 YAHOO.widget.LogReader.prototype._elConsole = null;
870 * LogReader footer element.
876 YAHOO.widget.LogReader.prototype._elFt = null;
879 * LogReader buttons container element.
885 YAHOO.widget.LogReader.prototype._elBtns = null;
888 * Container element for LogReader category filter checkboxes.
890 * @property _elCategoryFilters
894 YAHOO.widget.LogReader.prototype._elCategoryFilters = null;
897 * Container element for LogReader source filter checkboxes.
899 * @property _elSourceFilters
903 YAHOO.widget.LogReader.prototype._elSourceFilters = null;
906 * LogReader pause button element.
908 * @property _btnPause
912 YAHOO.widget.LogReader.prototype._btnPause = null;
915 * Clear button element.
917 * @property _btnClear
921 YAHOO.widget.LogReader.prototype._btnClear = null;
923 /////////////////////////////////////////////////////////////////////////////
927 /////////////////////////////////////////////////////////////////////////////
930 * Initializes the primary container element.
932 * @method _initContainerEl
933 * @param elContainer {HTMLElement} Container element by reference or string ID.
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");
944 // ...or create container from scratch
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;
956 containerStyle.width = this.width;
959 containerStyle.right = this.right;
962 containerStyle.top = this.top;
965 containerStyle.left = this.left;
966 containerStyle.right = "auto";
969 containerStyle.bottom = this.bottom;
970 containerStyle.top = "auto";
973 containerStyle.fontSize = this.fontSize;
976 if(navigator.userAgent.toLowerCase().indexOf("opera") != -1) {
977 document.body.style += '';
983 * Initializes the header element.
985 * @method _initHeaderEl
988 YAHOO.widget.LogReader.prototype._initHeaderEl = function() {
994 YAHOO.util.Event.purgeElement(this._elHd, true);
996 // Remove DOM elements
997 this._elHd.innerHTML = "";
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
1028 YAHOO.widget.LogReader.prototype._initConsoleEl = function() {
1030 if(this._elConsole) {
1031 // Unhook DOM events
1032 YAHOO.util.Event.purgeElement(this._elConsole, true);
1034 // Remove DOM elements
1035 this._elConsole.innerHTML = "";
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
1044 this._elConsole.style.height = this.height;
1049 * Initializes the footer element.
1051 * @method _initFooterEl
1054 YAHOO.widget.LogReader.prototype._initFooterEl = function() {
1057 // Don't create footer elements if footer is disabled
1058 if(this.footerEnabled) {
1061 // Unhook DOM events
1062 YAHOO.util.Event.purgeElement(this._elFt, true);
1064 // Remove DOM elements
1065 this._elFt.innerHTML = "";
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";
1102 * Initializes Drag and Drop on the header element.
1104 * @method _initDragDrop
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";
1120 * Initializes category filters.
1122 * @method _initCategories
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);
1144 * Initializes source filters.
1146 * @method _initSources
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);
1168 * Creates the UI for a category filter in the LogReader footer element.
1170 * @method _createCategoryCheckbox
1171 * @param sCategory {String} Category name.
1174 YAHOO.widget.LogReader.prototype._createCategoryCheckbox = function(sCategory) {
1178 var elParent = this._elCategoryFilters;
1179 var elFilter = elParent.appendChild(document.createElement("span"));
1180 elFilter.className = "yui-log-filtergrp";
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;
1201 this._filterCheckboxes[sCategory] = chkCategory;
1206 * Creates a checkbox in the LogReader footer element to filter by source.
1208 * @method _createSourceCheckbox
1209 * @param sSource {String} Source name.
1212 YAHOO.widget.LogReader.prototype._createSourceCheckbox = function(sSource) {
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;
1239 this._filterCheckboxes[sSource] = chkSource;
1244 * Reprints all log messages in the stack through filters.
1246 * @method _filterLogs
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());
1258 * Sends buffer of log messages to output and clears buffer.
1260 * @method _printBuffer
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) {
1271 for (var i=0; i<this._buffer.length; i++) {
1272 entries[i] = this._buffer[i];
1275 this._printToConsole(entries);
1281 if(!this.newestOnTop) {
1282 this._elConsole.scrollTop = this._elConsole.scrollHeight;
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.
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)) {
1302 var entriesStartIndex = (entriesLen > thresholdMin) ? (entriesLen - thresholdMin) : 0;
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;
1323 if(okToFilterCats) {
1324 for(var k=0; k<categoryFiltersLen; k++) {
1325 if(category == this._categoryFilters[k]) {
1332 var output = this.formatMsg(entry);
1333 if(this.newestOnTop) {
1334 this._elConsole.innerHTML = output + this._elConsole.innerHTML;
1337 this._elConsole.innerHTML += output;
1339 this._consoleMsgCount++;
1340 this._lastTime = entry.time.getTime();
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.
1360 YAHOO.widget.LogReader.prototype._onCategoryCreate = function(sType, aArgs, oSelf) {
1361 var category = aArgs[0];
1363 // Add category to the internal array of filters
1364 oSelf._categoryFilters.push(category);
1367 oSelf._createCategoryCheckbox(category);
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.
1380 YAHOO.widget.LogReader.prototype._onSourceCreate = function(sType, aArgs, oSelf) {
1381 var source = aArgs[0];
1383 // Add source to the internal array of filters
1384 oSelf._sourceFilters.push(source);
1387 oSelf._createSourceCheckbox(source);
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.
1399 YAHOO.widget.LogReader.prototype._onCheckCategory = function(v, oSelf) {
1400 var category = this.category;
1402 oSelf.hideCategory(category);
1405 oSelf.showCategory(category);
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.
1417 YAHOO.widget.LogReader.prototype._onCheckSource = function(v, oSelf) {
1418 var source = this.source;
1420 oSelf.hideSource(source);
1423 oSelf.showSource(source);
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
1435 YAHOO.widget.LogReader.prototype._onClickCollapseBtn = function(v, oSelf) {
1436 if(!oSelf.isCollapsed) {
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.
1452 YAHOO.widget.LogReader.prototype._onClickPauseBtn = function(v, oSelf) {
1453 if(!oSelf.isPaused) {
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.
1469 YAHOO.widget.LogReader.prototype._onClickClearBtn = function(v, oSelf) {
1470 oSelf.clearConsole();
1474 * Handles Logger's newLogEvent.
1477 * @param sType {String} The event.
1478 * @param aArgs {Object[]} Data passed from event firer.
1479 * @param oSelf {Object} The LogReader instance.
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);
1492 * Handles Logger's resetEvent.
1495 * @param sType {String} The event.
1496 * @param aArgs {Object[]} Data passed from event firer.
1497 * @param oSelf {Object} The LogReader instance.
1500 YAHOO.widget.LogReader.prototype._onReset = function(sType, aArgs, oSelf) {
1501 oSelf._filterLogs();
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
1512 * @requires yahoo, event, dom
1513 * @optional dragdrop
1514 * @namespace YAHOO.widget
1515 * @title Logger Widget
1518 /****************************************************************************/
1519 /****************************************************************************/
1520 /****************************************************************************/
1523 if(!YAHOO.widget.Logger) {
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.
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
1546 /////////////////////////////////////////////////////////////////////////////
1548 // Public properties
1550 /////////////////////////////////////////////////////////////////////////////
1552 * True if Logger is enabled, false otherwise.
1554 * @property loggerEnabled
1561 * Array of categories.
1563 * @property categories
1566 * @default ["info","warn","error","time","window"]
1575 * @default ["global"]
1579 * Upper limit on size of internal stack.
1581 * @property maxStackEntries
1587 /////////////////////////////////////////////////////////////////////////////
1589 // Private properties
1591 /////////////////////////////////////////////////////////////////////////////
1593 * Internal property to track whether output to browser console is enabled.
1595 * @property _browserConsoleEnabled
1603 * Array to hold all log messages.
1611 * Static timestamp of Logger initialization.
1613 * @property _startTime
1619 * Timestamp of last logged message.
1621 * @property _lastTime
1626 /////////////////////////////////////////////////////////////////////////////
1630 /////////////////////////////////////////////////////////////////////////////
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.
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.
1642 YAHOO.widget.Logger.log = function(sMsg, sCategory, sSource) {
1643 if(this.loggerEnabled) {
1645 sCategory = "info"; // default category
1648 sCategory = sCategory.toLocaleLowerCase();
1649 if(this._isNewCategory(sCategory)) {
1650 this._createNewCategory(sCategory);
1653 var sClass = "global"; // default source
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);
1666 if(this._isNewSource(sClass)) {
1667 this._createNewSource(sClass);
1671 var timestamp = new Date();
1672 var logEntry = new YAHOO.widget.LogMsg({
1675 category: sCategory,
1677 sourceDetail: sDetail
1680 var stack = this._stack;
1681 var maxStackEntries = this.maxStackEntries;
1682 if(maxStackEntries && !isNaN(maxStackEntries) &&
1683 (stack.length >= maxStackEntries)) {
1686 stack.push(logEntry);
1687 this.newLogEvent.fire(logEntry);
1689 if(this._browserConsoleEnabled) {
1690 this._printToBrowserConsole(logEntry);
1700 * Resets internal stack and startTime, enables Logger, and fires logResetEvent.
1704 YAHOO.widget.Logger.reset = function() {
1706 this._startTime = new Date().getTime();
1707 this.loggerEnabled = true;
1708 this.log("Logger reset");
1709 this.logResetEvent.fire();
1713 * Public accessor to internal stack of log message objects.
1716 * @return {Object[]} Array of log message objects.
1718 YAHOO.widget.Logger.getStack = function() {
1723 * Public accessor to internal start time.
1725 * @method getStartTime
1726 * @return {Date} Internal date of when Logger singleton was initialized.
1728 YAHOO.widget.Logger.getStartTime = function() {
1729 return this._startTime;
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.
1736 * @method disableBrowserConsole
1738 YAHOO.widget.Logger.disableBrowserConsole = function() {
1739 YAHOO.log("Logger output to the function console.log() has been disabled.");
1740 this._browserConsoleEnabled = false;
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.
1747 * @method enableBrowserConsole
1749 YAHOO.widget.Logger.enableBrowserConsole = function() {
1750 this._browserConsoleEnabled = true;
1751 YAHOO.log("Logger output to the function console.log() has been enabled.");
1754 /////////////////////////////////////////////////////////////////////////////
1758 /////////////////////////////////////////////////////////////////////////////
1761 * Fired when a new category has been created.
1763 * @event categoryCreateEvent
1764 * @param sCategory {String} Category name.
1766 YAHOO.widget.Logger.categoryCreateEvent =
1767 new YAHOO.util.CustomEvent("categoryCreate", this, true);
1770 * Fired when a new source has been named.
1772 * @event sourceCreateEvent
1773 * @param sSource {String} Source name.
1775 YAHOO.widget.Logger.sourceCreateEvent =
1776 new YAHOO.util.CustomEvent("sourceCreate", this, true);
1779 * Fired when a new log message has been created.
1781 * @event newLogEvent
1782 * @param sMsg {String} Log message.
1784 YAHOO.widget.Logger.newLogEvent = new YAHOO.util.CustomEvent("newLog", this, true);
1787 * Fired when the Logger has been reset has been created.
1789 * @event logResetEvent
1791 YAHOO.widget.Logger.logResetEvent = new YAHOO.util.CustomEvent("logReset", this, true);
1793 /////////////////////////////////////////////////////////////////////////////
1797 /////////////////////////////////////////////////////////////////////////////
1800 * Creates a new category of log messages and fires categoryCreateEvent.
1802 * @method _createNewCategory
1803 * @param sCategory {String} Category name.
1806 YAHOO.widget.Logger._createNewCategory = function(sCategory) {
1807 this.categories.push(sCategory);
1808 this.categoryCreateEvent.fire(sCategory);
1812 * Checks to see if a category has already been created.
1814 * @method _isNewCategory
1815 * @param sCategory {String} Category name.
1816 * @return {Boolean} Returns true if category is unknown, else returns false.
1819 YAHOO.widget.Logger._isNewCategory = function(sCategory) {
1820 for(var i=0; i < this.categories.length; i++) {
1821 if(sCategory == this.categories[i]) {
1829 * Creates a new source of log messages and fires sourceCreateEvent.
1831 * @method _createNewSource
1832 * @param sSource {String} Source name.
1835 YAHOO.widget.Logger._createNewSource = function(sSource) {
1836 this.sources.push(sSource);
1837 this.sourceCreateEvent.fire(sSource);
1841 * Checks to see if a source already exists.
1843 * @method _isNewSource
1844 * @param sSource {String} Source name.
1845 * @return {Boolean} Returns true if source is unknown, else returns false.
1848 YAHOO.widget.Logger._isNewSource = function(sSource) {
1850 for(var i=0; i < this.sources.length; i++) {
1851 if(sSource == this.sources[i]) {
1860 * Outputs a log message to global console.log() function.
1862 * @method _printToBrowserConsole
1863 * @param oEntry {Object} Log entry object.
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();
1876 localTime = time.toString();
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;
1886 elapsedTime + "ms): " +
1887 oEntry.source + ": " +
1890 console.log(output);
1894 /////////////////////////////////////////////////////////////////////////////
1896 // Private event handlers
1898 /////////////////////////////////////////////////////////////////////////////
1901 * Handles logging of messages due to window error events.
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.
1909 YAHOO.widget.Logger._onWindowError = function(sMsg,sUrl,sLine) {
1910 // Logger is not in scope of this event handler
1912 YAHOO.widget.Logger.log(sMsg+' ('+sUrl+', line '+sLine+')', "window");
1913 if(YAHOO.widget.Logger._origOnWindowError) {
1914 YAHOO.widget.Logger._origOnWindowError();
1922 /////////////////////////////////////////////////////////////////////////////
1924 // Enable handling of native JavaScript errors
1925 // NB: Not all browsers support the window.onerror event
1927 /////////////////////////////////////////////////////////////////////////////
1929 if(window.onerror) {
1930 // Save any previously defined handler to call
1931 YAHOO.widget.Logger._origOnWindowError = window.onerror;
1933 window.onerror = YAHOO.widget.Logger._onWindowError;
1935 /////////////////////////////////////////////////////////////////////////////
1939 /////////////////////////////////////////////////////////////////////////////
1941 YAHOO.widget.Logger.log("Logger initialized");
1945 YAHOO.register("logger", YAHOO.widget.Logger, {version: "2.3.0", build: "442"});