| /* |
| * Copyright (C) 2011 Google 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: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * 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. |
| * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT |
| * OWNER OR 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. |
| */ |
| |
| /** |
| * @constructor |
| * @extends {WebInspector.SDKModel} |
| * @param {!WebInspector.Target} target |
| */ |
| WebInspector.ConsoleModel = function(target) |
| { |
| WebInspector.SDKModel.call(this, WebInspector.ConsoleModel, target); |
| |
| /** @type {!Array.<!WebInspector.ConsoleMessage>} */ |
| this._messages = []; |
| /** @type {!Map<number, !WebInspector.ConsoleMessage>} */ |
| this._messageById = new Map(); |
| this._warnings = 0; |
| this._errors = 0; |
| this._revokedErrors = 0; |
| this._consoleAgent = target.consoleAgent(); |
| target.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this)); |
| this._enableAgent(); |
| } |
| |
| WebInspector.ConsoleModel.Events = { |
| ConsoleCleared: "ConsoleCleared", |
| MessageAdded: "MessageAdded", |
| MessageUpdated: "MessageUpdated", |
| CommandEvaluated: "CommandEvaluated", |
| } |
| |
| WebInspector.ConsoleModel.prototype = { |
| _enableAgent: function() |
| { |
| this._enablingConsole = true; |
| |
| /** |
| * @this {WebInspector.ConsoleModel} |
| */ |
| function callback() |
| { |
| delete this._enablingConsole; |
| } |
| this._consoleAgent.enable(callback.bind(this)); |
| }, |
| |
| /** |
| * @param {!WebInspector.ConsoleMessage} msg |
| */ |
| addMessage: function(msg) |
| { |
| if (this._isBlacklisted(msg)) |
| return; |
| |
| if (msg.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError && msg._relatedMessageId) { |
| var relatedMessage = this._messageById.get(msg._relatedMessageId); |
| if (!relatedMessage) |
| return; |
| this._errors--; |
| this._revokedErrors++; |
| relatedMessage.level = WebInspector.ConsoleMessage.MessageLevel.RevokedError; |
| this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageUpdated, relatedMessage); |
| return; |
| } |
| |
| this._messages.push(msg); |
| if (msg._messageId) |
| this._messageById.set(msg._messageId, msg); |
| this._incrementErrorWarningCount(msg); |
| this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg); |
| }, |
| |
| /** |
| * @param {!WebInspector.ConsoleMessage} msg |
| */ |
| _incrementErrorWarningCount: function(msg) |
| { |
| switch (msg.level) { |
| case WebInspector.ConsoleMessage.MessageLevel.Warning: |
| this._warnings++; |
| break; |
| case WebInspector.ConsoleMessage.MessageLevel.Error: |
| this._errors++; |
| break; |
| case WebInspector.ConsoleMessage.MessageLevel.RevokedError: |
| this._revokedErrors++; |
| break; |
| } |
| }, |
| |
| /** |
| * @param {!WebInspector.ConsoleMessage} msg |
| * @return {boolean} |
| */ |
| _isBlacklisted: function(msg) |
| { |
| if (msg.source != WebInspector.ConsoleMessage.MessageSource.Network || msg.level != WebInspector.ConsoleMessage.MessageLevel.Error || !msg.url || !msg.url.startsWith("chrome-extension")) |
| return false; |
| |
| // ignore Chromecast's cast_sender spam |
| if (msg.url.includes("://boadgeojelhgndaghljhdicfkmllpafd") || msg.url.includes("://dliochdbjfkdbacpmhlcpmleaejidimm") || msg.url.includes("://fjhoaacokmgbjemoflkofnenfaiekifl") || msg.url.includes("://ekpaaapppgpmolpcldedioblbkmijaca")) |
| return true; |
| |
| return false; |
| }, |
| |
| /** |
| * @return {!Array.<!WebInspector.ConsoleMessage>} |
| */ |
| messages: function() |
| { |
| return this._messages; |
| }, |
| |
| requestClearMessages: function() |
| { |
| this._consoleAgent.clearMessages(); |
| this._messagesCleared(); |
| }, |
| |
| _messagesCleared: function() |
| { |
| this._messages = []; |
| this._messageById.clear(); |
| this._errors = 0; |
| this._revokedErrors = 0; |
| this._warnings = 0; |
| this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared); |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| errors: function() |
| { |
| return this._errors; |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| revokedErrors: function() |
| { |
| return this._revokedErrors; |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| warnings: function() |
| { |
| return this._warnings; |
| }, |
| |
| __proto__: WebInspector.SDKModel.prototype |
| } |
| |
| /** |
| * @param {!WebInspector.ExecutionContext} executionContext |
| * @param {string} text |
| * @param {boolean=} useCommandLineAPI |
| */ |
| WebInspector.ConsoleModel.evaluateCommandInConsole = function(executionContext, text, useCommandLineAPI) |
| { |
| var target = executionContext.target(); |
| |
| var commandMessage = new WebInspector.ConsoleMessage(target, WebInspector.ConsoleMessage.MessageSource.JS, null, text, WebInspector.ConsoleMessage.MessageType.Command); |
| commandMessage.setExecutionContextId(executionContext.id); |
| target.consoleModel.addMessage(commandMessage); |
| |
| /** |
| * @param {?WebInspector.RemoteObject} result |
| * @param {boolean} wasThrown |
| * @param {?RuntimeAgent.RemoteObject=} valueResult |
| * @param {?DebuggerAgent.ExceptionDetails=} exceptionDetails |
| */ |
| function printResult(result, wasThrown, valueResult, exceptionDetails) |
| { |
| if (!result) |
| return; |
| |
| WebInspector.console.showPromise().then(reportUponEvaluation); |
| function reportUponEvaluation() |
| { |
| target.consoleModel.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated, {result: result, wasThrown: wasThrown, text: text, commandMessage: commandMessage, exceptionDetails: exceptionDetails}); |
| } |
| } |
| if (/^\s*\{/.test(text) && /\}\s*$/.test(text)) |
| text = '(' + text + ')'; |
| executionContext.evaluate(text, "console", !!useCommandLineAPI, false, false, true, printResult); |
| |
| WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ConsoleEvaluated); |
| } |
| |
| WebInspector.ConsoleModel.clearConsole = function() |
| { |
| var targets = WebInspector.targetManager.targets(); |
| for (var i = 0; i < targets.length; ++i) |
| targets[i].consoleModel.requestClearMessages(); |
| } |
| |
| |
| /** |
| * @constructor |
| * @param {?WebInspector.Target} target |
| * @param {string} source |
| * @param {?string} level |
| * @param {string} messageText |
| * @param {string=} type |
| * @param {?string=} url |
| * @param {number=} line |
| * @param {number=} column |
| * @param {!NetworkAgent.RequestId=} requestId |
| * @param {!Array.<!RuntimeAgent.RemoteObject>=} parameters |
| * @param {!Array.<!ConsoleAgent.CallFrame>=} stackTrace |
| * @param {number=} timestamp |
| * @param {!RuntimeAgent.ExecutionContextId=} executionContextId |
| * @param {!ConsoleAgent.AsyncStackTrace=} asyncStackTrace |
| * @param {?string=} scriptId |
| * @param {number=} messageId |
| * @param {number=} relatedMessageId |
| */ |
| WebInspector.ConsoleMessage = function(target, source, level, messageText, type, url, line, column, requestId, parameters, stackTrace, timestamp, executionContextId, asyncStackTrace, scriptId, messageId, relatedMessageId) |
| { |
| this._target = target; |
| this.source = source; |
| this.level = level; |
| this.messageText = messageText; |
| this.type = type || WebInspector.ConsoleMessage.MessageType.Log; |
| /** @type {string|undefined} */ |
| this.url = url || undefined; |
| /** @type {number} */ |
| this.line = line || 0; |
| /** @type {number} */ |
| this.column = column || 0; |
| this.parameters = parameters; |
| /** @type {!Array.<!ConsoleAgent.CallFrame>|undefined} */ |
| this.stackTrace = stackTrace; |
| this.timestamp = timestamp || Date.now(); |
| this.executionContextId = executionContextId || 0; |
| this.asyncStackTrace = asyncStackTrace; |
| this.scriptId = scriptId || null; |
| this._messageId = messageId || 0; |
| this._relatedMessageId = relatedMessageId || 0; |
| |
| this.request = requestId ? target.networkLog.requestForId(requestId) : null; |
| |
| if (this.request) { |
| var initiator = this.request.initiator(); |
| if (initiator) { |
| this.stackTrace = initiator.stackTrace || undefined; |
| this.asyncStackTrace = initiator.asyncStackTrace; |
| if (initiator.url) { |
| this.url = initiator.url; |
| this.line = initiator.lineNumber || 0; |
| } |
| } |
| } |
| } |
| |
| WebInspector.ConsoleMessage.prototype = { |
| /** |
| * @return {?WebInspector.Target} |
| */ |
| target: function() |
| { |
| return this._target; |
| }, |
| |
| /** |
| * @param {!WebInspector.ConsoleMessage} originatingMessage |
| */ |
| setOriginatingMessage: function(originatingMessage) |
| { |
| this._originatingConsoleMessage = originatingMessage; |
| this.executionContextId = originatingMessage.executionContextId; |
| }, |
| |
| /** |
| * @param {!RuntimeAgent.ExecutionContextId} executionContextId |
| */ |
| setExecutionContextId: function(executionContextId) |
| { |
| this.executionContextId = executionContextId; |
| }, |
| |
| /** |
| * @return {?WebInspector.ConsoleMessage} |
| */ |
| originatingMessage: function() |
| { |
| return this._originatingConsoleMessage; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| isGroupMessage: function() |
| { |
| return this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || |
| this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed || |
| this.type === WebInspector.ConsoleMessage.MessageType.EndGroup; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| isGroupStartMessage: function() |
| { |
| return this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || |
| this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| isErrorOrWarning: function() |
| { |
| return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error); |
| }, |
| |
| /** |
| * @param {?WebInspector.ConsoleMessage} msg |
| * @return {boolean} |
| */ |
| isEqual: function(msg) |
| { |
| if (!msg) |
| return false; |
| |
| if (this._messageId || msg._messageId) |
| return false; |
| if (this._relatedMessageId || msg._relatedMessageId) |
| return false; |
| |
| if (!this._isEqualStackTraces(this.stackTrace, msg.stackTrace)) |
| return false; |
| |
| var asyncTrace1 = this.asyncStackTrace; |
| var asyncTrace2 = msg.asyncStackTrace; |
| while (asyncTrace1 || asyncTrace2) { |
| if (!asyncTrace1 || !asyncTrace2) |
| return false; |
| if (asyncTrace1.description !== asyncTrace2.description) |
| return false; |
| if (!this._isEqualStackTraces(asyncTrace1.callFrames, asyncTrace2.callFrames)) |
| return false; |
| asyncTrace1 = asyncTrace1.asyncStackTrace; |
| asyncTrace2 = asyncTrace2.asyncStackTrace; |
| } |
| |
| if (this.parameters) { |
| if (!msg.parameters || this.parameters.length !== msg.parameters.length) |
| return false; |
| |
| for (var i = 0; i < msg.parameters.length; ++i) { |
| // Never treat objects as equal - their properties might change over time. |
| if (this.parameters[i].type !== msg.parameters[i].type || msg.parameters[i].type === "object" || this.parameters[i].value !== msg.parameters[i].value) |
| return false; |
| } |
| } |
| |
| return (this.target() === msg.target()) |
| && (this.source === msg.source) |
| && (this.type === msg.type) |
| && (this.level === msg.level) |
| && (this.line === msg.line) |
| && (this.url === msg.url) |
| && (this.messageText === msg.messageText) |
| && (this.request === msg.request) |
| && (this.executionContextId === msg.executionContextId) |
| && (this.scriptId === msg.scriptId); |
| }, |
| |
| /** |
| * @param {!Array.<!ConsoleAgent.CallFrame>|undefined} stackTrace1 |
| * @param {!Array.<!ConsoleAgent.CallFrame>|undefined} stackTrace2 |
| * @return {boolean} |
| */ |
| _isEqualStackTraces: function(stackTrace1, stackTrace2) |
| { |
| stackTrace1 = stackTrace1 || []; |
| stackTrace2 = stackTrace2 || []; |
| if (stackTrace1.length !== stackTrace2.length) |
| return false; |
| for (var i = 0, n = stackTrace1.length; i < n; ++i) { |
| if (stackTrace1[i].url !== stackTrace2[i].url || |
| stackTrace1[i].functionName !== stackTrace2[i].functionName || |
| stackTrace1[i].lineNumber !== stackTrace2[i].lineNumber || |
| stackTrace1[i].columnNumber !== stackTrace2[i].columnNumber) |
| return false; |
| } |
| return true; |
| } |
| } |
| |
| // Note: Keep these constants in sync with the ones in Console.h |
| /** |
| * @enum {string} |
| */ |
| WebInspector.ConsoleMessage.MessageSource = { |
| XML: "xml", |
| JS: "javascript", |
| Network: "network", |
| ConsoleAPI: "console-api", |
| Storage: "storage", |
| AppCache: "appcache", |
| Rendering: "rendering", |
| CSS: "css", |
| Security: "security", |
| Other: "other", |
| Deprecation: "deprecation" |
| } |
| |
| /** |
| * @enum {string} |
| */ |
| WebInspector.ConsoleMessage.MessageType = { |
| Log: "log", |
| Dir: "dir", |
| DirXML: "dirxml", |
| Table: "table", |
| Trace: "trace", |
| Clear: "clear", |
| StartGroup: "startGroup", |
| StartGroupCollapsed: "startGroupCollapsed", |
| EndGroup: "endGroup", |
| Assert: "assert", |
| Result: "result", |
| Profile: "profile", |
| ProfileEnd: "profileEnd", |
| Command: "command" |
| } |
| |
| /** |
| * @enum {string} |
| */ |
| WebInspector.ConsoleMessage.MessageLevel = { |
| Log: "log", |
| Info: "info", |
| Warning: "warning", |
| Error: "error", |
| Debug: "debug", |
| RevokedError: "revokedError" |
| }; |
| |
| /** |
| * @param {!WebInspector.ConsoleMessage} a |
| * @param {!WebInspector.ConsoleMessage} b |
| * @return {number} |
| */ |
| WebInspector.ConsoleMessage.timestampComparator = function (a, b) |
| { |
| return a.timestamp - b.timestamp; |
| } |
| |
| /** |
| * @constructor |
| * @implements {ConsoleAgent.Dispatcher} |
| * @param {!WebInspector.ConsoleModel} console |
| */ |
| WebInspector.ConsoleDispatcher = function(console) |
| { |
| this._console = console; |
| } |
| |
| WebInspector.ConsoleDispatcher.prototype = { |
| /** |
| * @override |
| * @param {!ConsoleAgent.ConsoleMessage} payload |
| */ |
| messageAdded: function(payload) |
| { |
| var consoleMessage = new WebInspector.ConsoleMessage( |
| this._console.target(), |
| payload.source, |
| payload.level, |
| payload.text, |
| payload.type, |
| payload.url, |
| payload.line, |
| payload.column, |
| payload.networkRequestId, |
| payload.parameters, |
| payload.stackTrace, |
| payload.timestamp * 1000, // Convert to ms. |
| payload.executionContextId, |
| payload.asyncStackTrace, |
| payload.scriptId, |
| payload.messageId, |
| payload.relatedMessageId); |
| this._console.addMessage(consoleMessage); |
| }, |
| |
| /** |
| * @override |
| * @param {number} count |
| */ |
| messageRepeatCountUpdated: function(count) |
| { |
| }, |
| |
| /** |
| * @override |
| */ |
| messagesCleared: function() |
| { |
| if (!WebInspector.moduleSetting("preserveConsoleLog").get()) |
| this._console._messagesCleared(); |
| } |
| } |
| |
| /** |
| * @constructor |
| * @extends {WebInspector.Object} |
| * @implements {WebInspector.TargetManager.Observer} |
| */ |
| WebInspector.MultitargetConsoleModel = function() |
| { |
| WebInspector.targetManager.observeTargets(this); |
| WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel, WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this); |
| WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel, WebInspector.ConsoleModel.Events.MessageUpdated, this._consoleMessageUpdated, this); |
| WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel, WebInspector.ConsoleModel.Events.CommandEvaluated, this._commandEvaluated, this); |
| } |
| |
| WebInspector.MultitargetConsoleModel.prototype = { |
| /** |
| * @override |
| * @param {!WebInspector.Target} target |
| */ |
| targetAdded: function(target) |
| { |
| if (!this._mainTarget) { |
| this._mainTarget = target; |
| target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this); |
| } |
| }, |
| |
| /** |
| * @override |
| * @param {!WebInspector.Target} target |
| */ |
| targetRemoved: function(target) |
| { |
| if (this._mainTarget === target) { |
| delete this._mainTarget; |
| target.consoleModel.removeEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this); |
| } |
| }, |
| |
| /** |
| * @return {!Array.<!WebInspector.ConsoleMessage>} |
| */ |
| messages: function() |
| { |
| var targets = WebInspector.targetManager.targets(); |
| var result = []; |
| for (var i = 0; i < targets.length; ++i) |
| result = result.concat(targets[i].consoleModel.messages()); |
| return result; |
| }, |
| |
| _consoleCleared: function() |
| { |
| this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared); |
| }, |
| |
| /** |
| * @param {!WebInspector.Event} event |
| */ |
| _consoleMessageAdded: function(event) |
| { |
| this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, event.data); |
| }, |
| |
| /** |
| * @param {!WebInspector.Event} event |
| */ |
| _consoleMessageUpdated: function(event) |
| { |
| this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageUpdated, event.data); |
| }, |
| |
| /** |
| * @param {!WebInspector.Event} event |
| */ |
| _commandEvaluated: function(event) |
| { |
| this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated, event.data); |
| }, |
| |
| __proto__: WebInspector.Object.prototype |
| } |
| |
| /** |
| * @type {!WebInspector.MultitargetConsoleModel} |
| */ |
| WebInspector.multitargetConsoleModel; |