Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: chrome/renderer/searchbox_extension.cc

Issue 10825304: Creating a new directory chrome/renderer/searchbox and moving appropriate code to it. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Removing sky from OWNERS. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/renderer/searchbox_extension.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/renderer/searchbox_extension.h"
6
7 #include "chrome/renderer/searchbox.h"
8 #include "content/public/renderer/render_view.h"
9 #include "grit/renderer_resources.h"
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
12 #include "ui/base/resource/resource_bundle.h"
13 #include "v8/include/v8.h"
14
15 namespace extensions_v8 {
16
17 static const char kSearchBoxExtensionName[] = "v8/SearchBox";
18
19 static const char kDispatchChangeEventScript[] =
20 "if (window.chrome &&"
21 " window.chrome.searchBox &&"
22 " window.chrome.searchBox.onchange &&"
23 " typeof window.chrome.searchBox.onchange == 'function') {"
24 " window.chrome.searchBox.onchange();"
25 " true;"
26 "}";
27
28 static const char kDispatchSubmitEventScript[] =
29 "if (window.chrome &&"
30 " window.chrome.searchBox &&"
31 " window.chrome.searchBox.onsubmit &&"
32 " typeof window.chrome.searchBox.onsubmit == 'function') {"
33 " window.chrome.searchBox.onsubmit();"
34 " true;"
35 "}";
36
37 static const char kDispatchCancelEventScript[] =
38 "if (window.chrome &&"
39 " window.chrome.searchBox &&"
40 " window.chrome.searchBox.oncancel &&"
41 " typeof window.chrome.searchBox.oncancel == 'function') {"
42 " window.chrome.searchBox.oncancel();"
43 " true;"
44 "}";
45
46 static const char kDispatchResizeEventScript[] =
47 "if (window.chrome &&"
48 " window.chrome.searchBox &&"
49 " window.chrome.searchBox.onresize &&"
50 " typeof window.chrome.searchBox.onresize == 'function') {"
51 " window.chrome.searchBox.onresize();"
52 " true;"
53 "}";
54
55 // We first send this script down to determine if the page supports instant.
56 static const char kSupportsInstantScript[] =
57 "if (window.chrome &&"
58 " window.chrome.searchBox &&"
59 " window.chrome.searchBox.onsubmit &&"
60 " typeof window.chrome.searchBox.onsubmit == 'function') {"
61 " true;"
62 "} else {"
63 " false;"
64 "}";
65
66 // ----------------------------------------------------------------------------
67
68 class SearchBoxExtensionWrapper : public v8::Extension {
69 public:
70 explicit SearchBoxExtensionWrapper(const base::StringPiece& code);
71
72 // Allows v8's javascript code to call the native functions defined
73 // in this class for window.chrome.
74 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
75 v8::Handle<v8::String> name);
76
77 // Helper function to find the RenderView. May return NULL.
78 static content::RenderView* GetRenderView();
79
80 // Gets the value of the user's search query.
81 static v8::Handle<v8::Value> GetValue(const v8::Arguments& args);
82
83 // Gets whether the |value| should be considered final -- as opposed to a
84 // partial match. This may be set if the user clicks a suggestion, presses
85 // forward delete, or in other cases where Chrome overrides.
86 static v8::Handle<v8::Value> GetVerbatim(const v8::Arguments& args);
87
88 // Gets the start of the selection in the search box.
89 static v8::Handle<v8::Value> GetSelectionStart(const v8::Arguments& args);
90
91 // Gets the end of the selection in the search box.
92 static v8::Handle<v8::Value> GetSelectionEnd(const v8::Arguments& args);
93
94 // Gets the x coordinate (relative to |window|) of the left edge of the
95 // region of the search box that overlaps the window.
96 static v8::Handle<v8::Value> GetX(const v8::Arguments& args);
97
98 // Gets the y coordinate (relative to |window|) of the right edge of the
99 // region of the search box that overlaps the window.
100 static v8::Handle<v8::Value> GetY(const v8::Arguments& args);
101
102 // Gets the width of the region of the search box that overlaps the window.
103 static v8::Handle<v8::Value> GetWidth(const v8::Arguments& args);
104
105 // Gets the height of the region of the search box that overlaps the window.
106 static v8::Handle<v8::Value> GetHeight(const v8::Arguments& args);
107
108 // Sets ordered suggestions. Valid for current |value|.
109 static v8::Handle<v8::Value> SetSuggestions(const v8::Arguments& args);
110
111 private:
112 DISALLOW_COPY_AND_ASSIGN(SearchBoxExtensionWrapper);
113 };
114
115 SearchBoxExtensionWrapper::SearchBoxExtensionWrapper(
116 const base::StringPiece& code)
117 : v8::Extension(kSearchBoxExtensionName, code.data(), 0, 0, code.size()) {
118 }
119
120 v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction(
121 v8::Handle<v8::String> name) {
122 if (name->Equals(v8::String::New("GetValue"))) {
123 return v8::FunctionTemplate::New(GetValue);
124 } else if (name->Equals(v8::String::New("GetVerbatim"))) {
125 return v8::FunctionTemplate::New(GetVerbatim);
126 } else if (name->Equals(v8::String::New("GetSelectionStart"))) {
127 return v8::FunctionTemplate::New(GetSelectionStart);
128 } else if (name->Equals(v8::String::New("GetSelectionEnd"))) {
129 return v8::FunctionTemplate::New(GetSelectionEnd);
130 } else if (name->Equals(v8::String::New("GetX"))) {
131 return v8::FunctionTemplate::New(GetX);
132 } else if (name->Equals(v8::String::New("GetY"))) {
133 return v8::FunctionTemplate::New(GetY);
134 } else if (name->Equals(v8::String::New("GetWidth"))) {
135 return v8::FunctionTemplate::New(GetWidth);
136 } else if (name->Equals(v8::String::New("GetHeight"))) {
137 return v8::FunctionTemplate::New(GetHeight);
138 } else if (name->Equals(v8::String::New("SetSuggestions"))) {
139 return v8::FunctionTemplate::New(SetSuggestions);
140 }
141 return v8::Handle<v8::FunctionTemplate>();
142 }
143
144 // static
145 content::RenderView* SearchBoxExtensionWrapper::GetRenderView() {
146 WebKit::WebFrame* webframe = WebKit::WebFrame::frameForEnteredContext();
147 DCHECK(webframe) << "There should be an active frame since we just got "
148 "a native function called.";
149 if (!webframe) return NULL;
150
151 WebKit::WebView* webview = webframe->view();
152 if (!webview) return NULL; // can happen during closing
153
154 return content::RenderView::FromWebView(webview);
155 }
156
157 // static
158 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetValue(
159 const v8::Arguments& args) {
160 content::RenderView* render_view = GetRenderView();
161 if (!render_view) return v8::Undefined();
162 return v8::String::New(
163 reinterpret_cast<const uint16_t*>(
164 SearchBox::Get(render_view)->value().data()),
165 SearchBox::Get(render_view)->value().length());
166 }
167
168 // static
169 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetVerbatim(
170 const v8::Arguments& args) {
171 content::RenderView* render_view = GetRenderView();
172 if (!render_view) return v8::Undefined();
173 return v8::Boolean::New(SearchBox::Get(render_view)->verbatim());
174 }
175
176 // static
177 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSelectionStart(
178 const v8::Arguments& args) {
179 content::RenderView* render_view = GetRenderView();
180 if (!render_view) return v8::Undefined();
181 return v8::Uint32::New(SearchBox::Get(render_view)->selection_start());
182 }
183
184 // static
185 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSelectionEnd(
186 const v8::Arguments& args) {
187 content::RenderView* render_view = GetRenderView();
188 if (!render_view) return v8::Undefined();
189 return v8::Uint32::New(SearchBox::Get(render_view)->selection_end());
190 }
191
192 // static
193 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetX(
194 const v8::Arguments& args) {
195 content::RenderView* render_view = GetRenderView();
196 if (!render_view) return v8::Undefined();
197 return v8::Int32::New(SearchBox::Get(render_view)->GetRect().x());
198 }
199
200 // static
201 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetY(
202 const v8::Arguments& args) {
203 content::RenderView* render_view = GetRenderView();
204 if (!render_view) return v8::Undefined();
205 return v8::Int32::New(SearchBox::Get(render_view)->GetRect().y());
206 }
207
208 // static
209 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetWidth(
210 const v8::Arguments& args) {
211 content::RenderView* render_view = GetRenderView();
212 if (!render_view) return v8::Undefined();
213 return v8::Int32::New(SearchBox::Get(render_view)->GetRect().width());
214 }
215
216 // static
217 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight(
218 const v8::Arguments& args) {
219 content::RenderView* render_view = GetRenderView();
220 if (!render_view) return v8::Undefined();
221 return v8::Int32::New(SearchBox::Get(render_view)->GetRect().height());
222 }
223
224 // static
225 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions(
226 const v8::Arguments& args) {
227 std::vector<string16> suggestions;
228 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW;
229
230 if (args.Length() && args[0]->IsObject()) {
231 v8::Local<v8::Object> suggestion_json = args[0]->ToObject();
232
233 v8::Local<v8::Value> complete_value =
234 suggestion_json->Get(v8::String::New("complete_behavior"));
235 if (complete_value->IsString()) {
236 if (complete_value->Equals(v8::String::New("now"))) {
237 behavior = INSTANT_COMPLETE_NOW;
238 } else if (complete_value->Equals(v8::String::New("never"))) {
239 behavior = INSTANT_COMPLETE_NEVER;
240 } else if (complete_value->Equals(v8::String::New("delayed"))) {
241 behavior = INSTANT_COMPLETE_DELAYED;
242 } else {
243 VLOG(1) << "Unsupported complete behavior '"
244 << *v8::String::Utf8Value(complete_value) << "'";
245 }
246 }
247
248 v8::Local<v8::Value> suggestions_field =
249 suggestion_json->Get(v8::String::New("suggestions"));
250
251 if (suggestions_field->IsArray()) {
252 v8::Local<v8::Array> suggestions_array =
253 suggestions_field.As<v8::Array>();
254
255 size_t length = suggestions_array->Length();
256 for (size_t i = 0; i < length; i++) {
257 v8::Local<v8::Value> suggestion_value = suggestions_array->Get(i);
258 if (!suggestion_value->IsObject()) continue;
259
260 v8::Local<v8::Object> suggestion_object = suggestion_value->ToObject();
261 v8::Local<v8::Value> suggestion_object_value =
262 suggestion_object->Get(v8::String::New("value"));
263 if (!suggestion_object_value->IsString()) continue;
264
265 string16 suggestion(reinterpret_cast<char16*>(*v8::String::Value(
266 suggestion_object_value->ToString())));
267 suggestions.push_back(suggestion);
268 }
269 }
270 }
271
272 if (content::RenderView* render_view = GetRenderView())
273 SearchBox::Get(render_view)->SetSuggestions(suggestions, behavior);
274 return v8::Undefined();
275 }
276
277 // static
278 void Dispatch(WebKit::WebFrame* frame, WebKit::WebString script) {
279 DCHECK(frame) << "Dispatch requires frame";
280 if (!frame) return;
281 frame->executeScript(WebKit::WebScriptSource(script));
282 }
283
284 // static
285 void SearchBoxExtension::DispatchChange(WebKit::WebFrame* frame) {
286 Dispatch(frame, kDispatchChangeEventScript);
287 }
288
289 // static
290 void SearchBoxExtension::DispatchSubmit(WebKit::WebFrame* frame) {
291 Dispatch(frame, kDispatchSubmitEventScript);
292 }
293
294 // static
295 void SearchBoxExtension::DispatchCancel(WebKit::WebFrame* frame) {
296 Dispatch(frame, kDispatchCancelEventScript);
297 }
298
299 // static
300 void SearchBoxExtension::DispatchResize(WebKit::WebFrame* frame) {
301 Dispatch(frame, kDispatchResizeEventScript);
302 }
303
304 // static
305 bool SearchBoxExtension::PageSupportsInstant(WebKit::WebFrame* frame) {
306 DCHECK(frame) << "PageSupportsInstant requires frame";
307 if (!frame) return false;
308
309 v8::Handle<v8::Value> v = frame->executeScriptAndReturnValue(
310 WebKit::WebScriptSource(kSupportsInstantScript));
311 bool supports_instant = !v.IsEmpty() && v->BooleanValue();
312
313 // Send a resize message to tell the page that Chrome is actively using the
314 // searchbox API with it. The page uses the message to transition from
315 // "homepage" mode to "search" mode.
316 if (supports_instant)
317 DispatchResize(frame);
318
319 return supports_instant;
320 }
321
322 // static
323 v8::Extension* SearchBoxExtension::Get() {
324 const base::StringPiece code =
325 ResourceBundle::GetSharedInstance().GetRawDataResource(
326 IDR_SEARCHBOX_API, ui::SCALE_FACTOR_NONE);
327 return new SearchBoxExtensionWrapper(code);
328 }
329
330 } // namespace extensions_v8
OLDNEW
« no previous file with comments | « chrome/renderer/searchbox_extension.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698