2
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4
* Copyright (C) 2010-2011 Google Inc. All rights reserved.
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions are
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
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.
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.
37
#include "JSInjectedScriptHost.h"
39
#if ENABLE(SQL_DATABASE)
41
#include "JSDatabase.h"
43
#include "ExceptionCode.h"
44
#include "InjectedScriptHost.h"
45
#include "InspectorDOMAgent.h"
46
#include "InspectorDebuggerAgent.h"
47
#include "InspectorValues.h"
48
#include "JSEventListener.h"
49
#include "JSFloat32Array.h"
50
#include "JSFloat64Array.h"
51
#include "JSHTMLAllCollection.h"
52
#include "JSHTMLCollection.h"
53
#include "JSInt16Array.h"
54
#include "JSInt32Array.h"
55
#include "JSInt8Array.h"
57
#include "JSNodeList.h"
58
#include "JSStorage.h"
59
#include "JSUint16Array.h"
60
#include "JSUint32Array.h"
61
#include "JSUint8Array.h"
62
#include "ScriptValue.h"
64
#include <parser/SourceCode.h>
65
#include <runtime/DateInstance.h>
66
#include <runtime/Error.h>
67
#include <runtime/JSArray.h>
68
#include <runtime/JSFunction.h>
69
#include <runtime/JSLock.h>
70
#include <runtime/RegExpObject.h>
76
Node* InjectedScriptHost::scriptValueAsNode(ScriptValue value)
78
if (!value.isObject() || value.isNull())
80
return toNode(value.jsValue());
83
ScriptValue InjectedScriptHost::nodeAsScriptValue(ScriptState* state, Node* node)
85
JSLockHolder lock(state);
86
return ScriptValue(state->globalData(), toJS(state, deprecatedGlobalObjectForPrototype(state), node));
89
JSValue JSInjectedScriptHost::inspectedObject(ExecState* exec)
91
if (exec->argumentCount() < 1)
94
InjectedScriptHost::InspectableObject* object = impl()->inspectedObject(exec->argument(0).toInt32(exec));
98
JSLockHolder lock(exec);
99
ScriptValue scriptValue = object->get(exec);
100
if (scriptValue.hasNoValue())
101
return jsUndefined();
103
return scriptValue.jsValue();
106
JSValue JSInjectedScriptHost::internalConstructorName(ExecState* exec)
108
if (exec->argumentCount() < 1)
109
return jsUndefined();
111
JSObject* thisObject = exec->argument(0).toThisObject(exec);
112
String result = thisObject->methodTable()->className(thisObject);
113
return jsStringWithCache(exec, result);
116
JSValue JSInjectedScriptHost::isHTMLAllCollection(ExecState* exec)
118
if (exec->argumentCount() < 1)
119
return jsUndefined();
121
JSValue value = exec->argument(0);
122
return jsBoolean(value.inherits(&JSHTMLAllCollection::s_info));
125
JSValue JSInjectedScriptHost::type(ExecState* exec)
127
if (exec->argumentCount() < 1)
128
return jsUndefined();
130
JSValue value = exec->argument(0);
131
if (value.isString())
132
return jsString(exec, String("string"));
133
if (value.inherits(&JSArray::s_info))
134
return jsString(exec, String("array"));
135
if (value.isBoolean())
136
return jsString(exec, String("boolean"));
137
if (value.isNumber())
138
return jsString(exec, String("number"));
139
if (value.inherits(&DateInstance::s_info))
140
return jsString(exec, String("date"));
141
if (value.inherits(&RegExpObject::s_info))
142
return jsString(exec, String("regexp"));
143
if (value.inherits(&JSNode::s_info))
144
return jsString(exec, String("node"));
145
if (value.inherits(&JSNodeList::s_info))
146
return jsString(exec, String("array"));
147
if (value.inherits(&JSHTMLCollection::s_info))
148
return jsString(exec, String("array"));
149
if (value.inherits(&JSInt8Array::s_info) || value.inherits(&JSInt16Array::s_info) || value.inherits(&JSInt32Array::s_info))
150
return jsString(exec, String("array"));
151
if (value.inherits(&JSUint8Array::s_info) || value.inherits(&JSUint16Array::s_info) || value.inherits(&JSUint32Array::s_info))
152
return jsString(exec, String("array"));
153
if (value.inherits(&JSFloat32Array::s_info) || value.inherits(&JSFloat64Array::s_info))
154
return jsString(exec, String("array"));
155
return jsUndefined();
158
JSValue JSInjectedScriptHost::functionDetails(ExecState* exec)
160
if (exec->argumentCount() < 1)
161
return jsUndefined();
162
JSValue value = exec->argument(0);
163
if (!value.asCell()->inherits(&JSFunction::s_info))
164
return jsUndefined();
165
JSFunction* function = jsCast<JSFunction*>(value);
167
const SourceCode* sourceCode = function->sourceCode();
169
return jsUndefined();
170
int lineNumber = sourceCode->firstLine();
172
lineNumber -= 1; // In the inspector protocol all positions are 0-based while in SourceCode they are 1-based
173
String scriptId = String::number(sourceCode->provider()->asID());
175
JSObject* location = constructEmptyObject(exec);
176
location->putDirect(exec->globalData(), Identifier(exec, "lineNumber"), jsNumber(lineNumber));
177
location->putDirect(exec->globalData(), Identifier(exec, "scriptId"), jsString(exec, scriptId));
179
JSObject* result = constructEmptyObject(exec);
180
result->putDirect(exec->globalData(), Identifier(exec, "location"), location);
181
String name = function->name(exec);
183
result->putDirect(exec->globalData(), Identifier(exec, "name"), jsStringWithCache(exec, name));
184
String displayName = function->displayName(exec);
185
if (!displayName.isEmpty())
186
result->putDirect(exec->globalData(), Identifier(exec, "displayName"), jsStringWithCache(exec, displayName));
187
// FIXME: provide function scope data in "scopesRaw" property when JSC supports it.
188
// https://bugs.webkit.org/show_bug.cgi?id=87192
192
JSValue JSInjectedScriptHost::getInternalProperties(ExecState*)
194
// FIXME: implement this. https://bugs.webkit.org/show_bug.cgi?id=94533
195
return jsUndefined();
198
static JSArray* getJSListenerFunctions(ExecState* exec, Document* document, const EventListenerInfo& listenerInfo)
200
JSArray* result = constructEmptyArray(exec, 0);
201
size_t handlersCount = listenerInfo.eventListenerVector.size();
202
for (size_t i = 0, outputIndex = 0; i < handlersCount; ++i) {
203
const JSEventListener* jsListener = JSEventListener::cast(listenerInfo.eventListenerVector[i].listener.get());
205
ASSERT_NOT_REACHED();
208
// Hide listeners from other contexts.
209
if (jsListener->isolatedWorld() != currentWorld(exec))
211
JSObject* function = jsListener->jsFunction(document);
214
JSObject* listenerEntry = constructEmptyObject(exec);
215
listenerEntry->putDirect(exec->globalData(), Identifier(exec, "listener"), function);
216
listenerEntry->putDirect(exec->globalData(), Identifier(exec, "useCapture"), jsBoolean(listenerInfo.eventListenerVector[i].useCapture));
217
result->putDirectIndex(exec, outputIndex++, JSValue(listenerEntry));
222
JSValue JSInjectedScriptHost::getEventListeners(ExecState* exec)
224
if (exec->argumentCount() < 1)
225
return jsUndefined();
226
JSValue value = exec->argument(0);
227
if (!value.isObject() || value.isNull())
228
return jsUndefined();
229
Node* node = toNode(value);
231
return jsUndefined();
232
// This can only happen for orphan DocumentType nodes.
233
Document* document = node->document();
234
if (!node->document())
235
return jsUndefined();
237
Vector<EventListenerInfo> listenersArray;
238
impl()->getEventListenersImpl(node, listenersArray);
240
JSObject* result = constructEmptyObject(exec);
241
for (size_t i = 0; i < listenersArray.size(); ++i) {
242
JSArray* listeners = getJSListenerFunctions(exec, document, listenersArray[i]);
243
if (!listeners->length())
245
AtomicString eventType = listenersArray[i].eventType;
246
result->putDirect(exec->globalData(), Identifier(exec, eventType.impl()), JSValue(listeners));
252
JSValue JSInjectedScriptHost::inspect(ExecState* exec)
254
if (exec->argumentCount() >= 2) {
255
ScriptValue object(exec->globalData(), exec->argument(0));
256
ScriptValue hints(exec->globalData(), exec->argument(1));
257
impl()->inspectImpl(object.toInspectorValue(exec), hints.toInspectorValue(exec));
259
return jsUndefined();
262
JSValue JSInjectedScriptHost::databaseId(ExecState* exec)
264
if (exec->argumentCount() < 1)
265
return jsUndefined();
266
#if ENABLE(SQL_DATABASE)
267
Database* database = toDatabase(exec->argument(0));
269
return jsStringWithCache(exec, impl()->databaseIdImpl(database));
271
return jsUndefined();
274
JSValue JSInjectedScriptHost::storageId(ExecState* exec)
276
if (exec->argumentCount() < 1)
277
return jsUndefined();
278
Storage* storage = toStorage(exec->argument(0));
280
return jsStringWithCache(exec, impl()->storageIdImpl(storage));
281
return jsUndefined();
284
JSValue JSInjectedScriptHost::evaluate(ExecState* exec)
286
JSValue expression = exec->argument(0);
287
if (!expression.isString())
288
return throwError(exec, createError(exec, "String argument expected."));
289
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
290
JSFunction* evalFunction = globalObject->evalFunction();
292
CallType callType = evalFunction->methodTable()->getCallData(evalFunction, callData);
293
if (callType == CallTypeNone)
294
return jsUndefined();
295
MarkedArgumentBuffer args;
296
args.append(expression);
298
bool wasEvalEnabled = globalObject->evalEnabled();
299
globalObject->setEvalEnabled(true);
300
JSValue result = JSC::call(exec, evalFunction, callType, callData, exec->globalThisValue(), args);
301
globalObject->setEvalEnabled(wasEvalEnabled);
306
} // namespace WebCore
308
#endif // ENABLE(INSPECTOR)