1 /*
2 * Copyright (C) 2007-2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "InspectorBackend.h"
33
34 #include "DOMWindow.h"
35 #include "Frame.h"
36 #include "FrameLoader.h"
37 #include "ExceptionCode.h"
38 #include "InspectorController.h"
39 #include "InspectorResource.h"
40 #include "NotImplemented.h"
41 #include "Node.h"
42 #include "Range.h"
43 #include "Page.h"
44 #include "TextIterator.h"
45 #include "VisiblePosition.h"
46
47 #include "V8Binding.h"
48 #include "V8CustomBinding.h"
49 #include "V8Proxy.h"
50
51 namespace WebCore {
52
CALLBACK_FUNC_DECL(InspectorBackendHighlightDOMNode)53 CALLBACK_FUNC_DECL(InspectorBackendHighlightDOMNode)
54 {
55 INC_STATS("InspectorBackend.highlightDOMNode()");
56
57 if (args.Length() < 1)
58 return v8::Undefined();
59
60 Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
61 if (!node)
62 return v8::Undefined();
63
64 InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
65 inspectorBackend->highlight(node);
66
67 return v8::Undefined();
68 }
69
CALLBACK_FUNC_DECL(InspectorBackendSearch)70 CALLBACK_FUNC_DECL(InspectorBackendSearch)
71 {
72 INC_STATS("InspectorBackend.search()");
73
74 if (args.Length() < 2)
75 return v8::Undefined();
76
77 Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
78 if (!node)
79 return v8::Undefined();
80
81 String target = toWebCoreStringWithNullCheck(args[1]);
82 if (target.isEmpty())
83 return v8::Undefined();
84
85 v8::Local<v8::Array> result = v8::Array::New();
86 RefPtr<Range> searchRange(rangeOfContents(node));
87
88 ExceptionCode ec = 0;
89 int index = 0;
90 do {
91 RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));
92 if (resultRange->collapsed(ec))
93 break;
94
95 // A non-collapsed result range can in some funky whitespace cases still not
96 // advance the range's start position (4509328). Break to avoid infinite loop.
97 VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
98 if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
99 break;
100
101 result->Set(v8::Number::New(index++), V8DOMWrapper::convertToV8Object(V8ClassIndex::RANGE, resultRange.release()));
102
103 setStart(searchRange.get(), newStart);
104 } while (true);
105
106 return result;
107 }
108
109 #if ENABLE(DATABASE)
CALLBACK_FUNC_DECL(InspectorBackendDatabaseTableNames)110 CALLBACK_FUNC_DECL(InspectorBackendDatabaseTableNames)
111 {
112 INC_STATS("InspectorBackend.databaseTableNames()");
113 v8::Local<v8::Array> result = v8::Array::New(0);
114 return result;
115 }
116 #endif
117
CALLBACK_FUNC_DECL(InspectorBackendInspectedWindow)118 CALLBACK_FUNC_DECL(InspectorBackendInspectedWindow)
119 {
120 INC_STATS("InspectorBackend.inspectedWindow()");
121
122 InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
123 InspectorController* ic = inspectorBackend->inspectorController();
124 if (!ic)
125 return v8::Undefined();
126 return V8DOMWrapper::convertToV8Object<DOMWindow>(V8ClassIndex::DOMWINDOW, ic->inspectedPage()->mainFrame()->domWindow());
127 }
128
CALLBACK_FUNC_DECL(InspectorBackendSetting)129 CALLBACK_FUNC_DECL(InspectorBackendSetting)
130 {
131 INC_STATS("InspectorBackend.setting()");
132
133 if (args.Length() < 1)
134 return v8::Undefined();
135
136 String key = toWebCoreStringWithNullCheck(args[0]);
137 if (key.isEmpty())
138 return v8::Undefined();
139
140 InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
141 InspectorController* ic = inspectorBackend->inspectorController();
142 if (!ic)
143 return v8::Undefined();
144 const InspectorController::Setting& setting = ic->setting(key);
145
146 switch (setting.type()) {
147 default:
148 case InspectorController::Setting::NoType:
149 return v8::Undefined();
150 case InspectorController::Setting::StringType:
151 return v8String(setting.string());
152 case InspectorController::Setting::DoubleType:
153 return v8::Number::New(setting.doubleValue());
154 case InspectorController::Setting::IntegerType:
155 return v8::Number::New(setting.integerValue());
156 case InspectorController::Setting::BooleanType:
157 return v8Boolean(setting.booleanValue());
158 case InspectorController::Setting::StringVectorType: {
159 const Vector<String>& strings = setting.stringVector();
160 v8::Local<v8::Array> stringsArray = v8::Array::New(strings.size());
161 const unsigned length = strings.size();
162 for (unsigned i = 0; i < length; ++i)
163 stringsArray->Set(v8::Number::New(i), v8String(strings[i]));
164 return stringsArray;
165 }
166 }
167 }
168
CALLBACK_FUNC_DECL(InspectorBackendSetSetting)169 CALLBACK_FUNC_DECL(InspectorBackendSetSetting)
170 {
171 INC_STATS("InspectorBackend.setSetting()");
172 if (args.Length() < 2)
173 return v8::Undefined();
174
175 String key = toWebCoreStringWithNullCheck(args[0]);
176 if (key.isEmpty())
177 return v8::Undefined();
178
179 InspectorController::Setting setting;
180
181 v8::Local<v8::Value> value = args[1];
182 if (value->IsUndefined() || value->IsNull()) {
183 // Do nothing. The setting is already NoType.
184 ASSERT(setting.type() == InspectorController::Setting::NoType);
185 } else if (value->IsString())
186 setting.set(toWebCoreStringWithNullCheck(value));
187 else if (value->IsNumber())
188 setting.set(value->NumberValue());
189 else if (value->IsBoolean())
190 setting.set(value->BooleanValue());
191 else if (value->IsArray()) {
192 v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(value);
193 Vector<String> strings;
194 for (unsigned i = 0; i < v8Array->Length(); ++i) {
195 String item = toWebCoreString(v8Array->Get(v8::Integer::New(i)));
196 if (item.isEmpty())
197 return v8::Undefined();
198 strings.append(item);
199 }
200 setting.set(strings);
201 } else
202 return v8::Undefined();
203
204 InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
205 InspectorController* ic = inspectorBackend->inspectorController();
206 if (ic)
207 inspectorBackend->inspectorController()->setSetting(key, setting);
208
209 return v8::Undefined();
210 }
211
CALLBACK_FUNC_DECL(InspectorBackendWrapCallback)212 CALLBACK_FUNC_DECL(InspectorBackendWrapCallback)
213 {
214 INC_STATS("InspectorBackend.wrapCallback()");
215 return args[0];
216 }
217
218 } // namespace WebCore
219