Diffstat (limited to 'frontend/beta/js/YUI/logger.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/YUI/logger.js | 1559 |
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 | /* | ||
2 | Copyright (c) 2006, Yahoo! Inc. All rights reserved. | ||
3 | Code licensed under the BSD License: | ||
4 | http://developer.yahoo.com/yui/license.txt | ||
5 | version: 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 | */ | ||
40 | YAHOO.widget.LogMsg.prototype.msg = null; | ||
41 | |||
42 | /** | ||
43 | * Log timestamp. | ||
44 | * | ||
45 | * @property time | ||
46 | * @type Date | ||
47 | */ | ||
48 | YAHOO.widget.LogMsg.prototype.time = null; | ||
49 | |||
50 | /** | ||
51 | * Log category. | ||
52 | * | ||
53 | * @property category | ||
54 | * @type String | ||
55 | */ | ||
56 | YAHOO.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 | */ | ||
64 | YAHOO.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 | */ | ||
73 | YAHOO.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 | */ | ||
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 | }; | ||
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 | */ | ||
108 | YAHOO.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 | */ | ||
119 | YAHOO.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 | */ | ||
129 | YAHOO.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 | */ | ||
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 | } | ||
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 | */ | ||
162 | YAHOO.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 | */ | ||
179 | YAHOO.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 | */ | ||
362 | YAHOO.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 | */ | ||
370 | YAHOO.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 | */ | ||
378 | YAHOO.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 | */ | ||
386 | YAHOO.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 | */ | ||
394 | YAHOO.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 | */ | ||
402 | YAHOO.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 | */ | ||
410 | YAHOO.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 | */ | ||
418 | YAHOO.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 | */ | ||
427 | YAHOO.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 | */ | ||
437 | YAHOO.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 | */ | ||
445 | YAHOO.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 | */ | ||
454 | YAHOO.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 | */ | ||
464 | YAHOO.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 | */ | ||
478 | YAHOO.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 | */ | ||
487 | YAHOO.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 | */ | ||
498 | YAHOO.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 | */ | ||
508 | YAHOO.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 | */ | ||
517 | YAHOO.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 | */ | ||
527 | YAHOO.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 | */ | ||
537 | YAHOO.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 | */ | ||
548 | YAHOO.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 | */ | ||
605 | YAHOO.widget.LogReader.prototype.html2Text = function(sHtml) { | ||
606 | if(sHtml) { | ||
607 | sHtml += ""; | ||
608 | return sHtml.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); | ||
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 | */ | ||
628 | YAHOO.widget.LogReader._index = 0; | ||
629 | |||
630 | /** | ||
631 | * Name of LogReader instance. | ||
632 | * | ||
633 | * @property _sName | ||
634 | * @type String | ||
635 | * @private | ||
636 | */ | ||
637 | YAHOO.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 | */ | ||
648 | YAHOO.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 | */ | ||
657 | YAHOO.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 | */ | ||
667 | YAHOO.widget.LogReader.prototype._consoleMsgCount = 0; | ||
668 | |||
669 | /** | ||
670 | * Date of last output log message. | ||
671 | * | ||
672 | * @property _lastTime | ||
673 | * @type Date | ||
674 | * @private | ||
675 | */ | ||
676 | YAHOO.widget.LogReader.prototype._lastTime = null; | ||
677 | |||
678 | /** | ||
679 | * Batched output timeout ID. | ||
680 | * | ||
681 | * @property _timeout | ||
682 | * @type Number | ||
683 | * @private | ||
684 | */ | ||
685 | YAHOO.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 | */ | ||
694 | YAHOO.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 | */ | ||
703 | YAHOO.widget.LogReader.prototype._sourceFilters = null; | ||
704 | |||
705 | /** | ||
706 | * Log reader container element. | ||
707 | * | ||
708 | * @property _elContainer | ||
709 | * @type HTMLElement | ||
710 | * @private | ||
711 | */ | ||
712 | YAHOO.widget.LogReader.prototype._elContainer = null; | ||
713 | |||
714 | /** | ||
715 | * Log reader header element. | ||
716 | * | ||
717 | * @property _elHd | ||
718 | * @type HTMLElement | ||
719 | * @private | ||
720 | */ | ||
721 | YAHOO.widget.LogReader.prototype._elHd = null; | ||
722 | |||
723 | /** | ||
724 | * Log reader collapse element. | ||
725 | * | ||
726 | * @property _elCollapse | ||
727 | * @type HTMLElement | ||
728 | * @private | ||
729 | */ | ||
730 | YAHOO.widget.LogReader.prototype._elCollapse = null; | ||
731 | |||
732 | /** | ||
733 | * Log reader collapse button element. | ||
734 | * | ||
735 | * @property _btnCollapse | ||
736 | * @type HTMLElement | ||
737 | * @private | ||
738 | */ | ||
739 | YAHOO.widget.LogReader.prototype._btnCollapse = null; | ||
740 | |||
741 | /** | ||
742 | * Log reader title header element. | ||
743 | * | ||
744 | * @property _title | ||
745 | * @type HTMLElement | ||
746 | * @private | ||
747 | */ | ||
748 | YAHOO.widget.LogReader.prototype._title = null; | ||
749 | |||
750 | /** | ||
751 | * Log reader console element. | ||
752 | * | ||
753 | * @property _elConsole | ||
754 | * @type HTMLElement | ||
755 | * @private | ||
756 | */ | ||
757 | YAHOO.widget.LogReader.prototype._elConsole = null; | ||
758 | |||
759 | /** | ||
760 | * Log reader footer element. | ||
761 | * | ||
762 | * @property _elFt | ||
763 | * @type HTMLElement | ||
764 | * @private | ||
765 | */ | ||
766 | YAHOO.widget.LogReader.prototype._elFt = null; | ||
767 | |||
768 | /** | ||
769 | * Log reader buttons container element. | ||
770 | * | ||
771 | * @property _elBtns | ||
772 | * @type HTMLElement | ||
773 | * @private | ||
774 | */ | ||
775 | YAHOO.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 | */ | ||
784 | YAHOO.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 | */ | ||
793 | YAHOO.widget.LogReader.prototype._elSourceFilters = null; | ||
794 | |||
795 | /** | ||
796 | * Log reader pause button element. | ||
797 | * | ||
798 | * @property _btnPause | ||
799 | * @type HTMLElement | ||
800 | * @private | ||
801 | */ | ||
802 | YAHOO.widget.LogReader.prototype._btnPause = null; | ||
803 | |||
804 | /** | ||
805 | * Clear button element. | ||
806 | * | ||
807 | * @property _btnClear | ||
808 | * @type HTMLElement | ||
809 | * @private | ||
810 | */ | ||
811 | YAHOO.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 | */ | ||
826 | YAHOO.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 | */ | ||
865 | YAHOO.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 | */ | ||
904 | YAHOO.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 | */ | ||
919 | YAHOO.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 | */ | ||
940 | YAHOO.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 | */ | ||
972 | YAHOO.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 | */ | ||
1040 | YAHOO.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 | */ | ||
1056 | YAHOO.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 | */ | ||
1071 | YAHOO.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 | */ | ||
1097 | YAHOO.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 | */ | ||
1123 | YAHOO.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 | */ | ||
1149 | YAHOO.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 | */ | ||
1169 | YAHOO.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 | */ | ||
1182 | YAHOO.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 | */ | ||
1200 | YAHOO.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 | */ | ||
1231 | YAHOO.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 | */ | ||
1259 | YAHOO.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 | */ | ||
1321 | YAHOO.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 | */ | ||
1335 | YAHOO.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 | */ | ||
1345 | YAHOO.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 | */ | ||
1355 | YAHOO.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 | */ | ||
1366 | YAHOO.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 | */ | ||
1383 | YAHOO.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 | */ | ||
1392 | YAHOO.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 | */ | ||
1401 | YAHOO.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 | */ | ||
1408 | YAHOO.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 | */ | ||
1423 | YAHOO.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 | */ | ||
1436 | YAHOO.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 | */ | ||
1452 | YAHOO.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 | */ | ||
1465 | YAHOO.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 | */ | ||
1483 | YAHOO.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 | */ | ||
1526 | YAHOO.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 | |||
1546 | if(window.onerror) { | ||
1547 | // Save any previously defined handler to call | ||
1548 | YAHOO.widget.Logger._origOnWindowError = window.onerror; | ||
1549 | } | ||
1550 | window.onerror = YAHOO.widget.Logger._onWindowError; | ||
1551 | |||
1552 | ///////////////////////////////////////////////////////////////////////////// | ||
1553 | // | ||
1554 | // First log | ||
1555 | // | ||
1556 | ///////////////////////////////////////////////////////////////////////////// | ||
1557 | |||
1558 | YAHOO.widget.Logger.log("Logger initialized"); | ||
1559 | |||