const ExpressionStopCharacters = " =:[({;,!+-*/&|^<>";
WebInspector.ConsoleView = function(drawer)
{
WebInspector.View.call(this, document.getElementById("console-view"));
this.messages = [];
this.drawer = drawer;
this.clearButton = document.getElementById("clear-console-status-bar-item");
this.clearButton.title = WebInspector.UIString("Clear console log.");
this.clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false);
this.messagesElement = document.getElementById("console-messages");
this.messagesElement.addEventListener("selectstart", this._messagesSelectStart.bind(this), false);
this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
this.promptElement = document.getElementById("console-prompt");
this.promptElement.className = "source-code";
this.promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true);
this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), ExpressionStopCharacters + ".");
this.prompt.history = WebInspector.settings.consoleHistory;
this.topGroup = new WebInspector.ConsoleGroup(null);
this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
this.currentGroup = this.topGroup;
this.toggleConsoleButton = document.getElementById("console-status-bar-item");
this.toggleConsoleButton.title = WebInspector.UIString("Show console.");
this.toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false);
this.filterBarElement = document.getElementById("console-filter");
function createDividerElement() {
var dividerElement = document.createElement("div");
dividerElement.addStyleClass("scope-bar-divider");
this.filterBarElement.appendChild(dividerElement);
}
var updateFilterHandler = this._updateFilter.bind(this);
function createFilterElement(category, label) {
var categoryElement = document.createElement("li");
categoryElement.category = category;
categoryElement.className = category;
categoryElement.addEventListener("click", updateFilterHandler, false);
categoryElement.textContent = label;
this.filterBarElement.appendChild(categoryElement);
return categoryElement;
}
this.allElement = createFilterElement.call(this, "all", WebInspector.UIString("All"));
createDividerElement.call(this);
this.errorElement = createFilterElement.call(this, "errors", WebInspector.UIString("Errors"));
this.warningElement = createFilterElement.call(this, "warnings", WebInspector.UIString("Warnings"));
this.logElement = createFilterElement.call(this, "logs", WebInspector.UIString("Logs"));
this.filter(this.allElement, false);
this._registerShortcuts();
this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
this._customFormatters = {
"object": this._formatobject,
"array": this._formatarray,
"node": this._formatnode,
"string": this._formatstring
};
this._registerConsoleDomainDispatcher();
}
WebInspector.ConsoleView.Events = {
ConsoleCleared: "console-cleared",
EntryAdded: "console-entry-added",
MessageAdded: "console-message-added"
}
WebInspector.ConsoleView.prototype = {
_registerConsoleDomainDispatcher: function() {
var console = this;
var dispatcher = {
messageAdded: function(payload)
{
var consoleMessage = new WebInspector.ConsoleMessage(
payload.source,
payload.type,
payload.level,
payload.line,
payload.url,
payload.repeatCount,
payload.text,
payload.parameters,
payload.stackTrace,
payload.networkIdentifier);
console.addMessage(consoleMessage);
},
messageRepeatCountUpdated: function(count)
{
var msg = console.previousMessage;
var prevRepeatCount = msg.totalRepeatCount;
if (!console.commandSincePreviousMessage) {
msg.repeatDelta = count - prevRepeatCount;
msg.repeatCount = msg.repeatCount + msg.repeatDelta;
msg.totalRepeatCount = count;
msg._updateRepeatCount();
console._incrementErrorWarningCount(msg);
} else {
var msgCopy = new WebInspector.ConsoleMessage(msg.source, msg.type, msg.level, msg.line, msg.url, count - prevRepeatCount, msg._messageText, msg._parameters, msg._stackTrace, msg._requestId);
msgCopy.totalRepeatCount = count;
msgCopy._formatMessage();
console.addMessage(msgCopy);
}
},
messagesCleared: function()
{
console.clearMessages();
},
}
InspectorBackend.registerDomainDispatcher("Console", dispatcher);
},
setConsoleMessageExpiredCount: function(count)
{
if (count) {
var message = String.sprintf(WebInspector.UIString("%d console messages are not shown."), count);
this.addMessage(WebInspector.ConsoleMessage.createTextMessage(message, WebInspector.ConsoleMessage.MessageLevel.Warning));
}
},
_updateFilter: function(e)
{
var isMac = WebInspector.isMac();
var selectMultiple = false;
if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
selectMultiple = true;
if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
selectMultiple = true;
this.filter(e.target, selectMultiple);
},
filter: function(target, selectMultiple)
{
function unselectAll()
{
this.allElement.removeStyleClass("selected");
this.errorElement.removeStyleClass("selected");
this.warningElement.removeStyleClass("selected");
this.logElement.removeStyleClass("selected");
this.messagesElement.removeStyleClass("filter-all");
this.messagesElement.removeStyleClass("filter-errors");
this.messagesElement.removeStyleClass("filter-warnings");
this.messagesElement.removeStyleClass("filter-logs");
}
var targetFilterClass = "filter-" + target.category;
if (target.category === "all") {
if (target.hasStyleClass("selected")) {
return;
}
unselectAll.call(this);
} else {
if (this.allElement.hasStyleClass("selected")) {
this.allElement.removeStyleClass("selected");
this.messagesElement.removeStyleClass("filter-all");
}
}
if (!selectMultiple) {
unselectAll.call(this);
target.addStyleClass("selected");
this.messagesElement.addStyleClass(targetFilterClass);
return;
}
if (target.hasStyleClass("selected")) {
target.removeStyleClass("selected");
this.messagesElement.removeStyleClass(targetFilterClass);
} else {
target.addStyleClass("selected");
this.messagesElement.addStyleClass(targetFilterClass);
}
},
_toggleConsoleButtonClicked: function()
{
this.drawer.visibleView = this;
},
attach: function(mainElement, statusBarElement)
{
mainElement.appendChild(this.element);
statusBarElement.appendChild(this.clearButton);
statusBarElement.appendChild(this.filterBarElement);
},
show: function()
{
this.toggleConsoleButton.addStyleClass("toggled-on");
this.toggleConsoleButton.title = WebInspector.UIString("Hide console.");
if (!this.prompt.isCaretInsidePrompt())
this.prompt.moveCaretToEndOfPrompt();
},
afterShow: function()
{
WebInspector.currentFocusElement = this.promptElement;
},
hide: function()
{
this.toggleConsoleButton.removeStyleClass("toggled-on");
this.toggleConsoleButton.title = WebInspector.UIString("Show console.");
},
_scheduleScrollIntoView: function()
{
if (this._scrollIntoViewTimer)
return;
function scrollIntoView()
{
this.promptElement.scrollIntoView(true);
delete this._scrollIntoViewTimer;
}
this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20);
},
addMessage: function(msg)
{
var shouldScrollToLastMessage = this.messagesElement.isScrolledToBottom();
if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) {
this._incrementErrorWarningCount(msg);
this.dispatchEventToListeners(WebInspector.ConsoleView.Events.MessageAdded, msg);
this.commandSincePreviousMessage = false;
this.previousMessage = msg;
} else if (msg instanceof WebInspector.ConsoleCommand) {
if (this.previousMessage) {
this.commandSincePreviousMessage = true;
}
}
this.messages.push(msg);
if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
var parentGroup = this.currentGroup.parentGroup
if (parentGroup)
this.currentGroup = parentGroup;
} else {
if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
var group = new WebInspector.ConsoleGroup(this.currentGroup);
this.currentGroup.messagesElement.appendChild(group.element);
this.currentGroup = group;
}
this.currentGroup.addMessage(msg);
}
if (shouldScrollToLastMessage || (msg instanceof WebInspector.ConsoleCommandResult))
this._scheduleScrollIntoView();
this.dispatchEventToListeners(WebInspector.ConsoleView.Events.EntryAdded, msg);
},
_incrementErrorWarningCount: function(msg)
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
WebInspector.warnings += msg.repeatDelta;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
WebInspector.errors += msg.repeatDelta;
break;
}
},
requestClearMessages: function()
{
ConsoleAgent.clearConsoleMessages();
},
clearMessages: function()
{
this.dispatchEventToListeners(WebInspector.ConsoleView.Events.ConsoleCleared);
this.messages = [];
this.currentGroup = this.topGroup;
this.topGroup.messagesElement.removeChildren();
WebInspector.errors = 0;
WebInspector.warnings = 0;
delete this.commandSincePreviousMessage;
delete this.previousMessage;
},
completions: function(wordRange, bestMatchOnly, completionsReadyCallback)
{
var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, ExpressionStopCharacters, this.promptElement, "backward");
var expressionString = expressionRange.toString();
var lastIndex = expressionString.length - 1;
var dotNotation = (expressionString[lastIndex] === ".");
var bracketNotation = (expressionString[lastIndex] === "[");
if (dotNotation || bracketNotation)
expressionString = expressionString.substr(0, lastIndex);
var prefix = wordRange.toString();
if (!expressionString && !prefix)
return;
this.evalInInspectedWindow(expressionString, "completion", true, evaluated.bind(this));
function evaluated(result, wasThrown)
{
if (wasThrown)
return;
result.getAllProperties(evaluatedProperties.bind(this));
}
function evaluatedProperties(properties)
{
RuntimeAgent.releaseObjectGroup("completion");
var propertyNames = [];
for (var i = 0; properties && i < properties.length; ++i)
propertyNames.push(properties[i].name);
var includeCommandLineAPI = (!dotNotation && !bracketNotation);
if (includeCommandLineAPI)
propertyNames.splice(0, 0, "dir", "dirxml", "keys", "values", "profile", "profileEnd", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear");
this._reportCompletions(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, propertyNames);
}
},
_reportCompletions: function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, properties) {
if (bracketNotation) {
if (prefix.length && prefix[0] === "'")
var quoteUsed = "'";
else
var quoteUsed = "\"";
}
var results = [];
properties.sort();
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
if (dotNotation && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(property))
continue;
if (bracketNotation) {
if (!/^[0-9]+$/.test(property))
property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + quoteUsed;
property += "]";
}
if (property.length < prefix.length)
continue;
if (property.indexOf(prefix) !== 0)
continue;
results.push(property);
if (bestMatchOnly)
break;
}
completionsReadyCallback(results);
},
_clearButtonClicked: function()
{
this.requestClearMessages();
},
_handleContextMenuEvent: function(event)
{
if (!window.getSelection().isCollapsed) {
return;
}
var itemAction = function () {
WebInspector.settings.monitoringXHREnabled = !WebInspector.settings.monitoringXHREnabled;
ConsoleAgent.setMonitoringXHREnabled(WebInspector.settings.monitoringXHREnabled);
}.bind(this);
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "XMLHttpRequest logging" : "XMLHttpRequest Logging"), itemAction, WebInspector.settings.monitoringXHREnabled)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear console" : "Clear Console"), this.requestClearMessages.bind(this));
contextMenu.show(event);
},
_messagesSelectStart: function(event)
{
if (this._selectionTimeout)
clearTimeout(this._selectionTimeout);
this.prompt.clearAutoComplete();
function moveBackIfOutside()
{
delete this._selectionTimeout;
if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
this.prompt.moveCaretToEndOfPrompt();
this.prompt.autoCompleteSoon();
}
this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
},
_messagesClicked: function(event)
{
var link = event.target.enclosingNodeOrSelfWithNodeName("a");
if (!link || !link.representedNode)
return;
WebInspector.updateFocusedNode(link.representedNode.id);
event.stopPropagation();
event.preventDefault();
},
_registerShortcuts: function()
{
this._shortcuts = {};
var shortcut = WebInspector.KeyboardShortcut;
var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);
this._shortcuts[shortcutK.key] = this.requestClearMessages.bind(this);
this._shortcuts[shortcutK.key].isMacOnly = true;
var clearConsoleHandler = this.requestClearMessages.bind(this);
var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
this._shortcuts[shortcutL.key] = clearConsoleHandler;
var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("Console"));
var keys = WebInspector.isMac() ? [ shortcutK.name, shortcutL.name ] : [ shortcutL.name ];
section.addAlternateKeys(keys, WebInspector.UIString("Clear Console"));
keys = [
shortcut.shortcutToString(shortcut.Keys.Tab),
shortcut.shortcutToString(shortcut.Keys.Tab, shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous suggestion"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));
keys = [
shortcut.shortcutToString(shortcut.Keys.Down),
shortcut.shortcutToString(shortcut.Keys.Up)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));
keys = [
shortcut.shortcutToString("N", shortcut.Modifiers.Alt),
shortcut.shortcutToString("P", shortcut.Modifiers.Alt)
];
if (WebInspector.isMac())
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
},
_promptKeyDown: function(event)
{
if (isEnterKey(event)) {
this._enterKeyPressed(event);
return;
}
var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcut];
if (handler) {
if (!this._shortcuts[shortcut].isMacOnly || WebInspector.isMac()) {
handler();
event.preventDefault();
return;
}
}
},
evalInInspectedWindow: function(expression, objectGroup, includeCommandLineAPI, callback)
{
if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) {
WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, objectGroup, includeCommandLineAPI, callback);
return;
}
if (!expression) {
expression = "this";
}
function evalCallback(error, result, wasThrown)
{
if (!error)
callback(WebInspector.RemoteObject.fromPayload(result), wasThrown);
}
RuntimeAgent.evaluate(expression, objectGroup, includeCommandLineAPI, evalCallback);
},
_enterKeyPressed: function(event)
{
if (event.altKey || event.ctrlKey || event.shiftKey)
return;
event.preventDefault();
event.stopPropagation();
this.prompt.clearAutoComplete(true);
var str = this.prompt.text;
if (!str.length)
return;
var commandMessage = new WebInspector.ConsoleCommand(str);
this.addMessage(commandMessage);
var self = this;
function printResult(result, wasThrown)
{
self.prompt.history.push(str);
self.prompt.historyOffset = 0;
self.prompt.text = "";
WebInspector.settings.consoleHistory = self.prompt.history.slice(-30);
self.addMessage(new WebInspector.ConsoleCommandResult(result, wasThrown, commandMessage));
}
this.evalInInspectedWindow(str, "console", true, printResult);
},
_format: function(output, forceObjectFormat)
{
var isProxy = (output != null && typeof output === "object");
var type = (forceObjectFormat ? "object" : WebInspector.RemoteObject.type(output));
var formatter = this._customFormatters[type];
if (!formatter || !isProxy) {
formatter = this._formatvalue;
output = output.description;
}
var span = document.createElement("span");
span.className = "console-formatted-" + type + " source-code";
formatter.call(this, output, span);
return span;
},
_formatvalue: function(val, elem)
{
elem.appendChild(document.createTextNode(val));
},
_formatobject: function(obj, elem)
{
elem.appendChild(new WebInspector.ObjectPropertiesSection(obj, obj.description).element);
},
_formatnode: function(object, elem)
{
function printNode(nodeId)
{
if (!nodeId) {
this._formatobject(object, elem);
return;
}
var treeOutline = new WebInspector.ElementsTreeOutline();
treeOutline.showInElementsPanelEnabled = true;
treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
treeOutline.element.addStyleClass("outline-disclosure");
if (!treeOutline.children[0].hasChildren)
treeOutline.element.addStyleClass("single-node");
elem.appendChild(treeOutline.element);
}
object.pushNodeToFrontend(printNode.bind(this));
},
_formatarray: function(arr, elem)
{
arr.getOwnProperties(this._printArray.bind(this, elem));
},
_formatstring: function(output, elem)
{
var span = document.createElement("span");
span.className = "console-formatted-string source-code";
span.appendChild(WebInspector.linkifyStringAsFragment(output.description));
elem.removeStyleClass("console-formatted-string");
elem.appendChild(document.createTextNode("\""));
elem.appendChild(span);
elem.appendChild(document.createTextNode("\""));
},
_printArray: function(elem, properties)
{
if (!properties)
return;
var elements = [];
for (var i = 0; i < properties.length; ++i) {
var name = properties[i].name;
if (name == parseInt(name))
elements[name] = this._formatAsArrayEntry(properties[i].value);
}
elem.appendChild(document.createTextNode("["));
for (var i = 0; i < elements.length; ++i) {
var element = elements[i];
if (element)
elem.appendChild(element);
else
elem.appendChild(document.createTextNode("undefined"))
if (i < elements.length - 1)
elem.appendChild(document.createTextNode(", "));
}
elem.appendChild(document.createTextNode("]"));
},
_formatAsArrayEntry: function(output)
{
return this._format(output, WebInspector.RemoteObject.type(output) === "array");
}
}
WebInspector.ConsoleView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.ConsoleMessage = function(source, type, level, line, url, repeatCount, message, parameters, stackTrace, requestId)
{
this.source = source;
this.type = type;
this.level = level;
this.line = line;
this.url = url;
this.repeatCount = repeatCount;
this.repeatDelta = repeatCount;
this.totalRepeatCount = repeatCount;
this._messageText = message;
this._parameters = parameters;
this._stackTrace = stackTrace;
this._requestId = requestId;
if (stackTrace && stackTrace.length) {
var topCallFrame = stackTrace[0];
if (!this.url)
this.url = topCallFrame.url;
if (!this.line)
this.line = topCallFrame.lineNumber;
}
this._formatMessage();
}
WebInspector.ConsoleMessage.createTextMessage = function(text, level)
{
level = level || WebInspector.ConsoleMessage.MessageLevel.Log;
return new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Log, level, 0, null, 1, null, [text], null);
}
WebInspector.ConsoleMessage.prototype = {
_formatMessage: function()
{
var stackTrace = this._stackTrace;
var messageText;
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Trace:
messageText = document.createTextNode("console.trace()");
break;
case WebInspector.ConsoleMessage.MessageType.UncaughtException:
messageText = document.createTextNode(this._messageText);
break;
case WebInspector.ConsoleMessage.MessageType.NetworkError:
var resource = this._requestId && WebInspector.networkResourceById(this._requestId);
if (resource) {
stackTrace = resource.stackTrace;
messageText = document.createElement("span");
messageText.appendChild(document.createTextNode(resource.requestMethod + " "));
messageText.appendChild(WebInspector.linkifyURLAsNode(resource.url));
if (resource.failed)
messageText.appendChild(document.createTextNode(" " + resource.localizedFailDescription));
else
messageText.appendChild(document.createTextNode(" " + resource.statusCode + " (" + resource.statusText + ")"));
} else
messageText = this._format([this._messageText]);
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
var args = [WebInspector.UIString("Assertion failed:")];
if (this._parameters)
args = args.concat(this._parameters);
messageText = this._format(args);
break;
case WebInspector.ConsoleMessage.MessageType.Object:
var obj = this._parameters ? this._parameters[0] : undefined;
var args = ["%O", obj];
messageText = this._format(args);
break;
default:
var args = this._parameters || [this._messageText];
messageText = this._format(args);
break;
}
this._formattedMessage = document.createElement("span");
this._formattedMessage.className = "console-message-text source-code";
if (this.url && this.url !== "undefined") {
var urlElement = WebInspector.linkifyResourceAsNode(this.url, "scripts", this.line, "console-message-url");
this._formattedMessage.appendChild(urlElement);
}
this._formattedMessage.appendChild(messageText);
if (this._stackTrace) {
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Trace:
case WebInspector.ConsoleMessage.MessageType.UncaughtException:
case WebInspector.ConsoleMessage.MessageType.NetworkError:
case WebInspector.ConsoleMessage.MessageType.Assert: {
var ol = document.createElement("ol");
ol.className = "outline-disclosure";
var treeOutline = new TreeOutline(ol);
var content = this._formattedMessage;
var root = new TreeElement(content, null, true);
content.treeElementForTest = root;
treeOutline.appendChild(root);
if (this.type === WebInspector.ConsoleMessage.MessageType.Trace)
root.expand();
this._populateStackTraceTreeElement(root);
this._formattedMessage = ol;
}
}
}
this.message = this._formattedMessage.textContent;
},
isErrorOrWarning: function()
{
return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
},
_format: function(parameters)
{
var formattedResult = document.createElement("span");
if (!parameters.length)
return formattedResult;
for (var i = 0; i < parameters.length; ++i) {
if (typeof parameters[i] === "object")
parameters[i] = WebInspector.RemoteObject.fromPayload(parameters[i]);
else
parameters[i] = WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]);
}
var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result;
if (shouldFormatMessage) {
var result = this._formatWithSubstitutionString(parameters, formattedResult);
parameters = result.unusedSubstitutions;
if (parameters.length)
formattedResult.appendChild(document.createTextNode(" "));
}
for (var i = 0; i < parameters.length; ++i) {
if (shouldFormatMessage && parameters[i].type === "string")
formattedResult.appendChild(document.createTextNode(parameters[i].description));
else
formattedResult.appendChild(WebInspector.console._format(parameters[i]));
if (i < parameters.length - 1)
formattedResult.appendChild(document.createTextNode(" "));
}
return formattedResult;
},
_formatWithSubstitutionString: function(parameters, formattedResult)
{
var formatters = {}
for (var i in String.standardFormatters)
formatters[i] = String.standardFormatters[i];
function consoleFormatWrapper(force)
{
return function(obj) {
return WebInspector.console._format(obj, force);
};
}
formatters.o = consoleFormatWrapper();
formatters.i = formatters.d;
formatters.O = consoleFormatWrapper(true);
function append(a, b)
{
if (!(b instanceof Node))
a.appendChild(WebInspector.linkifyStringAsFragment(b.toString()));
else
a.appendChild(b);
return a;
}
return String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append);
},
clearHighlight: function()
{
var highlightedMessage = this._formattedMessage;
delete this._formattedMessage;
this._formatMessage();
this._element.replaceChild(this._formattedMessage, highlightedMessage);
},
highlightSearchResults: function(regexObject)
{
regexObject.lastIndex = 0;
var text = this.message;
var match = regexObject.exec(text);
var offset = 0;
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}
highlightSearchResults(this._formattedMessage, matchRanges);
this._element.scrollIntoViewIfNeeded();
},
matchesRegex: function(regexObject)
{
return regexObject.test(this.message);
},
toMessageElement: function()
{
if (this._element)
return this._element;
var element = document.createElement("div");
element.message = this;
element.className = "console-message";
this._element = element;
switch (this.level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
element.addStyleClass("console-tip-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Log:
element.addStyleClass("console-log-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
element.addStyleClass("console-debug-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
element.addStyleClass("console-warning-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
element.addStyleClass("console-error-level");
break;
}
if (this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
element.addStyleClass("console-group-title");
element.appendChild(this._formattedMessage);
if (this.repeatCount > 1)
this._updateRepeatCount();
return element;
},
_populateStackTraceTreeElement: function(parentTreeElement)
{
for (var i = 0; i < this._stackTrace.length; i++) {
var frame = this._stackTrace[i];
var content = document.createElement("div");
var messageTextElement = document.createElement("span");
messageTextElement.className = "console-message-text source-code";
var functionName = frame.functionName || WebInspector.UIString("(anonymous function)");
messageTextElement.appendChild(document.createTextNode(functionName));
content.appendChild(messageTextElement);
var urlElement = WebInspector.linkifyResourceAsNode(frame.url, "scripts", frame.lineNumber, "console-message-url");
content.appendChild(urlElement);
var treeElement = new TreeElement(content);
parentTreeElement.appendChild(treeElement);
}
},
_updateRepeatCount: function() {
if (!this.repeatCountElement) {
this.repeatCountElement = document.createElement("span");
this.repeatCountElement.className = "bubble";
this._element.insertBefore(this.repeatCountElement, this._element.firstChild);
this._element.addStyleClass("repeated-message");
}
this.repeatCountElement.textContent = this.repeatCount;
},
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 typeString;
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Log:
case WebInspector.ConsoleMessage.MessageType.UncaughtException:
case WebInspector.ConsoleMessage.MessageType.NetworkError:
typeString = "Log";
break;
case WebInspector.ConsoleMessage.MessageType.Object:
typeString = "Object";
break;
case WebInspector.ConsoleMessage.MessageType.Trace:
typeString = "Trace";
break;
case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
case WebInspector.ConsoleMessage.MessageType.StartGroup:
typeString = "Start Group";
break;
case WebInspector.ConsoleMessage.MessageType.EndGroup:
typeString = "End Group";
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
typeString = "Assert";
break;
case WebInspector.ConsoleMessage.MessageType.Result:
typeString = "Result";
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.Debug:
levelString = "Debug";
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
levelString = "Error";
break;
}
return sourceString + " " + typeString + " " + levelString + ": " + this._formattedMessage.textContent + "\n" + this.url + " line " + this.line;
},
isEqual: function(msg)
{
if (!msg)
return false;
if (this._stackTrace) {
if (!msg._stackTrace)
return false;
var l = this._stackTrace;
var r = msg._stackTrace;
for (var i = 0; i < l.length; i++) {
if (l[i].url !== r[i].url ||
l[i].functionName !== r[i].functionName ||
l[i].lineNumber !== r[i].lineNumber ||
l[i].columnNumber !== r[i].columnNumber)
return false;
}
}
return (this.source === msg.source)
&& (this.type === msg.type)
&& (this.level === msg.level)
&& (this.line === msg.line)
&& (this.url === msg.url)
&& (this.message === msg.message)
&& (this._requestId === msg._requestId);
}
}
WebInspector.ConsoleMessage.MessageSource = {
HTML: "html",
XML: "xml",
JS: "javascript",
CSS: "css",
Other: "other"
}
WebInspector.ConsoleMessage.MessageType = {
Log: "log",
Object: "other",
Trace: "trace",
StartGroup: "startGroup",
StartGroupCollapsed: "startGroupCollapsed",
EndGroup: "endGroup",
Assert: "assert",
UncaughtException: "uncaughtException",
NetworkError: "networkError",
Result: "result"
}
WebInspector.ConsoleMessage.MessageLevel = {
Tip: "tip",
Log: "log",
Warning: "warning",
Error: "error",
Debug: "debug"
}
WebInspector.ConsoleCommand = function(command)
{
this.command = command;
}
WebInspector.ConsoleCommand.prototype = {
clearHighlight: function()
{
var highlightedMessage = this._formattedCommand;
delete this._formattedCommand;
this._formatCommand();
this._element.replaceChild(this._formattedCommand, highlightedMessage);
},
highlightSearchResults: function(regexObject)
{
regexObject.lastIndex = 0;
var text = this.command;
var match = regexObject.exec(text);
var offset = 0;
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}
highlightSearchResults(this._formattedCommand, matchRanges);
this._element.scrollIntoViewIfNeeded();
},
matchesRegex: function(regexObject)
{
return regexObject.test(this.command);
},
toMessageElement: function()
{
if (!this._element) {
this._element = document.createElement("div");
this._element.command = this;
this._element.className = "console-user-command";
this._formatCommand();
this._element.appendChild(this._formattedCommand);
}
return this._element;
},
_formatCommand: function()
{
this._formattedCommand = document.createElement("span");
this._formattedCommand.className = "console-message-text source-code";
this._formattedCommand.textContent = this.command;
},
}
WebInspector.ConsoleCommandResult = function(result, wasThrown, originatingCommand)
{
var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
this.originatingCommand = originatingCommand;
WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Result, level, -1, null, 1, null, [result]);
}
WebInspector.ConsoleCommandResult.prototype = {
toMessageElement: function()
{
var element = WebInspector.ConsoleMessage.prototype.toMessageElement.call(this);
element.addStyleClass("console-user-command-result");
return element;
}
}
WebInspector.ConsoleCommandResult.prototype.__proto__ = WebInspector.ConsoleMessage.prototype;
WebInspector.ConsoleGroup = function(parentGroup)
{
this.parentGroup = parentGroup;
var element = document.createElement("div");
element.className = "console-group";
element.group = this;
this.element = element;
var messagesElement = document.createElement("div");
messagesElement.className = "console-group-messages";
element.appendChild(messagesElement);
this.messagesElement = messagesElement;
}
WebInspector.ConsoleGroup.prototype = {
addMessage: function(msg)
{
var element = msg.toMessageElement();
if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
this.messagesElement.parentNode.insertBefore(element, this.messagesElement);
element.addEventListener("click", this._titleClicked.bind(this), false);
var groupElement = element.enclosingNodeOrSelfWithClass("console-group");
if (groupElement && msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
groupElement.addStyleClass("collapsed");
} else
this.messagesElement.appendChild(element);
if (element.previousSibling && msg.originatingCommand && element.previousSibling.command === msg.originatingCommand)
element.previousSibling.addStyleClass("console-adjacent-user-command-result");
},
_titleClicked: function(event)
{
var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title");
if (groupTitleElement) {
var groupElement = groupTitleElement.enclosingNodeOrSelfWithClass("console-group");
if (groupElement)
if (groupElement.hasStyleClass("collapsed"))
groupElement.removeStyleClass("collapsed");
else
groupElement.addStyleClass("collapsed");
groupTitleElement.scrollIntoViewIfNeeded(true);
}
event.stopPropagation();
event.preventDefault();
}
}