UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

373 lines (297 loc) 10.3 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2008 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Sebastian Werner (wpbasti) ************************************************************************ */ /** * Feature-rich console appender for the qooxdoo logging system. * * Creates a small inline element which is placed in the top-right corner * of the window. Prints all messages with a nice color highlighting. * * * Allows user command inputs. * * Command history enabled by default (Keyboard up/down arrows). * * Lazy creation on first open. * * Clearing the console using a button. * * Display of offset (time after loading) of each message * * Supports keyboard shortcuts F7 or Ctrl+D to toggle the visibility * * Note this class must be disposed of after use * * @require(qx.event.handler.Window) * @require(qx.event.handler.Keyboard) * @require(qx.event.handler.Gesture) */ qx.Class.define("qx.log.appender.Console", { statics : { /* --------------------------------------------------------------------------- INITIALIZATION AND SHUTDOWN --------------------------------------------------------------------------- */ __main : null, __log : null, __cmd : null, __lastCommand : null, /** * Initializes the console, building HTML and pushing last * log messages to the output window. * */ init : function() { // Build style sheet content var style = [ '.qxconsole{z-index:10000;width:600px;height:300px;top:0px;right:0px;position:absolute;border-left:1px solid black;color:black;border-bottom:1px solid black;color:black;font-family:Consolas,Monaco,monospace;font-size:11px;line-height:1.2;}', '.qxconsole .control{background:#cdcdcd;border-bottom:1px solid black;padding:4px 8px;}', '.qxconsole .control a{text-decoration:none;color:black;}', '.qxconsole .messages{background:white;height:100%;width:100%;overflow:auto;}', '.qxconsole .messages div{padding:0px 4px;}', '.qxconsole .messages .user-command{color:blue}', '.qxconsole .messages .user-result{background:white}', '.qxconsole .messages .user-error{background:#FFE2D5}', '.qxconsole .messages .level-debug{background:white}', '.qxconsole .messages .level-info{background:#DEEDFA}', '.qxconsole .messages .level-warn{background:#FFF7D5}', '.qxconsole .messages .level-error{background:#FFE2D5}', '.qxconsole .messages .level-user{background:#E3EFE9}', '.qxconsole .messages .type-string{color:black;font-weight:normal;}', '.qxconsole .messages .type-number{color:#155791;font-weight:normal;}', '.qxconsole .messages .type-boolean{color:#15BC91;font-weight:normal;}', '.qxconsole .messages .type-array{color:#CC3E8A;font-weight:bold;}', '.qxconsole .messages .type-map{color:#CC3E8A;font-weight:bold;}', '.qxconsole .messages .type-key{color:#565656;font-style:italic}', '.qxconsole .messages .type-class{color:#5F3E8A;font-weight:bold}', '.qxconsole .messages .type-instance{color:#565656;font-weight:bold}', '.qxconsole .messages .type-stringify{color:#565656;font-weight:bold}', '.qxconsole .command{background:white;padding:2px 4px;border-top:1px solid black;}', '.qxconsole .command input{width:100%;border:0 none;font-family:Consolas,Monaco,monospace;font-size:11px;line-height:1.2;}', '.qxconsole .command input:focus{outline:none;}' ]; // Include stylesheet qx.bom.Stylesheet.createElement(style.join("")); // Build markup var markup = [ '<div class="qxconsole">', '<div class="control"><a href="javascript:qx.log.appender.Console.clear()">Clear</a> | <a href="javascript:qx.log.appender.Console.toggle()">Hide</a></div>', '<div class="messages">', '</div>', '<div class="command">', '<input type="text"/>', '</div>', '</div>' ]; // Insert HTML to access DOM node var wrapper = document.createElement("DIV"); wrapper.innerHTML = markup.join(""); var main = wrapper.firstChild; document.body.appendChild(wrapper.firstChild); // Make important DOM nodes available this.__main = main; this.__log = main.childNodes[1]; this.__cmd = main.childNodes[2].firstChild; // Correct height of messages frame this.__onResize(); // Finally register to log engine qx.log.Logger.register(this); // Register to object manager qx.core.ObjectRegistry.register(this); }, /** * Used by the object registry to dispose this instance e.g. remove listeners etc. * */ dispose : function() { qx.event.Registration.removeListener(document.documentElement, "keypress", this.__onKeyPress, this); qx.log.Logger.unregister(this); }, /* --------------------------------------------------------------------------- INSERT & CLEAR --------------------------------------------------------------------------- */ /** * Clears the current console output. * */ clear : function() { // Remove all messages this.__log.innerHTML = ""; }, /** * Processes a single log entry * * @signature function(entry) * @param entry {Map} The entry to process */ process : function(entry) { // Append new content this.__log.appendChild(qx.log.appender.Util.toHtml(entry)); // Scroll down this.__scrollDown(); }, /** * Automatically scroll down to the last line */ __scrollDown : function() { this.__log.scrollTop = this.__log.scrollHeight; }, /* --------------------------------------------------------------------------- VISIBILITY TOGGLING --------------------------------------------------------------------------- */ /** @type {Boolean} Flag to store last visibility status */ __visible : true, /** * Toggles the visibility of the console between visible and hidden. * */ toggle : function() { if (!this.__main) { this.init(); } else if (this.__main.style.display == "none") { this.show(); } else { this.__main.style.display = "none"; } }, /** * Shows the console. * */ show : function() { if (!this.__main) { this.init(); } else { this.__main.style.display = "block"; this.__log.scrollTop = this.__log.scrollHeight; } }, /* --------------------------------------------------------------------------- COMMAND LINE SUPPORT --------------------------------------------------------------------------- */ /** @type {Array} List of all previous commands. */ __history : [], /** * Executes the currently given command * */ execute : function() { var value = this.__cmd.value; if (value == "") { return; } if (value == "clear") { this.clear(); return; } var command = document.createElement("div"); command.innerHTML = qx.log.appender.Util.escapeHTML(">>> " + value); command.className = "user-command"; this.__history.push(value); this.__lastCommand = this.__history.length; this.__log.appendChild(command); this.__scrollDown(); try { var ret = window.eval(value); } catch (ex) { qx.log.Logger.error(ex); } if (ret !== undefined) { qx.log.Logger.debug(ret); } }, /* --------------------------------------------------------------------------- EVENT LISTENERS --------------------------------------------------------------------------- */ /** * Event handler for resize listener * * @param e {Event} Event object */ __onResize : function(e) { this.__log.style.height = (this.__main.clientHeight - this.__main.firstChild.offsetHeight - this.__main.lastChild.offsetHeight) + "px"; }, /** * Event handler for keydown listener * * @param e {Event} Event object */ __onKeyPress : function(e) { if (e instanceof qx.event.type.Tap || e instanceof qx.event.type.Pointer) { var target = e.getTarget(); if (target && target.className && target.className.indexOf && target.className.indexOf("navigationbar") != -1) { this.toggle(); } return; } var iden = e.getKeyIdentifier(); // Console toggling if ((iden == "F7") || (iden == "D" && e.isCtrlPressed())) { this.toggle(); e.preventDefault(); } // Not yet created if (!this.__main) { return; } // Active element not in console if (!qx.dom.Hierarchy.contains(this.__main, e.getTarget())) { return; } // Command execution if (iden == "Enter" && this.__cmd.value != "") { this.execute(); this.__cmd.value = ""; } // History management if (iden == "Up" || iden == "Down") { this.__lastCommand += iden == "Up" ? -1 : 1; this.__lastCommand = Math.min(Math.max(0, this.__lastCommand), this.__history.length); var entry = this.__history[this.__lastCommand]; this.__cmd.value = entry || ""; this.__cmd.select(); } } }, /* ***************************************************************************** DEFER ***************************************************************************** */ defer : function(statics) { qx.event.Registration.addListener(document.documentElement, "keypress", statics.__onKeyPress, statics); qx.event.Registration.addListener(document.documentElement, "longtap", statics.__onKeyPress, statics); } });