[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/console/ -> console.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('console', function (Y, NAME) {
   9  
  10  /**
  11   * Console creates a visualization for messages logged through calls to a YUI
  12   * instance's <code>Y.log( message, category, source )</code> method.  The
  13   * debug versions of YUI modules will include logging statements to offer some
  14   * insight into the steps executed during that module's operation.  Including
  15   * log statements in your code will cause those messages to also appear in the
  16   * Console.  Use Console to aid in developing your page or application.
  17   *
  18   * Entry categories &quot;info&quot;, &quot;warn&quot;, and &quot;error&quot;
  19   * are also referred to as the log level, and entries are filtered against the
  20   * configured logLevel.
  21   *
  22   * @module console
  23   */
  24  var getCN = Y.ClassNameManager.getClassName,
  25      CHECKED        = 'checked',
  26      CLEAR          = 'clear',
  27      CLICK          = 'click',
  28      COLLAPSED      = 'collapsed',
  29      CONSOLE        = 'console',
  30      CONTENT_BOX    = 'contentBox',
  31      DISABLED       = 'disabled',
  32      ENTRY          = 'entry',
  33      ERROR          = 'error',
  34      HEIGHT         = 'height',
  35      INFO           = 'info',
  36      LAST_TIME      = 'lastTime',
  37      PAUSE          = 'pause',
  38      PAUSED         = 'paused',
  39      RESET          = 'reset',
  40      START_TIME     = 'startTime',
  41      TITLE          = 'title',
  42      WARN           = 'warn',
  43  
  44      DOT = '.',
  45  
  46      C_BUTTON           = getCN(CONSOLE,'button'),
  47      C_CHECKBOX         = getCN(CONSOLE,'checkbox'),
  48      C_CLEAR            = getCN(CONSOLE,CLEAR),
  49      C_COLLAPSE         = getCN(CONSOLE,'collapse'),
  50      C_COLLAPSED        = getCN(CONSOLE,COLLAPSED),
  51      C_CONSOLE_CONTROLS = getCN(CONSOLE,'controls'),
  52      C_CONSOLE_HD       = getCN(CONSOLE,'hd'),
  53      C_CONSOLE_BD       = getCN(CONSOLE,'bd'),
  54      C_CONSOLE_FT       = getCN(CONSOLE,'ft'),
  55      C_CONSOLE_TITLE    = getCN(CONSOLE,TITLE),
  56      C_ENTRY            = getCN(CONSOLE,ENTRY),
  57      C_ENTRY_CAT        = getCN(CONSOLE,ENTRY,'cat'),
  58      C_ENTRY_CONTENT    = getCN(CONSOLE,ENTRY,'content'),
  59      C_ENTRY_META       = getCN(CONSOLE,ENTRY,'meta'),
  60      C_ENTRY_SRC        = getCN(CONSOLE,ENTRY,'src'),
  61      C_ENTRY_TIME       = getCN(CONSOLE,ENTRY,'time'),
  62      C_PAUSE            = getCN(CONSOLE,PAUSE),
  63      C_PAUSE_LABEL      = getCN(CONSOLE,PAUSE,'label'),
  64  
  65      RE_INLINE_SOURCE = /^(\S+)\s/,
  66      RE_AMP = /&(?!#?[a-z0-9]+;)/g,
  67      RE_GT  = />/g,
  68      RE_LT  = /</g,
  69  
  70      ESC_AMP = '&#38;',
  71      ESC_GT  = '&#62;',
  72      ESC_LT  = '&#60;',
  73  
  74      ENTRY_TEMPLATE_STR =
  75          '<div class="{entry_class} {cat_class} {src_class}">'+
  76              '<p class="{entry_meta_class}">'+
  77                  '<span class="{entry_src_class}">'+
  78                      '{sourceAndDetail}'+
  79                  '</span>'+
  80                  '<span class="{entry_cat_class}">'+
  81                      '{category}</span>'+
  82                  '<span class="{entry_time_class}">'+
  83                      ' {totalTime}ms (+{elapsedTime}) {localTime}'+
  84                  '</span>'+
  85              '</p>'+
  86              '<pre class="{entry_content_class}">{message}</pre>'+
  87          '</div>',
  88  
  89      L = Y.Lang,
  90      create     = Y.Node.create,
  91      isNumber   = L.isNumber,
  92      isString   = L.isString,
  93      merge      = Y.merge,
  94      substitute = Y.Lang.sub;
  95  
  96  /**
  97  A basic console that displays messages logged throughout your application.
  98  
  99  @class Console
 100  @constructor
 101  @extends Widget
 102  @param [config] {Object} Object literal specifying widget configuration properties.
 103  **/
 104  function Console() {
 105      Console.superclass.constructor.apply(this,arguments);
 106  }
 107  
 108  Y.Console = Y.extend(Console, Y.Widget,
 109  
 110  // Y.Console prototype
 111  {
 112      /**
 113       * Category to prefix all event subscriptions to allow for ease of detach
 114       * during destroy.
 115       *
 116       * @property _evtCat
 117       * @type string
 118       * @protected
 119       */
 120      _evtCat : null,
 121  
 122      /**
 123       * Reference to the Node instance containing the header contents.
 124       *
 125       * @property _head
 126       * @type Node
 127       * @default null
 128       * @protected
 129       */
 130      _head    : null,
 131  
 132      /**
 133       * Reference to the Node instance that will house the console messages.
 134       *
 135       * @property _body
 136       * @type Node
 137       * @default null
 138       * @protected
 139       */
 140      _body    : null,
 141  
 142      /**
 143       * Reference to the Node instance containing the footer contents.
 144       *
 145       * @property _foot
 146       * @type Node
 147       * @default null
 148       * @protected
 149       */
 150      _foot    : null,
 151  
 152      /**
 153       * Holds the object API returned from <code>Y.later</code> for the print
 154       * loop interval.
 155       *
 156       * @property _printLoop
 157       * @type Object
 158       * @default null
 159       * @protected
 160       */
 161      _printLoop : null,
 162  
 163      /**
 164       * Array of normalized message objects awaiting printing.
 165       *
 166       * @property buffer
 167       * @type Array
 168       * @default null
 169       * @protected
 170       */
 171      buffer   : null,
 172  
 173      /**
 174       * Wrapper for <code>Y.log</code>.
 175       *
 176       * @method log
 177       * @param arg* {MIXED} (all arguments passed through to <code>Y.log</code>)
 178       * @chainable
 179       */
 180      log : function () {
 181          Y.log.apply(Y,arguments);
 182  
 183          return this;
 184      },
 185  
 186      /**
 187       * Clear the console of messages and flush the buffer of pending messages.
 188       *
 189       * @method clearConsole
 190       * @chainable
 191       */
 192      clearConsole : function () {
 193          // TODO: clear event listeners from console contents
 194          this._body.empty();
 195  
 196          this._cancelPrintLoop();
 197  
 198          this.buffer = [];
 199  
 200          return this;
 201      },
 202  
 203      /**
 204       * Clears the console and resets internal timers.
 205       *
 206       * @method reset
 207       * @chainable
 208       */
 209      reset : function () {
 210          this.fire(RESET);
 211  
 212          return this;
 213      },
 214  
 215      /**
 216       * Collapses the body and footer.
 217       *
 218       * @method collapse
 219       * @chainable
 220       */
 221      collapse : function () {
 222          this.set(COLLAPSED, true);
 223  
 224          return this;
 225      },
 226  
 227      /**
 228       * Expands the body and footer if collapsed.
 229       *
 230       * @method expand
 231       * @chainable
 232       */
 233      expand : function () {
 234          this.set(COLLAPSED, false);
 235  
 236          return this;
 237      },
 238  
 239      /**
 240       * Outputs buffered messages to the console UI.  This is typically called
 241       * from a scheduled interval until the buffer is empty (referred to as the
 242       * print loop).  The number of buffered messages output to the Console is
 243       * limited to the number provided as an argument.  If no limit is passed,
 244       * all buffered messages are rendered.
 245       *
 246       * @method printBuffer
 247       * @param limit {Number} (optional) max number of buffered entries to write
 248       * @chainable
 249       */
 250      printBuffer: function (limit) {
 251          var messages    = this.buffer,
 252              debug       = Y.config.debug,
 253              entries     = [],
 254              consoleLimit= this.get('consoleLimit'),
 255              newestOnTop = this.get('newestOnTop'),
 256              anchor      = newestOnTop ? this._body.get('firstChild') : null,
 257              i;
 258  
 259          if (messages.length > consoleLimit) {
 260              messages.splice(0, messages.length - consoleLimit);
 261          }
 262  
 263          limit = Math.min(messages.length, (limit || messages.length));
 264  
 265          // turn off logging system
 266          Y.config.debug = false;
 267  
 268          if (!this.get(PAUSED) && this.get('rendered')) {
 269  
 270              for (i = 0; i < limit && messages.length; ++i) {
 271                  entries[i] = this._createEntryHTML(messages.shift());
 272              }
 273  
 274              if (!messages.length) {
 275                  this._cancelPrintLoop();
 276              }
 277  
 278              if (entries.length) {
 279                  if (newestOnTop) {
 280                      entries.reverse();
 281                  }
 282  
 283                  this._body.insertBefore(create(entries.join('')), anchor);
 284  
 285                  if (this.get('scrollIntoView')) {
 286                      this.scrollToLatest();
 287                  }
 288  
 289                  this._trimOldEntries();
 290              }
 291          }
 292  
 293          // restore logging system
 294          Y.config.debug = debug;
 295  
 296          return this;
 297      },
 298  
 299  
 300      /**
 301       * Constructor code.  Set up the buffer and entry template, publish
 302       * internal events, and subscribe to the configured logEvent.
 303       *
 304       * @method initializer
 305       * @protected
 306       */
 307      initializer : function () {
 308          this._evtCat = Y.stamp(this) + '|';
 309  
 310          this.buffer = [];
 311  
 312          this.get('logSource').on(this._evtCat +
 313              this.get('logEvent'),Y.bind("_onLogEvent",this));
 314  
 315          /**
 316           * Transfers a received message to the print loop buffer.  Default
 317           * behavior defined in _defEntryFn.
 318           *
 319           * @event entry
 320           * @param event {EventFacade} An Event Facade object with the following attribute specific properties added:
 321           *  <dl>
 322           *      <dt>message</dt>
 323           *          <dd>The message data normalized into an object literal (see _normalizeMessage)</dd>
 324           *  </dl>
 325           * @preventable _defEntryFn
 326           */
 327          this.publish(ENTRY, { defaultFn: this._defEntryFn });
 328  
 329          /**
 330           * Triggers the reset behavior via the default logic in _defResetFn.
 331           *
 332           * @event reset
 333           * @param event {EventFacade} Event Facade object
 334           * @preventable _defResetFn
 335           */
 336          this.publish(RESET, { defaultFn: this._defResetFn });
 337  
 338          this.after('rendered', this._schedulePrint);
 339      },
 340  
 341      /**
 342       * Tears down the instance, flushing event subscriptions and purging the UI.
 343       *
 344       * @method destructor
 345       * @protected
 346       */
 347      destructor : function () {
 348          var bb = this.get('boundingBox');
 349  
 350          this._cancelPrintLoop();
 351  
 352          this.get('logSource').detach(this._evtCat + '*');
 353  
 354          bb.purge(true);
 355      },
 356  
 357      /**
 358       * Generate the Console UI.
 359       *
 360       * @method renderUI
 361       * @protected
 362       */
 363      renderUI : function () {
 364          this._initHead();
 365          this._initBody();
 366          this._initFoot();
 367  
 368          // Apply positioning to the bounding box if appropriate
 369          var style = this.get('style');
 370          if (style !== 'block') {
 371              this.get('boundingBox').addClass(this.getClassName(style));
 372          }
 373      },
 374  
 375      /**
 376       * Sync the UI state to the current attribute state.
 377       *
 378       * @method syncUI
 379       */
 380      syncUI : function () {
 381          this._uiUpdatePaused(this.get(PAUSED));
 382          this._uiUpdateCollapsed(this.get(COLLAPSED));
 383          this._uiSetHeight(this.get(HEIGHT));
 384      },
 385  
 386      /**
 387       * Set up event listeners to wire up the UI to the internal state.
 388       *
 389       * @method bindUI
 390       * @protected
 391       */
 392      bindUI : function () {
 393          this.get(CONTENT_BOX).one('button.'+C_COLLAPSE).
 394              on(CLICK,this._onCollapseClick,this);
 395  
 396          this.get(CONTENT_BOX).one('input[type=checkbox].'+C_PAUSE).
 397              on(CLICK,this._onPauseClick,this);
 398  
 399          this.get(CONTENT_BOX).one('button.'+C_CLEAR).
 400              on(CLICK,this._onClearClick,this);
 401  
 402          // Attribute changes
 403          this.after(this._evtCat + 'stringsChange',
 404              this._afterStringsChange);
 405          this.after(this._evtCat + 'pausedChange',
 406              this._afterPausedChange);
 407          this.after(this._evtCat + 'consoleLimitChange',
 408              this._afterConsoleLimitChange);
 409          this.after(this._evtCat + 'collapsedChange',
 410              this._afterCollapsedChange);
 411      },
 412  
 413  
 414      /**
 415       * Create the DOM structure for the header elements.
 416       *
 417       * @method _initHead
 418       * @protected
 419       */
 420      _initHead : function () {
 421          var cb   = this.get(CONTENT_BOX),
 422              info = merge(Console.CHROME_CLASSES, {
 423                          str_collapse : this.get('strings.collapse'),
 424                          str_title : this.get('strings.title')
 425                      });
 426  
 427          this._head = create(substitute(Console.HEADER_TEMPLATE,info));
 428  
 429          cb.insertBefore(this._head,cb.get('firstChild'));
 430      },
 431  
 432      /**
 433       * Create the DOM structure for the console body&#8212;where messages are
 434       * rendered.
 435       *
 436       * @method _initBody
 437       * @protected
 438       */
 439      _initBody : function () {
 440          this._body = create(substitute(
 441                              Console.BODY_TEMPLATE,
 442                              Console.CHROME_CLASSES));
 443  
 444          this.get(CONTENT_BOX).appendChild(this._body);
 445      },
 446  
 447      /**
 448       * Create the DOM structure for the footer elements.
 449       *
 450       * @method _initFoot
 451       * @protected
 452       */
 453      _initFoot : function () {
 454          var info = merge(Console.CHROME_CLASSES, {
 455                  id_guid   : Y.guid(),
 456                  str_pause : this.get('strings.pause'),
 457                  str_clear : this.get('strings.clear')
 458              });
 459  
 460          this._foot = create(substitute(Console.FOOTER_TEMPLATE,info));
 461  
 462          this.get(CONTENT_BOX).appendChild(this._foot);
 463      },
 464  
 465      /**
 466       * Determine if incoming log messages are within the configured logLevel
 467       * to be buffered for printing.
 468       *
 469       * @method _isInLogLevel
 470       * @protected
 471       */
 472      _isInLogLevel : function (e) {
 473          var cat = e.cat, lvl = this.get('logLevel');
 474  
 475          if (lvl !== INFO) {
 476              cat = cat || INFO;
 477  
 478              if (isString(cat)) {
 479                  cat = cat.toLowerCase();
 480              }
 481  
 482              if ((cat === WARN && lvl === ERROR) ||
 483                  (cat === INFO && lvl !== INFO)) {
 484                  return false;
 485              }
 486          }
 487  
 488          return true;
 489      },
 490  
 491      /**
 492       * Create a log entry message from the inputs including the following keys:
 493       * <ul>
 494       *     <li>time - this moment</li>
 495       *     <li>message - leg message</li>
 496       *     <li>category - logLevel or custom category for the message</li>
 497       *     <li>source - when provided, the widget or util calling Y.log</li>
 498       *     <li>sourceAndDetail - same as source but can include instance info</li>
 499       *     <li>localTime - readable version of time</li>
 500       *     <li>elapsedTime - ms since last entry</li>
 501       *     <li>totalTime - ms since Console was instantiated or reset</li>
 502       * </ul>
 503       *
 504       * @method _normalizeMessage
 505       * @param e {Event} custom event containing the log message
 506       * @return Object the message object
 507       * @protected
 508       */
 509      _normalizeMessage : function (e) {
 510  
 511          var msg = e.msg,
 512              cat = e.cat,
 513              src = e.src,
 514  
 515              m = {
 516                  time            : new Date(),
 517                  message         : msg,
 518                  category        : cat || this.get('defaultCategory'),
 519                  sourceAndDetail : src || this.get('defaultSource'),
 520                  source          : null,
 521                  localTime       : null,
 522                  elapsedTime     : null,
 523                  totalTime       : null
 524              };
 525  
 526          // Extract m.source "Foo" from m.sourceAndDetail "Foo bar baz"
 527          m.source          = RE_INLINE_SOURCE.test(m.sourceAndDetail) ?
 528                                  RegExp.$1 : m.sourceAndDetail;
 529          m.localTime       = m.time.toLocaleTimeString ?
 530                              m.time.toLocaleTimeString() : (m.time + '');
 531          m.elapsedTime     = m.time - this.get(LAST_TIME);
 532          m.totalTime       = m.time - this.get(START_TIME);
 533  
 534          this._set(LAST_TIME,m.time);
 535  
 536          return m;
 537      },
 538  
 539      /**
 540       * Sets an interval for buffered messages to be output to the console.
 541       *
 542       * @method _schedulePrint
 543       * @protected
 544       */
 545      _schedulePrint : function () {
 546          if (!this._printLoop && !this.get(PAUSED) && this.get('rendered')) {
 547              this._printLoop = Y.later(
 548                                  this.get('printTimeout'),
 549                                  this, this.printBuffer,
 550                                  this.get('printLimit'), true);
 551          }
 552      },
 553  
 554      /**
 555       * Translates message meta into the markup for a console entry.
 556       *
 557       * @method _createEntryHTML
 558       * @param m {Object} object literal containing normalized message metadata
 559       * @return String
 560       * @protected
 561       */
 562      _createEntryHTML : function (m) {
 563          m = merge(
 564                  this._htmlEscapeMessage(m),
 565                  Console.ENTRY_CLASSES,
 566                  {
 567                      cat_class : this.getClassName(ENTRY,m.category),
 568                      src_class : this.getClassName(ENTRY,m.source)
 569                  });
 570  
 571          return this.get('entryTemplate').replace(/\{(\w+)\}/g,
 572              function (_,token) {
 573                  return token in m ? m[token] : '';
 574              });
 575      },
 576  
 577      /**
 578       * Scrolls to the most recent entry
 579       *
 580       * @method scrollToLatest
 581       * @chainable
 582       */
 583      scrollToLatest : function () {
 584          var scrollTop = this.get('newestOnTop') ?
 585                              0 :
 586                              this._body.get('scrollHeight');
 587  
 588          this._body.set('scrollTop', scrollTop);
 589      },
 590  
 591      /**
 592       * Performs HTML escaping on strings in the message object.
 593       *
 594       * @method _htmlEscapeMessage
 595       * @param m {Object} the normalized message object
 596       * @return Object the message object with proper escapement
 597       * @protected
 598       */
 599      _htmlEscapeMessage : function (m) {
 600          m.message         = this._encodeHTML(m.message);
 601          m.source          = this._encodeHTML(m.source);
 602          m.sourceAndDetail = this._encodeHTML(m.sourceAndDetail);
 603          m.category        = this._encodeHTML(m.category);
 604  
 605          return m;
 606      },
 607  
 608      /**
 609       * Removes the oldest message entries from the UI to maintain the limit
 610       * specified in the consoleLimit configuration.
 611       *
 612       * @method _trimOldEntries
 613       * @protected
 614       */
 615      _trimOldEntries : function () {
 616          // Turn off the logging system for the duration of this operation
 617          // to prevent an infinite loop
 618          Y.config.debug = false;
 619  
 620          var bd = this._body,
 621              limit = this.get('consoleLimit'),
 622              debug = Y.config.debug,
 623              entries,e,i,l;
 624  
 625          if (bd) {
 626              entries = bd.all(DOT+C_ENTRY);
 627              l = entries.size() - limit;
 628  
 629              if (l > 0) {
 630                  if (this.get('newestOnTop')) {
 631                      i = limit;
 632                      l = entries.size();
 633                  } else {
 634                      i = 0;
 635                  }
 636  
 637                  this._body.setStyle('display','none');
 638  
 639                  for (;i < l; ++i) {
 640                      e = entries.item(i);
 641                      if (e) {
 642                          e.remove();
 643                      }
 644                  }
 645  
 646                  this._body.setStyle('display','');
 647              }
 648  
 649          }
 650  
 651          Y.config.debug = debug;
 652      },
 653  
 654      /**
 655       * Returns the input string with ampersands (&amp;), &lt, and &gt; encoded
 656       * as HTML entities.
 657       *
 658       * @method _encodeHTML
 659       * @param s {String} the raw string
 660       * @return String the encoded string
 661       * @protected
 662       */
 663      _encodeHTML : function (s) {
 664          return isString(s) ?
 665              s.replace(RE_AMP,ESC_AMP).
 666                replace(RE_LT, ESC_LT).
 667                replace(RE_GT, ESC_GT) :
 668              s;
 669      },
 670  
 671      /**
 672       * Clears the timeout for printing buffered messages.
 673       *
 674       * @method _cancelPrintLoop
 675       * @protected
 676       */
 677      _cancelPrintLoop : function () {
 678          if (this._printLoop) {
 679              this._printLoop.cancel();
 680              this._printLoop = null;
 681          }
 682      },
 683  
 684      /**
 685       * Validates input value for style attribute.  Accepts only values 'inline',
 686       * 'block', and 'separate'.
 687       *
 688       * @method _validateStyle
 689       * @param style {String} the proposed value
 690       * @return {Boolean} pass/fail
 691       * @protected
 692       */
 693      _validateStyle : function (style) {
 694          return style === 'inline' || style === 'block' || style === 'separate';
 695      },
 696  
 697      /**
 698       * Event handler for clicking on the Pause checkbox to update the paused
 699       * attribute.
 700       *
 701       * @method _onPauseClick
 702       * @param e {Event} DOM event facade for the click event
 703       * @protected
 704       */
 705      _onPauseClick : function (e) {
 706          this.set(PAUSED,e.target.get(CHECKED));
 707      },
 708  
 709      /**
 710       * Event handler for clicking on the Clear button.  Pass-through to
 711       * <code>this.clearConsole()</code>.
 712       *
 713       * @method _onClearClick
 714       * @param e {Event} DOM event facade for the click event
 715       * @protected
 716       */
 717      _onClearClick : function (e) {
 718          this.clearConsole();
 719      },
 720  
 721      /**
 722       * Event handler for clicking on the Collapse/Expand button. Sets the
 723       * &quot;collapsed&quot; attribute accordingly.
 724       *
 725       * @method _onCollapseClick
 726       * @param e {Event} DOM event facade for the click event
 727       * @protected
 728       */
 729      _onCollapseClick : function (e) {
 730          this.set(COLLAPSED, !this.get(COLLAPSED));
 731      },
 732  
 733  
 734      /**
 735       * Validator for logSource attribute.
 736       *
 737       * @method _validateLogSource
 738       * @param v {Object} the desired logSource
 739       * @return {Boolean} true if the input is an object with an <code>on</code>
 740       *                   method
 741       * @protected
 742       */
 743      _validateLogSource: function (v) {
 744          return v && Y.Lang.isFunction(v.on);
 745      },
 746  
 747      /**
 748       * Setter method for logLevel attribute.  Acceptable values are
 749       * &quot;error&quot, &quot;warn&quot, and &quot;info&quot (case
 750       * insensitive).  Other values are treated as &quot;info&quot;.
 751       *
 752       * @method _setLogLevel
 753       * @param v {String} the desired log level
 754       * @return String One of Console.LOG_LEVEL_INFO, _WARN, or _ERROR
 755       * @protected
 756       */
 757      _setLogLevel : function (v) {
 758          if (isString(v)) {
 759              v = v.toLowerCase();
 760          }
 761  
 762          return (v === WARN || v === ERROR) ? v : INFO;
 763      },
 764  
 765      /**
 766       * Getter method for useBrowserConsole attribute.  Just a pass through to
 767       * the YUI instance configuration setting.
 768       *
 769       * @method _getUseBrowserConsole
 770       * @return {Boolean} or null if logSource is not a YUI instance
 771       * @protected
 772       */
 773      _getUseBrowserConsole: function () {
 774          var logSource = this.get('logSource');
 775          return logSource instanceof YUI ?
 776              logSource.config.useBrowserConsole : null;
 777      },
 778  
 779      /**
 780       * Setter method for useBrowserConsole attributes.  Only functional if the
 781       * logSource attribute points to a YUI instance.  Passes the value down to
 782       * the YUI instance.  NOTE: multiple Console instances cannot maintain
 783       * independent useBrowserConsole values, since it is just a pass through to
 784       * the YUI instance configuration.
 785       *
 786       * @method _setUseBrowserConsole
 787       * @param v {Boolean} false to disable browser console printing (default)
 788       * @return {Boolean} true|false if logSource is a YUI instance
 789       * @protected
 790       */
 791      _setUseBrowserConsole: function (v) {
 792          var logSource = this.get('logSource');
 793          if (logSource instanceof YUI) {
 794              v = !!v;
 795              logSource.config.useBrowserConsole = v;
 796              return v;
 797          } else {
 798              return Y.Attribute.INVALID_VALUE;
 799          }
 800      },
 801  
 802      /**
 803       * Set the height of the Console container.  Set the body height to the
 804       * difference between the configured height and the calculated heights of
 805       * the header and footer.
 806       * Overrides Widget.prototype._uiSetHeight.
 807       *
 808       * @method _uiSetHeight
 809       * @param v {String|Number} the new height
 810       * @protected
 811       */
 812      _uiSetHeight : function (v) {
 813          Console.superclass._uiSetHeight.apply(this,arguments);
 814  
 815          if (this._head && this._foot) {
 816              var h = this.get('boundingBox').get('offsetHeight') -
 817                      this._head.get('offsetHeight') -
 818                      this._foot.get('offsetHeight');
 819  
 820              this._body.setStyle(HEIGHT,h+'px');
 821          }
 822      },
 823  
 824      /**
 825       * Over-ride default content box sizing to do nothing, since we're sizing
 826       * the body section to fill out height ourselves.
 827       *
 828       * @method _uiSizeCB
 829       * @protected
 830       */
 831      _uiSizeCB : function() {
 832          // Do Nothing. Ideally want to move to Widget-StdMod, which accounts for
 833          // _uiSizeCB
 834      },
 835  
 836      /**
 837       * Updates the UI if changes are made to any of the strings in the strings
 838       * attribute.
 839       *
 840       * @method _afterStringsChange
 841       * @param e {Event} Custom event for the attribute change
 842       * @protected
 843       */
 844      _afterStringsChange : function (e) {
 845          var prop   = e.subAttrName ? e.subAttrName.split(DOT)[1] : null,
 846              cb     = this.get(CONTENT_BOX),
 847              before = e.prevVal,
 848              after  = e.newVal;
 849  
 850          if ((!prop || prop === TITLE) && before.title !== after.title) {
 851              cb.all(DOT+C_CONSOLE_TITLE).setHTML(after.title);
 852          }
 853  
 854          if ((!prop || prop === PAUSE) && before.pause !== after.pause) {
 855              cb.all(DOT+C_PAUSE_LABEL).setHTML(after.pause);
 856          }
 857  
 858          if ((!prop || prop === CLEAR) && before.clear !== after.clear) {
 859              cb.all(DOT+C_CLEAR).set('value',after.clear);
 860          }
 861      },
 862  
 863      /**
 864       * Updates the UI and schedules or cancels the print loop.
 865       *
 866       * @method _afterPausedChange
 867       * @param e {Event} Custom event for the attribute change
 868       * @protected
 869       */
 870      _afterPausedChange : function (e) {
 871          var paused = e.newVal;
 872  
 873          if (e.src !== Y.Widget.SRC_UI) {
 874              this._uiUpdatePaused(paused);
 875          }
 876  
 877          if (!paused) {
 878              this._schedulePrint();
 879          } else if (this._printLoop) {
 880              this._cancelPrintLoop();
 881          }
 882      },
 883  
 884      /**
 885       * Checks or unchecks the paused checkbox
 886       *
 887       * @method _uiUpdatePaused
 888       * @param on {Boolean} the new checked state
 889       * @protected
 890       */
 891      _uiUpdatePaused : function (on) {
 892          var node = this._foot.all('input[type=checkbox].'+C_PAUSE);
 893  
 894          if (node) {
 895              node.set(CHECKED,on);
 896          }
 897      },
 898  
 899      /**
 900       * Calls this._trimOldEntries() in response to changes in the configured
 901       * consoleLimit attribute.
 902       *
 903       * @method _afterConsoleLimitChange
 904       * @param e {Event} Custom event for the attribute change
 905       * @protected
 906       */
 907      _afterConsoleLimitChange : function () {
 908          this._trimOldEntries();
 909      },
 910  
 911  
 912      /**
 913       * Updates the className of the contentBox, which should trigger CSS to
 914       * hide or show the body and footer sections depending on the new value.
 915       *
 916       * @method _afterCollapsedChange
 917       * @param e {Event} Custom event for the attribute change
 918       * @protected
 919       */
 920      _afterCollapsedChange : function (e) {
 921          this._uiUpdateCollapsed(e.newVal);
 922      },
 923  
 924      /**
 925       * Updates the UI to reflect the new Collapsed state
 926       *
 927       * @method _uiUpdateCollapsed
 928       * @param v {Boolean} true for collapsed, false for expanded
 929       * @protected
 930       */
 931      _uiUpdateCollapsed : function (v) {
 932          var bb     = this.get('boundingBox'),
 933              button = bb.all('button.'+C_COLLAPSE),
 934              method = v ? 'addClass' : 'removeClass',
 935              str    = this.get('strings.'+(v ? 'expand' : 'collapse'));
 936  
 937          bb[method](C_COLLAPSED);
 938  
 939          if (button) {
 940              button.setHTML(str);
 941          }
 942  
 943          this._uiSetHeight(v ? this._head.get('offsetHeight'): this.get(HEIGHT));
 944      },
 945  
 946      /**
 947       * Makes adjustments to the UI if needed when the Console is hidden or shown
 948       *
 949       * @method _afterVisibleChange
 950       * @param e {Event} the visibleChange event
 951       * @protected
 952       */
 953      _afterVisibleChange : function (e) {
 954          Console.superclass._afterVisibleChange.apply(this,arguments);
 955  
 956          this._uiUpdateFromHideShow(e.newVal);
 957      },
 958  
 959      /**
 960       * Recalculates dimensions and updates appropriately when shown
 961       *
 962       * @method _uiUpdateFromHideShow
 963       * @param v {Boolean} true for visible, false for hidden
 964       * @protected
 965       */
 966      _uiUpdateFromHideShow : function (v) {
 967          if (v) {
 968              this._uiSetHeight(this.get(HEIGHT));
 969          }
 970      },
 971  
 972      /**
 973       * Responds to log events by normalizing qualifying messages and passing
 974       * them along through the entry event for buffering etc.
 975       *
 976       * @method _onLogEvent
 977       * @param msg {String} the log message
 978       * @param cat {String} OPTIONAL the category or logLevel of the message
 979       * @param src {String} OPTIONAL the source of the message (e.g. widget name)
 980       * @protected
 981       */
 982      _onLogEvent : function (e) {
 983  
 984          if (!this.get(DISABLED) && this._isInLogLevel(e)) {
 985  
 986              var debug = Y.config.debug;
 987  
 988              /* TODO: needed? */
 989              Y.config.debug = false;
 990  
 991              this.fire(ENTRY, {
 992                  message : this._normalizeMessage(e)
 993              });
 994  
 995              Y.config.debug = debug;
 996          }
 997      },
 998  
 999      /**
1000       * Clears the console, resets the startTime attribute, enables and
1001       * unpauses the widget.
1002       *
1003       * @method _defResetFn
1004       * @protected
1005       */
1006      _defResetFn : function () {
1007          this.clearConsole();
1008          this.set(START_TIME,new Date());
1009          this.set(DISABLED,false);
1010          this.set(PAUSED,false);
1011      },
1012  
1013      /**
1014       * Buffers incoming message objects and schedules the printing.
1015       *
1016       * @method _defEntryFn
1017       * @param e {Event} The Custom event carrying the message in its payload
1018       * @protected
1019       */
1020      _defEntryFn : function (e) {
1021          if (e.message) {
1022              this.buffer.push(e.message);
1023              this._schedulePrint();
1024          }
1025      }
1026  
1027  },
1028  
1029  // Y.Console static properties
1030  {
1031      /**
1032       * The identity of the widget.
1033       *
1034       * @property NAME
1035       * @type String
1036       * @static
1037       */
1038      NAME : CONSOLE,
1039  
1040      /**
1041       * Static identifier for logLevel configuration setting to allow all
1042       * incoming messages to generate Console entries.
1043       *
1044       * @property LOG_LEVEL_INFO
1045       * @type String
1046       * @static
1047       */
1048      LOG_LEVEL_INFO  : INFO,
1049  
1050      /**
1051       * Static identifier for logLevel configuration setting to allow only
1052       * incoming messages of logLevel &quot;warn&quot; or &quot;error&quot;
1053       * to generate Console entries.
1054       *
1055       * @property LOG_LEVEL_WARN
1056       * @type String
1057       * @static
1058       */
1059      LOG_LEVEL_WARN  : WARN,
1060  
1061      /**
1062       * Static identifier for logLevel configuration setting to allow only
1063       * incoming messages of logLevel &quot;error&quot; to generate
1064       * Console entries.
1065       *
1066       * @property LOG_LEVEL_ERROR
1067       * @type String
1068       * @static
1069       */
1070      LOG_LEVEL_ERROR : ERROR,
1071  
1072      /**
1073       * Map (object) of classNames used to populate the placeholders in the
1074       * Console.ENTRY_TEMPLATE markup when rendering a new Console entry.
1075       *
1076       * <p>By default, the keys contained in the object are:</p>
1077       * <ul>
1078       *    <li>entry_class</li>
1079       *    <li>entry_meta_class</li>
1080       *    <li>entry_cat_class</li>
1081       *    <li>entry_src_class</li>
1082       *    <li>entry_time_class</li>
1083       *    <li>entry_content_class</li>
1084       * </ul>
1085       *
1086       * @property ENTRY_CLASSES
1087       * @type Object
1088       * @static
1089       */
1090      ENTRY_CLASSES   : {
1091          entry_class         : C_ENTRY,
1092          entry_meta_class    : C_ENTRY_META,
1093          entry_cat_class     : C_ENTRY_CAT,
1094          entry_src_class     : C_ENTRY_SRC,
1095          entry_time_class    : C_ENTRY_TIME,
1096          entry_content_class : C_ENTRY_CONTENT
1097      },
1098  
1099      /**
1100       * Map (object) of classNames used to populate the placeholders in the
1101       * Console.HEADER_TEMPLATE, Console.BODY_TEMPLATE, and
1102       * Console.FOOTER_TEMPLATE markup when rendering the Console UI.
1103       *
1104       * <p>By default, the keys contained in the object are:</p>
1105       * <ul>
1106       *   <li>console_hd_class</li>
1107       *   <li>console_bd_class</li>
1108       *   <li>console_ft_class</li>
1109       *   <li>console_controls_class</li>
1110       *   <li>console_checkbox_class</li>
1111       *   <li>console_pause_class</li>
1112       *   <li>console_pause_label_class</li>
1113       *   <li>console_button_class</li>
1114       *   <li>console_clear_class</li>
1115       *   <li>console_collapse_class</li>
1116       *   <li>console_title_class</li>
1117       * </ul>
1118       *
1119       * @property CHROME_CLASSES
1120       * @type Object
1121       * @static
1122       */
1123      CHROME_CLASSES  : {
1124          console_hd_class       : C_CONSOLE_HD,
1125          console_bd_class       : C_CONSOLE_BD,
1126          console_ft_class       : C_CONSOLE_FT,
1127          console_controls_class : C_CONSOLE_CONTROLS,
1128          console_checkbox_class : C_CHECKBOX,
1129          console_pause_class    : C_PAUSE,
1130          console_pause_label_class : C_PAUSE_LABEL,
1131          console_button_class   : C_BUTTON,
1132          console_clear_class    : C_CLEAR,
1133          console_collapse_class : C_COLLAPSE,
1134          console_title_class    : C_CONSOLE_TITLE
1135      },
1136  
1137      /**
1138       * Markup template used to generate the DOM structure for the header
1139       * section of the Console when it is rendered.  The template includes
1140       * these {placeholder}s:
1141       *
1142       * <ul>
1143       *   <li>console_button_class - contributed by Console.CHROME_CLASSES</li>
1144       *   <li>console_collapse_class - contributed by Console.CHROME_CLASSES</li>
1145       *   <li>console_hd_class - contributed by Console.CHROME_CLASSES</li>
1146       *   <li>console_title_class - contributed by Console.CHROME_CLASSES</li>
1147       *   <li>str_collapse - pulled from attribute strings.collapse</li>
1148       *   <li>str_title - pulled from attribute strings.title</li>
1149       * </ul>
1150       *
1151       * @property HEADER_TEMPLATE
1152       * @type String
1153       * @static
1154       */
1155      HEADER_TEMPLATE :
1156          '<div class="{console_hd_class}">'+
1157              '<h4 class="{console_title_class}">{str_title}</h4>'+
1158              '<button type="button" class="'+
1159                  '{console_button_class} {console_collapse_class}">{str_collapse}'+
1160              '</button>'+
1161          '</div>',
1162  
1163      /**
1164       * Markup template used to generate the DOM structure for the Console body
1165       * (where the messages are inserted) when it is rendered.  The template
1166       * includes only the {placeholder} &quot;console_bd_class&quot;, which is
1167       * constributed by Console.CHROME_CLASSES.
1168       *
1169       * @property BODY_TEMPLATE
1170       * @type String
1171       * @static
1172       */
1173      BODY_TEMPLATE : '<div class="{console_bd_class}"></div>',
1174  
1175      /**
1176       * Markup template used to generate the DOM structure for the footer
1177       * section of the Console when it is rendered.  The template includes
1178       * many of the {placeholder}s from Console.CHROME_CLASSES as well as:
1179       *
1180       * <ul>
1181       *   <li>id_guid - generated unique id, relates the label and checkbox</li>
1182       *   <li>str_pause - pulled from attribute strings.pause</li>
1183       *   <li>str_clear - pulled from attribute strings.clear</li>
1184       * </ul>
1185       *
1186       * @property FOOTER_TEMPLATE
1187       * @type String
1188       * @static
1189       */
1190      FOOTER_TEMPLATE :
1191          '<div class="{console_ft_class}">'+
1192              '<div class="{console_controls_class}">'+
1193                  '<label class="{console_pause_label_class}"><input type="checkbox" class="{console_checkbox_class} {console_pause_class}" value="1" id="{id_guid}"> {str_pause}</label>' +
1194                  '<button type="button" class="'+
1195                      '{console_button_class} {console_clear_class}">{str_clear}'+
1196                  '</button>'+
1197              '</div>'+
1198          '</div>',
1199  
1200      /**
1201       * Default markup template used to create the DOM structure for Console
1202       * entries. The markup contains {placeholder}s for content and classes
1203       * that are replaced via Y.Lang.sub.  The default template contains
1204       * the {placeholder}s identified in Console.ENTRY_CLASSES as well as the
1205       * following placeholders that will be populated by the log entry data:
1206       *
1207       * <ul>
1208       *   <li>cat_class</li>
1209       *   <li>src_class</li>
1210       *   <li>totalTime</li>
1211       *   <li>elapsedTime</li>
1212       *   <li>localTime</li>
1213       *   <li>sourceAndDetail</li>
1214       *   <li>message</li>
1215       * </ul>
1216       *
1217       * @property ENTRY_TEMPLATE
1218       * @type String
1219       * @static
1220       */
1221      ENTRY_TEMPLATE : ENTRY_TEMPLATE_STR,
1222  
1223      /**
1224       * Static property used to define the default attribute configuration of
1225       * the Widget.
1226       *
1227       * @property ATTRS
1228       * @Type Object
1229       * @static
1230       */
1231      ATTRS : {
1232  
1233          /**
1234           * Name of the custom event that will communicate log messages.
1235           *
1236           * @attribute logEvent
1237           * @type String
1238           * @default "yui:log"
1239           */
1240          logEvent : {
1241              value : 'yui:log',
1242              writeOnce : true,
1243              validator : isString
1244          },
1245  
1246          /**
1247           * Object that will emit the log events.  By default the YUI instance.
1248           * To have a single Console capture events from all YUI instances, set
1249           * this to the Y.Global object.
1250           *
1251           * @attribute logSource
1252           * @type EventTarget
1253           * @default Y
1254           */
1255          logSource : {
1256              value : Y,
1257              writeOnce : true,
1258              validator : function (v) {
1259                  return this._validateLogSource(v);
1260              }
1261          },
1262  
1263          /**
1264           * Collection of strings used to label elements in the Console UI.
1265           * Default collection contains the following name:value pairs:
1266           *
1267           * <ul>
1268           *   <li>title : &quot;Log Console&quot;</li>
1269           *   <li>pause : &quot;Pause&quot;</li>
1270           *   <li>clear : &quot;Clear&quot;</li>
1271           *   <li>collapse : &quot;Collapse&quot;</li>
1272           *   <li>expand : &quot;Expand&quot;</li>
1273           * </ul>
1274           *
1275           * @attribute strings
1276           * @type Object
1277           */
1278          strings : {
1279              valueFn: function() { return Y.Intl.get("console"); }
1280          },
1281  
1282          /**
1283           * Boolean to pause the outputting of new messages to the console.
1284           * When paused, messages will accumulate in the buffer.
1285           *
1286           * @attribute paused
1287           * @type boolean
1288           * @default false
1289           */
1290          paused : {
1291              value : false,
1292              validator : L.isBoolean
1293          },
1294  
1295          /**
1296           * If a category is not specified in the Y.log(..) statement, this
1297           * category will be used. Categories &quot;info&quot;,
1298           * &quot;warn&quot;, and &quot;error&quot; are also called log level.
1299           *
1300           * @attribute defaultCategory
1301           * @type String
1302           * @default "info"
1303           */
1304          defaultCategory : {
1305              value : INFO,
1306              validator : isString
1307          },
1308  
1309          /**
1310           * If a source is not specified in the Y.log(..) statement, this
1311           * source will be used.
1312           *
1313           * @attribute defaultSource
1314           * @type String
1315           * @default "global"
1316           */
1317          defaultSource   : {
1318              value : 'global',
1319              validator : isString
1320          },
1321  
1322          /**
1323           * Markup template used to create the DOM structure for Console entries.
1324           *
1325           * @attribute entryTemplate
1326           * @type String
1327           * @default Console.ENTRY_TEMPLATE
1328           */
1329          entryTemplate : {
1330              value : ENTRY_TEMPLATE_STR,
1331              validator : isString
1332          },
1333  
1334          /**
1335           * Minimum entry log level to render into the Console.  The initial
1336           * logLevel value for all Console instances defaults from the
1337           * Y.config.logLevel YUI configuration, or Console.LOG_LEVEL_INFO if
1338           * that configuration is not set.
1339           *
1340           * Possible values are &quot;info&quot;, &quot;warn&quot;,
1341           * &quot;error&quot; (case insensitive), or their corresponding statics
1342           * Console.LOG_LEVEL_INFO and so on.
1343           *
1344           * @attribute logLevel
1345           * @type String
1346           * @default Y.config.logLevel or Console.LOG_LEVEL_INFO
1347           */
1348          logLevel : {
1349              value : Y.config.logLevel || INFO,
1350              setter : function (v) {
1351                  return this._setLogLevel(v);
1352              }
1353          },
1354  
1355          /**
1356           * Millisecond timeout between iterations of the print loop, moving
1357           * entries from the buffer to the UI.
1358           *
1359           * @attribute printTimeout
1360           * @type Number
1361           * @default 100
1362           */
1363          printTimeout : {
1364              value : 100,
1365              validator : isNumber
1366          },
1367  
1368          /**
1369           * Maximum number of entries printed in each iteration of the print
1370           * loop. This is used to prevent excessive logging locking the page UI.
1371           *
1372           * @attribute printLimit
1373           * @type Number
1374           * @default 50
1375           */
1376          printLimit : {
1377              value : 50,
1378              validator : isNumber
1379          },
1380  
1381          /**
1382           * Maximum number of Console entries allowed in the Console body at one
1383           * time.  This is used to keep acquired messages from exploding the
1384           * DOM tree and impacting page performance.
1385           *
1386           * @attribute consoleLimit
1387           * @type Number
1388           * @default 300
1389           */
1390          consoleLimit : {
1391              value : 300,
1392              validator : isNumber
1393          },
1394  
1395          /**
1396           * New entries should display at the top of the Console or the bottom?
1397           *
1398           * @attribute newestOnTop
1399           * @type Boolean
1400           * @default true
1401           */
1402          newestOnTop : {
1403              value : true
1404          },
1405  
1406          /**
1407           * When new entries are added to the Console UI, should they be
1408           * scrolled into view?
1409           *
1410           * @attribute scrollIntoView
1411           * @type Boolean
1412           * @default true
1413           */
1414          scrollIntoView : {
1415              value : true
1416          },
1417  
1418          /**
1419           * The baseline time for this Console instance, used to measure elapsed
1420           * time from the moment the console module is <code>use</code>d to the
1421           * moment each new entry is logged (not rendered).
1422           *
1423           * This value is reset by the instance method myConsole.reset().
1424           *
1425           * @attribute startTime
1426           * @type Date
1427           * @default The moment the console module is <code>use</code>d
1428           */
1429          startTime : {
1430              value : new Date()
1431          },
1432  
1433          /**
1434           * The precise time the last entry was logged.  Used to measure elapsed
1435           * time between log messages.
1436           *
1437           * @attribute lastTime
1438           * @type Date
1439           * @default The moment the console module is <code>use</code>d
1440           */
1441          lastTime : {
1442              value : new Date(),
1443              readOnly: true
1444          },
1445  
1446          /**
1447           * Controls the collapsed state of the Console
1448           *
1449           * @attribute collapsed
1450           * @type Boolean
1451           * @default false
1452           */
1453          collapsed : {
1454              value : false
1455          },
1456  
1457          /**
1458          * String with units, or number, representing the height of the Console,
1459          * inclusive of header and footer. If a number is provided, the default
1460          * unit, defined by Widget's DEF_UNIT, property is used.
1461          *
1462          * @attribute height
1463          * @default "300px"
1464          * @type {String | Number}
1465          */
1466          height: {
1467              value: "300px"
1468          },
1469  
1470          /**
1471          * String with units, or number, representing the width of the Console.
1472          * If a number is provided, the default unit, defined by Widget's
1473          * DEF_UNIT, property is used.
1474          *
1475          * @attribute width
1476          * @default "300px"
1477          * @type {String | Number}
1478          */
1479          width: {
1480              value: "300px"
1481          },
1482  
1483          /**
1484           * Pass through to the YUI instance useBrowserConsole configuration.
1485           * By default this is set to false, which will disable logging to the
1486           * browser console when a Console instance is created.  If the
1487           * logSource is not a YUI instance, this has no effect.
1488           *
1489           * @attribute useBrowserConsole
1490           * @type {Boolean}
1491           * @default false
1492           */
1493           useBrowserConsole : {
1494              lazyAdd: false,
1495              value: false,
1496              getter : function () {
1497                  return this._getUseBrowserConsole();
1498              },
1499              setter : function (v) {
1500                  return this._setUseBrowserConsole(v);
1501              }
1502           },
1503  
1504           /**
1505            * Allows the Console to flow in the document.  Available values are
1506            * 'inline', 'block', and 'separate' (the default).
1507            *
1508            * @attribute style
1509            * @type {String}
1510            * @default 'separate'
1511            */
1512           style : {
1513              value : 'separate',
1514              writeOnce : true,
1515              validator : function (v) {
1516                  return this._validateStyle(v);
1517              }
1518           }
1519      }
1520  
1521  });
1522  
1523  
1524  }, '3.17.2', {"requires": ["yui-log", "widget"], "skinnable": true, "lang": ["en", "es", "hu", "it", "ja"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1