2 * Copyright (C) 2007, 2008, 2014 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4 * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "ConsoleMessage.h"
34 #include "IdentifiersFactory.h"
35 #include "InjectedScript.h"
36 #include "InjectedScriptManager.h"
37 #include "InspectorValues.h"
38 #include "ScriptArguments.h"
39 #include "ScriptCallFrame.h"
40 #include "ScriptCallStack.h"
41 #include "ScriptCallStackFactory.h"
42 #include "ScriptValue.h"
46 ConsoleMessage::ConsoleMessage(MessageSource source
, MessageType type
, MessageLevel level
, const String
& message
, unsigned long requestIdentifier
)
55 , m_requestId(IdentifiersFactory::requestId(requestIdentifier
))
59 ConsoleMessage::ConsoleMessage(MessageSource source
, MessageType type
, MessageLevel level
, const String
& message
, const String
& url
, unsigned line
, unsigned column
, JSC::ExecState
* state
, unsigned long requestIdentifier
)
68 , m_requestId(IdentifiersFactory::requestId(requestIdentifier
))
70 autogenerateMetadata(state
);
73 ConsoleMessage::ConsoleMessage(MessageSource source
, MessageType type
, MessageLevel level
, const String
& message
, PassRefPtr
<ScriptCallStack
> callStack
, unsigned long requestIdentifier
)
82 , m_requestId(IdentifiersFactory::requestId(requestIdentifier
))
84 m_callStack
= callStack
;
86 const ScriptCallFrame
* frame
= m_callStack
? m_callStack
->firstNonNativeCallFrame() : nullptr;
88 m_url
= frame
->sourceURL();
89 m_line
= frame
->lineNumber();
90 m_column
= frame
->columnNumber();
94 ConsoleMessage::ConsoleMessage(MessageSource source
, MessageType type
, MessageLevel level
, const String
& message
, PassRefPtr
<ScriptArguments
> arguments
, JSC::ExecState
* state
, unsigned long requestIdentifier
)
99 , m_arguments(arguments
)
104 , m_requestId(IdentifiersFactory::requestId(requestIdentifier
))
106 autogenerateMetadata(state
);
109 ConsoleMessage::~ConsoleMessage()
113 void ConsoleMessage::autogenerateMetadata(JSC::ExecState
* state
)
118 if (m_type
== MessageType::EndGroup
)
121 // FIXME: Should this really be using "for console" in the generic ConsoleMessage autogeneration? This can skip the first frame.
122 m_callStack
= createScriptCallStackForConsole(state
, ScriptCallStack::maxCallStackSizeToCapture
);
124 if (const ScriptCallFrame
* frame
= m_callStack
->firstNonNativeCallFrame()) {
125 m_url
= frame
->sourceURL();
126 m_line
= frame
->lineNumber();
127 m_column
= frame
->columnNumber();
132 static Inspector::Protocol::Console::ConsoleMessage::Source
messageSourceValue(MessageSource source
)
135 case MessageSource::XML
: return Inspector::Protocol::Console::ConsoleMessage::Source::XML
;
136 case MessageSource::JS
: return Inspector::Protocol::Console::ConsoleMessage::Source::Javascript
;
137 case MessageSource::Network
: return Inspector::Protocol::Console::ConsoleMessage::Source::Network
;
138 case MessageSource::ConsoleAPI
: return Inspector::Protocol::Console::ConsoleMessage::Source::ConsoleAPI
;
139 case MessageSource::Storage
: return Inspector::Protocol::Console::ConsoleMessage::Source::Storage
;
140 case MessageSource::AppCache
: return Inspector::Protocol::Console::ConsoleMessage::Source::Appcache
;
141 case MessageSource::Rendering
: return Inspector::Protocol::Console::ConsoleMessage::Source::Rendering
;
142 case MessageSource::CSS
: return Inspector::Protocol::Console::ConsoleMessage::Source::CSS
;
143 case MessageSource::Security
: return Inspector::Protocol::Console::ConsoleMessage::Source::Security
;
144 case MessageSource::ContentBlocker
: return Inspector::Protocol::Console::ConsoleMessage::Source::ContentBlocker
;
145 case MessageSource::Other
: return Inspector::Protocol::Console::ConsoleMessage::Source::Other
;
147 return Inspector::Protocol::Console::ConsoleMessage::Source::Other
;
150 static Inspector::Protocol::Console::ConsoleMessage::Type
messageTypeValue(MessageType type
)
153 case MessageType::Log
: return Inspector::Protocol::Console::ConsoleMessage::Type::Log
;
154 case MessageType::Clear
: return Inspector::Protocol::Console::ConsoleMessage::Type::Clear
;
155 case MessageType::Dir
: return Inspector::Protocol::Console::ConsoleMessage::Type::Dir
;
156 case MessageType::DirXML
: return Inspector::Protocol::Console::ConsoleMessage::Type::DirXML
;
157 case MessageType::Table
: return Inspector::Protocol::Console::ConsoleMessage::Type::Table
;
158 case MessageType::Trace
: return Inspector::Protocol::Console::ConsoleMessage::Type::Trace
;
159 case MessageType::StartGroup
: return Inspector::Protocol::Console::ConsoleMessage::Type::StartGroup
;
160 case MessageType::StartGroupCollapsed
: return Inspector::Protocol::Console::ConsoleMessage::Type::StartGroupCollapsed
;
161 case MessageType::EndGroup
: return Inspector::Protocol::Console::ConsoleMessage::Type::EndGroup
;
162 case MessageType::Assert
: return Inspector::Protocol::Console::ConsoleMessage::Type::Assert
;
163 case MessageType::Timing
: return Inspector::Protocol::Console::ConsoleMessage::Type::Timing
;
164 case MessageType::Profile
: return Inspector::Protocol::Console::ConsoleMessage::Type::Profile
;
165 case MessageType::ProfileEnd
: return Inspector::Protocol::Console::ConsoleMessage::Type::ProfileEnd
;
167 return Inspector::Protocol::Console::ConsoleMessage::Type::Log
;
170 static Inspector::Protocol::Console::ConsoleMessage::Level
messageLevelValue(MessageLevel level
)
173 case MessageLevel::Log
: return Inspector::Protocol::Console::ConsoleMessage::Level::Log
;
174 case MessageLevel::Info
: return Inspector::Protocol::Console::ConsoleMessage::Level::Info
;
175 case MessageLevel::Warning
: return Inspector::Protocol::Console::ConsoleMessage::Level::Warning
;
176 case MessageLevel::Error
: return Inspector::Protocol::Console::ConsoleMessage::Level::Error
;
177 case MessageLevel::Debug
: return Inspector::Protocol::Console::ConsoleMessage::Level::Debug
;
179 return Inspector::Protocol::Console::ConsoleMessage::Level::Log
;
182 void ConsoleMessage::addToFrontend(ConsoleFrontendDispatcher
* consoleFrontendDispatcher
, InjectedScriptManager
* injectedScriptManager
, bool generatePreview
)
184 Ref
<Inspector::Protocol::Console::ConsoleMessage
> jsonObj
= Inspector::Protocol::Console::ConsoleMessage::create()
185 .setSource(messageSourceValue(m_source
))
186 .setLevel(messageLevelValue(m_level
))
190 // FIXME: only send out type for ConsoleAPI source messages.
191 jsonObj
->setType(messageTypeValue(m_type
));
192 jsonObj
->setLine(static_cast<int>(m_line
));
193 jsonObj
->setColumn(static_cast<int>(m_column
));
194 jsonObj
->setUrl(m_url
);
195 jsonObj
->setRepeatCount(static_cast<int>(m_repeatCount
));
197 if (m_source
== MessageSource::Network
&& !m_requestId
.isEmpty())
198 jsonObj
->setNetworkRequestId(m_requestId
);
200 if (m_arguments
&& m_arguments
->argumentCount()) {
201 InjectedScript injectedScript
= injectedScriptManager
->injectedScriptFor(m_arguments
->globalState());
202 if (!injectedScript
.hasNoValue()) {
203 Ref
<Inspector::Protocol::Array
<Inspector::Protocol::Runtime::RemoteObject
>> jsonArgs
= Inspector::Protocol::Array
<Inspector::Protocol::Runtime::RemoteObject
>::create();
204 if (m_type
== MessageType::Table
&& generatePreview
&& m_arguments
->argumentCount()) {
205 Deprecated::ScriptValue table
= m_arguments
->argumentAt(0);
206 Deprecated::ScriptValue columns
= m_arguments
->argumentCount() > 1 ? m_arguments
->argumentAt(1) : Deprecated::ScriptValue();
207 RefPtr
<Inspector::Protocol::Runtime::RemoteObject
> inspectorValue
= injectedScript
.wrapTable(table
, columns
);
208 if (!inspectorValue
) {
209 ASSERT_NOT_REACHED();
212 jsonArgs
->addItem(inspectorValue
.copyRef());
213 if (m_arguments
->argumentCount() > 1)
214 jsonArgs
->addItem(injectedScript
.wrapObject(columns
, ASCIILiteral("console"), true));
216 for (unsigned i
= 0; i
< m_arguments
->argumentCount(); ++i
) {
217 RefPtr
<Inspector::Protocol::Runtime::RemoteObject
> inspectorValue
= injectedScript
.wrapObject(m_arguments
->argumentAt(i
), ASCIILiteral("console"), generatePreview
);
218 if (!inspectorValue
) {
219 ASSERT_NOT_REACHED();
222 jsonArgs
->addItem(inspectorValue
.copyRef());
225 jsonObj
->setParameters(WTF::move(jsonArgs
));
230 jsonObj
->setStackTrace(m_callStack
->buildInspectorArray());
232 consoleFrontendDispatcher
->messageAdded(WTF::move(jsonObj
));
235 void ConsoleMessage::updateRepeatCountInConsole(ConsoleFrontendDispatcher
* consoleFrontendDispatcher
)
237 consoleFrontendDispatcher
->messageRepeatCountUpdated(m_repeatCount
);
240 bool ConsoleMessage::isEqual(ConsoleMessage
* msg
) const
243 if (!m_arguments
->isEqual(msg
->m_arguments
.get()))
246 // Never treat objects as equal - their properties might change over time.
247 for (size_t i
= 0; i
< m_arguments
->argumentCount(); ++i
) {
248 if (m_arguments
->argumentAt(i
).isObject())
251 } else if (msg
->m_arguments
)
255 if (!m_callStack
->isEqual(msg
->m_callStack
.get()))
257 } else if (msg
->m_callStack
)
260 return msg
->m_source
== m_source
261 && msg
->m_type
== m_type
262 && msg
->m_level
== m_level
263 && msg
->m_message
== m_message
264 && msg
->m_line
== m_line
265 && msg
->m_column
== m_column
266 && msg
->m_url
== m_url
267 && msg
->m_requestId
== m_requestId
;
270 void ConsoleMessage::clear()
273 m_message
= ASCIILiteral("<message collected>");
276 m_arguments
= nullptr;
279 JSC::ExecState
* ConsoleMessage::scriptState() const
282 return m_arguments
->globalState();
287 unsigned ConsoleMessage::argumentCount() const
290 return m_arguments
->argumentCount();
295 } // namespace Inspector