Home | History | Annotate | Download | only in front_end
      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 
     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  */
    169 WebInspector.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 
    184 WebInspector.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  */
    230 WebInspector.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
    235 WebInspector.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 
    249 WebInspector.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 
    266 WebInspector.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  */
    280 WebInspector.ConsoleDispatcher = function(console)
    281 {
    282     this._console = console;
    283 }
    284 
    285 WebInspector.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  */
    325 WebInspector.console;
    326