Web Inspector: console should show an icon for console.info() messages
[WebKit-https.git] / Source / JavaScriptCore / runtime / ConsolePrototype.cpp
1 /*
2  * Copyright (C) 2014 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "ConsolePrototype.h"
28
29 #include "ConsoleClient.h"
30 #include "Error.h"
31 #include "ExceptionHelpers.h"
32 #include "JSCInlines.h"
33 #include "JSConsole.h"
34 #include "ScriptArguments.h"
35 #include "ScriptCallStackFactory.h"
36
37 namespace JSC {
38
39 const ClassInfo ConsolePrototype::s_info = { "ConsolePrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(ConsolePrototype) };
40
41 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDebug(ExecState*);
42 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncError(ExecState*);
43 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState*);
44 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncInfo(ExecState*);
45 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState*);
46 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncClear(ExecState*);
47 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDir(ExecState*);
48 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDirXML(ExecState*);
49 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTable(ExecState*);
50 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTrace(ExecState*);
51 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncAssert(ExecState*);
52 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncCount(ExecState*);
53 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfile(ExecState*);
54 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfileEnd(ExecState*);
55 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTime(ExecState*);
56 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeEnd(ExecState*);
57 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeStamp(ExecState*);
58 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroup(ExecState*);
59 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupCollapsed(ExecState*);
60 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupEnd(ExecState*);
61
62 void ConsolePrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
63 {
64     Base::finishCreation(vm);
65     ASSERT(inherits(info()));
66     vm.prototypeMap.addPrototype(this);
67
68     // For legacy reasons, console properties are enumerable, writable, deleteable,
69     // and all have a length of 0. This may change if Console is standardized.
70
71     JSC_NATIVE_FUNCTION("debug", consoleProtoFuncDebug, None, 0);
72     JSC_NATIVE_FUNCTION("error", consoleProtoFuncError, None, 0);
73     JSC_NATIVE_FUNCTION("log", consoleProtoFuncLog, None, 0);
74     JSC_NATIVE_FUNCTION("info", consoleProtoFuncInfo, None, 0);
75     JSC_NATIVE_FUNCTION("warn", consoleProtoFuncWarn, None, 0);
76
77     JSC_NATIVE_FUNCTION("clear", consoleProtoFuncClear, None, 0);
78     JSC_NATIVE_FUNCTION("dir", consoleProtoFuncDir, None, 0);
79     JSC_NATIVE_FUNCTION("dirxml", consoleProtoFuncDirXML, None, 0);
80     JSC_NATIVE_FUNCTION("table", consoleProtoFuncTable, None, 0);
81     JSC_NATIVE_FUNCTION("trace", consoleProtoFuncTrace, None, 0);
82     JSC_NATIVE_FUNCTION("assert", consoleProtoFuncAssert, None, 0);
83     JSC_NATIVE_FUNCTION("count", consoleProtoFuncCount, None, 0);
84     JSC_NATIVE_FUNCTION("profile", consoleProtoFuncProfile, None, 0);
85     JSC_NATIVE_FUNCTION("profileEnd", consoleProtoFuncProfileEnd, None, 0);
86     JSC_NATIVE_FUNCTION("time", consoleProtoFuncTime, None, 0);
87     JSC_NATIVE_FUNCTION("timeEnd", consoleProtoFuncTimeEnd, None, 0);
88     JSC_NATIVE_FUNCTION("timeStamp", consoleProtoFuncTimeStamp, None, 0);
89     JSC_NATIVE_FUNCTION("group", consoleProtoFuncGroup, None, 0);
90     JSC_NATIVE_FUNCTION("groupCollapsed", consoleProtoFuncGroupCollapsed, None, 0);
91     JSC_NATIVE_FUNCTION("groupEnd", consoleProtoFuncGroupEnd, None, 0);
92 }
93
94 static String valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValue value)
95 {
96     if (value.isUndefinedOrNull())
97         return String();
98     return value.toString(exec)->value(exec);
99 }
100
101 static EncodedJSValue consoleLogWithLevel(ExecState* exec, MessageLevel level)
102 {
103     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
104     if (!castedThis)
105         return throwVMTypeError(exec);
106     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
107     ConsoleClient* client = castedThis->globalObject()->consoleClient();
108     if (!client)
109         return JSValue::encode(jsUndefined());
110
111     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
112     client->logWithLevel(exec, arguments.release(), level);
113     return JSValue::encode(jsUndefined());
114 }
115
116 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDebug(ExecState* exec)
117 {
118     return consoleLogWithLevel(exec, MessageLevel::Debug);
119 }
120
121 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncError(ExecState* exec)
122 {
123     return consoleLogWithLevel(exec, MessageLevel::Error);
124 }
125
126 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState* exec)
127 {
128     return consoleLogWithLevel(exec, MessageLevel::Log);
129 }
130
131 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncInfo(ExecState* exec)
132 {
133     return consoleLogWithLevel(exec, MessageLevel::Info);
134 }
135
136 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState* exec)
137 {
138     return consoleLogWithLevel(exec, MessageLevel::Warning);
139 }
140
141 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncClear(ExecState* exec)
142 {
143     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
144     if (!castedThis)
145         return throwVMTypeError(exec);
146     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
147     ConsoleClient* client = castedThis->globalObject()->consoleClient();
148     if (!client)
149         return JSValue::encode(jsUndefined());
150
151     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
152     client->clear(exec, arguments.release());
153     return JSValue::encode(jsUndefined());
154 }
155
156 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDir(ExecState* exec)
157 {
158     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
159     if (!castedThis)
160         return throwVMTypeError(exec);
161     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
162     ConsoleClient* client = castedThis->globalObject()->consoleClient();
163     if (!client)
164         return JSValue::encode(jsUndefined());
165
166     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
167     client->dir(exec, arguments.release());
168     return JSValue::encode(jsUndefined());
169 }
170
171 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDirXML(ExecState* exec)
172 {
173     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
174     if (!castedThis)
175         return throwVMTypeError(exec);
176     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
177     ConsoleClient* client = castedThis->globalObject()->consoleClient();
178     if (!client)
179         return JSValue::encode(jsUndefined());
180
181     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
182     client->dirXML(exec, arguments.release());
183     return JSValue::encode(jsUndefined());
184 }
185
186 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTable(ExecState* exec)
187 {
188     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
189     if (!castedThis)
190         return throwVMTypeError(exec);
191     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
192     ConsoleClient* client = castedThis->globalObject()->consoleClient();
193     if (!client)
194         return JSValue::encode(jsUndefined());
195
196     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
197     client->table(exec, arguments.release());
198     return JSValue::encode(jsUndefined());
199 }
200
201 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTrace(ExecState* exec)
202 {
203     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
204     if (!castedThis)
205         return throwVMTypeError(exec);
206     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
207     ConsoleClient* client = castedThis->globalObject()->consoleClient();
208     if (!client)
209         return JSValue::encode(jsUndefined());
210
211     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
212     client->trace(exec, arguments.release());
213     return JSValue::encode(jsUndefined());
214 }
215
216 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncAssert(ExecState* exec)
217 {
218     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
219     if (!castedThis)
220         return throwVMTypeError(exec);
221     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
222     ConsoleClient* client = castedThis->globalObject()->consoleClient();
223     if (!client)
224         return JSValue::encode(jsUndefined());
225
226     bool condition(exec->argument(0).toBoolean(exec));
227     if (exec->hadException())
228         return JSValue::encode(jsUndefined());
229
230     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 1));
231     client->assertCondition(exec, arguments.release(), condition);
232     return JSValue::encode(jsUndefined());
233 }
234
235 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncCount(ExecState* exec)
236 {
237     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
238     if (!castedThis)
239         return throwVMTypeError(exec);
240     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
241     ConsoleClient* client = castedThis->globalObject()->consoleClient();
242     if (!client)
243         return JSValue::encode(jsUndefined());
244
245     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
246     client->count(exec, arguments.release());
247     return JSValue::encode(jsUndefined());
248 }
249
250 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfile(ExecState* exec)
251 {
252     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
253     if (!castedThis)
254         return throwVMTypeError(exec);
255     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
256     ConsoleClient* client = castedThis->globalObject()->consoleClient();
257     if (!client)
258         return JSValue::encode(jsUndefined());
259
260     size_t argsCount = exec->argumentCount();
261     if (argsCount <= 0) {
262         client->profile(exec, String());
263         return JSValue::encode(jsUndefined());
264     }
265
266     const String& title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
267     if (exec->hadException())
268         return JSValue::encode(jsUndefined());
269
270     client->profile(exec, title);
271     return JSValue::encode(jsUndefined());
272 }
273
274 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfileEnd(ExecState* exec)
275 {
276     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
277     if (!castedThis)
278         return throwVMTypeError(exec);
279     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
280     ConsoleClient* client = castedThis->globalObject()->consoleClient();
281     if (!client)
282         return JSValue::encode(jsUndefined());
283
284     size_t argsCount = exec->argumentCount();
285     if (argsCount <= 0) {
286         client->profileEnd(exec, String());
287         return JSValue::encode(jsUndefined());
288     }
289
290     const String& title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
291     if (exec->hadException())
292         return JSValue::encode(jsUndefined());
293
294     client->profileEnd(exec, title);
295     return JSValue::encode(jsUndefined());
296 }
297
298 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTime(ExecState* exec)
299 {
300     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
301     if (!castedThis)
302         return throwVMTypeError(exec);
303     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
304     ConsoleClient* client = castedThis->globalObject()->consoleClient();
305     if (!client)
306         return JSValue::encode(jsUndefined());
307
308     if (exec->argumentCount() < 1)
309         return throwVMError(exec, createNotEnoughArgumentsError(exec));
310
311     const String& title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
312     if (exec->hadException())
313         return JSValue::encode(jsUndefined());
314
315     client->time(exec, title);
316     return JSValue::encode(jsUndefined());
317 }
318
319 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeEnd(ExecState* exec)
320 {
321     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
322     if (!castedThis)
323         return throwVMTypeError(exec);
324     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
325     ConsoleClient* client = castedThis->globalObject()->consoleClient();
326     if (!client)
327         return JSValue::encode(jsUndefined());
328
329     if (exec->argumentCount() < 1)
330         return throwVMError(exec, createNotEnoughArgumentsError(exec));
331
332     const String& title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
333     if (exec->hadException())
334         return JSValue::encode(jsUndefined());
335
336     client->timeEnd(exec, title);
337     return JSValue::encode(jsUndefined());
338 }
339
340 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeStamp(ExecState* exec)
341 {
342     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
343     if (!castedThis)
344         return throwVMTypeError(exec);
345     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
346     ConsoleClient* client = castedThis->globalObject()->consoleClient();
347     if (!client)
348         return JSValue::encode(jsUndefined());
349
350     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
351     client->timeStamp(exec, arguments.release());
352     return JSValue::encode(jsUndefined());
353 }
354
355 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroup(ExecState* exec)
356 {
357     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
358     if (!castedThis)
359         return throwVMTypeError(exec);
360     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
361     ConsoleClient* client = castedThis->globalObject()->consoleClient();
362     if (!client)
363         return JSValue::encode(jsUndefined());
364
365     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
366     client->group(exec, arguments.release());
367     return JSValue::encode(jsUndefined());
368 }
369
370 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupCollapsed(ExecState* exec)
371 {
372     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
373     if (!castedThis)
374         return throwVMTypeError(exec);
375     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
376     ConsoleClient* client = castedThis->globalObject()->consoleClient();
377     if (!client)
378         return JSValue::encode(jsUndefined());
379
380     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
381     client->groupCollapsed(exec, arguments.release());
382     return JSValue::encode(jsUndefined());
383 }
384
385 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupEnd(ExecState* exec)
386 {
387     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
388     if (!castedThis)
389         return throwVMTypeError(exec);
390     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
391     ConsoleClient* client = castedThis->globalObject()->consoleClient();
392     if (!client)
393         return JSValue::encode(jsUndefined());
394
395     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
396     client->groupEnd(exec, arguments.release());
397     return JSValue::encode(jsUndefined());
398 }
399
400 }