Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / bindings / PresentationConsoleMessageHelper.js
1 /*
2  * Copyright (C) 2012 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  * @param {!WebInspector.Workspace} workspace
34  */
35 WebInspector.PresentationConsoleMessageHelper = function(workspace)
36 {
37     this._workspace = workspace;
38
39     /** @type {!Object.<string, !Array.<!WebInspector.ConsoleMessage>>} */
40     this._pendingConsoleMessages = {};
41
42     /** @type {!Array.<!WebInspector.PresentationConsoleMessage>} */
43     this._presentationConsoleMessages = [];
44
45     /** @type {!Map.<!WebInspector.UISourceCode, !Array.<!WebInspector.PresentationConsoleMessage>>} */
46     this._uiSourceCodeToMessages = new Map();
47
48     /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.Object>} */
49     this._uiSourceCodeToEventTarget = new Map();
50
51     workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
52     workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
53     WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
54     WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this);
55     WebInspector.multitargetConsoleModel.messages().forEach(this._consoleMessageAdded, this);
56     WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
57     WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
58     WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
59 }
60
61 /**
62  * @enum {string}
63  */
64 WebInspector.PresentationConsoleMessageHelper.Events = {
65     ConsoleMessageAdded: "ConsoleMessageAdded",
66     ConsoleMessageRemoved: "ConsoleMessageRemoved",
67     ConsoleMessagesCleared: "ConsoleMessagesCleared",
68 }
69
70 WebInspector.PresentationConsoleMessageHelper.prototype = {
71     /**
72      * @param {!WebInspector.PresentationConsoleMessageHelper.Events} eventType
73      * @param {!WebInspector.UISourceCode} uiSourceCode
74      * @param {function(!WebInspector.Event)} listener
75      * @param {!Object=} thisObject
76      */
77     addConsoleMessageEventListener: function(eventType, uiSourceCode, listener, thisObject)
78     {
79         var target = this._uiSourceCodeToEventTarget.get(uiSourceCode);
80         if (!target) {
81             target = new WebInspector.Object();
82             this._uiSourceCodeToEventTarget.set(uiSourceCode, target);
83         }
84         target.addEventListener(eventType, listener, thisObject);
85     },
86
87     /**
88      * @param {!WebInspector.PresentationConsoleMessageHelper.Events} eventType
89      * @param {!WebInspector.UISourceCode} uiSourceCode
90      * @param {function(!WebInspector.Event)} listener
91      * @param {!Object=} thisObject
92      */
93     removeConsoleMessageEventListener: function(eventType, uiSourceCode, listener, thisObject)
94     {
95         var target = this._uiSourceCodeToEventTarget.get(uiSourceCode);
96         if (!target)
97             return;
98         target.removeEventListener(eventType, listener, thisObject);
99     },
100
101     /**
102      * @param {!WebInspector.UISourceCode} uiSourceCode
103      * @return {!Array.<!WebInspector.PresentationConsoleMessage>}
104      */
105     consoleMessages: function(uiSourceCode)
106     {
107         return this._uiSourceCodeToMessages.get(uiSourceCode) || [];
108     },
109
110     /**
111      * @param {!WebInspector.PresentationConsoleMessageHelper.Events} eventType
112      * @param {!WebInspector.UISourceCode} uiSourceCode
113      * @param {!WebInspector.PresentationConsoleMessage=} message
114      */
115     _dispatchConsoleEvent: function(eventType, uiSourceCode, message)
116     {
117         var target = this._uiSourceCodeToEventTarget.get(uiSourceCode);
118         if (!target)
119             return;
120         target.dispatchEventToListeners(eventType, message);
121     },
122
123     /**
124      * @param {!WebInspector.Event} event
125      */
126     _uiSourceCodeRemoved: function(event)
127     {
128         var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
129         this._uiSourceCodeToEventTarget.remove(uiSourceCode);
130         this._uiSourceCodeToMessages.remove(uiSourceCode);
131     },
132
133     /**
134      * @param {!WebInspector.Event} event
135      */
136     _projectRemoved: function(event)
137     {
138         var project = /** @type {!WebInspector.Project} */ (event.data);
139         var uiSourceCodes = project.uiSourceCodes();
140         for (var i = 0; i < uiSourceCodes.length; ++i) {
141             this._uiSourceCodeToEventTarget.remove(uiSourceCodes[i]);
142             this._uiSourceCodeToMessages.remove(uiSourceCodes[i]);
143         }
144     },
145
146     /**
147      * @param {!WebInspector.Event} event
148      */
149     _onConsoleMessageAdded: function(event)
150     {
151         var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
152         this._consoleMessageAdded(message)
153     },
154
155     /**
156      * @param {!WebInspector.ConsoleMessage} message
157      */
158     _consoleMessageAdded: function(message)
159     {
160         if (!message.url || !message.isErrorOrWarning())
161             return;
162
163         var rawLocation = this._rawLocation(message);
164         if (rawLocation)
165             this._addConsoleMessageToScript(message, rawLocation);
166         else
167             this._addPendingConsoleMessage(message);
168     },
169
170     /**
171      * @param {!WebInspector.ConsoleMessage} message
172      * @return {?WebInspector.DebuggerModel.Location}
173      */
174     _rawLocation: function(message)
175     {
176         // FIXME(62725): stack trace line/column numbers are one-based.
177         var lineNumber = message.stackTrace ? message.stackTrace[0].lineNumber - 1 : message.line - 1;
178         var columnNumber = message.stackTrace && message.stackTrace[0].columnNumber ? message.stackTrace[0].columnNumber - 1 : 0;
179         if (message.scriptId)
180             return message.target().debuggerModel.createRawLocationByScriptId(message.scriptId, message.url || "", lineNumber, columnNumber);
181         return message.target().debuggerModel.createRawLocationByURL(message.url || "", lineNumber, columnNumber);
182     },
183
184     /**
185      * @param {!WebInspector.ConsoleMessage} message
186      * @param {!WebInspector.DebuggerModel.Location} rawLocation
187      */
188     _addConsoleMessageToScript: function(message, rawLocation)
189     {
190         this._presentationConsoleMessages.push(new WebInspector.PresentationConsoleMessage(message, rawLocation));
191     },
192
193     /**
194      * @param {!WebInspector.ConsoleMessage} message
195      */
196     _addPendingConsoleMessage: function(message)
197     {
198         if (!message.url)
199             return;
200         if (!this._pendingConsoleMessages[message.url])
201             this._pendingConsoleMessages[message.url] = [];
202         this._pendingConsoleMessages[message.url].push(message);
203     },
204
205     /**
206      * @param {!WebInspector.Event} event
207      */
208     _parsedScriptSource: function(event)
209     {
210         var script = /** @type {!WebInspector.Script} */ (event.data);
211
212         var messages = this._pendingConsoleMessages[script.sourceURL];
213         if (!messages)
214             return;
215
216         var pendingMessages = [];
217         for (var i = 0; i < messages.length; i++) {
218             var message = messages[i];
219             var rawLocation = this._rawLocation(message);
220             if (script.target() === message.target() && script.scriptId === rawLocation.scriptId)
221                 this._addConsoleMessageToScript(message, rawLocation);
222             else
223                 pendingMessages.push(message);
224         }
225
226         if (pendingMessages.length)
227             this._pendingConsoleMessages[script.sourceURL] = pendingMessages;
228         else
229             delete this._pendingConsoleMessages[script.sourceURL];
230     },
231
232     /**
233      * @param {!WebInspector.PresentationConsoleMessage} message
234      */
235     _presentationConsoleMessageAdded: function(message)
236     {
237         var uiSourceCode = message._uiLocation.uiSourceCode;
238         var messages = this._uiSourceCodeToMessages.get(uiSourceCode);
239         if (!messages) {
240             messages = [];
241             this._uiSourceCodeToMessages.set(uiSourceCode, messages);
242         }
243         messages.push(message);
244         this._dispatchConsoleEvent(WebInspector.PresentationConsoleMessageHelper.Events.ConsoleMessageAdded, uiSourceCode, message);
245     },
246
247     /**
248      * @param {!WebInspector.PresentationConsoleMessage} message
249      */
250     _presentationConsoleMessageRemoved: function(message)
251     {
252         var uiSourceCode = message._uiLocation.uiSourceCode;
253         var messages = this._uiSourceCodeToMessages.get(uiSourceCode);
254         if (!messages)
255             return;
256         messages.remove(message);
257         this._dispatchConsoleEvent(WebInspector.PresentationConsoleMessageHelper.Events.ConsoleMessageRemoved, uiSourceCode, message);
258     },
259
260     _consoleCleared: function()
261     {
262         this._pendingConsoleMessages = {};
263         for (var i = 0; i < this._presentationConsoleMessages.length; ++i)
264             this._presentationConsoleMessages[i].dispose();
265         this._presentationConsoleMessages = [];
266         var targets = this._uiSourceCodeToEventTarget.valuesArray();
267         for (var i = 0; i < targets.length; ++i)
268             targets[i].dispatchEventToListeners(WebInspector.PresentationConsoleMessageHelper.Events.ConsoleMessagesCleared);
269         this._uiSourceCodeToMessages.clear();
270     },
271
272     _debuggerReset: function()
273     {
274         this._consoleCleared();
275     }
276 }
277
278 /**
279  * @constructor
280  * @param {!WebInspector.ConsoleMessage} message
281  * @param {!WebInspector.DebuggerModel.Location} rawLocation
282  */
283 WebInspector.PresentationConsoleMessage = function(message, rawLocation)
284 {
285     this.originalMessage = message;
286     this._liveLocation = WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this._updateLocation.bind(this));
287 }
288
289 WebInspector.PresentationConsoleMessage.prototype = {
290     /**
291      * @param {!WebInspector.UILocation} uiLocation
292      */
293     _updateLocation: function(uiLocation)
294     {
295         if (this._uiLocation)
296             WebInspector.presentationConsoleMessageHelper._presentationConsoleMessageRemoved(this);
297         this._uiLocation = uiLocation;
298         WebInspector.presentationConsoleMessageHelper._presentationConsoleMessageAdded(this);
299     },
300
301     get lineNumber()
302     {
303         return this._uiLocation.lineNumber;
304     },
305
306     dispose: function()
307     {
308         this._liveLocation.dispose();
309     }
310 }
311
312 /** @type {!WebInspector.PresentationConsoleMessageHelper} */
313 WebInspector.presentationConsoleMessageHelper;