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