~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
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
 
 
35
#if ENABLE(INSPECTOR)
 
36
 
 
37
#include "JSInjectedScriptHost.h"
 
38
 
 
39
#if ENABLE(SQL_DATABASE)
 
40
#include "Database.h"
 
41
#include "JSDatabase.h"
 
42
#endif
 
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"
 
56
#include "JSNode.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"
 
63
#include "Storage.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>
 
71
 
 
72
using namespace JSC;
 
73
 
 
74
namespace WebCore {
 
75
 
 
76
Node* InjectedScriptHost::scriptValueAsNode(ScriptValue value)
 
77
{
 
78
    if (!value.isObject() || value.isNull())
 
79
        return 0;
 
80
    return toNode(value.jsValue());
 
81
}
 
82
 
 
83
ScriptValue InjectedScriptHost::nodeAsScriptValue(ScriptState* state, Node* node)
 
84
{
 
85
    JSLockHolder lock(state);
 
86
    return ScriptValue(state->globalData(), toJS(state, deprecatedGlobalObjectForPrototype(state), node));
 
87
}
 
88
 
 
89
JSValue JSInjectedScriptHost::inspectedObject(ExecState* exec)
 
90
{
 
91
    if (exec->argumentCount() < 1)
 
92
        return jsUndefined();
 
93
 
 
94
    InjectedScriptHost::InspectableObject* object = impl()->inspectedObject(exec->argument(0).toInt32(exec));
 
95
    if (!object)
 
96
        return jsUndefined();
 
97
 
 
98
    JSLockHolder lock(exec);
 
99
    ScriptValue scriptValue = object->get(exec);
 
100
    if (scriptValue.hasNoValue())
 
101
        return jsUndefined();
 
102
 
 
103
    return scriptValue.jsValue();
 
104
}
 
105
 
 
106
JSValue JSInjectedScriptHost::internalConstructorName(ExecState* exec)
 
107
{
 
108
    if (exec->argumentCount() < 1)
 
109
        return jsUndefined();
 
110
 
 
111
    JSObject* thisObject = exec->argument(0).toThisObject(exec);
 
112
    String result = thisObject->methodTable()->className(thisObject);
 
113
    return jsStringWithCache(exec, result);
 
114
}
 
115
 
 
116
JSValue JSInjectedScriptHost::isHTMLAllCollection(ExecState* exec)
 
117
{
 
118
    if (exec->argumentCount() < 1)
 
119
        return jsUndefined();
 
120
 
 
121
    JSValue value = exec->argument(0);
 
122
    return jsBoolean(value.inherits(&JSHTMLAllCollection::s_info));
 
123
}
 
124
 
 
125
JSValue JSInjectedScriptHost::type(ExecState* exec)
 
126
{
 
127
    if (exec->argumentCount() < 1)
 
128
        return jsUndefined();
 
129
 
 
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();
 
156
}
 
157
 
 
158
JSValue JSInjectedScriptHost::functionDetails(ExecState* exec)
 
159
{
 
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);
 
166
 
 
167
    const SourceCode* sourceCode = function->sourceCode();
 
168
    if (!sourceCode)
 
169
        return jsUndefined();
 
170
    int lineNumber = sourceCode->firstLine();
 
171
    if (lineNumber)
 
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());
 
174
 
 
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));
 
178
 
 
179
    JSObject* result = constructEmptyObject(exec);
 
180
    result->putDirect(exec->globalData(), Identifier(exec, "location"), location);
 
181
    String name = function->name(exec);
 
182
    if (!name.isEmpty())
 
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
 
189
    return result;
 
190
}
 
191
 
 
192
JSValue JSInjectedScriptHost::getInternalProperties(ExecState*)
 
193
{
 
194
    // FIXME: implement this. https://bugs.webkit.org/show_bug.cgi?id=94533
 
195
    return jsUndefined();
 
196
}
 
197
 
 
198
static JSArray* getJSListenerFunctions(ExecState* exec, Document* document, const EventListenerInfo& listenerInfo)
 
199
{
 
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());
 
204
        if (!jsListener) {
 
205
            ASSERT_NOT_REACHED();
 
206
            continue;
 
207
        }
 
208
        // Hide listeners from other contexts.
 
209
        if (jsListener->isolatedWorld() != currentWorld(exec))
 
210
            continue;
 
211
        JSObject* function = jsListener->jsFunction(document);
 
212
        if (!function)
 
213
            continue;
 
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));
 
218
    }
 
219
    return result;
 
220
}
 
221
 
 
222
JSValue JSInjectedScriptHost::getEventListeners(ExecState* exec)
 
223
{
 
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);
 
230
    if (!node)
 
231
        return jsUndefined();
 
232
    // This can only happen for orphan DocumentType nodes.
 
233
    Document* document = node->document();
 
234
    if (!node->document())
 
235
        return jsUndefined();
 
236
 
 
237
    Vector<EventListenerInfo> listenersArray;
 
238
    impl()->getEventListenersImpl(node, listenersArray);
 
239
 
 
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())
 
244
            continue;
 
245
        AtomicString eventType = listenersArray[i].eventType;
 
246
        result->putDirect(exec->globalData(), Identifier(exec, eventType.impl()), JSValue(listeners));
 
247
    }
 
248
 
 
249
    return result;
 
250
}
 
251
 
 
252
JSValue JSInjectedScriptHost::inspect(ExecState* exec)
 
253
{
 
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));
 
258
    }
 
259
    return jsUndefined();
 
260
}
 
261
 
 
262
JSValue JSInjectedScriptHost::databaseId(ExecState* exec)
 
263
{
 
264
    if (exec->argumentCount() < 1)
 
265
        return jsUndefined();
 
266
#if ENABLE(SQL_DATABASE)
 
267
    Database* database = toDatabase(exec->argument(0));
 
268
    if (database)
 
269
        return jsStringWithCache(exec, impl()->databaseIdImpl(database));
 
270
#endif
 
271
    return jsUndefined();
 
272
}
 
273
 
 
274
JSValue JSInjectedScriptHost::storageId(ExecState* exec)
 
275
{
 
276
    if (exec->argumentCount() < 1)
 
277
        return jsUndefined();
 
278
    Storage* storage = toStorage(exec->argument(0));
 
279
    if (storage)
 
280
        return jsStringWithCache(exec, impl()->storageIdImpl(storage));
 
281
    return jsUndefined();
 
282
}
 
283
 
 
284
JSValue JSInjectedScriptHost::evaluate(ExecState* exec)
 
285
{
 
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();
 
291
    CallData callData;
 
292
    CallType callType = evalFunction->methodTable()->getCallData(evalFunction, callData);
 
293
    if (callType == CallTypeNone)
 
294
        return jsUndefined();
 
295
    MarkedArgumentBuffer args;
 
296
    args.append(expression);
 
297
 
 
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);
 
302
 
 
303
    return result;
 
304
}
 
305
 
 
306
} // namespace WebCore
 
307
 
 
308
#endif // ENABLE(INSPECTOR)