2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * @extends {WebInspector.SDKModel}
34 * @param {!WebInspector.Target} target
36 WebInspector.ConsoleModel = function(target)
38 WebInspector.SDKModel.call(this, WebInspector.ConsoleModel, target);
40 /** @type {!Array.<!WebInspector.ConsoleMessage>} */
44 this._consoleAgent = target.consoleAgent();
45 target.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this));
49 WebInspector.ConsoleModel.Events = {
50 ConsoleCleared: "ConsoleCleared",
51 MessageAdded: "MessageAdded",
52 CommandEvaluated: "CommandEvaluated",
55 WebInspector.ConsoleModel.prototype = {
56 _enableAgent: function()
58 if (WebInspector.settings.monitoringXHREnabled.get())
59 this._consoleAgent.setMonitoringXHREnabled(true);
61 this._enablingConsole = true;
64 * @this {WebInspector.ConsoleModel}
68 delete this._enablingConsole;
70 this._consoleAgent.enable(callback.bind(this));
76 enablingConsole: function()
78 return !!this._enablingConsole;
82 * @param {!WebInspector.ConsoleMessage} msg
84 addMessage: function(msg)
86 if (WebInspector.NetworkManager.hasDevToolsRequestHeader(msg.request))
89 msg.index = this._messages.length;
90 this._messages.push(msg);
91 this._incrementErrorWarningCount(msg);
93 this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg);
97 * @param {!WebInspector.ConsoleMessage} msg
99 _incrementErrorWarningCount: function(msg)
102 case WebInspector.ConsoleMessage.MessageLevel.Warning:
105 case WebInspector.ConsoleMessage.MessageLevel.Error:
112 * @return {!Array.<!WebInspector.ConsoleMessage>}
116 return this._messages;
119 requestClearMessages: function()
121 this._consoleAgent.clearMessages();
122 this._messagesCleared();
125 _messagesCleared: function()
130 this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
133 __proto__: WebInspector.SDKModel.prototype
137 * @param {!WebInspector.ExecutionContext} executionContext
138 * @param {string} text
139 * @param {boolean=} useCommandLineAPI
141 WebInspector.ConsoleModel.evaluateCommandInConsole = function(executionContext, text, useCommandLineAPI)
143 useCommandLineAPI = !!useCommandLineAPI;
144 var target = executionContext.target();
146 var commandMessage = new WebInspector.ConsoleMessage(target, WebInspector.ConsoleMessage.MessageSource.JS, null, text, WebInspector.ConsoleMessage.MessageType.Command);
147 commandMessage.setExecutionContextId(executionContext.id);
148 target.consoleModel.addMessage(commandMessage);
151 * @param {?WebInspector.RemoteObject} result
152 * @param {boolean} wasThrown
153 * @param {?RuntimeAgent.RemoteObject=} valueResult
154 * @param {?DebuggerAgent.ExceptionDetails=} exceptionDetails
155 * @this {WebInspector.ConsoleModel}
157 function printResult(result, wasThrown, valueResult, exceptionDetails)
162 WebInspector.console.show();
163 this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated, {result: result, wasThrown: wasThrown, text: text, commandMessage: commandMessage, exceptionDetails: exceptionDetails});
166 executionContext.evaluate(text, "console", useCommandLineAPI, false, false, true, printResult.bind(target.consoleModel));
168 WebInspector.userMetrics.ConsoleEvaluated.record();
174 * @param {?WebInspector.Target} target
175 * @param {string} source
176 * @param {?string} level
177 * @param {string} messageText
178 * @param {string=} type
179 * @param {?string=} url
180 * @param {number=} line
181 * @param {number=} column
182 * @param {!NetworkAgent.RequestId=} requestId
183 * @param {!Array.<!RuntimeAgent.RemoteObject>=} parameters
184 * @param {!Array.<!ConsoleAgent.CallFrame>=} stackTrace
185 * @param {number=} timestamp
186 * @param {boolean=} isOutdated
187 * @param {!RuntimeAgent.ExecutionContextId=} executionContextId
188 * @param {!ConsoleAgent.AsyncStackTrace=} asyncStackTrace
189 * @param {?string=} scriptId
191 WebInspector.ConsoleMessage = function(target, source, level, messageText, type, url, line, column, requestId, parameters, stackTrace, timestamp, isOutdated, executionContextId, asyncStackTrace, scriptId)
193 this._target = target;
194 this.source = source;
196 this.messageText = messageText;
197 this.type = type || WebInspector.ConsoleMessage.MessageType.Log;
198 /** @type {string|undefined} */
199 this.url = url || undefined;
200 /** @type {number} */
201 this.line = line || 0;
202 /** @type {number} */
203 this.column = column || 0;
204 this.parameters = parameters;
205 /** @type {!Array.<!ConsoleAgent.CallFrame>|undefined} */
206 this.stackTrace = stackTrace;
207 this.timestamp = timestamp || Date.now();
208 this.isOutdated = isOutdated;
209 this.executionContextId = executionContextId || 0;
210 this.asyncStackTrace = asyncStackTrace;
211 this.scriptId = scriptId || null;
213 this.request = requestId ? target.networkLog.requestForId(requestId) : null;
216 var initiator = this.request.initiator();
218 this.stackTrace = initiator.stackTrace || undefined;
219 this.asyncStackTrace = initiator.asyncStackTrace;
221 this.url = initiator.url;
222 this.line = initiator.lineNumber || 0;
228 WebInspector.ConsoleMessage.prototype = {
230 * @return {?WebInspector.Target}
238 * @param {!WebInspector.ConsoleMessage} originatingMessage
240 setOriginatingMessage: function(originatingMessage)
242 this._originatingConsoleMessage = originatingMessage;
243 this.executionContextId = originatingMessage.executionContextId;
247 * @param {!RuntimeAgent.ExecutionContextId} executionContextId
249 setExecutionContextId: function(executionContextId)
251 this.executionContextId = executionContextId;
255 * @return {?WebInspector.ConsoleMessage}
257 originatingMessage: function()
259 return this._originatingConsoleMessage;
265 isGroupMessage: function()
267 return this.type === WebInspector.ConsoleMessage.MessageType.StartGroup ||
268 this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed ||
269 this.type === WebInspector.ConsoleMessage.MessageType.EndGroup;
275 isGroupStartMessage: function()
277 return this.type === WebInspector.ConsoleMessage.MessageType.StartGroup ||
278 this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed;
284 isErrorOrWarning: function()
286 return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
290 * @return {!WebInspector.ConsoleMessage}
294 return new WebInspector.ConsoleMessage(
303 this.request ? this.request.requestId : undefined,
308 this.executionContextId,
309 this.asyncStackTrace,
314 * @param {?WebInspector.ConsoleMessage} msg
317 isEqual: function(msg)
322 if (!this._isEqualStackTraces(this.stackTrace, msg.stackTrace))
325 var asyncTrace1 = this.asyncStackTrace;
326 var asyncTrace2 = msg.asyncStackTrace;
327 while (asyncTrace1 || asyncTrace2) {
328 if (!asyncTrace1 || !asyncTrace2)
330 if (asyncTrace1.description !== asyncTrace2.description)
332 if (!this._isEqualStackTraces(asyncTrace1.callFrames, asyncTrace2.callFrames))
334 asyncTrace1 = asyncTrace1.asyncStackTrace;
335 asyncTrace2 = asyncTrace2.asyncStackTrace;
338 if (this.parameters) {
339 if (!msg.parameters || this.parameters.length !== msg.parameters.length)
342 for (var i = 0; i < msg.parameters.length; ++i) {
343 // Never treat objects as equal - their properties might change over time.
344 if (this.parameters[i].type !== msg.parameters[i].type || msg.parameters[i].type === "object" || this.parameters[i].value !== msg.parameters[i].value)
349 return (this.target() === msg.target())
350 && (this.source === msg.source)
351 && (this.type === msg.type)
352 && (this.level === msg.level)
353 && (this.line === msg.line)
354 && (this.url === msg.url)
355 && (this.messageText === msg.messageText)
356 && (this.request === msg.request)
357 && (this.executionContextId === msg.executionContextId)
358 && (this.scriptId === msg.scriptId);
362 * @param {!Array.<!ConsoleAgent.CallFrame>|undefined} stackTrace1
363 * @param {!Array.<!ConsoleAgent.CallFrame>|undefined} stackTrace2
366 _isEqualStackTraces: function(stackTrace1, stackTrace2)
368 stackTrace1 = stackTrace1 || [];
369 stackTrace2 = stackTrace2 || [];
370 if (stackTrace1.length !== stackTrace2.length)
372 for (var i = 0, n = stackTrace1.length; i < n; ++i) {
373 if (stackTrace1[i].url !== stackTrace2[i].url ||
374 stackTrace1[i].functionName !== stackTrace2[i].functionName ||
375 stackTrace1[i].lineNumber !== stackTrace2[i].lineNumber ||
376 stackTrace1[i].columnNumber !== stackTrace2[i].columnNumber)
383 // Note: Keep these constants in sync with the ones in Console.h
387 WebInspector.ConsoleMessage.MessageSource = {
391 ConsoleAPI: "console-api",
393 AppCache: "appcache",
394 Rendering: "rendering",
396 Security: "security",
398 Deprecation: "deprecation"
404 WebInspector.ConsoleMessage.MessageType = {
411 StartGroup: "startGroup",
412 StartGroupCollapsed: "startGroupCollapsed",
413 EndGroup: "endGroup",
417 ProfileEnd: "profileEnd",
424 WebInspector.ConsoleMessage.MessageLevel = {
432 WebInspector.ConsoleMessage._messageLevelPriority = {
441 * @param {!WebInspector.ConsoleMessage} a
442 * @param {!WebInspector.ConsoleMessage} b
445 WebInspector.ConsoleMessage.messageLevelComparator = function(a, b)
447 return WebInspector.ConsoleMessage._messageLevelPriority[a.level] - WebInspector.ConsoleMessage._messageLevelPriority[b.level];
451 * @param {!WebInspector.ConsoleMessage} a
452 * @param {!WebInspector.ConsoleMessage} b
455 WebInspector.ConsoleMessage.timestampComparator = function (a, b)
457 return a.timestamp - b.timestamp;
462 * @implements {ConsoleAgent.Dispatcher}
463 * @param {!WebInspector.ConsoleModel} console
465 WebInspector.ConsoleDispatcher = function(console)
467 this._console = console;
470 WebInspector.ConsoleDispatcher.prototype = {
472 * @param {!ConsoleAgent.ConsoleMessage} payload
474 messageAdded: function(payload)
476 var consoleMessage = new WebInspector.ConsoleMessage(
477 this._console.target(),
485 payload.networkRequestId,
488 payload.timestamp * 1000, // Convert to ms.
489 this._console._enablingConsole,
490 payload.executionContextId,
491 payload.asyncStackTrace,
493 this._console.addMessage(consoleMessage);
497 * @param {number} count
499 messageRepeatCountUpdated: function(count)
503 messagesCleared: function()
505 if (!WebInspector.settings.preserveConsoleLog.get())
506 this._console._messagesCleared();
512 * @extends {WebInspector.Object}
513 * @implements {WebInspector.TargetManager.Observer}
515 WebInspector.MultitargetConsoleModel = function()
517 WebInspector.targetManager.observeTargets(this);
518 WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel, WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
519 WebInspector.targetManager.addModelListener(WebInspector.ConsoleModel, WebInspector.ConsoleModel.Events.CommandEvaluated, this._commandEvaluated, this);
522 WebInspector.MultitargetConsoleModel.prototype = {
524 * @param {!WebInspector.Target} target
526 targetAdded: function(target)
528 if (!this._mainTarget) {
529 this._mainTarget = target;
530 target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
535 * @param {!WebInspector.Target} target
537 targetRemoved: function(target)
539 if (this._mainTarget === target) {
540 delete this._mainTarget;
541 target.consoleModel.removeEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
546 * @return {!Array.<!WebInspector.ConsoleMessage>}
550 var targets = WebInspector.targetManager.targets();
552 for (var i = 0; i < targets.length; ++i)
553 result = result.concat(targets[i].consoleModel.messages());
557 _consoleCleared: function()
559 this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
563 * @param {!WebInspector.Event} event
565 _consoleMessageAdded: function(event)
567 this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, event.data);
571 * @param {!WebInspector.Event} event
573 _commandEvaluated: function(event)
575 this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated, event.data);
578 __proto__: WebInspector.Object.prototype
582 * @type {!WebInspector.MultitargetConsoleModel}
584 WebInspector.multitargetConsoleModel;