summaryrefslogtreecommitdiff
path: root/frontend/beta/js/YUI/logger.js
Unidiff
Diffstat (limited to 'frontend/beta/js/YUI/logger.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/YUI/logger.js1559
1 files changed, 1559 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI/logger.js b/frontend/beta/js/YUI/logger.js
new file mode 100644
index 0000000..a2b40b2
--- a/dev/null
+++ b/frontend/beta/js/YUI/logger.js
@@ -0,0 +1,1559 @@
1/*
2Copyright (c) 2006, Yahoo! Inc. All rights reserved.
3Code licensed under the BSD License:
4http://developer.yahoo.com/yui/license.txt
5version: 0.12.0
6*/
7
8/****************************************************************************/
9/****************************************************************************/
10/****************************************************************************/
11
12/**
13 * The LogMsg class defines a single log message.
14 *
15 * @class LogMsg
16 * @constructor
17 * @param oConfigs {Object} Object literal of configuration params.
18 */
19 YAHOO.widget.LogMsg = function(oConfigs) {
20 // Parse configs
21 if (typeof oConfigs == "object") {
22 for(var param in oConfigs) {
23 this[param] = oConfigs[param];
24 }
25 }
26 };
27
28/////////////////////////////////////////////////////////////////////////////
29//
30// Public member variables
31//
32/////////////////////////////////////////////////////////////////////////////
33
34/**
35 * Log message.
36 *
37 * @property msg
38 * @type String
39 */
40YAHOO.widget.LogMsg.prototype.msg = null;
41
42/**
43 * Log timestamp.
44 *
45 * @property time
46 * @type Date
47 */
48YAHOO.widget.LogMsg.prototype.time = null;
49
50/**
51 * Log category.
52 *
53 * @property category
54 * @type String
55 */
56YAHOO.widget.LogMsg.prototype.category = null;
57
58/**
59 * Log source. The first word passed in as the source argument.
60 *
61 * @property source
62 * @type String
63 */
64YAHOO.widget.LogMsg.prototype.source = null;
65
66/**
67 * Log source detail. The remainder of the string passed in as the source argument, not
68 * including the first word (if any).
69 *
70 * @property sourceDetail
71 * @type String
72 */
73YAHOO.widget.LogMsg.prototype.sourceDetail = null;
74
75/****************************************************************************/
76/****************************************************************************/
77/****************************************************************************/
78
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 */
87YAHOO.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 };
95
96/////////////////////////////////////////////////////////////////////////////
97//
98// Public methods
99//
100/////////////////////////////////////////////////////////////////////////////
101
102 /**
103 * Public accessor to the unique name of the LogWriter instance.
104 *
105 * @method toString
106 * @return {String} Unique name of the LogWriter instance.
107 */
108YAHOO.widget.LogWriter.prototype.toString = function() {
109 return "LogWriter " + this._sSource;
110};
111
112/**
113 * Logs a message attached to the source of the LogWriter.
114 *
115 * @method log
116 * @param sMsg {String} The log message.
117 * @param sCategory {String} Category name.
118 */
119YAHOO.widget.LogWriter.prototype.log = function(sMsg, sCategory) {
120 YAHOO.widget.Logger.log(sMsg, sCategory, this._source);
121};
122
123/**
124 * Public accessor to get the source name.
125 *
126 * @method getSource
127 * @return {String} The LogWriter source.
128 */
129YAHOO.widget.LogWriter.prototype.getSource = function() {
130 return this._sSource;
131};
132
133/**
134 * Public accessor to set the source name.
135 *
136 * @method setSource
137 * @param sSource {String} Source of LogWriter instance.
138 */
139YAHOO.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 }
147};
148
149/////////////////////////////////////////////////////////////////////////////
150//
151// Private member variables
152//
153/////////////////////////////////////////////////////////////////////////////
154
155/**
156 * Source of the LogWriter instance.
157 *
158 * @property _source
159 * @type String
160 * @private
161 */
162YAHOO.widget.LogWriter.prototype._source = null;
163
164
165
166/****************************************************************************/
167/****************************************************************************/
168/****************************************************************************/
169
170/**
171 * The LogReader class provides UI to read messages logged to YAHOO.widget.Logger.
172 *
173 * @class LogReader
174 * @constructor
175 * @param elContainer {HTMLElement} (optional) DOM element reference of an existing DIV.
176 * @param elContainer {String} (optional) String ID of an existing DIV.
177 * @param oConfigs {Object} (optional) Object literal of configuration params.
178 */
179YAHOO.widget.LogReader = function(elContainer, oConfigs) {
180 var oSelf = this;
181 this._sName = YAHOO.widget.LogReader._index;
182 YAHOO.widget.LogReader._index++;
183
184 // Parse config vars here
185 if (typeof oConfigs == "object") {
186 for(var param in oConfigs) {
187 this[param] = oConfigs[param];
188 }
189 }
190
191 // Attach container...
192 if(elContainer) {
193 if(typeof elContainer == "string") {
194 this._elContainer = document.getElementById(elContainer);
195 }
196 else if(elContainer.tagName) {
197 this._elContainer = elContainer;
198 }
199 this._elContainer.className = "yui-log";
200 }
201 // ...or create container from scratch
202 if(!this._elContainer) {
203 if(YAHOO.widget.LogReader._elDefaultContainer) {
204 this._elContainer = YAHOO.widget.LogReader._elDefaultContainer;
205 }
206 else {
207 this._elContainer = document.body.appendChild(document.createElement("div"));
208 this._elContainer.id = "yui-log";
209 this._elContainer.className = "yui-log";
210
211 YAHOO.widget.LogReader._elDefaultContainer = this._elContainer;
212 }
213
214 // If implementer has provided container values, trust and set those
215 var containerStyle = this._elContainer.style;
216 if(this.width) {
217 containerStyle.width = this.width;
218 }
219 if(this.left) {
220 containerStyle.left = this.left;
221 }
222 if(this.right) {
223 containerStyle.right = this.right;
224 }
225 if(this.bottom) {
226 containerStyle.bottom = this.bottom;
227 }
228 if(this.top) {
229 containerStyle.top = this.top;
230 }
231 if(this.fontSize) {
232 containerStyle.fontSize = this.fontSize;
233 }
234 }
235
236 if(this._elContainer) {
237 // Create header
238 if(!this._elHd) {
239 this._elHd = this._elContainer.appendChild(document.createElement("div"));
240 this._elHd.id = "yui-log-hd" + this._sName;
241 this._elHd.className = "yui-log-hd";
242
243 this._elCollapse = this._elHd.appendChild(document.createElement("div"));
244 this._elCollapse.className = "yui-log-btns";
245
246 this._btnCollapse = document.createElement("input");
247 this._btnCollapse.type = "button";
248 this._btnCollapse.style.fontSize =
249 YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
250 this._btnCollapse.className = "yui-log-button";
251 this._btnCollapse.value = "Collapse";
252 this._btnCollapse = this._elCollapse.appendChild(this._btnCollapse);
253 YAHOO.util.Event.addListener(
254 oSelf._btnCollapse,'click',oSelf._onClickCollapseBtn,oSelf);
255
256 this._title = this._elHd.appendChild(document.createElement("h4"));
257 this._title.innerHTML = "Logger Console";
258
259 // If Drag and Drop utility is available...
260 // ...and this container was created from scratch...
261 // ...then make the header draggable
262 if(YAHOO.util.DD &&
263 (YAHOO.widget.LogReader._elDefaultContainer == this._elContainer)) {
264 var ylog_dd = new YAHOO.util.DD(this._elContainer.id);
265 ylog_dd.setHandleElId(this._elHd.id);
266 this._elHd.style.cursor = "move";
267 }
268 }
269 // Ceate console
270 if(!this._elConsole) {
271 this._elConsole =
272 this._elContainer.appendChild(document.createElement("div"));
273 this._elConsole.className = "yui-log-bd";
274
275 // If implementer has provided console, trust and set those
276 if(this.height) {
277 this._elConsole.style.height = this.height;
278 }
279 }
280 // Don't create footer if disabled
281 if(!this._elFt && this.footerEnabled) {
282 this._elFt = this._elContainer.appendChild(document.createElement("div"));
283 this._elFt.className = "yui-log-ft";
284
285 this._elBtns = this._elFt.appendChild(document.createElement("div"));
286 this._elBtns.className = "yui-log-btns";
287
288 this._btnPause = document.createElement("input");
289 this._btnPause.type = "button";
290 this._btnPause.style.fontSize =
291 YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
292 this._btnPause.className = "yui-log-button";
293 this._btnPause.value = "Pause";
294 this._btnPause = this._elBtns.appendChild(this._btnPause);
295 YAHOO.util.Event.addListener(
296 oSelf._btnPause,'click',oSelf._onClickPauseBtn,oSelf);
297
298 this._btnClear = document.createElement("input");
299 this._btnClear.type = "button";
300 this._btnClear.style.fontSize =
301 YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
302 this._btnClear.className = "yui-log-button";
303 this._btnClear.value = "Clear";
304 this._btnClear = this._elBtns.appendChild(this._btnClear);
305 YAHOO.util.Event.addListener(
306 oSelf._btnClear,'click',oSelf._onClickClearBtn,oSelf);
307
308 this._elCategoryFilters = this._elFt.appendChild(document.createElement("div"));
309 this._elCategoryFilters.className = "yui-log-categoryfilters";
310 this._elSourceFilters = this._elFt.appendChild(document.createElement("div"));
311 this._elSourceFilters.className = "yui-log-sourcefilters";
312 }
313 }
314
315 // Initialize internal vars
316 if(!this._buffer) {
317 this._buffer = []; // output buffer
318 }
319 // Timestamp of last log message to console
320 this._lastTime = YAHOO.widget.Logger.getStartTime();
321
322 // Subscribe to Logger custom events
323 YAHOO.widget.Logger.newLogEvent.subscribe(this._onNewLog, this);
324 YAHOO.widget.Logger.logResetEvent.subscribe(this._onReset, this);
325
326 // Initialize category filters
327 this._categoryFilters = [];
328 var catsLen = YAHOO.widget.Logger.categories.length;
329 if(this._elCategoryFilters) {
330 for(var i=0; i < catsLen; i++) {
331 this._createCategoryCheckbox(YAHOO.widget.Logger.categories[i]);
332 }
333 }
334 // Initialize source filters
335 this._sourceFilters = [];
336 var sourcesLen = YAHOO.widget.Logger.sources.length;
337 if(this._elSourceFilters) {
338 for(var j=0; j < sourcesLen; j++) {
339 this._createSourceCheckbox(YAHOO.widget.Logger.sources[j]);
340 }
341 }
342 YAHOO.widget.Logger.categoryCreateEvent.subscribe(this._onCategoryCreate, this);
343 YAHOO.widget.Logger.sourceCreateEvent.subscribe(this._onSourceCreate, this);
344
345 this._filterLogs();
346 YAHOO.log("LogReader initialized", null, this.toString());
347};
348
349/////////////////////////////////////////////////////////////////////////////
350//
351// Public member variables
352//
353/////////////////////////////////////////////////////////////////////////////
354
355/**
356 * Whether or not the log reader is enabled to output log messages.
357 *
358 * @property logReaderEnabled
359 * @type Boolean
360 * @default true
361 */
362YAHOO.widget.LogReader.prototype.logReaderEnabled = true;
363
364/**
365 * Public member to access CSS width of the log reader container.
366 *
367 * @property width
368 * @type String
369 */
370YAHOO.widget.LogReader.prototype.width = null;
371
372/**
373 * Public member to access CSS height of the log reader container.
374 *
375 * @property height
376 * @type String
377 */
378YAHOO.widget.LogReader.prototype.height = null;
379
380/**
381 * Public member to access CSS top position of the log reader container.
382 *
383 * @property top
384 * @type String
385 */
386YAHOO.widget.LogReader.prototype.top = null;
387
388/**
389 * Public member to access CSS left position of the log reader container.
390 *
391 * @property left
392 * @type String
393 */
394YAHOO.widget.LogReader.prototype.left = null;
395
396/**
397 * Public member to access CSS right position of the log reader container.
398 *
399 * @property right
400 * @type String
401 */
402YAHOO.widget.LogReader.prototype.right = null;
403
404/**
405 * Public member to access CSS bottom position of the log reader container.
406 *
407 * @property bottom
408 * @type String
409 */
410YAHOO.widget.LogReader.prototype.bottom = null;
411
412/**
413 * Public member to access CSS font size of the log reader container.
414 *
415 * @property fontSize
416 * @type String
417 */
418YAHOO.widget.LogReader.prototype.fontSize = null;
419
420/**
421 * Whether or not the footer UI is enabled for the log reader.
422 *
423 * @property footerEnabled
424 * @type Boolean
425 * @default true
426 */
427YAHOO.widget.LogReader.prototype.footerEnabled = true;
428
429/**
430 * Whether or not output is verbose (more readable). Setting to true will make
431 * output more compact (less readable).
432 *
433 * @property verboseOutput
434 * @type Boolean
435 * @default true
436 */
437YAHOO.widget.LogReader.prototype.verboseOutput = true;
438
439/**
440 * Whether or not newest message is printed on top.
441 *
442 * @property newestOnTop
443 * @type Boolean
444 */
445YAHOO.widget.LogReader.prototype.newestOnTop = true;
446
447/**
448 * Maximum number of messages a LogReader console will display.
449 *
450 * @property thresholdMax
451 * @type Number
452 * @default 500
453 */
454YAHOO.widget.LogReader.prototype.thresholdMax = 500;
455
456/**
457 * When a LogReader console reaches its thresholdMax, it will clear out messages
458 * and print out the latest thresholdMin number of messages.
459 *
460 * @property thresholdMin
461 * @type Number
462 * @default 100
463 */
464YAHOO.widget.LogReader.prototype.thresholdMin = 100;
465
466/////////////////////////////////////////////////////////////////////////////
467//
468// Public methods
469//
470/////////////////////////////////////////////////////////////////////////////
471
472 /**
473 * Public accessor to the unique name of the LogReader instance.
474 *
475 * @method toString
476 * @return {String} Unique name of the LogReader instance.
477 */
478YAHOO.widget.LogReader.prototype.toString = function() {
479 return "LogReader instance" + this._sName;
480};
481/**
482 * Pauses output of log messages. While paused, log messages are not lost, but
483 * get saved to a buffer and then output upon resume of log reader.
484 *
485 * @method pause
486 */
487YAHOO.widget.LogReader.prototype.pause = function() {
488 this._timeout = null;
489 this.logReaderEnabled = false;
490};
491
492/**
493 * Resumes output of log messages, including outputting any log messages that
494 * have been saved to buffer while paused.
495 *
496 * @method resume
497 */
498YAHOO.widget.LogReader.prototype.resume = function() {
499 this.logReaderEnabled = true;
500 this._printBuffer();
501};
502
503/**
504 * Hides UI of log reader. Logging functionality is not disrupted.
505 *
506 * @method hide
507 */
508YAHOO.widget.LogReader.prototype.hide = function() {
509 this._elContainer.style.display = "none";
510};
511
512/**
513 * Shows UI of log reader. Logging functionality is not disrupted.
514 *
515 * @method show
516 */
517YAHOO.widget.LogReader.prototype.show = function() {
518 this._elContainer.style.display = "block";
519};
520
521/**
522 * Updates title to given string.
523 *
524 * @method setTitle
525 * @param sTitle {String} New title.
526 */
527YAHOO.widget.LogReader.prototype.setTitle = function(sTitle) {
528 this._title.innerHTML = this.html2Text(sTitle);
529};
530
531/**
532 * Gets timestamp of the last log.
533 *
534 * @method getLastTime
535 * @return {Date} Timestamp of the last log.
536 */
537YAHOO.widget.LogReader.prototype.getLastTime = function() {
538 return this._lastTime;
539};
540
541/**
542 * Formats message string to HTML for output to console.
543 *
544 * @method formatMsg
545 * @param oLogMsg {Object} Log message object.
546 * @return {String} HTML-formatted message for output to console.
547 */
548YAHOO.widget.LogReader.prototype.formatMsg = function(oLogMsg) {
549 var category = oLogMsg.category;
550
551 // Label for color-coded display
552 var label = category.substring(0,4).toUpperCase();
553
554 // Calculate the elapsed time to be from the last item that passed through the filter,
555 // not the absolute previous item in the stack
556
557 var time = oLogMsg.time;
558 if (time.toLocaleTimeString) {
559 var localTime = time.toLocaleTimeString();
560 }
561 else {
562 localTime = time.toString();
563 }
564
565 var msecs = time.getTime();
566 var startTime = YAHOO.widget.Logger.getStartTime();
567 var totalTime = msecs - startTime;
568 var elapsedTime = msecs - this.getLastTime();
569
570 var source = oLogMsg.source;
571 var sourceDetail = oLogMsg.sourceDetail;
572 var sourceAndDetail = (sourceDetail) ?
573 source + " " + sourceDetail : source;
574
575 // Escape HTML entities in the log message itself for output to console
576 var msg = this.html2Text(oLogMsg.msg);
577
578 // Verbose output includes extra line breaks
579 var output = (this.verboseOutput) ?
580 ["<p><span class='", category, "'>", label, "</span> ",
581 totalTime, "ms (+", elapsedTime, ") ",
582 localTime, ": ",
583 "</p><p>",
584 sourceAndDetail,
585 ": </p><p>",
586 msg,
587 "</p>"] :
588
589 ["<p><span class='", category, "'>", label, "</span> ",
590 totalTime, "ms (+", elapsedTime, ") ",
591 localTime, ": ",
592 sourceAndDetail, ": ",
593 msg,"</p>"];
594
595 return output.join("");
596};
597
598/**
599 * Converts input chars "<", ">", and "&" to HTML entities.
600 *
601 * @method html2Text
602 * @param sHtml {String} String to convert.
603 * @private
604 */
605YAHOO.widget.LogReader.prototype.html2Text = function(sHtml) {
606 if(sHtml) {
607 sHtml += "";
608 return sHtml.replace(/&/g, "&#38;").replace(/</g, "&#60;").replace(/>/g, "&#62;");
609 }
610 return "";
611};
612
613/////////////////////////////////////////////////////////////////////////////
614//
615// Private member variables
616//
617/////////////////////////////////////////////////////////////////////////////
618
619/**
620 * Internal class member to index multiple log reader instances.
621 *
622 * @property _memberName
623 * @static
624 * @type Number
625 * @default 0
626 * @private
627 */
628YAHOO.widget.LogReader._index = 0;
629
630/**
631 * Name of LogReader instance.
632 *
633 * @property _sName
634 * @type String
635 * @private
636 */
637YAHOO.widget.LogReader.prototype._sName = null;
638
639/**
640 * A class member shared by all log readers if a container needs to be
641 * created during instantiation. Will be null if a container element never needs to
642 * be created on the fly, such as when the implementer passes in their own element.
643 *
644 * @property _elDefaultContainer
645 * @type HTMLElement
646 * @private
647 */
648YAHOO.widget.LogReader._elDefaultContainer = null;
649
650/**
651 * Buffer of log message objects for batch output.
652 *
653 * @property _buffer
654 * @type Object[]
655 * @private
656 */
657YAHOO.widget.LogReader.prototype._buffer = null;
658
659/**
660 * Number of log messages output to console.
661 *
662 * @property _consoleMsgCount
663 * @type Number
664 * @default 0
665 * @private
666 */
667YAHOO.widget.LogReader.prototype._consoleMsgCount = 0;
668
669/**
670 * Date of last output log message.
671 *
672 * @property _lastTime
673 * @type Date
674 * @private
675 */
676YAHOO.widget.LogReader.prototype._lastTime = null;
677
678/**
679 * Batched output timeout ID.
680 *
681 * @property _timeout
682 * @type Number
683 * @private
684 */
685YAHOO.widget.LogReader.prototype._timeout = null;
686
687/**
688 * Array of filters for log message categories.
689 *
690 * @property _categoryFilters
691 * @type String[]
692 * @private
693 */
694YAHOO.widget.LogReader.prototype._categoryFilters = null;
695
696/**
697 * Array of filters for log message sources.
698 *
699 * @property _sourceFilters
700 * @type String[]
701 * @private
702 */
703YAHOO.widget.LogReader.prototype._sourceFilters = null;
704
705/**
706 * Log reader container element.
707 *
708 * @property _elContainer
709 * @type HTMLElement
710 * @private
711 */
712YAHOO.widget.LogReader.prototype._elContainer = null;
713
714/**
715 * Log reader header element.
716 *
717 * @property _elHd
718 * @type HTMLElement
719 * @private
720 */
721YAHOO.widget.LogReader.prototype._elHd = null;
722
723/**
724 * Log reader collapse element.
725 *
726 * @property _elCollapse
727 * @type HTMLElement
728 * @private
729 */
730YAHOO.widget.LogReader.prototype._elCollapse = null;
731
732/**
733 * Log reader collapse button element.
734 *
735 * @property _btnCollapse
736 * @type HTMLElement
737 * @private
738 */
739YAHOO.widget.LogReader.prototype._btnCollapse = null;
740
741/**
742 * Log reader title header element.
743 *
744 * @property _title
745 * @type HTMLElement
746 * @private
747 */
748YAHOO.widget.LogReader.prototype._title = null;
749
750/**
751 * Log reader console element.
752 *
753 * @property _elConsole
754 * @type HTMLElement
755 * @private
756 */
757YAHOO.widget.LogReader.prototype._elConsole = null;
758
759/**
760 * Log reader footer element.
761 *
762 * @property _elFt
763 * @type HTMLElement
764 * @private
765 */
766YAHOO.widget.LogReader.prototype._elFt = null;
767
768/**
769 * Log reader buttons container element.
770 *
771 * @property _elBtns
772 * @type HTMLElement
773 * @private
774 */
775YAHOO.widget.LogReader.prototype._elBtns = null;
776
777/**
778 * Container element for log reader category filter checkboxes.
779 *
780 * @property _elCategoryFilters
781 * @type HTMLElement
782 * @private
783 */
784YAHOO.widget.LogReader.prototype._elCategoryFilters = null;
785
786/**
787 * Container element for log reader source filter checkboxes.
788 *
789 * @property _elSourceFilters
790 * @type HTMLElement
791 * @private
792 */
793YAHOO.widget.LogReader.prototype._elSourceFilters = null;
794
795/**
796 * Log reader pause button element.
797 *
798 * @property _btnPause
799 * @type HTMLElement
800 * @private
801 */
802YAHOO.widget.LogReader.prototype._btnPause = null;
803
804/**
805 * Clear button element.
806 *
807 * @property _btnClear
808 * @type HTMLElement
809 * @private
810 */
811YAHOO.widget.LogReader.prototype._btnClear = null;
812
813/////////////////////////////////////////////////////////////////////////////
814//
815// Private methods
816//
817/////////////////////////////////////////////////////////////////////////////
818
819/**
820 * Creates the UI for a category filter in the log reader footer element.
821 *
822 * @method _createCategoryCheckbox
823 * @param sCategory {String} Category name.
824 * @private
825 */
826YAHOO.widget.LogReader.prototype._createCategoryCheckbox = function(sCategory) {
827 var oSelf = this;
828
829 if(this._elFt) {
830 var elParent = this._elCategoryFilters;
831 var filters = this._categoryFilters;
832
833 var elFilter = elParent.appendChild(document.createElement("span"));
834 elFilter.className = "yui-log-filtergrp";
835 // Append el at the end so IE 5.5 can set "type" attribute
836 // and THEN set checked property
837 var chkCategory = document.createElement("input");
838 chkCategory.id = "yui-log-filter-" + sCategory + this._sName;
839 chkCategory.className = "yui-log-filter-" + sCategory;
840 chkCategory.type = "checkbox";
841 chkCategory.category = sCategory;
842 chkCategory = elFilter.appendChild(chkCategory);
843 chkCategory.checked = true;
844
845 // Add this checked filter to the internal array of filters
846 filters.push(sCategory);
847 // Subscribe to the click event
848 YAHOO.util.Event.addListener(chkCategory,'click',oSelf._onCheckCategory,oSelf);
849
850 // Create and class the text label
851 var lblCategory = elFilter.appendChild(document.createElement("label"));
852 lblCategory.htmlFor = chkCategory.id;
853 lblCategory.className = sCategory;
854 lblCategory.innerHTML = sCategory;
855 }
856};
857
858/**
859 * Creates a checkbox in the log reader footer element to filter by source.
860 *
861 * @method _createSourceCheckbox
862 * @param sSource {String} Source name.
863 * @private
864 */
865YAHOO.widget.LogReader.prototype._createSourceCheckbox = function(sSource) {
866 var oSelf = this;
867
868 if(this._elFt) {
869 var elParent = this._elSourceFilters;
870 var filters = this._sourceFilters;
871
872 var elFilter = elParent.appendChild(document.createElement("span"));
873 elFilter.className = "yui-log-filtergrp";
874
875 // Append el at the end so IE 5.5 can set "type" attribute
876 // and THEN set checked property
877 var chkSource = document.createElement("input");
878 chkSource.id = "yui-log-filter" + sSource + this._sName;
879 chkSource.className = "yui-log-filter" + sSource;
880 chkSource.type = "checkbox";
881 chkSource.source = sSource;
882 chkSource = elFilter.appendChild(chkSource);
883 chkSource.checked = true;
884
885 // Add this checked filter to the internal array of filters
886 filters.push(sSource);
887 // Subscribe to the click event
888 YAHOO.util.Event.addListener(chkSource,'click',oSelf._onCheckSource,oSelf);
889
890 // Create and class the text label
891 var lblSource = elFilter.appendChild(document.createElement("label"));
892 lblSource.htmlFor = chkSource.id;
893 lblSource.className = sSource;
894 lblSource.innerHTML = sSource;
895 }
896};
897
898/**
899 * Reprints all log messages in the stack through filters.
900 *
901 * @method _filterLogs
902 * @private
903 */
904YAHOO.widget.LogReader.prototype._filterLogs = function() {
905 // Reprint stack with new filters
906 if (this._elConsole !== null) {
907 this._clearConsole();
908 this._printToConsole(YAHOO.widget.Logger.getStack());
909 }
910};
911
912/**
913 * Clears all outputted log messages from the console and resets the time of the
914 * last output log message.
915 *
916 * @method _clearConsole
917 * @private
918 */
919YAHOO.widget.LogReader.prototype._clearConsole = function() {
920 // Clear the buffer of any pending messages
921 this._timeout = null;
922 this._buffer = [];
923 this._consoleMsgCount = 0;
924
925 // Reset the rolling timer
926 this._lastTime = YAHOO.widget.Logger.getStartTime();
927
928 var elConsole = this._elConsole;
929 while(elConsole.hasChildNodes()) {
930 elConsole.removeChild(elConsole.firstChild);
931 }
932};
933
934/**
935 * Sends buffer of log messages to output and clears buffer.
936 *
937 * @method _printBuffer
938 * @private
939 */
940YAHOO.widget.LogReader.prototype._printBuffer = function() {
941 this._timeout = null;
942
943 if(this._elConsole !== null) {
944 var thresholdMax = this.thresholdMax;
945 thresholdMax = (thresholdMax && !isNaN(thresholdMax)) ? thresholdMax : 500;
946 if(this._consoleMsgCount < thresholdMax) {
947 var entries = [];
948 for (var i=0; i<this._buffer.length; i++) {
949 entries[i] = this._buffer[i];
950 }
951 this._buffer = [];
952 this._printToConsole(entries);
953 }
954 else {
955 this._filterLogs();
956 }
957
958 if(!this.newestOnTop) {
959 this._elConsole.scrollTop = this._elConsole.scrollHeight;
960 }
961 }
962};
963
964/**
965 * Cycles through an array of log messages, and outputs each one to the console
966 * if its category has not been filtered out.
967 *
968 * @method _printToConsole
969 * @param aEntries {Object[]} Array of LogMsg objects to output to console.
970 * @private
971 */
972YAHOO.widget.LogReader.prototype._printToConsole = function(aEntries) {
973 // Manage the number of messages displayed in the console
974 var entriesLen = aEntries.length;
975 var thresholdMin = this.thresholdMin;
976 if(isNaN(thresholdMin) || (thresholdMin > this.thresholdMax)) {
977 thresholdMin = 0;
978 }
979 var entriesStartIndex = (entriesLen > thresholdMin) ? (entriesLen - thresholdMin) : 0;
980
981 // Iterate through all log entries
982 var sourceFiltersLen = this._sourceFilters.length;
983 var categoryFiltersLen = this._categoryFilters.length;
984 for(var i=entriesStartIndex; i<entriesLen; i++) {
985 // Print only the ones that filter through
986 var okToPrint = false;
987 var okToFilterCats = false;
988
989 // Get log message details
990 var entry = aEntries[i];
991 var source = entry.source;
992 var category = entry.category;
993
994 for(var j=0; j<sourceFiltersLen; j++) {
995 if(source == this._sourceFilters[j]) {
996 okToFilterCats = true;
997 break;
998 }
999 }
1000 if(okToFilterCats) {
1001 for(var k=0; k<categoryFiltersLen; k++) {
1002 if(category == this._categoryFilters[k]) {
1003 okToPrint = true;
1004 break;
1005 }
1006 }
1007 }
1008 if(okToPrint) {
1009 var output = this.formatMsg(entry);
1010
1011 // Verbose output uses <code> tag instead of <pre> tag (for wrapping)
1012 var container = (this.verboseOutput) ? "CODE" : "PRE";
1013 var oNewElement = (this.newestOnTop) ?
1014 this._elConsole.insertBefore(
1015 document.createElement(container),this._elConsole.firstChild):
1016 this._elConsole.appendChild(document.createElement(container));
1017
1018 oNewElement.innerHTML = output;
1019 this._consoleMsgCount++;
1020 this._lastTime = entry.time.getTime();
1021 }
1022 }
1023};
1024
1025/////////////////////////////////////////////////////////////////////////////
1026//
1027// Private event handlers
1028//
1029/////////////////////////////////////////////////////////////////////////////
1030
1031/**
1032 * Handles Logger's categoryCreateEvent.
1033 *
1034 * @method _onCategoryCreate
1035 * @param sType {String} The event.
1036 * @param aArgs {Object[]} Data passed from event firer.
1037 * @param oSelf {Object} The LogReader instance.
1038 * @private
1039 */
1040YAHOO.widget.LogReader.prototype._onCategoryCreate = function(sType, aArgs, oSelf) {
1041 var category = aArgs[0];
1042 if(oSelf._elFt) {
1043 oSelf._createCategoryCheckbox(category);
1044 }
1045};
1046
1047/**
1048 * Handles Logger's sourceCreateEvent.
1049 *
1050 * @method _onSourceCreate
1051 * @param sType {String} The event.
1052 * @param aArgs {Object[]} Data passed from event firer.
1053 * @param oSelf {Object} The LogReader instance.
1054 * @private
1055 */
1056YAHOO.widget.LogReader.prototype._onSourceCreate = function(sType, aArgs, oSelf) {
1057 var source = aArgs[0];
1058 if(oSelf._elFt) {
1059 oSelf._createSourceCheckbox(source);
1060 }
1061};
1062
1063/**
1064 * Handles check events on the category filter checkboxes.
1065 *
1066 * @method _onCheckCategory
1067 * @param v {HTMLEvent} The click event.
1068 * @param oSelf {Object} The LogReader instance.
1069 * @private
1070 */
1071YAHOO.widget.LogReader.prototype._onCheckCategory = function(v, oSelf) {
1072 var newFilter = this.category;
1073 var filtersArray = oSelf._categoryFilters;
1074
1075 if(!this.checked) { // Remove category from filters
1076 for(var i=0; i<filtersArray.length; i++) {
1077 if(newFilter == filtersArray[i]) {
1078 filtersArray.splice(i, 1);
1079 break;
1080 }
1081 }
1082 }
1083 else { // Add category to filters
1084 filtersArray.push(newFilter);
1085 }
1086 oSelf._filterLogs();
1087};
1088
1089/**
1090 * Handles check events on the category filter checkboxes.
1091 *
1092 * @method _onCheckSource
1093 * @param v {HTMLEvent} The click event.
1094 * @param oSelf {Object} The log reader instance.
1095 * @private
1096 */
1097YAHOO.widget.LogReader.prototype._onCheckSource = function(v, oSelf) {
1098 var newFilter = this.source;
1099 var filtersArray = oSelf._sourceFilters;
1100
1101 if(!this.checked) { // Remove category from filters
1102 for(var i=0; i<filtersArray.length; i++) {
1103 if(newFilter == filtersArray[i]) {
1104 filtersArray.splice(i, 1);
1105 break;
1106 }
1107 }
1108 }
1109 else { // Add category to filters
1110 filtersArray.push(newFilter);
1111 }
1112 oSelf._filterLogs();
1113};
1114
1115/**
1116 * Handles click events on the collapse button.
1117 *
1118 * @method _onClickCollapseBtn
1119 * @param v {HTMLEvent} The click event.
1120 * @param oSelf {Object} The LogReader instance
1121 * @private
1122 */
1123YAHOO.widget.LogReader.prototype._onClickCollapseBtn = function(v, oSelf) {
1124 var btn = oSelf._btnCollapse;
1125 if(btn.value == "Expand") {
1126 oSelf._elConsole.style.display = "block";
1127 if(oSelf._elFt) {
1128 oSelf._elFt.style.display = "block";
1129 }
1130 btn.value = "Collapse";
1131 }
1132 else {
1133 oSelf._elConsole.style.display = "none";
1134 if(oSelf._elFt) {
1135 oSelf._elFt.style.display = "none";
1136 }
1137 btn.value = "Expand";
1138 }
1139};
1140
1141/**
1142 * Handles click events on the pause button.
1143 *
1144 * @method _onClickPauseBtn
1145 * @param v {HTMLEvent} The click event.
1146 * @param oSelf {Object} The LogReader instance.
1147 * @private
1148 */
1149YAHOO.widget.LogReader.prototype._onClickPauseBtn = function(v, oSelf) {
1150 var btn = oSelf._btnPause;
1151 if(btn.value == "Resume") {
1152 oSelf.resume();
1153 btn.value = "Pause";
1154 }
1155 else {
1156 oSelf.pause();
1157 btn.value = "Resume";
1158 }
1159};
1160
1161/**
1162 * Handles click events on the clear button.
1163 *
1164 * @method _onClickClearBtn
1165 * @param v {HTMLEvent} The click event.
1166 * @param oSelf {Object} The LogReader instance.
1167 * @private
1168 */
1169YAHOO.widget.LogReader.prototype._onClickClearBtn = function(v, oSelf) {
1170 oSelf._clearConsole();
1171};
1172
1173/**
1174 * Handles Logger's newLogEvent.
1175 *
1176 * @method _onNewLog
1177 * @param sType {String} The event.
1178 * @param aArgs {Object[]} Data passed from event firer.
1179 * @param oSelf {Object} The LogReader instance.
1180 * @private
1181 */
1182YAHOO.widget.LogReader.prototype._onNewLog = function(sType, aArgs, oSelf) {
1183 var logEntry = aArgs[0];
1184 oSelf._buffer.push(logEntry);
1185
1186 if (oSelf.logReaderEnabled === true && oSelf._timeout === null) {
1187 oSelf._timeout = setTimeout(function(){oSelf._printBuffer();}, 100);
1188 }
1189};
1190
1191/**
1192 * Handles Logger's resetEvent.
1193 *
1194 * @method _onReset
1195 * @param sType {String} The event.
1196 * @param aArgs {Object[]} Data passed from event firer.
1197 * @param oSelf {Object} The LogReader instance.
1198 * @private
1199 */
1200YAHOO.widget.LogReader.prototype._onReset = function(sType, aArgs, oSelf) {
1201 oSelf._filterLogs();
1202};
1203 /**
1204 * The Logger widget provides a simple way to read or write log messages in
1205 * JavaScript code. Integration with the YUI Library's debug builds allow
1206 * implementers to access under-the-hood events, errors, and debugging messages.
1207 * Output may be read through a LogReader console and/or output to a browser
1208 * console.
1209 *
1210 * @module logger
1211 * @requires yahoo, event, dom
1212 * @optional dragdrop
1213 * @namespace YAHOO.widget
1214 * @title Logger Widget
1215 */
1216
1217/****************************************************************************/
1218/****************************************************************************/
1219/****************************************************************************/
1220
1221/**
1222 * The singleton Logger class provides core log management functionality. Saves
1223 * logs written through the global YAHOO.log function or written by a LogWriter
1224 * instance. Provides access to logs for reading by a LogReader instance or
1225 * native browser console such as the Firebug extension to Firefox or Safari's
1226 * JavaScript console through integration with the console.log() method.
1227 *
1228 * @class Logger
1229 * @static
1230 */
1231YAHOO.widget.Logger = {
1232 // Initialize members
1233 loggerEnabled: true,
1234 _browserConsoleEnabled: false,
1235 categories: ["info","warn","error","time","window"],
1236 sources: ["global"],
1237 _stack: [], // holds all log msgs
1238 maxStackEntries: 2500,
1239 _startTime: new Date().getTime(), // static start timestamp
1240 _lastTime: null // timestamp of last logged message
1241};
1242
1243/////////////////////////////////////////////////////////////////////////////
1244//
1245// Public methods
1246//
1247/////////////////////////////////////////////////////////////////////////////
1248/**
1249 * Saves a log message to the stack and fires newLogEvent. If the log message is
1250 * assigned to an unknown category, creates a new category. If the log message is
1251 * from an unknown source, creates a new source. If browser console is enabled,
1252 * outputs the log message to browser console.
1253 *
1254 * @method log
1255 * @param sMsg {String} The log message.
1256 * @param sCategory {String} Category of log message, or null.
1257 * @param sSource {String} Source of LogWriter, or null if global.
1258 */
1259YAHOO.widget.Logger.log = function(sMsg, sCategory, sSource) {
1260 if(this.loggerEnabled) {
1261 if(!sCategory) {
1262 sCategory = "info"; // default category
1263 }
1264 else {
1265 sCategory = sCategory.toLocaleLowerCase();
1266 if(this._isNewCategory(sCategory)) {
1267 this._createNewCategory(sCategory);
1268 }
1269 }
1270 var sClass = "global"; // default source
1271 var sDetail = null;
1272 if(sSource) {
1273 var spaceIndex = sSource.indexOf(" ");
1274 if(spaceIndex > 0) {
1275 // Substring until first space
1276 sClass = sSource.substring(0,spaceIndex);
1277 // The rest of the source
1278 sDetail = sSource.substring(spaceIndex,sSource.length);
1279 }
1280 else {
1281 sClass = sSource;
1282 }
1283 if(this._isNewSource(sClass)) {
1284 this._createNewSource(sClass);
1285 }
1286 }
1287
1288 var timestamp = new Date();
1289 var logEntry = new YAHOO.widget.LogMsg({
1290 msg: sMsg,
1291 time: timestamp,
1292 category: sCategory,
1293 source: sClass,
1294 sourceDetail: sDetail
1295 });
1296
1297 var stack = this._stack;
1298 var maxStackEntries = this.maxStackEntries;
1299 if(maxStackEntries && !isNaN(maxStackEntries) &&
1300 (stack.length >= maxStackEntries)) {
1301 stack.shift();
1302 }
1303 stack.push(logEntry);
1304 this.newLogEvent.fire(logEntry);
1305
1306 if(this._browserConsoleEnabled) {
1307 this._printToBrowserConsole(logEntry);
1308 }
1309 return true;
1310 }
1311 else {
1312 return false;
1313 }
1314};
1315
1316/**
1317 * Resets internal stack and startTime, enables Logger, and fires logResetEvent.
1318 *
1319 * @method reset
1320 */
1321YAHOO.widget.Logger.reset = function() {
1322 this._stack = [];
1323 this._startTime = new Date().getTime();
1324 this.loggerEnabled = true;
1325 this.log("Logger reset");
1326 this.logResetEvent.fire();
1327};
1328
1329/**
1330 * Public accessor to internal stack of log message objects.
1331 *
1332 * @method getStack
1333 * @return {Object[]} Array of log message objects.
1334 */
1335YAHOO.widget.Logger.getStack = function() {
1336 return this._stack;
1337};
1338
1339/**
1340 * Public accessor to internal start time.
1341 *
1342 * @method getStartTime
1343 * @return {Date} Internal date of when Logger singleton was initialized.
1344 */
1345YAHOO.widget.Logger.getStartTime = function() {
1346 return this._startTime;
1347};
1348
1349/**
1350 * Disables output to the browser's global console.log() function, which is used
1351 * by the Firebug extension to Firefox as well as Safari.
1352 *
1353 * @method disableBrowserConsole
1354 */
1355YAHOO.widget.Logger.disableBrowserConsole = function() {
1356 YAHOO.log("Logger output to the function console.log() has been disabled.");
1357 this._browserConsoleEnabled = false;
1358};
1359
1360/**
1361 * Enables output to the browser's global console.log() function, which is used
1362 * by the Firebug extension to Firefox as well as Safari.
1363 *
1364 * @method enableBrowserConsole
1365 */
1366YAHOO.widget.Logger.enableBrowserConsole = function() {
1367 this._browserConsoleEnabled = true;
1368 YAHOO.log("Logger output to the function console.log() has been enabled.");
1369};
1370
1371/////////////////////////////////////////////////////////////////////////////
1372//
1373// Public events
1374//
1375/////////////////////////////////////////////////////////////////////////////
1376
1377 /**
1378 * Fired when a new category has been created.
1379 *
1380 * @event categoryCreateEvent
1381 * @param sCategory {String} Category name.
1382 */
1383YAHOO.widget.Logger.categoryCreateEvent =
1384 new YAHOO.util.CustomEvent("categoryCreate", this, true);
1385
1386 /**
1387 * Fired when a new source has been named.
1388 *
1389 * @event sourceCreateEvent
1390 * @param sSource {String} Source name.
1391 */
1392YAHOO.widget.Logger.sourceCreateEvent =
1393 new YAHOO.util.CustomEvent("sourceCreate", this, true);
1394
1395 /**
1396 * Fired when a new log message has been created.
1397 *
1398 * @event newLogEvent
1399 * @param sMsg {String} Log message.
1400 */
1401YAHOO.widget.Logger.newLogEvent = new YAHOO.util.CustomEvent("newLog", this, true);
1402
1403/**
1404 * Fired when the Logger has been reset has been created.
1405 *
1406 * @event logResetEvent
1407 */
1408YAHOO.widget.Logger.logResetEvent = new YAHOO.util.CustomEvent("logReset", this, true);
1409
1410/////////////////////////////////////////////////////////////////////////////
1411//
1412// Private methods
1413//
1414/////////////////////////////////////////////////////////////////////////////
1415
1416/**
1417 * Creates a new category of log messages and fires categoryCreateEvent.
1418 *
1419 * @method _createNewCategory
1420 * @param sCategory {String} Category name.
1421 * @private
1422 */
1423YAHOO.widget.Logger._createNewCategory = function(sCategory) {
1424 this.categories.push(sCategory);
1425 this.categoryCreateEvent.fire(sCategory);
1426};
1427
1428/**
1429 * Checks to see if a category has already been created.
1430 *
1431 * @method _isNewCategory
1432 * @param sCategory {String} Category name.
1433 * @return {Boolean} Returns true if category is unknown, else returns false.
1434 * @private
1435 */
1436YAHOO.widget.Logger._isNewCategory = function(sCategory) {
1437 for(var i=0; i < this.categories.length; i++) {
1438 if(sCategory == this.categories[i]) {
1439 return false;
1440 }
1441 }
1442 return true;
1443};
1444
1445/**
1446 * Creates a new source of log messages and fires sourceCreateEvent.
1447 *
1448 * @method _createNewSource
1449 * @param sSource {String} Source name.
1450 * @private
1451 */
1452YAHOO.widget.Logger._createNewSource = function(sSource) {
1453 this.sources.push(sSource);
1454 this.sourceCreateEvent.fire(sSource);
1455};
1456
1457/**
1458 * Checks to see if a source already exists.
1459 *
1460 * @method _isNewSource
1461 * @param sSource {String} Source name.
1462 * @return {Boolean} Returns true if source is unknown, else returns false.
1463 * @private
1464 */
1465YAHOO.widget.Logger._isNewSource = function(sSource) {
1466 if(sSource) {
1467 for(var i=0; i < this.sources.length; i++) {
1468 if(sSource == this.sources[i]) {
1469 return false;
1470 }
1471 }
1472 return true;
1473 }
1474};
1475
1476/**
1477 * Outputs a log message to global console.log() function.
1478 *
1479 * @method _printToBrowserConsole
1480 * @param oEntry {Object} Log entry object.
1481 * @private
1482 */
1483YAHOO.widget.Logger._printToBrowserConsole = function(oEntry) {
1484 if(window.console && console.log) {
1485 var category = oEntry.category;
1486 var label = oEntry.category.substring(0,4).toUpperCase();
1487
1488 var time = oEntry.time;
1489 if (time.toLocaleTimeString) {
1490 var localTime = time.toLocaleTimeString();
1491 }
1492 else {
1493 localTime = time.toString();
1494 }
1495
1496 var msecs = time.getTime();
1497 var elapsedTime = (YAHOO.widget.Logger._lastTime) ?
1498 (msecs - YAHOO.widget.Logger._lastTime) : 0;
1499 YAHOO.widget.Logger._lastTime = msecs;
1500
1501 var output =
1502 localTime + " (" +
1503 elapsedTime + "ms): " +
1504 oEntry.source + ": " +
1505 oEntry.msg;
1506
1507 console.log(output);
1508 }
1509};
1510
1511/////////////////////////////////////////////////////////////////////////////
1512//
1513// Private event handlers
1514//
1515/////////////////////////////////////////////////////////////////////////////
1516
1517/**
1518 * Handles logging of messages due to window error events.
1519 *
1520 * @method _onWindowError
1521 * @param sMsg {String} The error message.
1522 * @param sUrl {String} URL of the error.
1523 * @param sLine {String} Line number of the error.
1524 * @private
1525 */
1526YAHOO.widget.Logger._onWindowError = function(sMsg,sUrl,sLine) {
1527 // Logger is not in scope of this event handler
1528 try {
1529 YAHOO.widget.Logger.log(sMsg+' ('+sUrl+', line '+sLine+')', "window");
1530 if(YAHOO.widget.Logger._origOnWindowError) {
1531 YAHOO.widget.Logger._origOnWindowError();
1532 }
1533 }
1534 catch(e) {
1535 return false;
1536 }
1537};
1538
1539/////////////////////////////////////////////////////////////////////////////
1540//
1541// Enable handling of native JavaScript errors
1542// NB: Not all browsers support the window.onerror event
1543//
1544/////////////////////////////////////////////////////////////////////////////
1545
1546if(window.onerror) {
1547 // Save any previously defined handler to call
1548 YAHOO.widget.Logger._origOnWindowError = window.onerror;
1549}
1550window.onerror = YAHOO.widget.Logger._onWindowError;
1551
1552/////////////////////////////////////////////////////////////////////////////
1553//
1554// First log
1555//
1556/////////////////////////////////////////////////////////////////////////////
1557
1558YAHOO.widget.Logger.log("Logger initialized");
1559