Home | History | Annotate | Download | only in js
      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