1/* 2 * Copyright (C) 2012 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 33#if ENABLE(INSPECTOR) 34 35#include "InjectedScript.h" 36 37#include "InjectedScriptHost.h" 38#include "InjectedScriptModule.h" 39#include "InspectorValues.h" 40#include "Node.h" 41#include "ScriptFunctionCall.h" 42#include "SerializedScriptValue.h" 43#include <wtf/text/WTFString.h> 44 45using WebCore::TypeBuilder::Array; 46using WebCore::TypeBuilder::Debugger::CallFrame; 47using WebCore::TypeBuilder::Runtime::PropertyDescriptor; 48using WebCore::TypeBuilder::Runtime::InternalPropertyDescriptor; 49using WebCore::TypeBuilder::Debugger::FunctionDetails; 50using WebCore::TypeBuilder::Runtime::RemoteObject; 51 52namespace WebCore { 53 54InjectedScript::InjectedScript() 55 : InjectedScriptBase("InjectedScript") 56{ 57} 58 59InjectedScript::InjectedScript(ScriptObject injectedScriptObject, InspectedStateAccessCheck accessCheck) 60 : InjectedScriptBase("InjectedScript", injectedScriptObject, accessCheck) 61{ 62} 63 64void InjectedScript::evaluate(ErrorString* errorString, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown) 65{ 66 ScriptFunctionCall function(injectedScriptObject(), "evaluate"); 67 function.appendArgument(expression); 68 function.appendArgument(objectGroup); 69 function.appendArgument(includeCommandLineAPI); 70 function.appendArgument(returnByValue); 71 function.appendArgument(generatePreview); 72 makeEvalCall(errorString, function, result, wasThrown); 73} 74 75void InjectedScript::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown) 76{ 77 ScriptFunctionCall function(injectedScriptObject(), "callFunctionOn"); 78 function.appendArgument(objectId); 79 function.appendArgument(expression); 80 function.appendArgument(arguments); 81 function.appendArgument(returnByValue); 82 function.appendArgument(generatePreview); 83 makeEvalCall(errorString, function, result, wasThrown); 84} 85 86void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, const ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, RefPtr<RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown) 87{ 88 ScriptFunctionCall function(injectedScriptObject(), "evaluateOnCallFrame"); 89 function.appendArgument(callFrames); 90 function.appendArgument(callFrameId); 91 function.appendArgument(expression); 92 function.appendArgument(objectGroup); 93 function.appendArgument(includeCommandLineAPI); 94 function.appendArgument(returnByValue); 95 function.appendArgument(generatePreview); 96 makeEvalCall(errorString, function, result, wasThrown); 97} 98 99void InjectedScript::restartFrame(ErrorString* errorString, const ScriptValue& callFrames, const String& callFrameId, RefPtr<InspectorObject>* result) 100{ 101 ScriptFunctionCall function(injectedScriptObject(), "restartFrame"); 102 function.appendArgument(callFrames); 103 function.appendArgument(callFrameId); 104 RefPtr<InspectorValue> resultValue; 105 makeCall(function, &resultValue); 106 if (resultValue) { 107 if (resultValue->type() == InspectorValue::TypeString) { 108 resultValue->asString(errorString); 109 return; 110 } 111 if (resultValue->type() == InspectorValue::TypeObject) { 112 *result = resultValue->asObject(); 113 return; 114 } 115 } 116 *errorString = "Internal error"; 117} 118 119void InjectedScript::setVariableValue(ErrorString* errorString, const ScriptValue& callFrames, const String* callFrameIdOpt, const String* functionObjectIdOpt, int scopeNumber, const String& variableName, const String& newValueStr) 120{ 121 ScriptFunctionCall function(injectedScriptObject(), "setVariableValue"); 122 if (callFrameIdOpt) { 123 function.appendArgument(callFrames); 124 function.appendArgument(*callFrameIdOpt); 125 } else { 126 function.appendArgument(false); 127 function.appendArgument(false); 128 } 129 if (functionObjectIdOpt) 130 function.appendArgument(*functionObjectIdOpt); 131 else 132 function.appendArgument(false); 133 function.appendArgument(scopeNumber); 134 function.appendArgument(variableName); 135 function.appendArgument(newValueStr); 136 RefPtr<InspectorValue> resultValue; 137 makeCall(function, &resultValue); 138 if (!resultValue) { 139 *errorString = "Internal error"; 140 return; 141 } 142 if (resultValue->type() == InspectorValue::TypeString) { 143 resultValue->asString(errorString); 144 return; 145 } 146 // Normal return. 147} 148 149void InjectedScript::getFunctionDetails(ErrorString* errorString, const String& functionId, RefPtr<FunctionDetails>* result) 150{ 151 ScriptFunctionCall function(injectedScriptObject(), "getFunctionDetails"); 152 function.appendArgument(functionId); 153 RefPtr<InspectorValue> resultValue; 154 makeCall(function, &resultValue); 155 if (!resultValue || resultValue->type() != InspectorValue::TypeObject) { 156 if (!resultValue->asString(errorString)) 157 *errorString = "Internal error"; 158 return; 159 } 160 *result = FunctionDetails::runtimeCast(resultValue); 161} 162 163void InjectedScript::getProperties(ErrorString* errorString, const String& objectId, bool ownProperties, RefPtr<Array<PropertyDescriptor> >* properties) 164{ 165 ScriptFunctionCall function(injectedScriptObject(), "getProperties"); 166 function.appendArgument(objectId); 167 function.appendArgument(ownProperties); 168 169 RefPtr<InspectorValue> result; 170 makeCall(function, &result); 171 if (!result || result->type() != InspectorValue::TypeArray) { 172 *errorString = "Internal error"; 173 return; 174 } 175 *properties = Array<PropertyDescriptor>::runtimeCast(result); 176} 177 178void InjectedScript::getInternalProperties(ErrorString* errorString, const String& objectId, RefPtr<Array<InternalPropertyDescriptor> >* properties) 179{ 180 ScriptFunctionCall function(injectedScriptObject(), "getInternalProperties"); 181 function.appendArgument(objectId); 182 183 RefPtr<InspectorValue> result; 184 makeCall(function, &result); 185 if (!result || result->type() != InspectorValue::TypeArray) { 186 *errorString = "Internal error"; 187 return; 188 } 189 RefPtr<Array<InternalPropertyDescriptor> > array = Array<InternalPropertyDescriptor>::runtimeCast(result); 190 if (array->length() > 0) 191 *properties = array; 192} 193 194Node* InjectedScript::nodeForObjectId(const String& objectId) 195{ 196 if (hasNoValue() || !canAccessInspectedWindow()) 197 return 0; 198 199 ScriptFunctionCall function(injectedScriptObject(), "nodeForObjectId"); 200 function.appendArgument(objectId); 201 202 bool hadException = false; 203 ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException); 204 ASSERT(!hadException); 205 206 return InjectedScriptHost::scriptValueAsNode(resultValue); 207} 208 209void InjectedScript::releaseObject(const String& objectId) 210{ 211 ScriptFunctionCall function(injectedScriptObject(), "releaseObject"); 212 function.appendArgument(objectId); 213 RefPtr<InspectorValue> result; 214 makeCall(function, &result); 215} 216 217#if ENABLE(JAVASCRIPT_DEBUGGER) 218PassRefPtr<Array<CallFrame> > InjectedScript::wrapCallFrames(const ScriptValue& callFrames) 219{ 220 ASSERT(!hasNoValue()); 221 ScriptFunctionCall function(injectedScriptObject(), "wrapCallFrames"); 222 function.appendArgument(callFrames); 223 bool hadException = false; 224 ScriptValue callFramesValue = callFunctionWithEvalEnabled(function, hadException); 225 ASSERT(!hadException); 226 RefPtr<InspectorValue> result = callFramesValue.toInspectorValue(scriptState()); 227 if (result->type() == InspectorValue::TypeArray) 228 return Array<CallFrame>::runtimeCast(result); 229 return Array<CallFrame>::create(); 230} 231#endif 232 233PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapObject(const ScriptValue& value, const String& groupName, bool generatePreview) const 234{ 235 ASSERT(!hasNoValue()); 236 ScriptFunctionCall wrapFunction(injectedScriptObject(), "wrapObject"); 237 wrapFunction.appendArgument(value); 238 wrapFunction.appendArgument(groupName); 239 wrapFunction.appendArgument(canAccessInspectedWindow()); 240 wrapFunction.appendArgument(generatePreview); 241 bool hadException = false; 242 ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException); 243 if (hadException) 244 return 0; 245 RefPtr<InspectorObject> rawResult = r.toInspectorValue(scriptState())->asObject(); 246 return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult); 247} 248 249PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapTable(const ScriptValue& table, const ScriptValue& columns) const 250{ 251 ASSERT(!hasNoValue()); 252 ScriptFunctionCall wrapFunction(injectedScriptObject(), "wrapTable"); 253 wrapFunction.appendArgument(canAccessInspectedWindow()); 254 wrapFunction.appendArgument(table); 255 if (columns.hasNoValue()) 256 wrapFunction.appendArgument(false); 257 else 258 wrapFunction.appendArgument(columns); 259 bool hadException = false; 260 ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException); 261 if (hadException) 262 return 0; 263 RefPtr<InspectorObject> rawResult = r.toInspectorValue(scriptState())->asObject(); 264 return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult); 265} 266 267PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapNode(Node* node, const String& groupName) 268{ 269 return wrapObject(nodeAsScriptValue(node), groupName); 270} 271 272ScriptValue InjectedScript::findObjectById(const String& objectId) const 273{ 274 ASSERT(!hasNoValue()); 275 ScriptFunctionCall function(injectedScriptObject(), "findObjectById"); 276 function.appendArgument(objectId); 277 278 bool hadException = false; 279 ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException); 280 ASSERT(!hadException); 281 return resultValue; 282} 283 284void InjectedScript::inspectNode(Node* node) 285{ 286 ASSERT(!hasNoValue()); 287 ScriptFunctionCall function(injectedScriptObject(), "inspectNode"); 288 function.appendArgument(nodeAsScriptValue(node)); 289 RefPtr<InspectorValue> result; 290 makeCall(function, &result); 291} 292 293void InjectedScript::releaseObjectGroup(const String& objectGroup) 294{ 295 ASSERT(!hasNoValue()); 296 ScriptFunctionCall releaseFunction(injectedScriptObject(), "releaseObjectGroup"); 297 releaseFunction.appendArgument(objectGroup); 298 bool hadException = false; 299 callFunctionWithEvalEnabled(releaseFunction, hadException); 300 ASSERT(!hadException); 301} 302 303ScriptValue InjectedScript::nodeAsScriptValue(Node* node) 304{ 305 return InjectedScriptHost::nodeAsScriptValue(scriptState(), node); 306} 307 308} // namespace WebCore 309 310#endif // ENABLE(INSPECTOR) 311