[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 YUI.add('yui2-logger', function(Y) { 2 var YAHOO = Y.YUI2; 3 /* 4 Copyright (c) 2011, Yahoo! Inc. All rights reserved. 5 Code licensed under the BSD License: 6 http://developer.yahoo.com/yui/license.html 7 version: 2.9.0 8 */ 9 /****************************************************************************/ 10 /****************************************************************************/ 11 /****************************************************************************/ 12 13 /** 14 * The LogMsg class defines a single log message. 15 * 16 * @class LogMsg 17 * @constructor 18 * @param oConfigs {Object} Object literal of configuration params. 19 */ 20 YAHOO.widget.LogMsg = function(oConfigs) { 21 // Parse configs 22 /** 23 * Log message. 24 * 25 * @property msg 26 * @type String 27 */ 28 this.msg = 29 /** 30 * Log timestamp. 31 * 32 * @property time 33 * @type Date 34 */ 35 this.time = 36 37 /** 38 * Log category. 39 * 40 * @property category 41 * @type String 42 */ 43 this.category = 44 45 /** 46 * Log source. The first word passed in as the source argument. 47 * 48 * @property source 49 * @type String 50 */ 51 this.source = 52 53 /** 54 * Log source detail. The remainder of the string passed in as the source argument, not 55 * including the first word (if any). 56 * 57 * @property sourceDetail 58 * @type String 59 */ 60 this.sourceDetail = null; 61 62 if (oConfigs && (oConfigs.constructor == Object)) { 63 for(var param in oConfigs) { 64 if (oConfigs.hasOwnProperty(param)) { 65 this[param] = oConfigs[param]; 66 } 67 } 68 } 69 }; 70 /****************************************************************************/ 71 /****************************************************************************/ 72 /****************************************************************************/ 73 74 /** 75 * The LogWriter class provides a mechanism to log messages through 76 * YAHOO.widget.Logger from a named source. 77 * 78 * @class LogWriter 79 * @constructor 80 * @param sSource {String} Source of LogWriter instance. 81 */ 82 YAHOO.widget.LogWriter = function(sSource) { 83 if(!sSource) { 84 YAHOO.log("Could not instantiate LogWriter due to invalid source.", 85 "error", "LogWriter"); 86 return; 87 } 88 this._source = sSource; 89 }; 90 91 ///////////////////////////////////////////////////////////////////////////// 92 // 93 // Public methods 94 // 95 ///////////////////////////////////////////////////////////////////////////// 96 97 /** 98 * Public accessor to the unique name of the LogWriter instance. 99 * 100 * @method toString 101 * @return {String} Unique name of the LogWriter instance. 102 */ 103 YAHOO.widget.LogWriter.prototype.toString = function() { 104 return "LogWriter " + this._sSource; 105 }; 106 107 /** 108 * Logs a message attached to the source of the LogWriter. 109 * Note: the LogReader adds the message and category to the DOM as HTML. 110 * 111 * @method log 112 * @param sMsg {HTML} The log message. 113 * @param sCategory {HTML} Category name. 114 */ 115 YAHOO.widget.LogWriter.prototype.log = function(sMsg, sCategory) { 116 YAHOO.widget.Logger.log(sMsg, sCategory, this._source); 117 }; 118 119 /** 120 * Public accessor to get the source name. 121 * 122 * @method getSource 123 * @return {String} The LogWriter source. 124 */ 125 YAHOO.widget.LogWriter.prototype.getSource = function() { 126 return this._source; 127 }; 128 129 /** 130 * Public accessor to set the source name. 131 * 132 * @method setSource 133 * @param sSource {String} Source of LogWriter instance. 134 */ 135 YAHOO.widget.LogWriter.prototype.setSource = function(sSource) { 136 if(!sSource) { 137 YAHOO.log("Could not set source due to invalid source.", "error", this.toString()); 138 return; 139 } 140 else { 141 this._source = sSource; 142 } 143 }; 144 145 ///////////////////////////////////////////////////////////////////////////// 146 // 147 // Private member variables 148 // 149 ///////////////////////////////////////////////////////////////////////////// 150 151 /** 152 * Source of the LogWriter instance. 153 * 154 * @property _source 155 * @type String 156 * @private 157 */ 158 YAHOO.widget.LogWriter.prototype._source = null; 159 160 161 162 /** 163 * The Logger widget provides a simple way to read or write log messages in 164 * JavaScript code. Integration with the YUI Library's debug builds allow 165 * implementers to access under-the-hood events, errors, and debugging messages. 166 * Output may be read through a LogReader console and/or output to a browser 167 * console. 168 * 169 * @module logger 170 * @requires yahoo, event, dom 171 * @optional dragdrop 172 * @namespace YAHOO.widget 173 * @title Logger Widget 174 */ 175 176 /****************************************************************************/ 177 /****************************************************************************/ 178 /****************************************************************************/ 179 180 // Define once 181 if(!YAHOO.widget.Logger) { 182 /** 183 * The singleton Logger class provides core log management functionality. Saves 184 * logs written through the global YAHOO.log function or written by a LogWriter 185 * instance. Provides access to logs for reading by a LogReader instance or 186 * native browser console such as the Firebug extension to Firefox or Safari's 187 * JavaScript console through integration with the console.log() method. 188 * 189 * @class Logger 190 * @static 191 */ 192 YAHOO.widget.Logger = { 193 // Initialize properties 194 loggerEnabled: true, 195 _browserConsoleEnabled: false, 196 categories: ["info","warn","error","time","window"], 197 sources: ["global"], 198 _stack: [], // holds all log msgs 199 maxStackEntries: 2500, 200 _startTime: new Date().getTime(), // static start timestamp 201 _lastTime: null, // timestamp of last logged message 202 _windowErrorsHandled: false, 203 _origOnWindowError: null 204 }; 205 206 ///////////////////////////////////////////////////////////////////////////// 207 // 208 // Public properties 209 // 210 ///////////////////////////////////////////////////////////////////////////// 211 /** 212 * True if Logger is enabled, false otherwise. 213 * 214 * @property loggerEnabled 215 * @type Boolean 216 * @static 217 * @default true 218 */ 219 220 /** 221 * Array of categories. 222 * 223 * @property categories 224 * @type String[] 225 * @static 226 * @default ["info","warn","error","time","window"] 227 */ 228 229 /** 230 * Array of sources. 231 * 232 * @property sources 233 * @type String[] 234 * @static 235 * @default ["global"] 236 */ 237 238 /** 239 * Upper limit on size of internal stack. 240 * 241 * @property maxStackEntries 242 * @type Number 243 * @static 244 * @default 2500 245 */ 246 247 ///////////////////////////////////////////////////////////////////////////// 248 // 249 // Private properties 250 // 251 ///////////////////////////////////////////////////////////////////////////// 252 /** 253 * Internal property to track whether output to browser console is enabled. 254 * 255 * @property _browserConsoleEnabled 256 * @type Boolean 257 * @static 258 * @default false 259 * @private 260 */ 261 262 /** 263 * Array to hold all log messages. 264 * 265 * @property _stack 266 * @type Array 267 * @static 268 * @private 269 */ 270 /** 271 * Static timestamp of Logger initialization. 272 * 273 * @property _startTime 274 * @type Date 275 * @static 276 * @private 277 */ 278 /** 279 * Timestamp of last logged message. 280 * 281 * @property _lastTime 282 * @type Date 283 * @static 284 * @private 285 */ 286 ///////////////////////////////////////////////////////////////////////////// 287 // 288 // Public methods 289 // 290 ///////////////////////////////////////////////////////////////////////////// 291 /** 292 * Saves a log message to the stack and fires newLogEvent. If the log message is 293 * assigned to an unknown category, creates a new category. If the log message is 294 * from an unknown source, creates a new source. If browser console is enabled, 295 * outputs the log message to browser console. 296 * Note: the LogReader adds the message, category, and source to the DOM 297 * as HTML. 298 * 299 * @method log 300 * @param sMsg {HTML} The log message. 301 * @param sCategory {HTML} Category of log message, or null. 302 * @param sSource {HTML} Source of LogWriter, or null if global. 303 */ 304 YAHOO.widget.Logger.log = function(sMsg, sCategory, sSource) { 305 if(this.loggerEnabled) { 306 if(!sCategory) { 307 sCategory = "info"; // default category 308 } 309 else { 310 sCategory = sCategory.toLocaleLowerCase(); 311 if(this._isNewCategory(sCategory)) { 312 this._createNewCategory(sCategory); 313 } 314 } 315 var sClass = "global"; // default source 316 var sDetail = null; 317 if(sSource) { 318 var spaceIndex = sSource.indexOf(" "); 319 if(spaceIndex > 0) { 320 // Substring until first space 321 sClass = sSource.substring(0,spaceIndex); 322 // The rest of the source 323 sDetail = sSource.substring(spaceIndex,sSource.length); 324 } 325 else { 326 sClass = sSource; 327 } 328 if(this._isNewSource(sClass)) { 329 this._createNewSource(sClass); 330 } 331 } 332 333 var timestamp = new Date(); 334 var logEntry = new YAHOO.widget.LogMsg({ 335 msg: sMsg, 336 time: timestamp, 337 category: sCategory, 338 source: sClass, 339 sourceDetail: sDetail 340 }); 341 342 var stack = this._stack; 343 var maxStackEntries = this.maxStackEntries; 344 if(maxStackEntries && !isNaN(maxStackEntries) && 345 (stack.length >= maxStackEntries)) { 346 stack.shift(); 347 } 348 stack.push(logEntry); 349 this.newLogEvent.fire(logEntry); 350 351 if(this._browserConsoleEnabled) { 352 this._printToBrowserConsole(logEntry); 353 } 354 return true; 355 } 356 else { 357 return false; 358 } 359 }; 360 361 /** 362 * Resets internal stack and startTime, enables Logger, and fires logResetEvent. 363 * 364 * @method reset 365 */ 366 YAHOO.widget.Logger.reset = function() { 367 this._stack = []; 368 this._startTime = new Date().getTime(); 369 this.loggerEnabled = true; 370 this.log("Logger reset"); 371 this.logResetEvent.fire(); 372 }; 373 374 /** 375 * Public accessor to internal stack of log message objects. 376 * 377 * @method getStack 378 * @return {Object[]} Array of log message objects. 379 */ 380 YAHOO.widget.Logger.getStack = function() { 381 return this._stack; 382 }; 383 384 /** 385 * Public accessor to internal start time. 386 * 387 * @method getStartTime 388 * @return {Date} Internal date of when Logger singleton was initialized. 389 */ 390 YAHOO.widget.Logger.getStartTime = function() { 391 return this._startTime; 392 }; 393 394 /** 395 * Disables output to the browser's global console.log() function, which is used 396 * by the Firebug extension to Firefox as well as Safari. 397 * 398 * @method disableBrowserConsole 399 */ 400 YAHOO.widget.Logger.disableBrowserConsole = function() { 401 YAHOO.log("Logger output to the function console.log() has been disabled."); 402 this._browserConsoleEnabled = false; 403 }; 404 405 /** 406 * Enables output to the browser's global console.log() function, which is used 407 * by the Firebug extension to Firefox as well as Safari. 408 * 409 * @method enableBrowserConsole 410 */ 411 YAHOO.widget.Logger.enableBrowserConsole = function() { 412 this._browserConsoleEnabled = true; 413 YAHOO.log("Logger output to the function console.log() has been enabled."); 414 }; 415 416 /** 417 * Surpresses native JavaScript errors and outputs to console. By default, 418 * Logger does not handle JavaScript window error events. 419 * NB: Not all browsers support the window.onerror event. 420 * 421 * @method handleWindowErrors 422 */ 423 YAHOO.widget.Logger.handleWindowErrors = function() { 424 if(!YAHOO.widget.Logger._windowErrorsHandled) { 425 // Save any previously defined handler to call 426 if(window.error) { 427 YAHOO.widget.Logger._origOnWindowError = window.onerror; 428 } 429 window.onerror = YAHOO.widget.Logger._onWindowError; 430 YAHOO.widget.Logger._windowErrorsHandled = true; 431 YAHOO.log("Logger handling of window.onerror has been enabled."); 432 } 433 else { 434 YAHOO.log("Logger handling of window.onerror had already been enabled."); 435 } 436 }; 437 438 /** 439 * Unsurpresses native JavaScript errors. By default, 440 * Logger does not handle JavaScript window error events. 441 * NB: Not all browsers support the window.onerror event. 442 * 443 * @method unhandleWindowErrors 444 */ 445 YAHOO.widget.Logger.unhandleWindowErrors = function() { 446 if(YAHOO.widget.Logger._windowErrorsHandled) { 447 // Revert to any previously defined handler to call 448 if(YAHOO.widget.Logger._origOnWindowError) { 449 window.onerror = YAHOO.widget.Logger._origOnWindowError; 450 YAHOO.widget.Logger._origOnWindowError = null; 451 } 452 else { 453 window.onerror = null; 454 } 455 YAHOO.widget.Logger._windowErrorsHandled = false; 456 YAHOO.log("Logger handling of window.onerror has been disabled."); 457 } 458 else { 459 YAHOO.log("Logger handling of window.onerror had already been disabled."); 460 } 461 }; 462 463 ///////////////////////////////////////////////////////////////////////////// 464 // 465 // Public events 466 // 467 ///////////////////////////////////////////////////////////////////////////// 468 469 /** 470 * Fired when a new category has been created. 471 * 472 * @event categoryCreateEvent 473 * @param sCategory {String} Category name. 474 */ 475 YAHOO.widget.Logger.categoryCreateEvent = 476 new YAHOO.util.CustomEvent("categoryCreate", this, true); 477 478 /** 479 * Fired when a new source has been named. 480 * 481 * @event sourceCreateEvent 482 * @param sSource {String} Source name. 483 */ 484 YAHOO.widget.Logger.sourceCreateEvent = 485 new YAHOO.util.CustomEvent("sourceCreate", this, true); 486 487 /** 488 * Fired when a new log message has been created. 489 * 490 * @event newLogEvent 491 * @param sMsg {String} Log message. 492 */ 493 YAHOO.widget.Logger.newLogEvent = new YAHOO.util.CustomEvent("newLog", this, true); 494 495 /** 496 * Fired when the Logger has been reset has been created. 497 * 498 * @event logResetEvent 499 */ 500 YAHOO.widget.Logger.logResetEvent = new YAHOO.util.CustomEvent("logReset", this, true); 501 502 ///////////////////////////////////////////////////////////////////////////// 503 // 504 // Private methods 505 // 506 ///////////////////////////////////////////////////////////////////////////// 507 508 /** 509 * Creates a new category of log messages and fires categoryCreateEvent. 510 * 511 * @method _createNewCategory 512 * @param sCategory {String} Category name. 513 * @private 514 */ 515 YAHOO.widget.Logger._createNewCategory = function(sCategory) { 516 this.categories.push(sCategory); 517 this.categoryCreateEvent.fire(sCategory); 518 }; 519 520 /** 521 * Checks to see if a category has already been created. 522 * 523 * @method _isNewCategory 524 * @param sCategory {String} Category name. 525 * @return {Boolean} Returns true if category is unknown, else returns false. 526 * @private 527 */ 528 YAHOO.widget.Logger._isNewCategory = function(sCategory) { 529 for(var i=0; i < this.categories.length; i++) { 530 if(sCategory == this.categories[i]) { 531 return false; 532 } 533 } 534 return true; 535 }; 536 537 /** 538 * Creates a new source of log messages and fires sourceCreateEvent. 539 * 540 * @method _createNewSource 541 * @param sSource {String} Source name. 542 * @private 543 */ 544 YAHOO.widget.Logger._createNewSource = function(sSource) { 545 this.sources.push(sSource); 546 this.sourceCreateEvent.fire(sSource); 547 }; 548 549 /** 550 * Checks to see if a source already exists. 551 * 552 * @method _isNewSource 553 * @param sSource {String} Source name. 554 * @return {Boolean} Returns true if source is unknown, else returns false. 555 * @private 556 */ 557 YAHOO.widget.Logger._isNewSource = function(sSource) { 558 if(sSource) { 559 for(var i=0; i < this.sources.length; i++) { 560 if(sSource == this.sources[i]) { 561 return false; 562 } 563 } 564 return true; 565 } 566 }; 567 568 /** 569 * Outputs a log message to global console.log() function. 570 * 571 * @method _printToBrowserConsole 572 * @param oEntry {Object} Log entry object. 573 * @private 574 */ 575 YAHOO.widget.Logger._printToBrowserConsole = function(oEntry) { 576 if ((window.console && console.log) || 577 (window.opera && opera.postError)) { 578 var category = oEntry.category; 579 var label = oEntry.category.substring(0,4).toUpperCase(); 580 581 var time = oEntry.time; 582 var localTime; 583 if (time.toLocaleTimeString) { 584 localTime = time.toLocaleTimeString(); 585 } 586 else { 587 localTime = time.toString(); 588 } 589 590 var msecs = time.getTime(); 591 var elapsedTime = (YAHOO.widget.Logger._lastTime) ? 592 (msecs - YAHOO.widget.Logger._lastTime) : 0; 593 YAHOO.widget.Logger._lastTime = msecs; 594 595 var output = 596 localTime + " (" + 597 elapsedTime + "ms): " + 598 oEntry.source + ": "; 599 600 if (window.console) { 601 console.log(output, oEntry.msg); 602 } else { 603 opera.postError(output + oEntry.msg); 604 } 605 } 606 }; 607 608 ///////////////////////////////////////////////////////////////////////////// 609 // 610 // Private event handlers 611 // 612 ///////////////////////////////////////////////////////////////////////////// 613 614 /** 615 * Handles logging of messages due to window error events. 616 * 617 * @method _onWindowError 618 * @param sMsg {String} The error message. 619 * @param sUrl {String} URL of the error. 620 * @param sLine {String} Line number of the error. 621 * @private 622 */ 623 YAHOO.widget.Logger._onWindowError = function(sMsg,sUrl,sLine) { 624 // Logger is not in scope of this event handler 625 try { 626 YAHOO.widget.Logger.log(sMsg+' ('+sUrl+', line '+sLine+')', "window"); 627 if(YAHOO.widget.Logger._origOnWindowError) { 628 YAHOO.widget.Logger._origOnWindowError(); 629 } 630 } 631 catch(e) { 632 return false; 633 } 634 }; 635 636 ///////////////////////////////////////////////////////////////////////////// 637 // 638 // First log 639 // 640 ///////////////////////////////////////////////////////////////////////////// 641 642 YAHOO.widget.Logger.log("Logger initialized"); 643 } 644 645 /****************************************************************************/ 646 /****************************************************************************/ 647 /****************************************************************************/ 648 (function () { 649 var Logger = YAHOO.widget.Logger, 650 u = YAHOO.util, 651 Dom = u.Dom, 652 Event = u.Event, 653 d = document; 654 655 function make(el,props) { 656 el = d.createElement(el); 657 if (props) { 658 for (var p in props) { 659 if (props.hasOwnProperty(p)) { 660 el[p] = props[p]; 661 } 662 } 663 } 664 return el; 665 } 666 667 /** 668 * The LogReader class provides UI to read messages logged to YAHOO.widget.Logger. 669 * 670 * @class LogReader 671 * @constructor 672 * @param elContainer {HTMLElement} (optional) DOM element reference of an existing DIV. 673 * @param elContainer {String} (optional) String ID of an existing DIV. 674 * @param oConfigs {Object} (optional) Object literal of configuration params. 675 */ 676 function LogReader(elContainer, oConfigs) { 677 this._sName = LogReader._index; 678 LogReader._index++; 679 680 this._init.apply(this,arguments); 681 682 /** 683 * Render the LogReader immediately upon instantiation. If set to false, 684 * you must call myLogReader.render() to generate the UI. 685 * 686 * @property autoRender 687 * @type {Boolean} 688 * @default true 689 */ 690 if (this.autoRender !== false) { 691 this.render(); 692 } 693 } 694 695 ///////////////////////////////////////////////////////////////////////////// 696 // 697 // Static member variables 698 // 699 ///////////////////////////////////////////////////////////////////////////// 700 YAHOO.lang.augmentObject(LogReader, { 701 /** 702 * Internal class member to index multiple LogReader instances. 703 * 704 * @property _memberName 705 * @static 706 * @type Number 707 * @default 0 708 * @private 709 */ 710 _index : 0, 711 712 /** 713 * Node template for the log entries 714 * @property ENTRY_TEMPLATE 715 * @static 716 * @type {HTMLElement} 717 * @default <code>pre</code> element with class yui-log-entry 718 */ 719 ENTRY_TEMPLATE : (function () { 720 return make('pre',{ className: 'yui-log-entry' }); 721 })(), 722 723 /** 724 * Template used for innerHTML of verbose entry output. 725 * @property VERBOSE_TEMPLATE 726 * @static 727 * @default "<p><span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}:</p><p>{sourceAndDetail}</p><p>{message}</p>" 728 */ 729 VERBOSE_TEMPLATE : "<p><span class='{category}'>{label}</span> {totalTime}ms (+{elapsedTime}) {localTime}:</p><p>{sourceAndDetail}</p><p>{message}</p>", 730 731 /** 732 * Template used for innerHTML of compact entry output. 733 * @property BASIC_TEMPLATE 734 * @static 735 * @default "<p><span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}: {sourceAndDetail}: {message}</p>" 736 */ 737 BASIC_TEMPLATE : "<p><span class='{category}'>{label}</span> {totalTime}ms (+{elapsedTime}) {localTime}: {sourceAndDetail}: {message}</p>" 738 }); 739 740 ///////////////////////////////////////////////////////////////////////////// 741 // 742 // Public member variables 743 // 744 ///////////////////////////////////////////////////////////////////////////// 745 746 LogReader.prototype = { 747 /** 748 * Whether or not LogReader is enabled to output log messages. 749 * 750 * @property logReaderEnabled 751 * @type Boolean 752 * @default true 753 */ 754 logReaderEnabled : true, 755 756 /** 757 * Public member to access CSS width of the LogReader container. 758 * 759 * @property width 760 * @type String 761 */ 762 width : null, 763 764 /** 765 * Public member to access CSS height of the LogReader container. 766 * 767 * @property height 768 * @type String 769 */ 770 height : null, 771 772 /** 773 * Public member to access CSS top position of the LogReader container. 774 * 775 * @property top 776 * @type String 777 */ 778 top : null, 779 780 /** 781 * Public member to access CSS left position of the LogReader container. 782 * 783 * @property left 784 * @type String 785 */ 786 left : null, 787 788 /** 789 * Public member to access CSS right position of the LogReader container. 790 * 791 * @property right 792 * @type String 793 */ 794 right : null, 795 796 /** 797 * Public member to access CSS bottom position of the LogReader container. 798 * 799 * @property bottom 800 * @type String 801 */ 802 bottom : null, 803 804 /** 805 * Public member to access CSS font size of the LogReader container. 806 * 807 * @property fontSize 808 * @type String 809 */ 810 fontSize : null, 811 812 /** 813 * Whether or not the footer UI is enabled for the LogReader. 814 * 815 * @property footerEnabled 816 * @type Boolean 817 * @default true 818 */ 819 footerEnabled : true, 820 821 /** 822 * Whether or not output is verbose (more readable). Setting to true will make 823 * output more compact (less readable). 824 * 825 * @property verboseOutput 826 * @type Boolean 827 * @default true 828 */ 829 verboseOutput : true, 830 831 /** 832 * Custom output format for log messages. Defaults to null, which falls 833 * back to verboseOutput param deciding between LogReader.VERBOSE_TEMPLATE 834 * and LogReader.BASIC_TEMPLATE. Use bracketed place holders to mark where 835 * message info should go. Available place holder names include: 836 * <ul> 837 * <li>category</li> 838 * <li>label</li> 839 * <li>sourceAndDetail</li> 840 * <li>message</li> 841 * <li>localTime</li> 842 * <li>elapsedTime</li> 843 * <li>totalTime</li> 844 * </ul> 845 * 846 * @property entryFormat 847 * @type String 848 * @default null 849 */ 850 entryFormat : null, 851 852 /** 853 * Whether or not newest message is printed on top. 854 * 855 * @property newestOnTop 856 * @type Boolean 857 */ 858 newestOnTop : true, 859 860 /** 861 * Output timeout buffer in milliseconds. 862 * 863 * @property outputBuffer 864 * @type Number 865 * @default 100 866 */ 867 outputBuffer : 100, 868 869 /** 870 * Maximum number of messages a LogReader console will display. 871 * 872 * @property thresholdMax 873 * @type Number 874 * @default 500 875 */ 876 thresholdMax : 500, 877 878 /** 879 * When a LogReader console reaches its thresholdMax, it will clear out messages 880 * and print out the latest thresholdMin number of messages. 881 * 882 * @property thresholdMin 883 * @type Number 884 * @default 100 885 */ 886 thresholdMin : 100, 887 888 /** 889 * True when LogReader is in a collapsed state, false otherwise. 890 * 891 * @property isCollapsed 892 * @type Boolean 893 * @default false 894 */ 895 isCollapsed : false, 896 897 /** 898 * True when LogReader is in a paused state, false otherwise. 899 * 900 * @property isPaused 901 * @type Boolean 902 * @default false 903 */ 904 isPaused : false, 905 906 /** 907 * Enables draggable LogReader if DragDrop Utility is present. 908 * 909 * @property draggable 910 * @type Boolean 911 * @default true 912 */ 913 draggable : true, 914 915 ///////////////////////////////////////////////////////////////////////////// 916 // 917 // Public methods 918 // 919 ///////////////////////////////////////////////////////////////////////////// 920 921 /** 922 * Public accessor to the unique name of the LogReader instance. 923 * 924 * @method toString 925 * @return {String} Unique name of the LogReader instance. 926 */ 927 toString : function() { 928 return "LogReader instance" + this._sName; 929 }, 930 /** 931 * Pauses output of log messages. While paused, log messages are not lost, but 932 * get saved to a buffer and then output upon resume of LogReader. 933 * 934 * @method pause 935 */ 936 pause : function() { 937 this.isPaused = true; 938 this._timeout = null; 939 this.logReaderEnabled = false; 940 if (this._btnPause) { 941 this._btnPause.value = "Resume"; 942 } 943 }, 944 945 /** 946 * Resumes output of log messages, including outputting any log messages that 947 * have been saved to buffer while paused. 948 * 949 * @method resume 950 */ 951 resume : function() { 952 this.isPaused = false; 953 this.logReaderEnabled = true; 954 this._printBuffer(); 955 if (this._btnPause) { 956 this._btnPause.value = "Pause"; 957 } 958 }, 959 960 /** 961 * Adds the UI to the DOM, attaches event listeners, and bootstraps initial 962 * UI state. 963 * 964 * @method render 965 */ 966 render : function () { 967 if (this.rendered) { 968 return; 969 } 970 971 this._initContainerEl(); 972 973 this._initHeaderEl(); 974 this._initConsoleEl(); 975 this._initFooterEl(); 976 977 this._initCategories(); 978 this._initSources(); 979 980 this._initDragDrop(); 981 982 // Subscribe to Logger custom events 983 Logger.newLogEvent.subscribe(this._onNewLog, this); 984 Logger.logResetEvent.subscribe(this._onReset, this); 985 986 Logger.categoryCreateEvent.subscribe(this._onCategoryCreate, this); 987 Logger.sourceCreateEvent.subscribe(this._onSourceCreate, this); 988 989 this.rendered = true; 990 991 this._filterLogs(); 992 }, 993 994 /** 995 * Removes the UI from the DOM entirely and detaches all event listeners. 996 * Implementers should note that Logger will still accumulate messages. 997 * 998 * @method destroy 999 */ 1000 destroy : function () { 1001 Event.purgeElement(this._elContainer,true); 1002 this._elContainer.innerHTML = ''; 1003 this._elContainer.parentNode.removeChild(this._elContainer); 1004 1005 this.rendered = false; 1006 }, 1007 1008 /** 1009 * Hides UI of LogReader. Logging functionality is not disrupted. 1010 * 1011 * @method hide 1012 */ 1013 hide : function() { 1014 this._elContainer.style.display = "none"; 1015 }, 1016 1017 /** 1018 * Shows UI of LogReader. Logging functionality is not disrupted. 1019 * 1020 * @method show 1021 */ 1022 show : function() { 1023 this._elContainer.style.display = "block"; 1024 }, 1025 1026 /** 1027 * Collapses UI of LogReader. Logging functionality is not disrupted. 1028 * 1029 * @method collapse 1030 */ 1031 collapse : function() { 1032 this._elConsole.style.display = "none"; 1033 if(this._elFt) { 1034 this._elFt.style.display = "none"; 1035 } 1036 this._btnCollapse.value = "Expand"; 1037 this.isCollapsed = true; 1038 }, 1039 1040 /** 1041 * Expands UI of LogReader. Logging functionality is not disrupted. 1042 * 1043 * @method expand 1044 */ 1045 expand : function() { 1046 this._elConsole.style.display = "block"; 1047 if(this._elFt) { 1048 this._elFt.style.display = "block"; 1049 } 1050 this._btnCollapse.value = "Collapse"; 1051 this.isCollapsed = false; 1052 }, 1053 1054 /** 1055 * Returns related checkbox element for given filter (i.e., category or source). 1056 * 1057 * @method getCheckbox 1058 * @param {String} Category or source name. 1059 * @return {Array} Array of all filter checkboxes. 1060 */ 1061 getCheckbox : function(filter) { 1062 return this._filterCheckboxes[filter]; 1063 }, 1064 1065 /** 1066 * Returns array of enabled categories. 1067 * 1068 * @method getCategories 1069 * @return {String[]} Array of enabled categories. 1070 */ 1071 getCategories : function() { 1072 return this._categoryFilters; 1073 }, 1074 1075 /** 1076 * Shows log messages associated with given category. 1077 * 1078 * @method showCategory 1079 * @param {String} Category name. 1080 */ 1081 showCategory : function(sCategory) { 1082 var filtersArray = this._categoryFilters; 1083 // Don't do anything if category is already enabled 1084 // Use Array.indexOf if available... 1085 if(filtersArray.indexOf) { 1086 if(filtersArray.indexOf(sCategory) > -1) { 1087 return; 1088 } 1089 } 1090 // ...or do it the old-fashioned way 1091 else { 1092 for(var i=0; i<filtersArray.length; i++) { 1093 if(filtersArray[i] === sCategory){ 1094 return; 1095 } 1096 } 1097 } 1098 1099 this._categoryFilters.push(sCategory); 1100 this._filterLogs(); 1101 var elCheckbox = this.getCheckbox(sCategory); 1102 if(elCheckbox) { 1103 elCheckbox.checked = true; 1104 } 1105 }, 1106 1107 /** 1108 * Hides log messages associated with given category. 1109 * 1110 * @method hideCategory 1111 * @param {String} Category name. 1112 */ 1113 hideCategory : function(sCategory) { 1114 var filtersArray = this._categoryFilters; 1115 for(var i=0; i<filtersArray.length; i++) { 1116 if(sCategory == filtersArray[i]) { 1117 filtersArray.splice(i, 1); 1118 break; 1119 } 1120 } 1121 this._filterLogs(); 1122 var elCheckbox = this.getCheckbox(sCategory); 1123 if(elCheckbox) { 1124 elCheckbox.checked = false; 1125 } 1126 }, 1127 1128 /** 1129 * Returns array of enabled sources. 1130 * 1131 * @method getSources 1132 * @return {Array} Array of enabled sources. 1133 */ 1134 getSources : function() { 1135 return this._sourceFilters; 1136 }, 1137 1138 /** 1139 * Shows log messages associated with given source. 1140 * 1141 * @method showSource 1142 * @param {String} Source name. 1143 */ 1144 showSource : function(sSource) { 1145 var filtersArray = this._sourceFilters; 1146 // Don't do anything if category is already enabled 1147 // Use Array.indexOf if available... 1148 if(filtersArray.indexOf) { 1149 if(filtersArray.indexOf(sSource) > -1) { 1150 return; 1151 } 1152 } 1153 // ...or do it the old-fashioned way 1154 else { 1155 for(var i=0; i<filtersArray.length; i++) { 1156 if(sSource == filtersArray[i]){ 1157 return; 1158 } 1159 } 1160 } 1161 filtersArray.push(sSource); 1162 this._filterLogs(); 1163 var elCheckbox = this.getCheckbox(sSource); 1164 if(elCheckbox) { 1165 elCheckbox.checked = true; 1166 } 1167 }, 1168 1169 /** 1170 * Hides log messages associated with given source. 1171 * 1172 * @method hideSource 1173 * @param {String} Source name. 1174 */ 1175 hideSource : function(sSource) { 1176 var filtersArray = this._sourceFilters; 1177 for(var i=0; i<filtersArray.length; i++) { 1178 if(sSource == filtersArray[i]) { 1179 filtersArray.splice(i, 1); 1180 break; 1181 } 1182 } 1183 this._filterLogs(); 1184 var elCheckbox = this.getCheckbox(sSource); 1185 if(elCheckbox) { 1186 elCheckbox.checked = false; 1187 } 1188 }, 1189 1190 /** 1191 * Does not delete any log messages, but clears all printed log messages from 1192 * the console. Log messages will be printed out again if user re-filters. The 1193 * static method YAHOO.widget.Logger.reset() should be called in order to 1194 * actually delete log messages. 1195 * 1196 * @method clearConsole 1197 */ 1198 clearConsole : function() { 1199 // Clear the buffer of any pending messages 1200 this._timeout = null; 1201 this._buffer = []; 1202 this._consoleMsgCount = 0; 1203 1204 var elConsole = this._elConsole; 1205 elConsole.innerHTML = ''; 1206 }, 1207 1208 /** 1209 * Updates title to given string. 1210 * 1211 * @method setTitle 1212 * @param sTitle {String} New title. 1213 */ 1214 setTitle : function(sTitle) { 1215 this._title.innerHTML = this.html2Text(sTitle); 1216 }, 1217 1218 /** 1219 * Gets timestamp of the last log. 1220 * 1221 * @method getLastTime 1222 * @return {Date} Timestamp of the last log. 1223 */ 1224 getLastTime : function() { 1225 return this._lastTime; 1226 }, 1227 1228 formatMsg : function (entry) { 1229 var entryFormat = this.entryFormat || (this.verboseOutput ? 1230 LogReader.VERBOSE_TEMPLATE : LogReader.BASIC_TEMPLATE), 1231 info = { 1232 category : entry.category, 1233 1234 // Label for color-coded display 1235 label : entry.category.substring(0,4).toUpperCase(), 1236 1237 sourceAndDetail : entry.sourceDetail ? 1238 entry.source + " " + entry.sourceDetail : 1239 entry.source, 1240 1241 // Escape HTML entities in the log message itself for output 1242 // to console 1243 message : this.html2Text(entry.msg || entry.message || '') 1244 }; 1245 1246 // Add time info 1247 if (entry.time && entry.time.getTime) { 1248 info.localTime = entry.time.toLocaleTimeString ? 1249 entry.time.toLocaleTimeString() : 1250 entry.time.toString(); 1251 1252 // Calculate the elapsed time to be from the last item that 1253 // passed through the filter, not the absolute previous item 1254 // in the stack 1255 info.elapsedTime = entry.time.getTime() - this.getLastTime(); 1256 1257 info.totalTime = entry.time.getTime() - Logger.getStartTime(); 1258 } 1259 1260 var msg = LogReader.ENTRY_TEMPLATE.cloneNode(true); 1261 if (this.verboseOutput) { 1262 msg.className += ' yui-log-verbose'; 1263 } 1264 1265 // Bug 2061169: Workaround for YAHOO.lang.substitute() 1266 msg.innerHTML = entryFormat.replace(/\{(\w+)\}/g, 1267 function (x, placeholder) { 1268 return (placeholder in info) ? info[placeholder] : ''; 1269 }); 1270 1271 return msg; 1272 }, 1273 1274 /** 1275 * Converts input chars "<", ">", and "&" to HTML entities. 1276 * 1277 * @method html2Text 1278 * @param sHtml {String} String to convert. 1279 * @private 1280 */ 1281 html2Text : function(sHtml) { 1282 if(sHtml) { 1283 sHtml += ""; 1284 return sHtml.replace(/&/g, "&"). 1285 replace(/</g, "<"). 1286 replace(/>/g, ">"); 1287 } 1288 return ""; 1289 }, 1290 1291 ///////////////////////////////////////////////////////////////////////////// 1292 // 1293 // Private member variables 1294 // 1295 ///////////////////////////////////////////////////////////////////////////// 1296 1297 /** 1298 * Name of LogReader instance. 1299 * 1300 * @property _sName 1301 * @type String 1302 * @private 1303 */ 1304 _sName : null, 1305 1306 //TODO: remove 1307 /** 1308 * A class member shared by all LogReaders if a container needs to be 1309 * created during instantiation. Will be null if a container element never needs to 1310 * be created on the fly, such as when the implementer passes in their own element. 1311 * 1312 * @property _elDefaultContainer 1313 * @type HTMLElement 1314 * @private 1315 */ 1316 //YAHOO.widget.LogReader._elDefaultContainer = null; 1317 1318 /** 1319 * Buffer of log message objects for batch output. 1320 * 1321 * @property _buffer 1322 * @type Object[] 1323 * @private 1324 */ 1325 _buffer : null, 1326 1327 /** 1328 * Number of log messages output to console. 1329 * 1330 * @property _consoleMsgCount 1331 * @type Number 1332 * @default 0 1333 * @private 1334 */ 1335 _consoleMsgCount : 0, 1336 1337 /** 1338 * Date of last output log message. 1339 * 1340 * @property _lastTime 1341 * @type Date 1342 * @private 1343 */ 1344 _lastTime : null, 1345 1346 /** 1347 * Batched output timeout ID. 1348 * 1349 * @property _timeout 1350 * @type Number 1351 * @private 1352 */ 1353 _timeout : null, 1354 1355 /** 1356 * Hash of filters and their related checkbox elements. 1357 * 1358 * @property _filterCheckboxes 1359 * @type Object 1360 * @private 1361 */ 1362 _filterCheckboxes : null, 1363 1364 /** 1365 * Array of filters for log message categories. 1366 * 1367 * @property _categoryFilters 1368 * @type String[] 1369 * @private 1370 */ 1371 _categoryFilters : null, 1372 1373 /** 1374 * Array of filters for log message sources. 1375 * 1376 * @property _sourceFilters 1377 * @type String[] 1378 * @private 1379 */ 1380 _sourceFilters : null, 1381 1382 /** 1383 * LogReader container element. 1384 * 1385 * @property _elContainer 1386 * @type HTMLElement 1387 * @private 1388 */ 1389 _elContainer : null, 1390 1391 /** 1392 * LogReader header element. 1393 * 1394 * @property _elHd 1395 * @type HTMLElement 1396 * @private 1397 */ 1398 _elHd : null, 1399 1400 /** 1401 * LogReader collapse element. 1402 * 1403 * @property _elCollapse 1404 * @type HTMLElement 1405 * @private 1406 */ 1407 _elCollapse : null, 1408 1409 /** 1410 * LogReader collapse button element. 1411 * 1412 * @property _btnCollapse 1413 * @type HTMLElement 1414 * @private 1415 */ 1416 _btnCollapse : null, 1417 1418 /** 1419 * LogReader title header element. 1420 * 1421 * @property _title 1422 * @type HTMLElement 1423 * @private 1424 */ 1425 _title : null, 1426 1427 /** 1428 * LogReader console element. 1429 * 1430 * @property _elConsole 1431 * @type HTMLElement 1432 * @private 1433 */ 1434 _elConsole : null, 1435 1436 /** 1437 * LogReader footer element. 1438 * 1439 * @property _elFt 1440 * @type HTMLElement 1441 * @private 1442 */ 1443 _elFt : null, 1444 1445 /** 1446 * LogReader buttons container element. 1447 * 1448 * @property _elBtns 1449 * @type HTMLElement 1450 * @private 1451 */ 1452 _elBtns : null, 1453 1454 /** 1455 * Container element for LogReader category filter checkboxes. 1456 * 1457 * @property _elCategoryFilters 1458 * @type HTMLElement 1459 * @private 1460 */ 1461 _elCategoryFilters : null, 1462 1463 /** 1464 * Container element for LogReader source filter checkboxes. 1465 * 1466 * @property _elSourceFilters 1467 * @type HTMLElement 1468 * @private 1469 */ 1470 _elSourceFilters : null, 1471 1472 /** 1473 * LogReader pause button element. 1474 * 1475 * @property _btnPause 1476 * @type HTMLElement 1477 * @private 1478 */ 1479 _btnPause : null, 1480 1481 /** 1482 * Clear button element. 1483 * 1484 * @property _btnClear 1485 * @type HTMLElement 1486 * @private 1487 */ 1488 _btnClear : null, 1489 1490 ///////////////////////////////////////////////////////////////////////////// 1491 // 1492 // Private methods 1493 // 1494 ///////////////////////////////////////////////////////////////////////////// 1495 1496 /** 1497 * Initializes the instance's message buffer, start time, etc 1498 * 1499 * @method _init 1500 * @param container {String|HTMLElement} (optional) the render target 1501 * @param config {Object} (optional) instance configuration 1502 * @protected 1503 */ 1504 _init : function (container, config) { 1505 // Internal vars 1506 this._buffer = []; // output buffer 1507 this._filterCheckboxes = {}; // pointers to checkboxes 1508 this._lastTime = Logger.getStartTime(); // timestamp of last log message to console 1509 1510 // Parse config vars here 1511 if (config && (config.constructor == Object)) { 1512 for(var param in config) { 1513 if (config.hasOwnProperty(param)) { 1514 this[param] = config[param]; 1515 } 1516 } 1517 } 1518 1519 this._elContainer = Dom.get(container); 1520 1521 YAHOO.log("LogReader initialized", null, this.toString()); 1522 }, 1523 1524 /** 1525 * Initializes the primary container element. 1526 * 1527 * @method _initContainerEl 1528 * @private 1529 */ 1530 _initContainerEl : function() { 1531 1532 // Default the container if unset or not a div 1533 if(!this._elContainer || !/div$/i.test(this._elContainer.tagName)) { 1534 this._elContainer = d.body.insertBefore(make("div"),d.body.firstChild); 1535 // Only position absolutely if an in-DOM element is not supplied 1536 Dom.addClass(this._elContainer,"yui-log-container"); 1537 } 1538 1539 Dom.addClass(this._elContainer,"yui-log"); 1540 1541 // If implementer has provided container values, trust and set those 1542 var style = this._elContainer.style, 1543 styleProps = ['width','right','top','fontSize'], 1544 prop,i; 1545 1546 for (i = styleProps.length - 1; i >= 0; --i) { 1547 prop = styleProps[i]; 1548 if (this[prop]){ 1549 style[prop] = this[prop]; 1550 } 1551 } 1552 1553 if(this.left) { 1554 style.left = this.left; 1555 style.right = "auto"; 1556 } 1557 if(this.bottom) { 1558 style.bottom = this.bottom; 1559 style.top = "auto"; 1560 } 1561 1562 // Opera needs a little prodding to reflow sometimes 1563 if (YAHOO.env.ua.opera) { 1564 d.body.style += ''; 1565 } 1566 1567 }, 1568 1569 /** 1570 * Initializes the header element. 1571 * 1572 * @method _initHeaderEl 1573 * @private 1574 */ 1575 _initHeaderEl : function() { 1576 // Destroy header if present 1577 if(this._elHd) { 1578 // Unhook DOM events 1579 Event.purgeElement(this._elHd, true); 1580 1581 // Remove DOM elements 1582 this._elHd.innerHTML = ""; 1583 } 1584 1585 // Create header 1586 // TODO: refactor this into an innerHTML 1587 this._elHd = make("div",{ 1588 className: "yui-log-hd" 1589 }); 1590 Dom.generateId(this._elHd, 'yui-log-hd' + this._sName); 1591 1592 this._elCollapse = make("div",{ className: 'yui-log-btns' }); 1593 1594 this._btnCollapse = make("input",{ 1595 type: 'button', 1596 className: 'yui-log-button', 1597 value: 'Collapse' 1598 }); 1599 Event.on(this._btnCollapse,'click',this._onClickCollapseBtn,this); 1600 1601 1602 this._title = make("h4",{ innerHTML : "Logger Console" }); 1603 1604 this._elCollapse.appendChild(this._btnCollapse); 1605 this._elHd.appendChild(this._elCollapse); 1606 this._elHd.appendChild(this._title); 1607 this._elContainer.appendChild(this._elHd); 1608 }, 1609 1610 /** 1611 * Initializes the console element. 1612 * 1613 * @method _initConsoleEl 1614 * @private 1615 */ 1616 _initConsoleEl : function() { 1617 // Destroy console 1618 if(this._elConsole) { 1619 // Unhook DOM events 1620 Event.purgeElement(this._elConsole, true); 1621 1622 // Remove DOM elements 1623 this._elConsole.innerHTML = ""; 1624 } 1625 1626 // Ceate console 1627 this._elConsole = make("div", { className: "yui-log-bd" }); 1628 1629 // If implementer has provided console, trust and set those 1630 if(this.height) { 1631 this._elConsole.style.height = this.height; 1632 } 1633 1634 this._elContainer.appendChild(this._elConsole); 1635 }, 1636 1637 /** 1638 * Initializes the footer element. 1639 * 1640 * @method _initFooterEl 1641 * @private 1642 */ 1643 _initFooterEl : function() { 1644 // Don't create footer elements if footer is disabled 1645 if(this.footerEnabled) { 1646 // Destroy console 1647 if(this._elFt) { 1648 // Unhook DOM events 1649 Event.purgeElement(this._elFt, true); 1650 1651 // Remove DOM elements 1652 this._elFt.innerHTML = ""; 1653 } 1654 1655 // TODO: use innerHTML 1656 this._elFt = make("div",{ className: "yui-log-ft" }); 1657 this._elBtns = make("div", { className: "yui-log-btns" }); 1658 this._btnPause = make("input", { 1659 type: "button", 1660 className: "yui-log-button", 1661 value: "Pause" 1662 }); 1663 1664 Event.on(this._btnPause,'click',this._onClickPauseBtn,this); 1665 1666 this._btnClear = make("input", { 1667 type: "button", 1668 className: "yui-log-button", 1669 value: "Clear" 1670 }); 1671 1672 Event.on(this._btnClear,'click',this._onClickClearBtn,this); 1673 1674 this._elCategoryFilters = make("div", { className: "yui-log-categoryfilters" }); 1675 this._elSourceFilters = make("div", { className: "yui-log-sourcefilters" }); 1676 1677 this._elBtns.appendChild(this._btnPause); 1678 this._elBtns.appendChild(this._btnClear); 1679 this._elFt.appendChild(this._elBtns); 1680 this._elFt.appendChild(this._elCategoryFilters); 1681 this._elFt.appendChild(this._elSourceFilters); 1682 this._elContainer.appendChild(this._elFt); 1683 } 1684 }, 1685 1686 /** 1687 * Initializes Drag and Drop on the header element. 1688 * 1689 * @method _initDragDrop 1690 * @private 1691 */ 1692 _initDragDrop : function() { 1693 // If Drag and Drop utility is available... 1694 // ...and draggable is true... 1695 // ...then make the header draggable 1696 if(u.DD && this.draggable && this._elHd) { 1697 var ylog_dd = new u.DD(this._elContainer); 1698 ylog_dd.setHandleElId(this._elHd.id); 1699 //TODO: use class name 1700 this._elHd.style.cursor = "move"; 1701 } 1702 }, 1703 1704 /** 1705 * Initializes category filters. 1706 * 1707 * @method _initCategories 1708 * @private 1709 */ 1710 _initCategories : function() { 1711 // Initialize category filters 1712 this._categoryFilters = []; 1713 var aInitialCategories = Logger.categories; 1714 1715 for(var j=0; j < aInitialCategories.length; j++) { 1716 var sCategory = aInitialCategories[j]; 1717 1718 // Add category to the internal array of filters 1719 this._categoryFilters.push(sCategory); 1720 1721 // Add checkbox element if UI is enabled 1722 if(this._elCategoryFilters) { 1723 this._createCategoryCheckbox(sCategory); 1724 } 1725 } 1726 }, 1727 1728 /** 1729 * Initializes source filters. 1730 * 1731 * @method _initSources 1732 * @private 1733 */ 1734 _initSources : function() { 1735 // Initialize source filters 1736 this._sourceFilters = []; 1737 var aInitialSources = Logger.sources; 1738 1739 for(var j=0; j < aInitialSources.length; j++) { 1740 var sSource = aInitialSources[j]; 1741 1742 // Add source to the internal array of filters 1743 this._sourceFilters.push(sSource); 1744 1745 // Add checkbox element if UI is enabled 1746 if(this._elSourceFilters) { 1747 this._createSourceCheckbox(sSource); 1748 } 1749 } 1750 }, 1751 1752 /** 1753 * Creates the UI for a category filter in the LogReader footer element. 1754 * 1755 * @method _createCategoryCheckbox 1756 * @param sCategory {String} Category name. 1757 * @private 1758 */ 1759 _createCategoryCheckbox : function(sCategory) { 1760 if(this._elFt) { 1761 var filter = make("span",{ className: "yui-log-filtergrp" }), 1762 checkid = Dom.generateId(null, "yui-log-filter-" + sCategory + this._sName), 1763 check = make("input", { 1764 id: checkid, 1765 className: "yui-log-filter-" + sCategory, 1766 type: "checkbox", 1767 category: sCategory 1768 }), 1769 label = make("label", { 1770 htmlFor: checkid, 1771 className: sCategory, 1772 innerHTML: sCategory 1773 }); 1774 1775 1776 // Subscribe to the click event 1777 Event.on(check,'click',this._onCheckCategory,this); 1778 1779 this._filterCheckboxes[sCategory] = check; 1780 1781 // Append el at the end so IE 5.5 can set "type" attribute 1782 // and THEN set checked property 1783 filter.appendChild(check); 1784 filter.appendChild(label); 1785 this._elCategoryFilters.appendChild(filter); 1786 check.checked = true; 1787 } 1788 }, 1789 1790 /** 1791 * Creates a checkbox in the LogReader footer element to filter by source. 1792 * 1793 * @method _createSourceCheckbox 1794 * @param sSource {String} Source name. 1795 * @private 1796 */ 1797 _createSourceCheckbox : function(sSource) { 1798 if(this._elFt) { 1799 var filter = make("span",{ className: "yui-log-filtergrp" }), 1800 checkid = Dom.generateId(null, "yui-log-filter-" + sSource + this._sName), 1801 check = make("input", { 1802 id: checkid, 1803 className: "yui-log-filter-" + sSource, 1804 type: "checkbox", 1805 source: sSource 1806 }), 1807 label = make("label", { 1808 htmlFor: checkid, 1809 className: sSource, 1810 innerHTML: sSource 1811 }); 1812 1813 1814 // Subscribe to the click event 1815 Event.on(check,'click',this._onCheckSource,this); 1816 1817 this._filterCheckboxes[sSource] = check; 1818 1819 // Append el at the end so IE 5.5 can set "type" attribute 1820 // and THEN set checked property 1821 filter.appendChild(check); 1822 filter.appendChild(label); 1823 this._elSourceFilters.appendChild(filter); 1824 check.checked = true; 1825 } 1826 }, 1827 1828 /** 1829 * Reprints all log messages in the stack through filters. 1830 * 1831 * @method _filterLogs 1832 * @private 1833 */ 1834 _filterLogs : function() { 1835 // Reprint stack with new filters 1836 if (this._elConsole !== null) { 1837 this.clearConsole(); 1838 this._printToConsole(Logger.getStack()); 1839 } 1840 }, 1841 1842 /** 1843 * Sends buffer of log messages to output and clears buffer. 1844 * 1845 * @method _printBuffer 1846 * @private 1847 */ 1848 _printBuffer : function() { 1849 this._timeout = null; 1850 1851 if(this._elConsole !== null) { 1852 var thresholdMax = this.thresholdMax; 1853 thresholdMax = (thresholdMax && !isNaN(thresholdMax)) ? thresholdMax : 500; 1854 if(this._consoleMsgCount < thresholdMax) { 1855 var entries = []; 1856 for (var i=0; i<this._buffer.length; i++) { 1857 entries[i] = this._buffer[i]; 1858 } 1859 this._buffer = []; 1860 this._printToConsole(entries); 1861 } 1862 else { 1863 this._filterLogs(); 1864 } 1865 1866 if(!this.newestOnTop) { 1867 this._elConsole.scrollTop = this._elConsole.scrollHeight; 1868 } 1869 } 1870 }, 1871 1872 /** 1873 * Cycles through an array of log messages, and outputs each one to the console 1874 * if its category has not been filtered out. 1875 * 1876 * @method _printToConsole 1877 * @param aEntries {Object[]} Array of LogMsg objects to output to console. 1878 * @private 1879 */ 1880 _printToConsole : function(aEntries) { 1881 // Manage the number of messages displayed in the console 1882 var entriesLen = aEntries.length, 1883 df = d.createDocumentFragment(), 1884 msgHTML = [], 1885 thresholdMin = this.thresholdMin, 1886 sourceFiltersLen = this._sourceFilters.length, 1887 categoryFiltersLen = this._categoryFilters.length, 1888 entriesStartIndex, 1889 i, j, msg, before; 1890 1891 if(isNaN(thresholdMin) || (thresholdMin > this.thresholdMax)) { 1892 thresholdMin = 0; 1893 } 1894 entriesStartIndex = (entriesLen > thresholdMin) ? (entriesLen - thresholdMin) : 0; 1895 1896 // Iterate through all log entries 1897 for(i=entriesStartIndex; i<entriesLen; i++) { 1898 // Print only the ones that filter through 1899 var okToPrint = false, 1900 okToFilterCats = false, 1901 entry = aEntries[i], 1902 source = entry.source, 1903 category = entry.category; 1904 1905 for(j=0; j<sourceFiltersLen; j++) { 1906 if(source == this._sourceFilters[j]) { 1907 okToFilterCats = true; 1908 break; 1909 } 1910 } 1911 if(okToFilterCats) { 1912 for(j=0; j<categoryFiltersLen; j++) { 1913 if(category == this._categoryFilters[j]) { 1914 okToPrint = true; 1915 break; 1916 } 1917 } 1918 } 1919 if(okToPrint) { 1920 // Start from 0ms elapsed time 1921 if (this._consoleMsgCount === 0) { 1922 this._lastTime = entry.time.getTime(); 1923 } 1924 1925 msg = this.formatMsg(entry); 1926 if (typeof msg === 'string') { 1927 msgHTML[msgHTML.length] = msg; 1928 } else { 1929 df.insertBefore(msg, this.newestOnTop ? 1930 df.firstChild || null : null); 1931 } 1932 this._consoleMsgCount++; 1933 this._lastTime = entry.time.getTime(); 1934 } 1935 } 1936 1937 if (msgHTML.length) { 1938 msgHTML.splice(0,0,this._elConsole.innerHTML); 1939 this._elConsole.innerHTML = this.newestOnTop ? 1940 msgHTML.reverse().join('') : 1941 msgHTML.join(''); 1942 } else if (df.firstChild) { 1943 this._elConsole.insertBefore(df, this.newestOnTop ? 1944 this._elConsole.firstChild || null : null); 1945 } 1946 }, 1947 1948 ///////////////////////////////////////////////////////////////////////////// 1949 // 1950 // Private event handlers 1951 // 1952 ///////////////////////////////////////////////////////////////////////////// 1953 1954 /** 1955 * Handles Logger's categoryCreateEvent. 1956 * 1957 * @method _onCategoryCreate 1958 * @param sType {String} The event. 1959 * @param aArgs {Object[]} Data passed from event firer. 1960 * @param oSelf {Object} The LogReader instance. 1961 * @private 1962 */ 1963 _onCategoryCreate : function(sType, aArgs, oSelf) { 1964 var category = aArgs[0]; 1965 1966 // Add category to the internal array of filters 1967 oSelf._categoryFilters.push(category); 1968 1969 if(oSelf._elFt) { 1970 oSelf._createCategoryCheckbox(category); 1971 } 1972 }, 1973 1974 /** 1975 * Handles Logger's sourceCreateEvent. 1976 * 1977 * @method _onSourceCreate 1978 * @param sType {String} The event. 1979 * @param aArgs {Object[]} Data passed from event firer. 1980 * @param oSelf {Object} The LogReader instance. 1981 * @private 1982 */ 1983 _onSourceCreate : function(sType, aArgs, oSelf) { 1984 var source = aArgs[0]; 1985 1986 // Add source to the internal array of filters 1987 oSelf._sourceFilters.push(source); 1988 1989 if(oSelf._elFt) { 1990 oSelf._createSourceCheckbox(source); 1991 } 1992 }, 1993 1994 /** 1995 * Handles check events on the category filter checkboxes. 1996 * 1997 * @method _onCheckCategory 1998 * @param v {HTMLEvent} The click event. 1999 * @param oSelf {Object} The LogReader instance. 2000 * @private 2001 */ 2002 _onCheckCategory : function(v, oSelf) { 2003 var category = this.category; 2004 if(!this.checked) { 2005 oSelf.hideCategory(category); 2006 } 2007 else { 2008 oSelf.showCategory(category); 2009 } 2010 }, 2011 2012 /** 2013 * Handles check events on the category filter checkboxes. 2014 * 2015 * @method _onCheckSource 2016 * @param v {HTMLEvent} The click event. 2017 * @param oSelf {Object} The LogReader instance. 2018 * @private 2019 */ 2020 _onCheckSource : function(v, oSelf) { 2021 var source = this.source; 2022 if(!this.checked) { 2023 oSelf.hideSource(source); 2024 } 2025 else { 2026 oSelf.showSource(source); 2027 } 2028 }, 2029 2030 /** 2031 * Handles click events on the collapse button. 2032 * 2033 * @method _onClickCollapseBtn 2034 * @param v {HTMLEvent} The click event. 2035 * @param oSelf {Object} The LogReader instance 2036 * @private 2037 */ 2038 _onClickCollapseBtn : function(v, oSelf) { 2039 if(!oSelf.isCollapsed) { 2040 oSelf.collapse(); 2041 } 2042 else { 2043 oSelf.expand(); 2044 } 2045 }, 2046 2047 /** 2048 * Handles click events on the pause button. 2049 * 2050 * @method _onClickPauseBtn 2051 * @param v {HTMLEvent} The click event. 2052 * @param oSelf {Object} The LogReader instance. 2053 * @private 2054 */ 2055 _onClickPauseBtn : function(v, oSelf) { 2056 if(!oSelf.isPaused) { 2057 oSelf.pause(); 2058 } 2059 else { 2060 oSelf.resume(); 2061 } 2062 }, 2063 2064 /** 2065 * Handles click events on the clear button. 2066 * 2067 * @method _onClickClearBtn 2068 * @param v {HTMLEvent} The click event. 2069 * @param oSelf {Object} The LogReader instance. 2070 * @private 2071 */ 2072 _onClickClearBtn : function(v, oSelf) { 2073 oSelf.clearConsole(); 2074 }, 2075 2076 /** 2077 * Handles Logger's newLogEvent. 2078 * 2079 * @method _onNewLog 2080 * @param sType {String} The event. 2081 * @param aArgs {Object[]} Data passed from event firer. 2082 * @param oSelf {Object} The LogReader instance. 2083 * @private 2084 */ 2085 _onNewLog : function(sType, aArgs, oSelf) { 2086 var logEntry = aArgs[0]; 2087 oSelf._buffer.push(logEntry); 2088 2089 if (oSelf.logReaderEnabled === true && oSelf._timeout === null) { 2090 oSelf._timeout = setTimeout(function(){oSelf._printBuffer();}, oSelf.outputBuffer); 2091 } 2092 }, 2093 2094 /** 2095 * Handles Logger's resetEvent. 2096 * 2097 * @method _onReset 2098 * @param sType {String} The event. 2099 * @param aArgs {Object[]} Data passed from event firer. 2100 * @param oSelf {Object} The LogReader instance. 2101 * @private 2102 */ 2103 _onReset : function(sType, aArgs, oSelf) { 2104 oSelf._filterLogs(); 2105 } 2106 }; 2107 2108 YAHOO.widget.LogReader = LogReader; 2109 2110 })(); 2111 YAHOO.register("logger", YAHOO.widget.Logger, {version: "2.9.0", build: "2800"}); 2112 2113 }, '2.9.0' ,{"requires": ["yui2-yahoo", "yui2-dom", "yui2-event", "yui2-skin-sam-logger"], "optional": ["yui2-dragdrop"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |