1 /* 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Matt Lilek <webkit (at) 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 are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following disclaimer 14 * in the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the name of Google Inc. nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include "config.h" 34 #include "JSInjectedScriptHost.h" 35 36 #if ENABLE(INSPECTOR) 37 38 #include "Console.h" 39 #if ENABLE(DATABASE) 40 #include "Database.h" 41 #include "JSDatabase.h" 42 #endif 43 #include "ExceptionCode.h" 44 #include "Frame.h" 45 #include "FrameLoader.h" 46 #include "InjectedScript.h" 47 #include "InjectedScriptHost.h" 48 #include "InspectorController.h" 49 #include "InspectorResource.h" 50 #include "JSDOMWindow.h" 51 #include "JSNode.h" 52 #include "JSRange.h" 53 #include "Node.h" 54 #include "Page.h" 55 #if ENABLE(DOM_STORAGE) 56 #include "SerializedScriptValue.h" 57 #include "Storage.h" 58 #include "JSStorage.h" 59 #endif 60 #include "TextIterator.h" 61 #include "VisiblePosition.h" 62 #include <parser/SourceCode.h> 63 #include <runtime/JSArray.h> 64 #include <runtime/JSLock.h> 65 #include <wtf/RefPtr.h> 66 #include <wtf/Vector.h> 67 68 #if ENABLE(JAVASCRIPT_DEBUGGER) 69 #include "JavaScriptCallFrame.h" 70 #include "JavaScriptDebugServer.h" 71 #include "JSJavaScriptCallFrame.h" 72 #endif 73 74 using namespace JSC; 75 76 namespace WebCore { 77 78 static ScriptObject createInjectedScript(const String& source, InjectedScriptHost* injectedScriptHost, ScriptState* scriptState, long id) 79 { 80 SourceCode sourceCode = makeSource(source); 81 JSLock lock(SilenceAssertionsOnly); 82 JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); 83 JSValue globalThisValue = scriptState->globalThisValue(); 84 Completion comp = JSC::evaluate(scriptState, globalObject->globalScopeChain(), sourceCode, globalThisValue); 85 if (comp.complType() != JSC::Normal && comp.complType() != JSC::ReturnValue) 86 return ScriptObject(); 87 JSValue functionValue = comp.value(); 88 CallData callData; 89 CallType callType = functionValue.getCallData(callData); 90 if (callType == CallTypeNone) 91 return ScriptObject(); 92 93 MarkedArgumentBuffer args; 94 args.append(toJS(scriptState, globalObject, injectedScriptHost)); 95 args.append(globalThisValue); 96 args.append(jsNumber(scriptState, id)); 97 JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args); 98 if (result.isObject()) 99 return ScriptObject(scriptState, result.getObject()); 100 return ScriptObject(); 101 } 102 103 #if ENABLE(DATABASE) 104 JSValue JSInjectedScriptHost::databaseForId(ExecState* exec, const ArgList& args) 105 { 106 if (args.size() < 1) 107 return jsUndefined(); 108 109 InspectorController* ic = impl()->inspectorController(); 110 if (!ic) 111 return jsUndefined(); 112 113 Database* database = impl()->databaseForId(args.at(0).toInt32(exec)); 114 if (!database) 115 return jsUndefined(); 116 return toJS(exec, database); 117 } 118 #endif 119 120 #if ENABLE(JAVASCRIPT_DEBUGGER) 121 122 JSValue JSInjectedScriptHost::currentCallFrame(ExecState* exec, const ArgList&) 123 { 124 JavaScriptCallFrame* callFrame = impl()->currentCallFrame(); 125 if (!callFrame || !callFrame->isValid()) 126 return jsUndefined(); 127 128 JSLock lock(SilenceAssertionsOnly); 129 return toJS(exec, callFrame); 130 } 131 132 JSValue JSInjectedScriptHost::isActivation(ExecState*, const ArgList& args) 133 { 134 JSObject* object = args.at(0).getObject(); 135 return jsBoolean(object && object->isActivationObject()); 136 } 137 138 #endif 139 140 JSValue JSInjectedScriptHost::nodeForId(ExecState* exec, const ArgList& args) 141 { 142 if (args.size() < 1) 143 return jsUndefined(); 144 145 Node* node = impl()->nodeForId(args.at(0).toInt32(exec)); 146 if (!node) 147 return jsUndefined(); 148 149 InspectorController* ic = impl()->inspectorController(); 150 if (!ic) 151 return jsUndefined(); 152 153 JSLock lock(SilenceAssertionsOnly); 154 return toJS(exec, node); 155 } 156 157 JSValue JSInjectedScriptHost::pushNodePathToFrontend(ExecState* exec, const ArgList& args) 158 { 159 if (args.size() < 3) 160 return jsUndefined(); 161 162 Node* node = toNode(args.at(0)); 163 if (!node) 164 return jsUndefined(); 165 166 bool withChildren = args.at(1).toBoolean(exec); 167 bool selectInUI = args.at(2).toBoolean(exec); 168 return jsNumber(exec, impl()->pushNodePathToFrontend(node, withChildren, selectInUI)); 169 } 170 171 #if ENABLE(DATABASE) 172 JSValue JSInjectedScriptHost::selectDatabase(ExecState*, const ArgList& args) 173 { 174 if (args.size() < 1) 175 return jsUndefined(); 176 177 Database* database = toDatabase(args.at(0)); 178 if (database) 179 impl()->selectDatabase(database); 180 return jsUndefined(); 181 } 182 #endif 183 184 #if ENABLE(DOM_STORAGE) 185 JSValue JSInjectedScriptHost::selectDOMStorage(ExecState*, const ArgList& args) 186 { 187 if (args.size() < 1) 188 return jsUndefined(); 189 InspectorController* ic = impl()->inspectorController(); 190 if (!ic) 191 return jsUndefined(); 192 193 Storage* storage = toStorage(args.at(0)); 194 if (storage) 195 impl()->selectDOMStorage(storage); 196 return jsUndefined(); 197 } 198 #endif 199 200 JSValue JSInjectedScriptHost::reportDidDispatchOnInjectedScript(ExecState* exec, const ArgList& args) 201 { 202 if (args.size() < 3) 203 return jsUndefined(); 204 205 if (!args.at(0).isInt32()) 206 return jsUndefined(); 207 int callId = args.at(0).asInt32(); 208 209 RefPtr<SerializedScriptValue> result(SerializedScriptValue::create(exec, args.at(1))); 210 211 bool isException; 212 if (!args.at(2).getBoolean(isException)) 213 return jsUndefined(); 214 impl()->reportDidDispatchOnInjectedScript(callId, result.get(), isException); 215 return jsUndefined(); 216 } 217 218 InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState* scriptState) 219 { 220 JSLock lock(SilenceAssertionsOnly); 221 JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); 222 JSObject* injectedScript = globalObject->injectedScript(); 223 if (injectedScript) 224 return InjectedScript(ScriptObject(scriptState, injectedScript)); 225 226 ASSERT(!m_injectedScriptSource.isEmpty()); 227 ScriptObject injectedScriptObject = createInjectedScript(m_injectedScriptSource, this, scriptState, m_nextInjectedScriptId); 228 globalObject->setInjectedScript(injectedScriptObject.jsObject()); 229 InjectedScript result(injectedScriptObject); 230 m_idToInjectedScript.set(m_nextInjectedScriptId, result); 231 m_nextInjectedScriptId++; 232 return result; 233 } 234 235 } // namespace WebCore 236 237 #endif // ENABLE(INSPECTOR) 238