Version 3.18.1
Show:

File: console/js/console.js

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