Web Inspector: console.error output broken, does not produce ObjectTree
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Models / IssueMessage.js
1 /*
2  * Copyright (C) 2013 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.IssueMessage = function(source, level, text, url, lineNumber, columnNumber, parameters)
27 {
28     WebInspector.Object.call(this);
29
30     this._level = level;
31     this._text = text;
32
33     // FIXME: Move to a SourceCodeLocation.
34
35     // FIXME <http://webkit.org/b/76404>: Remove the string equality checks for undefined
36     // once we don't get that value anymore from WebCore.
37
38     // FIXME: If the URL is undefined, get the URL from the stacktrace.
39     if (url && url !== "undefined")
40         this._url = url;
41
42     if (typeof lineNumber === "number" && lineNumber >= 0)
43         this._lineNumber = lineNumber;
44
45     if (typeof columnNumber === "number" && columnNumber >= 0)
46         this._columnNumber = columnNumber;
47
48     // FIXME: <https://webkit.org/b/142553> Web Inspector: Merge IssueMessage/ConsoleMessage - both attempt to modify the Console Messages parameter independently
49
50     if (parameters && parameters !== "undefined") {
51         this._parameters = [];
52         for (var i = 0; i < parameters.length; ++i) {
53             if (parameters[i] instanceof WebInspector.RemoteObject) {
54                 this._parameters.push(parameters[i]);
55                 continue;
56             }
57
58             if (typeof parameters[i] === "object")
59                 this._parameters.push(WebInspector.RemoteObject.fromPayload(parameters[i]));
60             else
61                 this._parameters.push(WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]));
62         }
63     }
64
65     this._formatTextIfNecessary();
66
67     switch (source) {
68     case "javascript":
69         // FIXME: It would be nice if we had this information (the specific type of JavaScript error)
70         // as part of the data passed from WebCore, instead of having to determine it ourselves.
71         var prefixRegex = /^([^:]+): (?:DOM Exception \d+: )?/;
72         var match = prefixRegex.exec(this._text);
73         if (match && match[1] in WebInspector.IssueMessage.Type._prefixTypeMap) {
74             this._type = WebInspector.IssueMessage.Type._prefixTypeMap[match[1]];
75             this._text = this._text.substring(match[0].length);
76         } else
77             this._type = WebInspector.IssueMessage.Type.OtherIssue;
78         break;
79
80     case "html":
81     case "css":
82     case "wml":
83     case "xml":
84         this._type = WebInspector.IssueMessage.Type.PageIssue;
85         break;
86
87     case "network":
88         this._type = WebInspector.IssueMessage.Type.NetworkIssue;
89         break;
90
91     case "console-api":
92     case "other":
93         this._type = WebInspector.IssueMessage.Type.OtherIssue;
94         break;
95
96     default:
97         console.error("Unknown issue source:", source);
98         this._type = WebInspector.IssueMessage.Type.OtherIssue;
99     }
100 };
101
102 WebInspector.IssueMessage.Level = {
103     Error: "error",
104     Warning: "warning"
105 };
106
107 WebInspector.IssueMessage.Type = {
108     SemanticIssue: "issue-message-type-semantic-issue",
109     RangeIssue: "issue-message-type-range-issue",
110     ReferenceIssue: "issue-message-type-reference-issue",
111     TypeIssue: "issue-message-type-type-issue",
112     PageIssue: "issue-message-type-page-issue",
113     NetworkIssue: "issue-message-type-network-issue",
114     SecurityIssue: "issue-message-type-security-issue",
115     OtherIssue: "issue-message-type-other-issue"
116 };
117
118 WebInspector.IssueMessage.Type._prefixTypeMap = {
119     "SyntaxError": WebInspector.IssueMessage.Type.SemanticIssue,
120     "URIError": WebInspector.IssueMessage.Type.SemanticIssue,
121     "EvalError": WebInspector.IssueMessage.Type.SemanticIssue,
122     "INVALID_CHARACTER_ERR": WebInspector.IssueMessage.Type.SemanticIssue,
123     "SYNTAX_ERR": WebInspector.IssueMessage.Type.SemanticIssue,
124
125     "RangeError": WebInspector.IssueMessage.Type.RangeIssue,
126     "INDEX_SIZE_ERR": WebInspector.IssueMessage.Type.RangeIssue,
127     "DOMSTRING_SIZE_ERR": WebInspector.IssueMessage.Type.RangeIssue,
128
129     "ReferenceError": WebInspector.IssueMessage.Type.ReferenceIssue,
130     "HIERARCHY_REQUEST_ERR": WebInspector.IssueMessage.Type.ReferenceIssue,
131     "INVALID_STATE_ERR": WebInspector.IssueMessage.Type.ReferenceIssue,
132     "NOT_FOUND_ERR": WebInspector.IssueMessage.Type.ReferenceIssue,
133     "WRONG_DOCUMENT_ERR": WebInspector.IssueMessage.Type.ReferenceIssue,
134
135     "TypeError": WebInspector.IssueMessage.Type.TypeIssue,
136     "INVALID_NODE_TYPE_ERR": WebInspector.IssueMessage.Type.TypeIssue,
137     "TYPE_MISMATCH_ERR": WebInspector.IssueMessage.Type.TypeIssue,
138
139     "SECURITY_ERR": WebInspector.IssueMessage.Type.SecurityIssue,
140
141     "NETWORK_ERR": WebInspector.IssueMessage.Type.NetworkIssue,
142
143     "ABORT_ERR": WebInspector.IssueMessage.Type.OtherIssue,
144     "DATA_CLONE_ERR": WebInspector.IssueMessage.Type.OtherIssue,
145     "INUSE_ATTRIBUTE_ERR": WebInspector.IssueMessage.Type.OtherIssue,
146     "INVALID_ACCESS_ERR": WebInspector.IssueMessage.Type.OtherIssue,
147     "INVALID_MODIFICATION_ERR": WebInspector.IssueMessage.Type.OtherIssue,
148     "NAMESPACE_ERR": WebInspector.IssueMessage.Type.OtherIssue,
149     "NOT_SUPPORTED_ERR": WebInspector.IssueMessage.Type.OtherIssue,
150     "NO_DATA_ALLOWED_ERR": WebInspector.IssueMessage.Type.OtherIssue,
151     "NO_MODIFICATION_ALLOWED_ERR": WebInspector.IssueMessage.Type.OtherIssue,
152     "QUOTA_EXCEEDED_ERR": WebInspector.IssueMessage.Type.OtherIssue,
153     "TIMEOUT_ERR": WebInspector.IssueMessage.Type.OtherIssue,
154     "URL_MISMATCH_ERR": WebInspector.IssueMessage.Type.OtherIssue,
155     "VALIDATION_ERR": WebInspector.IssueMessage.Type.OtherIssue
156 };
157
158 WebInspector.IssueMessage.Type.displayName = function(type)
159 {
160     switch(type) {
161     case WebInspector.IssueMessage.Type.SemanticIssue:
162         return WebInspector.UIString("Semantic Issue");
163     case WebInspector.IssueMessage.Type.RangeIssue:
164         return WebInspector.UIString("Range Issue");
165     case WebInspector.IssueMessage.Type.ReferenceIssue:
166         return WebInspector.UIString("Reference Issue");
167     case WebInspector.IssueMessage.Type.TypeIssue:
168         return WebInspector.UIString("Type Issue");
169     case WebInspector.IssueMessage.Type.PageIssue:
170         return WebInspector.UIString("Page Issue");
171     case WebInspector.IssueMessage.Type.NetworkIssue:
172         return WebInspector.UIString("Network Issue");
173     case WebInspector.IssueMessage.Type.SecurityIssue:
174         return WebInspector.UIString("Security Issue");
175     case WebInspector.IssueMessage.Type.OtherIssue:
176         return WebInspector.UIString("Other Issue");
177     default:
178         console.error("Unknown issue message type:", type);
179         return WebInspector.UIString("Other Issue");
180     }
181 };
182
183 WebInspector.IssueMessage.prototype = {
184     constructor: WebInspector.IssueMessage,
185     __proto__: WebInspector.Object.prototype,
186
187     get type()
188     {
189         return this._type;
190     },
191
192     get level()
193     {
194         return this._level;
195     },
196
197     get text()
198     {
199         return this._text;
200     },
201
202     get url()
203     {
204         return this._url;
205     },
206
207     get lineNumber()
208     {
209         return this._lineNumber;
210     },
211
212     get columnNumber()
213     {
214         return this._columnNumber;
215     },
216
217     // Private
218
219     _formatTextIfNecessary()
220     {
221         if (!this._parameters)
222             return;
223
224         if (WebInspector.RemoteObject.type(this._parameters[0]) !== "string")
225             return;
226
227         function valueFormatter(obj)
228         {
229             return obj.description;
230         }
231
232         var formatters = {};
233         formatters.o = valueFormatter;
234         formatters.s = valueFormatter;
235         formatters.f = valueFormatter;
236         formatters.i = valueFormatter;
237         formatters.d = valueFormatter;
238
239         function append(a, b)
240         {
241             a += b;
242             return a;
243         }
244
245         var result = String.format(this._parameters[0].description, this._parameters.slice(1), formatters, "", append);
246         var resultText = result.formattedResult;
247
248         for (var i = 0; i < result.unusedSubstitutions.length; ++i)
249             resultText += " " + result.unusedSubstitutions[i].description;
250
251         this._text = resultText;
252     }
253 };