1/* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 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 13 * distribution. 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. 17 * 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. 29 */ 30 31/** 32 * @constructor 33 * @extends {WebInspector.Object} 34 */ 35WebInspector.ConsoleModel = function() 36{ 37 this.messages = []; 38 this.warnings = 0; 39 this.errors = 0; 40 this._interruptRepeatCount = false; 41 InspectorBackend.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this)); 42} 43 44WebInspector.ConsoleModel.Events = { 45 ConsoleCleared: "console-cleared", 46 MessageAdded: "console-message-added", 47 RepeatCountUpdated: "repeat-count-updated" 48} 49 50WebInspector.ConsoleModel.prototype = { 51 enableAgent: function() 52 { 53 if (WebInspector.settings.monitoringXHREnabled.get()) 54 ConsoleAgent.setMonitoringXHREnabled(true); 55 56 this._enablingConsole = true; 57 58 /** 59 * @this {WebInspector.ConsoleModel} 60 */ 61 function callback() 62 { 63 delete this._enablingConsole; 64 } 65 ConsoleAgent.enable(callback.bind(this)); 66 }, 67 68 /** 69 * @return {boolean} 70 */ 71 enablingConsole: function() 72 { 73 return !!this._enablingConsole; 74 }, 75 76 /** 77 * @param {!WebInspector.ConsoleMessage} msg 78 * @param {boolean=} isFromBackend 79 */ 80 addMessage: function(msg, isFromBackend) 81 { 82 if (isFromBackend && WebInspector.SourceMap.hasSourceMapRequestHeader(msg.request())) 83 return; 84 85 msg.index = this.messages.length; 86 this.messages.push(msg); 87 this._incrementErrorWarningCount(msg); 88 89 if (isFromBackend) 90 this._previousMessage = msg; 91 92 this._interruptRepeatCount = !isFromBackend; 93 94 this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg); 95 }, 96 97 /** 98 * @param {!WebInspector.ConsoleMessage} msg 99 */ 100 _incrementErrorWarningCount: function(msg) 101 { 102 switch (msg.level) { 103 case WebInspector.ConsoleMessage.MessageLevel.Warning: 104 this.warnings += msg.repeatDelta; 105 break; 106 case WebInspector.ConsoleMessage.MessageLevel.Error: 107 this.errors += msg.repeatDelta; 108 break; 109 } 110 }, 111 112 requestClearMessages: function() 113 { 114 ConsoleAgent.clearMessages(); 115 this.clearMessages(); 116 }, 117 118 clearMessages: function() 119 { 120 this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared); 121 122 this.messages = []; 123 delete this._previousMessage; 124 125 this.errors = 0; 126 this.warnings = 0; 127 }, 128 129 /** 130 * @param {number} count 131 */ 132 _messageRepeatCountUpdated: function(count) 133 { 134 var msg = this._previousMessage; 135 if (!msg) 136 return; 137 138 var prevRepeatCount = msg.totalRepeatCount; 139 140 if (!this._interruptRepeatCount) { 141 msg.repeatDelta = count - prevRepeatCount; 142 msg.repeatCount = msg.repeatCount + msg.repeatDelta; 143 msg.totalRepeatCount = count; 144 msg.updateRepeatCount(); 145 146 this._incrementErrorWarningCount(msg); 147 this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.RepeatCountUpdated, msg); 148 } else { 149 var msgCopy = msg.clone(); 150 msgCopy.totalRepeatCount = count; 151 msgCopy.repeatCount = (count - prevRepeatCount) || 1; 152 msgCopy.repeatDelta = msgCopy.repeatCount; 153 this.addMessage(msgCopy, true); 154 } 155 }, 156 157 __proto__: WebInspector.Object.prototype 158} 159 160/** 161 * @constructor 162 * @param {string} source 163 * @param {string} level 164 * @param {string=} url 165 * @param {number=} line 166 * @param {number=} column 167 * @param {number=} repeatCount 168 */ 169WebInspector.ConsoleMessage = function(source, level, url, line, column, repeatCount) 170{ 171 this.source = source; 172 this.level = level; 173 this.url = url || null; 174 this.line = line || 0; 175 this.column = column || 0; 176 this.message = ""; 177 178 repeatCount = repeatCount || 1; 179 this.repeatCount = repeatCount; 180 this.repeatDelta = repeatCount; 181 this.totalRepeatCount = repeatCount; 182} 183 184WebInspector.ConsoleMessage.prototype = { 185 /** 186 * @return {boolean} 187 */ 188 isErrorOrWarning: function() 189 { 190 return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error); 191 }, 192 193 updateRepeatCount: function() 194 { 195 // Implemented by concrete instances 196 }, 197 198 /** 199 * @return {!WebInspector.ConsoleMessage} 200 */ 201 clone: function() 202 { 203 // Implemented by concrete instances 204 }, 205 206 /** 207 * @return {!WebInspector.DebuggerModel.Location} 208 */ 209 location: function() 210 { 211 // Implemented by concrete instances 212 } 213} 214 215/** 216 * @param {string} source 217 * @param {string} level 218 * @param {string} message 219 * @param {string=} type 220 * @param {string=} url 221 * @param {number=} line 222 * @param {number=} column 223 * @param {number=} repeatCount 224 * @param {!Array.<!RuntimeAgent.RemoteObject>=} parameters 225 * @param {!ConsoleAgent.StackTrace=} stackTrace 226 * @param {!NetworkAgent.RequestId=} requestId 227 * @param {boolean=} isOutdated 228 * @return {!WebInspector.ConsoleMessage} 229 */ 230WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, column, repeatCount, parameters, stackTrace, requestId, isOutdated) 231{ 232} 233 234// Note: Keep these constants in sync with the ones in Console.h 235WebInspector.ConsoleMessage.MessageSource = { 236 XML: "xml", 237 JS: "javascript", 238 Network: "network", 239 ConsoleAPI: "console-api", 240 Storage: "storage", 241 AppCache: "appcache", 242 Rendering: "rendering", 243 CSS: "css", 244 Security: "security", 245 Other: "other", 246 Deprecation: "deprecation" 247} 248 249WebInspector.ConsoleMessage.MessageType = { 250 Log: "log", 251 Dir: "dir", 252 DirXML: "dirxml", 253 Table: "table", 254 Trace: "trace", 255 Clear: "clear", 256 StartGroup: "startGroup", 257 StartGroupCollapsed: "startGroupCollapsed", 258 EndGroup: "endGroup", 259 Assert: "assert", 260 Result: "result", 261 Profile: "profile", 262 ProfileEnd: "profileEnd", 263 Command: "command" 264} 265 266WebInspector.ConsoleMessage.MessageLevel = { 267 Log: "log", 268 Info: "info", 269 Warning: "warning", 270 Error: "error", 271 Debug: "debug" 272} 273 274 275/** 276 * @constructor 277 * @implements {ConsoleAgent.Dispatcher} 278 * @param {!WebInspector.ConsoleModel} console 279 */ 280WebInspector.ConsoleDispatcher = function(console) 281{ 282 this._console = console; 283} 284 285WebInspector.ConsoleDispatcher.prototype = { 286 /** 287 * @param {!ConsoleAgent.ConsoleMessage} payload 288 */ 289 messageAdded: function(payload) 290 { 291 var consoleMessage = WebInspector.ConsoleMessage.create( 292 payload.source, 293 payload.level, 294 payload.text, 295 payload.type, 296 payload.url, 297 payload.line, 298 payload.column, 299 payload.repeatCount, 300 payload.parameters, 301 payload.stackTrace, 302 payload.networkRequestId, 303 this._console._enablingConsole); 304 this._console.addMessage(consoleMessage, true); 305 }, 306 307 /** 308 * @param {number} count 309 */ 310 messageRepeatCountUpdated: function(count) 311 { 312 this._console._messageRepeatCountUpdated(count); 313 }, 314 315 messagesCleared: function() 316 { 317 if (!WebInspector.settings.preserveConsoleLog.get()) 318 this._console.clearMessages(); 319 } 320} 321 322/** 323 * @type {!WebInspector.ConsoleModel} 324 */ 325WebInspector.console; 326