1 /*
2 * Copyright (C) 2010 Google 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 are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "InjectedScript.h"
33
34 #if ENABLE(INSPECTOR)
35
36 #include "Frame.h"
37 #include "InjectedScriptHost.h"
38 #include "InjectedScriptManager.h"
39 #include "InspectorValues.h"
40 #include "Node.h"
41 #include "PlatformString.h"
42 #include "ScriptFunctionCall.h"
43
44 namespace WebCore {
45
InjectedScript()46 InjectedScript::InjectedScript()
47 : m_inspectedStateAccessCheck(0)
48 {
49 }
50
InjectedScript(ScriptObject injectedScriptObject,InspectedStateAccessCheck accessCheck)51 InjectedScript::InjectedScript(ScriptObject injectedScriptObject, InspectedStateAccessCheck accessCheck)
52 : m_injectedScriptObject(injectedScriptObject)
53 , m_inspectedStateAccessCheck(accessCheck)
54 {
55 }
56
evaluate(ErrorString * errorString,const String & expression,const String & objectGroup,bool includeCommandLineAPI,RefPtr<InspectorObject> * result)57 void InjectedScript::evaluate(ErrorString* errorString, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result)
58 {
59 ScriptFunctionCall function(m_injectedScriptObject, "evaluate");
60 function.appendArgument(expression);
61 function.appendArgument(objectGroup);
62 function.appendArgument(includeCommandLineAPI);
63 makeObjectCall(errorString, function, result);
64 }
65
evaluateOn(ErrorString * errorString,const String & objectId,const String & expression,RefPtr<InspectorObject> * result)66 void InjectedScript::evaluateOn(ErrorString* errorString, const String& objectId, const String& expression, RefPtr<InspectorObject>* result)
67 {
68 ScriptFunctionCall function(m_injectedScriptObject, "evaluateOn");
69 function.appendArgument(objectId);
70 function.appendArgument(expression);
71 makeObjectCall(errorString, function, result);
72 }
73
evaluateOnCallFrame(ErrorString * errorString,const String & callFrameId,const String & expression,const String & objectGroup,bool includeCommandLineAPI,RefPtr<InspectorObject> * result)74 void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result)
75 {
76 ScriptFunctionCall function(m_injectedScriptObject, "evaluateOnCallFrame");
77 function.appendArgument(callFrameId);
78 function.appendArgument(expression);
79 function.appendArgument(objectGroup);
80 function.appendArgument(includeCommandLineAPI);
81 makeObjectCall(errorString, function, result);
82 }
83
getProperties(ErrorString * errorString,const String & objectId,bool ignoreHasOwnProperty,RefPtr<InspectorArray> * properties)84 void InjectedScript::getProperties(ErrorString* errorString, const String& objectId, bool ignoreHasOwnProperty, RefPtr<InspectorArray>* properties)
85 {
86 ScriptFunctionCall function(m_injectedScriptObject, "getProperties");
87 function.appendArgument(objectId);
88 function.appendArgument(ignoreHasOwnProperty);
89
90 RefPtr<InspectorValue> result;
91 makeCall(function, &result);
92 if (!result || result->type() != InspectorValue::TypeArray) {
93 *errorString = "Internal error";
94 return;
95 }
96 *properties = result->asArray();
97 }
98
nodeForObjectId(const String & objectId)99 Node* InjectedScript::nodeForObjectId(const String& objectId)
100 {
101 if (hasNoValue() || !canAccessInspectedWindow())
102 return 0;
103
104 ScriptFunctionCall function(m_injectedScriptObject, "nodeForObjectId");
105 function.appendArgument(objectId);
106
107 bool hadException = false;
108 ScriptValue resultValue = function.call(hadException);
109 ASSERT(!hadException);
110
111 return InjectedScriptHost::scriptValueAsNode(resultValue);
112 }
113
setPropertyValue(ErrorString * errorString,const String & objectId,const String & propertyName,const String & expression)114 void InjectedScript::setPropertyValue(ErrorString* errorString, const String& objectId, const String& propertyName, const String& expression)
115 {
116 ScriptFunctionCall function(m_injectedScriptObject, "setPropertyValue");
117 function.appendArgument(objectId);
118 function.appendArgument(propertyName);
119 function.appendArgument(expression);
120 RefPtr<InspectorValue> result;
121 makeCall(function, &result);
122 result->asString(errorString);
123 }
124
releaseObject(const String & objectId)125 void InjectedScript::releaseObject(const String& objectId)
126 {
127 ScriptFunctionCall function(m_injectedScriptObject, "releaseObject");
128 function.appendArgument(objectId);
129 RefPtr<InspectorValue> result;
130 makeCall(function, &result);
131 }
132
133 #if ENABLE(JAVASCRIPT_DEBUGGER)
callFrames()134 PassRefPtr<InspectorArray> InjectedScript::callFrames()
135 {
136 ASSERT(!hasNoValue());
137 ScriptFunctionCall function(m_injectedScriptObject, "callFrames");
138 ScriptValue callFramesValue = function.call();
139 RefPtr<InspectorValue> result = callFramesValue.toInspectorValue(m_injectedScriptObject.scriptState());
140 if (result->type() == InspectorValue::TypeArray)
141 return result->asArray();
142 return InspectorArray::create();
143 }
144 #endif
145
wrapObject(ScriptValue value,const String & groupName)146 PassRefPtr<InspectorObject> InjectedScript::wrapObject(ScriptValue value, const String& groupName)
147 {
148 ASSERT(!hasNoValue());
149 ScriptFunctionCall wrapFunction(m_injectedScriptObject, "wrapObject");
150 wrapFunction.appendArgument(value);
151 wrapFunction.appendArgument(groupName);
152 wrapFunction.appendArgument(canAccessInspectedWindow());
153 bool hadException = false;
154 ScriptValue r = wrapFunction.call(hadException);
155 if (hadException) {
156 RefPtr<InspectorObject> result = InspectorObject::create();
157 result->setString("description", "<exception>");
158 return result;
159 }
160 return r.toInspectorValue(m_injectedScriptObject.scriptState())->asObject();
161 }
162
wrapNode(Node * node)163 PassRefPtr<InspectorObject> InjectedScript::wrapNode(Node* node)
164 {
165 return wrapObject(nodeAsScriptValue(node), "");
166 }
167
inspectNode(Node * node)168 void InjectedScript::inspectNode(Node* node)
169 {
170 ASSERT(!hasNoValue());
171 ScriptFunctionCall function(m_injectedScriptObject, "inspectNode");
172 function.appendArgument(nodeAsScriptValue(node));
173 RefPtr<InspectorValue> result;
174 makeCall(function, &result);
175 }
176
releaseObjectGroup(const String & objectGroup)177 void InjectedScript::releaseObjectGroup(const String& objectGroup)
178 {
179 ASSERT(!hasNoValue());
180 ScriptFunctionCall releaseFunction(m_injectedScriptObject, "releaseObjectGroup");
181 releaseFunction.appendArgument(objectGroup);
182 releaseFunction.call();
183 }
184
canAccessInspectedWindow()185 bool InjectedScript::canAccessInspectedWindow()
186 {
187 return m_inspectedStateAccessCheck(m_injectedScriptObject.scriptState());
188 }
189
makeCall(ScriptFunctionCall & function,RefPtr<InspectorValue> * result)190 void InjectedScript::makeCall(ScriptFunctionCall& function, RefPtr<InspectorValue>* result)
191 {
192 if (hasNoValue() || !canAccessInspectedWindow()) {
193 *result = InspectorValue::null();
194 return;
195 }
196
197 bool hadException = false;
198 ScriptValue resultValue = function.call(hadException);
199
200 ASSERT(!hadException);
201 if (!hadException)
202 *result = resultValue.toInspectorValue(m_injectedScriptObject.scriptState());
203 else
204 *result = InspectorString::create("Exception while making a call.");
205 }
206
makeObjectCall(ErrorString * errorString,ScriptFunctionCall & function,RefPtr<InspectorObject> * objectResult)207 void InjectedScript::makeObjectCall(ErrorString* errorString, ScriptFunctionCall& function, RefPtr<InspectorObject>* objectResult)
208 {
209 RefPtr<InspectorValue> result;
210 makeCall(function, &result);
211 if (result && result->type() == InspectorValue::TypeString) {
212 result->asString(errorString);
213 return;
214 }
215
216 if (!result || result->type() != InspectorValue::TypeObject) {
217 *errorString = "Internal error";
218 return;
219 }
220 *objectResult = result->asObject();
221 }
222
nodeAsScriptValue(Node * node)223 ScriptValue InjectedScript::nodeAsScriptValue(Node* node)
224 {
225 return InjectedScriptHost::nodeAsScriptValue(m_injectedScriptObject.scriptState(), node);
226 }
227
228 } // namespace WebCore
229
230 #endif // ENABLE(INSPECTOR)
231