2 * Copyright (C) 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "ChromeClient.h"
35 #include "FrameLoader.h"
36 #include "FrameTree.h"
37 #include "InspectorConsoleInstrumentation.h"
38 #include "InspectorController.h"
39 #include "MemoryInfo.h"
41 #include "PageGroup.h"
42 #include "PlatformString.h"
43 #include "ScriptArguments.h"
44 #include "ScriptCallStack.h"
45 #include "ScriptProfile.h"
46 #include "ScriptProfiler.h"
47 #include "ScriptValue.h"
49 #include <wtf/UnusedParam.h>
50 #include <wtf/text/CString.h>
52 #if PLATFORM(CHROMIUM)
53 #include "TraceEvent.h"
62 Console::Console(Frame* frame)
63 : DOMWindowProperty(frame)
71 static void printSourceURLAndLine(const String& sourceURL, unsigned lineNumber)
73 if (!sourceURL.isEmpty()) {
75 printf("%s:%d: ", sourceURL.utf8().data(), lineNumber);
77 printf("%s: ", sourceURL.utf8().data());
81 static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel level)
83 const char* sourceString;
85 case HTMLMessageSource:
86 sourceString = "HTML";
88 case XMLMessageSource:
94 case NetworkMessageSource:
95 sourceString = "NETWORK";
97 case ConsoleAPIMessageSource:
98 sourceString = "CONSOLEAPI";
100 case OtherMessageSource:
101 sourceString = "OTHER";
104 ASSERT_NOT_REACHED();
105 sourceString = "UNKNOWN";
109 const char* levelString;
111 case TipMessageLevel:
114 case LogMessageLevel:
117 case WarningMessageLevel:
118 levelString = "WARN";
120 case ErrorMessageLevel:
121 levelString = "ERROR";
123 case DebugMessageLevel:
124 levelString = "DEBUG";
127 ASSERT_NOT_REACHED();
128 levelString = "UNKNOWN";
132 printf("%s %s:", sourceString, levelString);
135 void Console::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack)
137 addMessage(source, type, level, message, String(), 0, callStack);
140 void Console::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack> callStack)
143 if (muteCount && source != ConsoleAPIMessageSource)
146 Page* page = this->page();
150 page->chrome()->client()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL);
153 InspectorInstrumentation::addMessageToConsole(page, source, type, level, message, 0, callStack);
155 InspectorInstrumentation::addMessageToConsole(page, source, type, level, message, sourceURL, lineNumber);
157 if (!Console::shouldPrintExceptions())
160 printSourceURLAndLine(sourceURL, lineNumber);
161 printMessageSourceAndLevelPrefix(source, level);
163 printf(" %s\n", message.utf8().data());
166 void Console::addMessage(MessageType type, MessageLevel level, PassRefPtr<ScriptArguments> prpArguments, PassRefPtr<ScriptCallStack> prpCallStack, bool acceptNoArguments)
168 RefPtr<ScriptArguments> arguments = prpArguments;
169 RefPtr<ScriptCallStack> callStack = prpCallStack;
171 Page* page = this->page();
175 const ScriptCallFrame& lastCaller = callStack->at(0);
177 if (!acceptNoArguments && !arguments->argumentCount())
180 if (Console::shouldPrintExceptions()) {
181 printSourceURLAndLine(lastCaller.sourceURL(), 0);
182 printMessageSourceAndLevelPrefix(ConsoleAPIMessageSource, level);
184 for (unsigned i = 0; i < arguments->argumentCount(); ++i) {
186 if (arguments->argumentAt(i).getString(arguments->globalState(), argAsString))
187 printf(" %s", argAsString.utf8().data());
193 if (arguments->getFirstArgumentAsString(message))
194 page->chrome()->client()->addMessageToConsole(ConsoleAPIMessageSource, type, level, message, lastCaller.lineNumber(), lastCaller.sourceURL());
196 InspectorInstrumentation::addMessageToConsole(page, ConsoleAPIMessageSource, type, level, message, arguments, callStack);
199 void Console::debug(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
201 #if ENABLE(TIZEN_DISPLAY_MESSAGE_TO_CONSOLE)
202 addMessage(LogMessageType, LogMessageLevel, arguments, callStack);
205 // In Firebug, console.debug has the same behavior as console.log. So we'll do the same.
206 log(arguments, callStack);
209 void Console::error(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
211 addMessage(LogMessageType, ErrorMessageLevel, arguments, callStack);
214 void Console::info(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
216 log(arguments, callStack);
219 void Console::log(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
221 addMessage(LogMessageType, LogMessageLevel, arguments, callStack);
224 void Console::warn(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
226 addMessage(LogMessageType, WarningMessageLevel, arguments, callStack);
229 void Console::dir(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
231 addMessage(DirMessageType, LogMessageLevel, arguments, callStack);
234 void Console::dirxml(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
236 addMessage(DirXMLMessageType, LogMessageLevel, arguments, callStack);
239 void Console::trace(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> prpCallStack)
241 RefPtr<ScriptCallStack> callStack = prpCallStack;
242 addMessage(TraceMessageType, LogMessageLevel, arguments, callStack, true);
244 if (!shouldPrintExceptions())
247 printf("Stack Trace\n");
248 for (unsigned i = 0; i < callStack->size(); ++i) {
249 String functionName = String(callStack->at(i).functionName());
250 printf("\t%s\n", functionName.utf8().data());
254 void Console::assertCondition(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack, bool condition)
259 addMessage(AssertMessageType, ErrorMessageLevel, arguments, callStack, true);
262 void Console::count(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
264 InspectorInstrumentation::consoleCount(page(), arguments, callStack);
267 void Console::markTimeline(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack>)
269 InspectorInstrumentation::consoleTimeStamp(page(), arguments);
272 #if ENABLE(JAVASCRIPT_DEBUGGER)
274 void Console::profile(const String& title, ScriptState* state, PassRefPtr<ScriptCallStack> callStack)
276 Page* page = this->page();
280 // FIXME: log a console message when profiling is disabled.
281 if (!InspectorInstrumentation::profilerEnabled(page))
284 String resolvedTitle = title;
285 if (title.isNull()) // no title so give it the next user initiated profile title.
286 resolvedTitle = InspectorInstrumentation::getCurrentUserInitiatedProfileName(page, true);
288 ScriptProfiler::start(state, resolvedTitle);
290 const ScriptCallFrame& lastCaller = callStack->at(0);
291 InspectorInstrumentation::addStartProfilingMessageToConsole(page, resolvedTitle, lastCaller.lineNumber(), lastCaller.sourceURL());
294 void Console::profileEnd(const String& title, ScriptState* state, PassRefPtr<ScriptCallStack> callStack)
296 Page* page = this->page();
300 if (!InspectorInstrumentation::profilerEnabled(page))
303 RefPtr<ScriptProfile> profile = ScriptProfiler::stop(state, title);
307 m_profiles.append(profile);
308 InspectorInstrumentation::addProfile(page, profile, callStack);
313 void Console::time(const String& title)
315 InspectorInstrumentation::startConsoleTiming(page(), title);
316 #if PLATFORM(CHROMIUM)
317 TRACE_EVENT_COPY_ASYNC_BEGIN0("webkit", title.utf8().data(), this);
321 void Console::timeEnd(PassRefPtr<ScriptArguments>, PassRefPtr<ScriptCallStack> callStack, const String& title)
323 #if PLATFORM(CHROMIUM)
324 TRACE_EVENT_COPY_ASYNC_END0("webkit", title.utf8().data(), this);
326 InspectorInstrumentation::stopConsoleTiming(page(), title, callStack);
329 void Console::timeStamp(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack>)
331 InspectorInstrumentation::consoleTimeStamp(page(), arguments);
334 void Console::group(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
336 InspectorInstrumentation::addMessageToConsole(page(), ConsoleAPIMessageSource, StartGroupMessageType, LogMessageLevel, String(), arguments, callStack);
339 void Console::groupCollapsed(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
341 InspectorInstrumentation::addMessageToConsole(page(), ConsoleAPIMessageSource, StartGroupCollapsedMessageType, LogMessageLevel, String(), arguments, callStack);
344 void Console::groupEnd()
346 InspectorInstrumentation::addMessageToConsole(page(), ConsoleAPIMessageSource, EndGroupMessageType, LogMessageLevel, String(), String(), 0);
356 void Console::unmute()
358 ASSERT(muteCount > 0);
362 PassRefPtr<MemoryInfo> Console::memory() const
364 // FIXME: Because we create a new object here each time,
365 // console.memory !== console.memory, which seems wrong.
366 return MemoryInfo::create(m_frame);
369 static bool printExceptions = false;
371 bool Console::shouldPrintExceptions()
373 return printExceptions;
376 void Console::setShouldPrintExceptions(bool print)
378 printExceptions = print;
381 Page* Console::page() const
385 return m_frame->page();
388 } // namespace WebCore