|
1 /* |
|
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
|
3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> |
|
4 * Copyright (C) 2009 Google Inc. All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions |
|
8 * are met: |
|
9 * |
|
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 Computer, 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. |
|
18 * |
|
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. |
|
29 */ |
|
30 |
|
31 #include "config.h" |
|
32 #include "ConsoleMessage.h" |
|
33 |
|
34 #include "InjectedScript.h" |
|
35 #include "InjectedScriptHost.h" |
|
36 #include "InspectorFrontend.h" |
|
37 #include "ScriptCallStack.h" |
|
38 #include "ScriptObject.h" |
|
39 #include "SerializedScriptValue.h" |
|
40 |
|
41 namespace WebCore { |
|
42 |
|
43 ConsoleMessage::CallFrame::CallFrame(const ScriptCallFrame& frame) |
|
44 : m_functionName(frame.functionName()) |
|
45 , m_sourceURL(frame.sourceURL()) |
|
46 , m_lineNumber(frame.lineNumber()) |
|
47 { |
|
48 } |
|
49 |
|
50 ConsoleMessage::CallFrame::CallFrame() |
|
51 : m_lineNumber(0) |
|
52 { |
|
53 } |
|
54 |
|
55 bool ConsoleMessage::CallFrame::isEqual(const ConsoleMessage::CallFrame& o) const |
|
56 { |
|
57 return m_functionName == o.m_functionName |
|
58 && m_sourceURL == o.m_sourceURL |
|
59 && m_lineNumber == o.m_lineNumber; |
|
60 } |
|
61 |
|
62 ScriptObject ConsoleMessage::CallFrame::buildObject(InspectorFrontend* frontend) const |
|
63 { |
|
64 ScriptObject frame = frontend->newScriptObject(); |
|
65 frame.set("functionName", m_functionName); |
|
66 frame.set("sourceURL", m_sourceURL.string()); |
|
67 frame.set("lineNumber", m_lineNumber); |
|
68 return frame; |
|
69 } |
|
70 |
|
71 ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, unsigned li, const String& u, unsigned g) |
|
72 : m_source(s) |
|
73 , m_type(t) |
|
74 , m_level(l) |
|
75 , m_message(m) |
|
76 , m_line(li) |
|
77 , m_url(u) |
|
78 , m_groupLevel(g) |
|
79 , m_repeatCount(1) |
|
80 { |
|
81 } |
|
82 |
|
83 ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, ScriptCallStack* callStack, unsigned g, bool storeTrace) |
|
84 : m_source(s) |
|
85 , m_type(t) |
|
86 , m_level(l) |
|
87 , m_message(m) |
|
88 #if ENABLE(INSPECTOR) |
|
89 , m_arguments(callStack->at(0).argumentCount()) |
|
90 , m_scriptState(callStack->globalState()) |
|
91 #endif |
|
92 , m_frames(storeTrace ? callStack->size() : 0) |
|
93 , m_groupLevel(g) |
|
94 , m_repeatCount(1) |
|
95 { |
|
96 const ScriptCallFrame& lastCaller = callStack->at(0); |
|
97 m_line = lastCaller.lineNumber(); |
|
98 m_url = lastCaller.sourceURL().string(); |
|
99 |
|
100 if (storeTrace) { |
|
101 for (unsigned i = 0; i < callStack->size(); ++i) |
|
102 m_frames[i] = ConsoleMessage::CallFrame(callStack->at(i)); |
|
103 } |
|
104 |
|
105 #if ENABLE(INSPECTOR) |
|
106 for (unsigned i = 0; i < lastCaller.argumentCount(); ++i) |
|
107 m_arguments[i] = lastCaller.argumentAt(i); |
|
108 #endif |
|
109 } |
|
110 |
|
111 #if ENABLE(INSPECTOR) |
|
112 void ConsoleMessage::addToFrontend(InspectorFrontend* frontend, InjectedScriptHost* injectedScriptHost) |
|
113 { |
|
114 ScriptObject jsonObj = frontend->newScriptObject(); |
|
115 jsonObj.set("source", static_cast<int>(m_source)); |
|
116 jsonObj.set("type", static_cast<int>(m_type)); |
|
117 jsonObj.set("level", static_cast<int>(m_level)); |
|
118 jsonObj.set("line", static_cast<int>(m_line)); |
|
119 jsonObj.set("url", m_url); |
|
120 jsonObj.set("groupLevel", static_cast<int>(m_groupLevel)); |
|
121 jsonObj.set("repeatCount", static_cast<int>(m_repeatCount)); |
|
122 jsonObj.set("message", m_message); |
|
123 if (!m_arguments.isEmpty()) { |
|
124 ScriptArray jsonArgs = frontend->newScriptArray(); |
|
125 InjectedScript injectedScript = injectedScriptHost->injectedScriptFor(m_scriptState.get()); |
|
126 for (unsigned i = 0; i < m_arguments.size(); ++i) { |
|
127 RefPtr<SerializedScriptValue> serializedValue = injectedScript.wrapForConsole(m_arguments[i]); |
|
128 if (!jsonArgs.set(i, serializedValue.get())) { |
|
129 ASSERT_NOT_REACHED(); |
|
130 return; |
|
131 } |
|
132 } |
|
133 jsonObj.set("parameters", jsonArgs); |
|
134 } |
|
135 if (!m_frames.isEmpty()) { |
|
136 ScriptArray frames = frontend->newScriptArray(); |
|
137 for (unsigned i = 0; i < m_frames.size(); i++) |
|
138 frames.set(i, m_frames.at(i).buildObject(frontend)); |
|
139 jsonObj.set("stackTrace", frames); |
|
140 } |
|
141 frontend->addConsoleMessage(jsonObj); |
|
142 } |
|
143 |
|
144 void ConsoleMessage::updateRepeatCountInConsole(InspectorFrontend* frontend) |
|
145 { |
|
146 frontend->updateConsoleMessageRepeatCount(m_repeatCount); |
|
147 } |
|
148 #endif // ENABLE(INSPECTOR) |
|
149 |
|
150 bool ConsoleMessage::isEqual(ScriptState* state, ConsoleMessage* msg) const |
|
151 { |
|
152 #if ENABLE(INSPECTOR) |
|
153 if (msg->m_arguments.size() != m_arguments.size()) |
|
154 return false; |
|
155 if (!state && msg->m_arguments.size()) |
|
156 return false; |
|
157 |
|
158 ASSERT_ARG(state, state || msg->m_arguments.isEmpty()); |
|
159 |
|
160 for (size_t i = 0; i < msg->m_arguments.size(); ++i) { |
|
161 if (!m_arguments[i].isEqual(state, msg->m_arguments[i])) |
|
162 return false; |
|
163 } |
|
164 #else |
|
165 UNUSED_PARAM(state); |
|
166 #endif // ENABLE(INSPECTOR) |
|
167 |
|
168 size_t frameCount = msg->m_frames.size(); |
|
169 if (frameCount != m_frames.size()) |
|
170 return false; |
|
171 |
|
172 for (size_t i = 0; i < frameCount; ++i) { |
|
173 if (!m_frames[i].isEqual(msg->m_frames[i])) |
|
174 return false; |
|
175 } |
|
176 |
|
177 return msg->m_source == m_source |
|
178 && msg->m_type == m_type |
|
179 && msg->m_level == m_level |
|
180 && msg->m_message == m_message |
|
181 && msg->m_line == m_line |
|
182 && msg->m_url == m_url |
|
183 && msg->m_groupLevel == m_groupLevel; |
|
184 } |
|
185 |
|
186 } // namespace WebCore |