diff options
Diffstat (limited to 'WebCore/page/inspector/ConsolePanel.js')
-rw-r--r-- | WebCore/page/inspector/ConsolePanel.js | 459 |
1 files changed, 459 insertions, 0 deletions
diff --git a/WebCore/page/inspector/ConsolePanel.js b/WebCore/page/inspector/ConsolePanel.js new file mode 100644 index 0000000..57bf331 --- /dev/null +++ b/WebCore/page/inspector/ConsolePanel.js @@ -0,0 +1,459 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +WebInspector.ConsolePanel = function() +{ + WebInspector.Panel.call(this); + + this.messages = []; + + this.commandHistory = []; + this.commandOffset = 0; + + this.messageList = document.createElement("ol"); + this.messageList.className = "console-message-list"; + this.element.appendChild(this.messageList); + + this.messageList.addEventListener("click", this.messageListClicked.bind(this), true); + + this.consolePrompt = document.createElement("textarea"); + this.consolePrompt.className = "console-prompt"; + this.element.appendChild(this.consolePrompt); + + this.consolePrompt.addEventListener("keydown", this.promptKeyDown.bind(this), false); + + var clearButtonText = WebInspector.UIString("Clear"); + this.clearMessagesElement = document.createElement("button"); + this.clearMessagesElement.appendChild(document.createTextNode(clearButtonText)); + this.clearMessagesElement.title = clearButtonText; + this.clearMessagesElement.addEventListener("click", this.clearButtonClicked.bind(this), false); +} + +WebInspector.ConsolePanel.prototype = { + show: function() + { + WebInspector.Panel.prototype.show.call(this); + WebInspector.consoleListItem.select(); + + this.clearMessagesElement.removeStyleClass("hidden"); + if (!this.clearMessagesElement.parentNode) + document.getElementById("toolbarButtons").appendChild(this.clearMessagesElement); + }, + + hide: function() + { + WebInspector.Panel.prototype.hide.call(this); + WebInspector.consoleListItem.deselect(); + this.clearMessagesElement.addStyleClass("hidden"); + }, + + addMessage: function(msg) + { + if (msg.url in WebInspector.resourceURLMap) { + msg.resource = WebInspector.resourceURLMap[msg.url]; + switch (msg.level) { + case WebInspector.ConsoleMessage.MessageLevel.Warning: + ++msg.resource.warnings; + msg.resource.panel.addMessageToSource(msg); + break; + case WebInspector.ConsoleMessage.MessageLevel.Error: + ++msg.resource.errors; + msg.resource.panel.addMessageToSource(msg); + break; + } + } + this.messages.push(msg); + + var item = msg.toListItem(); + item.message = msg; + this.messageList.appendChild(item); + item.scrollIntoView(false); + }, + + clearMessages: function() + { + for (var i = 0; i < this.messages.length; ++i) { + var resource = this.messages[i].resource; + if (!resource) + continue; + + resource.errors = 0; + resource.warnings = 0; + } + + this.messages = []; + this.messageList.removeChildren(); + }, + + clearButtonClicked: function() + { + this.clearMessages(); + }, + + messageListClicked: function(event) + { + var link = event.target.firstParentOrSelfWithNodeName("a"); + if (link && link.representedNode) { + WebInspector.updateFocusedNode(link.representedNode); + return; + } + + var item = event.target.firstParentOrSelfWithNodeName("li"); + if (!item) + return; + + var resource = item.message.resource; + if (!resource) + return; + + if (link && link.hasStyleClass("console-message-url")) { + WebInspector.navigateToResource(resource); + resource.panel.showSourceLine(item.message.line); + } + + event.stopPropagation(); + event.preventDefault(); + }, + + promptKeyDown: function(event) + { + switch (event.keyIdentifier) { + case "Enter": + this._onEnterPressed(event); + break; + case "Up": + this._onUpPressed(event); + break; + case "Down": + this._onDownPressed(event); + break; + } + }, + + _onEnterPressed: function(event) + { + event.preventDefault(); + event.stopPropagation(); + + var str = this.consolePrompt.value; + if (!str.length) + return; + + this.commandHistory.push(str); + this.commandOffset = 0; + + this.consolePrompt.value = ""; + + var result; + var exception = false; + try { + // This with block is needed to work around http://bugs.webkit.org/show_bug.cgi?id=11399 + with (InspectorController.inspectedWindow()) { + result = eval(str); + } + } catch(e) { + result = e; + exception = true; + } + + var level = exception ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log; + + this.addMessage(new WebInspector.ConsoleCommand(str, this._format(result))); + }, + + _onUpPressed: function(event) + { + event.preventDefault(); + event.stopPropagation(); + + if (this.commandOffset == this.commandHistory.length) + return; + + if (this.commandOffset == 0) + this.tempSavedCommand = this.consolePrompt.value; + + ++this.commandOffset; + this.consolePrompt.value = this.commandHistory[this.commandHistory.length - this.commandOffset]; + this.consolePrompt.moveCursorToEnd(); + }, + + _onDownPressed: function(event) + { + event.preventDefault(); + event.stopPropagation(); + + if (this.commandOffset == 0) + return; + + --this.commandOffset; + + if (this.commandOffset == 0) { + this.consolePrompt.value = this.tempSavedCommand; + this.consolePrompt.moveCursorToEnd(); + delete this.tempSavedCommand; + return; + } + + this.consolePrompt.value = this.commandHistory[this.commandHistory.length - this.commandOffset]; + this.consolePrompt.moveCursorToEnd(); + }, + + _format: function(output) + { + var type = Object.type(output); + if (type === "object") { + if (output instanceof Node) + type = "node"; + } + + // We don't perform any special formatting on these types, so we just + // pass them through the simple _formatvalue function. + var undecoratedTypes = { + "undefined": 1, + "null": 1, + "boolean": 1, + "number": 1, + "date": 1, + "function": 1, + }; + + var formatter; + if (type in undecoratedTypes) + formatter = "_formatvalue"; + else { + formatter = "_format" + type; + if (!(formatter in this)) { + formatter = "_formatobject"; + type = "object"; + } + } + + var span = document.createElement("span"); + span.addStyleClass("console-formatted-" + type); + this[formatter](output, span); + return span; + }, + + _formatvalue: function(val, elem) + { + elem.appendChild(document.createTextNode(val)); + }, + + _formatstring: function(str, elem) + { + elem.appendChild(document.createTextNode("\"" + str + "\"")); + }, + + _formatregexp: function(re, elem) + { + var formatted = String(re).replace(/([\\\/])/g, "\\$1").replace(/\\(\/[gim]*)$/, "$1").substring(1); + elem.appendChild(document.createTextNode(formatted)); + }, + + _formatarray: function(arr, elem) + { + elem.appendChild(document.createTextNode("[")); + for (var i = 0; i < arr.length; ++i) { + elem.appendChild(this._format(arr[i])); + if (i < arr.length - 1) + elem.appendChild(document.createTextNode(", ")); + } + elem.appendChild(document.createTextNode("]")); + }, + + _formatnode: function(node, elem) + { + var anchor = document.createElement("a"); + anchor.innerHTML = node.titleInfo().title; + anchor.representedNode = node; + elem.appendChild(anchor); + }, + + _formatobject: function(obj, elem) + { + elem.appendChild(document.createTextNode(Object.describe(obj))); + }, +} + +WebInspector.ConsolePanel.prototype.__proto__ = WebInspector.Panel.prototype; + +WebInspector.ConsoleMessage = function(source, level, message, line, url) +{ + this.source = source; + this.level = level; + this.message = message; + this.line = line; + this.url = url; +} + +WebInspector.ConsoleMessage.prototype = { + get shortURL() + { + if (this.resource) + return this.resource.displayName; + return this.url; + }, + + toListItem: function() + { + var item = document.createElement("li"); + item.className = "console-message"; + switch (this.source) { + case WebInspector.ConsoleMessage.MessageSource.HTML: + item.className += " console-html-source"; + break; + case WebInspector.ConsoleMessage.MessageSource.XML: + item.className += " console-xml-source"; + break; + case WebInspector.ConsoleMessage.MessageSource.JS: + item.className += " console-js-source"; + break; + case WebInspector.ConsoleMessage.MessageSource.CSS: + item.className += " console-css-source"; + break; + case WebInspector.ConsoleMessage.MessageSource.Other: + item.className += " console-other-source"; + break; + } + + switch (this.level) { + case WebInspector.ConsoleMessage.MessageLevel.Tip: + item.className += " console-tip-level"; + break; + case WebInspector.ConsoleMessage.MessageLevel.Log: + item.className += " console-log-level"; + break; + case WebInspector.ConsoleMessage.MessageLevel.Warning: + item.className += " console-warning-level"; + break; + case WebInspector.ConsoleMessage.MessageLevel.Error: + item.className += " console-error-level"; + } + + var messageDiv = document.createElement("div"); + messageDiv.className = "console-message-message"; + messageDiv.textContent = this.message; + item.appendChild(messageDiv); + + if (this.url && this.url !== "undefined") { + var urlElement = document.createElement("a"); + urlElement.className = "console-message-url"; + + if (this.line > 0) + urlElement.textContent = WebInspector.UIString("%s (line %d)", this.url, this.line); + else + urlElement.textContent = this.url; + + item.appendChild(urlElement); + } + + return item; + }, + + toString: function() + { + var sourceString; + switch (this.source) { + case WebInspector.ConsoleMessage.MessageSource.HTML: + sourceString = "HTML"; + break; + case WebInspector.ConsoleMessage.MessageSource.XML: + sourceString = "XML"; + break; + case WebInspector.ConsoleMessage.MessageSource.JS: + sourceString = "JS"; + break; + case WebInspector.ConsoleMessage.MessageSource.CSS: + sourceString = "CSS"; + break; + case WebInspector.ConsoleMessage.MessageSource.Other: + sourceString = "Other"; + break; + } + + var levelString; + switch (this.level) { + case WebInspector.ConsoleMessage.MessageLevel.Tip: + levelString = "Tip"; + break; + case WebInspector.ConsoleMessage.MessageLevel.Log: + levelString = "Log"; + break; + case WebInspector.ConsoleMessage.MessageLevel.Warning: + levelString = "Warning"; + break; + case WebInspector.ConsoleMessage.MessageLevel.Error: + levelString = "Error"; + break; + } + + return sourceString + " " + levelString + ": " + this.message + "\n" + this.url + " line " + this.line; + } +} + +// Note: Keep these constants in sync with the ones in Chrome.h +WebInspector.ConsoleMessage.MessageSource = { + HTML: 0, + XML: 1, + JS: 2, + CSS: 3, + Other: 4, +}; + +WebInspector.ConsoleMessage.MessageLevel = { + Tip: 0, + Log: 1, + Warning: 2, + Error: 3, +}; + +WebInspector.ConsoleCommand = function(input, output) +{ + this.input = input; + this.output = output; +} + +WebInspector.ConsoleCommand.prototype = { + toListItem: function() + { + var item = document.createElement("li"); + item.className = "console-command"; + + var inputDiv = document.createElement("div"); + inputDiv.className = "console-command-input"; + inputDiv.textContent = this.input; + item.appendChild(inputDiv); + + var outputDiv = document.createElement("div"); + outputDiv.className = "console-command-output"; + outputDiv.appendChild(this.output); + item.appendChild(outputDiv); + + return item; + } +} |