2
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4
* Copyright (C) 2009 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.
34
#include "JSInspectorBackend.h"
41
#include "JSDatabase.h"
43
#include "ExceptionCode.h"
45
#include "FrameLoader.h"
46
#include "InspectorBackend.h"
47
#include "InspectorController.h"
48
#include "InspectorResource.h"
49
#include "JSDOMWindow.h"
50
#include "JSInspectedObjectWrapper.h"
51
#include "JSInspectorCallbackWrapper.h"
56
#if ENABLE(DOM_STORAGE)
58
#include "JSStorage.h"
60
#include "TextIterator.h"
61
#include "VisiblePosition.h"
62
#include <runtime/JSArray.h>
63
#include <runtime/JSLock.h>
64
#include <wtf/Vector.h>
66
#if ENABLE(JAVASCRIPT_DEBUGGER)
67
#include "JavaScriptCallFrame.h"
68
#include "JavaScriptDebugServer.h"
69
#include "JavaScriptProfile.h"
70
#include "JSJavaScriptCallFrame.h"
71
#include <profiler/Profile.h>
72
#include <profiler/Profiler.h>
79
JSValue JSInspectorBackend::highlightDOMNode(JSC::ExecState* exec, const JSC::ArgList& args)
84
impl()->highlight(args.at(0).toInt32(exec));
88
JSValue JSInspectorBackend::search(ExecState* exec, const ArgList& args)
93
Node* node = toNode(args.at(0));
97
String target = args.at(1).toString(exec);
98
if (exec->hadException())
101
MarkedArgumentBuffer result;
102
RefPtr<Range> searchRange(rangeOfContents(node));
104
ExceptionCode ec = 0;
106
RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));
107
if (resultRange->collapsed(ec))
110
// A non-collapsed result range can in some funky whitespace cases still not
111
// advance the range's start position (4509328). Break to avoid infinite loop.
112
VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
113
if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
116
result.append(toJS(exec, resultRange.get()));
118
setStart(searchRange.get(), newStart);
121
return constructArray(exec, result);
125
JSValue JSInspectorBackend::databaseTableNames(ExecState* exec, const ArgList& args)
128
return jsUndefined();
130
JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0));
132
return jsUndefined();
134
Database* database = toDatabase(wrapper->unwrappedObject());
136
return jsUndefined();
138
MarkedArgumentBuffer result;
140
Vector<String> tableNames = database->tableNames();
141
unsigned length = tableNames.size();
142
for (unsigned i = 0; i < length; ++i)
143
result.append(jsString(exec, tableNames[i]));
145
return constructArray(exec, result);
149
JSValue JSInspectorBackend::inspectedWindow(ExecState*, const ArgList&)
151
InspectorController* ic = impl()->inspectorController();
153
return jsUndefined();
154
JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame());
155
return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow);
158
JSValue JSInspectorBackend::setting(ExecState* exec, const ArgList& args)
161
return jsUndefined();
163
String key = args.at(0).toString(exec);
164
if (exec->hadException())
165
return jsUndefined();
167
InspectorController* ic = impl()->inspectorController();
169
return jsUndefined();
170
const InspectorController::Setting& setting = ic->setting(key);
172
switch (setting.type()) {
174
case InspectorController::Setting::NoType:
175
return jsUndefined();
176
case InspectorController::Setting::StringType:
177
return jsString(exec, setting.string());
178
case InspectorController::Setting::DoubleType:
179
return jsNumber(exec, setting.doubleValue());
180
case InspectorController::Setting::IntegerType:
181
return jsNumber(exec, setting.integerValue());
182
case InspectorController::Setting::BooleanType:
183
return jsBoolean(setting.booleanValue());
184
case InspectorController::Setting::StringVectorType: {
185
MarkedArgumentBuffer stringsArray;
186
const Vector<String>& strings = setting.stringVector();
187
const unsigned length = strings.size();
188
for (unsigned i = 0; i < length; ++i)
189
stringsArray.append(jsString(exec, strings[i]));
190
return constructArray(exec, stringsArray);
195
JSValue JSInspectorBackend::setSetting(ExecState* exec, const ArgList& args)
198
return jsUndefined();
200
String key = args.at(0).toString(exec);
201
if (exec->hadException())
202
return jsUndefined();
204
InspectorController::Setting setting;
206
JSValue value = args.at(1);
207
if (value.isUndefined() || value.isNull()) {
208
// Do nothing. The setting is already NoType.
209
ASSERT(setting.type() == InspectorController::Setting::NoType);
210
} else if (value.isString())
211
setting.set(value.toString(exec));
212
else if (value.isNumber())
213
setting.set(value.toNumber(exec));
214
else if (value.isBoolean())
215
setting.set(value.toBoolean(exec));
217
JSArray* jsArray = asArray(value);
219
return jsUndefined();
220
Vector<String> strings;
221
for (unsigned i = 0; i < jsArray->length(); ++i) {
222
String item = jsArray->get(exec, i).toString(exec);
223
if (exec->hadException())
224
return jsUndefined();
225
strings.append(item);
227
setting.set(strings);
230
if (exec->hadException())
231
return jsUndefined();
233
InspectorController* ic = impl()->inspectorController();
235
ic->setSetting(key, setting);
237
return jsUndefined();
240
JSValue JSInspectorBackend::wrapCallback(ExecState* exec, const ArgList& args)
243
return jsUndefined();
245
return JSInspectorCallbackWrapper::wrap(exec, args.at(0));
248
#if ENABLE(JAVASCRIPT_DEBUGGER)
250
JSValue JSInspectorBackend::currentCallFrame(ExecState* exec, const ArgList&)
252
JavaScriptCallFrame* callFrame = impl()->currentCallFrame();
253
if (!callFrame || !callFrame->isValid())
254
return jsUndefined();
256
// FIXME: I am not sure if this is actually needed. Can we just use exec?
257
ExecState* globalExec = callFrame->scopeChain()->globalObject->globalExec();
259
JSLock lock(SilenceAssertionsOnly);
260
return JSInspectedObjectWrapper::wrap(globalExec, toJS(exec, callFrame));
263
JSValue JSInspectorBackend::profiles(JSC::ExecState* exec, const JSC::ArgList&)
265
JSLock lock(SilenceAssertionsOnly);
266
MarkedArgumentBuffer result;
267
InspectorController* ic = impl()->inspectorController();
269
return jsUndefined();
270
const Vector<RefPtr<Profile> >& profiles = ic->profiles();
272
for (size_t i = 0; i < profiles.size(); ++i)
273
result.append(toJS(exec, profiles[i].get()));
275
return constructArray(exec, result);
280
JSValue JSInspectorBackend::nodeForId(ExecState* exec, const ArgList& args)
283
return jsUndefined();
285
Node* node = impl()->nodeForId(args.at(0).toInt32(exec));
287
return jsUndefined();
289
InspectorController* ic = impl()->inspectorController();
291
return jsUndefined();
293
JSLock lock(SilenceAssertionsOnly);
294
JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame());
295
return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), toJS(exec, deprecatedGlobalObjectForPrototype(inspectedWindow->globalExec()), node));
298
JSValue JSInspectorBackend::wrapObject(ExecState*, const ArgList& args)
301
return jsUndefined();
303
return impl()->wrapObject(ScriptValue(args.at(0))).jsValue();
306
JSValue JSInspectorBackend::unwrapObject(ExecState* exec, const ArgList& args)
309
return jsUndefined();
311
return impl()->unwrapObject(args.at(0).toString(exec)).jsValue();
314
JSValue JSInspectorBackend::pushNodePathToFrontend(ExecState* exec, const ArgList& args)
317
return jsUndefined();
319
JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0));
321
return jsUndefined();
323
Node* node = toNode(wrapper->unwrappedObject());
325
return jsUndefined();
327
bool selectInUI = args.at(1).toBoolean(exec);
328
return jsNumber(exec, impl()->pushNodePathToFrontend(node, selectInUI));
332
JSValue JSInspectorBackend::selectDatabase(ExecState*, const ArgList& args)
335
return jsUndefined();
337
JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0));
339
return jsUndefined();
341
Database* database = toDatabase(wrapper->unwrappedObject());
343
impl()->selectDatabase(database);
344
return jsUndefined();
348
#if ENABLE(DOM_STORAGE)
349
JSValue JSInspectorBackend::selectDOMStorage(ExecState*, const ArgList& args)
352
return jsUndefined();
353
InspectorController* ic = impl()->inspectorController();
355
return jsUndefined();
357
JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0));
359
return jsUndefined();
361
Storage* storage = toStorage(wrapper->unwrappedObject());
363
impl()->selectDOMStorage(storage);
364
return jsUndefined();
368
} // namespace WebCore
370
#endif // ENABLE(INSPECTOR)