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

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

Issue 10809063: Adding Javascript support for the Extended Searchbox API. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Adding missing file from last upload. 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/searchbox_extension.h" 5 #include "chrome/renderer/searchbox_extension.h"
6 6
7 #include <ctype.h>
8 #include <vector>
9
10 #include "base/string_number_conversions.h"
11 #include "base/string_piece.h"
12 #include "base/utf_string_conversions.h"
7 #include "chrome/renderer/searchbox.h" 13 #include "chrome/renderer/searchbox.h"
8 #include "content/public/renderer/render_view.h" 14 #include "content/public/renderer/render_view.h"
9 #include "grit/renderer_resources.h" 15 #include "grit/renderer_resources.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLReques t.h"
sreeram 2012/08/09 22:13:51 No need for this include.
Shishir 2012/08/10 18:16:57 Done.
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
12 #include "ui/base/resource/resource_bundle.h" 20 #include "ui/base/resource/resource_bundle.h"
13 #include "v8/include/v8.h" 21 #include "v8/include/v8.h"
14 22
23 namespace {
24
25 // Splits the string in |number| into two pieces, a leading number token (saved
26 // in |number|) and the rest (saved in |suffix|). Either piece may become empty,
27 // depending on whether the input had no digits or only digits. Neither argument
28 // may be NULL.
29 void SplitLeadingNumberToken(std::string* number, std::string* suffix) {
30 size_t i = 0;
31 while (i < number->size() && isdigit((*number)[i]))
32 ++i;
33 suffix->assign(*number, i, number->size() - i);
34 number->resize(i);
35 }
36
37 } // namespace
38
15 namespace extensions_v8 { 39 namespace extensions_v8 {
16 40
17 static const char kSearchBoxExtensionName[] = "v8/SearchBox"; 41 static const char kSearchBoxExtensionName[] = "v8/SearchBox";
18 42
19 static const char kDispatchChangeEventScript[] = 43 static const char kDispatchChangeEventScript[] =
20 "if (window.chrome &&" 44 "if (window.chrome &&"
21 " window.chrome.searchBox &&" 45 " window.chrome.searchBox &&"
22 " window.chrome.searchBox.onchange &&" 46 " window.chrome.searchBox.onchange &&"
23 " typeof window.chrome.searchBox.onchange == 'function') {" 47 " typeof window.chrome.searchBox.onchange == 'function') {"
24 " window.chrome.searchBox.onchange();" 48 " window.chrome.searchBox.onchange();"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 static const char kSupportsInstantScript[] = 80 static const char kSupportsInstantScript[] =
57 "if (window.chrome &&" 81 "if (window.chrome &&"
58 " window.chrome.searchBox &&" 82 " window.chrome.searchBox &&"
59 " window.chrome.searchBox.onsubmit &&" 83 " window.chrome.searchBox.onsubmit &&"
60 " typeof window.chrome.searchBox.onsubmit == 'function') {" 84 " typeof window.chrome.searchBox.onsubmit == 'function') {"
61 " true;" 85 " true;"
62 "} else {" 86 "} else {"
63 " false;" 87 " false;"
64 "}"; 88 "}";
65 89
90 // Extended API.
91 static const char kDispatchNativeSuggestionsEventScript[] =
sreeram 2012/08/09 22:13:51 kDispatchNativeSuggestionsEventScript -> kDispatch
Shishir 2012/08/10 18:16:57 Done.
92 "if (window.chrome &&"
93 " window.chrome.searchBox &&"
94 " window.chrome.searchBox.onnativesuggestions &&"
95 " typeof window.chrome.searchBox.onnativesuggestions == 'function') {"
96 " window.chrome.searchBox.onnativesuggestions();"
97 " true;"
98 "}";
99
100 static const char kDispatchKeyPressEventScript[] =
101 "if (window.chrome &&"
102 " window.chrome.searchBox &&"
103 " window.chrome.searchBox.onkeypress &&"
104 " typeof window.chrome.searchBox.onkeypress == 'function') {"
105 " window.chrome.searchBox.onkeypress("
106 " {keyCode:window.chrome.searchBox.keyCode});"
107 " true;"
108 "}";
109
110 static const char kDispatchFocusEventScript[] =
111 "if (window.chrome &&"
112 " window.chrome.searchBox &&"
113 " window.chrome.searchBox.onfocus &&"
114 " typeof window.chrome.searchBox.onfocus == 'function') {"
115 " window.chrome.searchBox.onfocus();"
116 " true;"
117 "}";
118
119 static const char kDispatchBlurEventScript[] =
120 "if (window.chrome &&"
121 " window.chrome.searchBox &&"
122 " window.chrome.searchBox.onblur &&"
123 " typeof window.chrome.searchBox.onblur == 'function') {"
124 " window.chrome.searchBox.onblur();"
125 " true;"
126 "}";
127
66 // ---------------------------------------------------------------------------- 128 // ----------------------------------------------------------------------------
67 129
68 class SearchBoxExtensionWrapper : public v8::Extension { 130 class SearchBoxExtensionWrapper : public v8::Extension {
69 public: 131 public:
70 explicit SearchBoxExtensionWrapper(const base::StringPiece& code); 132 explicit SearchBoxExtensionWrapper(const base::StringPiece& code);
71 133
72 // Allows v8's javascript code to call the native functions defined 134 // Allows v8's javascript code to call the native functions defined
73 // in this class for window.chrome. 135 // in this class for window.chrome.
74 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( 136 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
75 v8::Handle<v8::String> name); 137 v8::Handle<v8::String> name);
(...skipping 22 matching lines...) Expand all
98 // Gets the y coordinate (relative to |window|) of the right edge of the 160 // Gets the y coordinate (relative to |window|) of the right edge of the
99 // region of the search box that overlaps the window. 161 // region of the search box that overlaps the window.
100 static v8::Handle<v8::Value> GetY(const v8::Arguments& args); 162 static v8::Handle<v8::Value> GetY(const v8::Arguments& args);
101 163
102 // Gets the width of the region of the search box that overlaps the window. 164 // 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); 165 static v8::Handle<v8::Value> GetWidth(const v8::Arguments& args);
104 166
105 // Gets the height of the region of the search box that overlaps the window. 167 // 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); 168 static v8::Handle<v8::Value> GetHeight(const v8::Arguments& args);
107 169
170 // Gets the native suggestions from search box.
171 static v8::Handle<v8::Value> GetNativeSuggestions(const v8::Arguments& args);
sreeram 2012/08/09 22:13:51 Don't you need to also make changes to chrome/rend
Shishir 2012/08/10 18:16:57 Done.
172
173 // Gets the last key code entered in search box.
174 static v8::Handle<v8::Value> GetKeyCode(const v8::Arguments& args);
175
176 // Gets some info about the last search session committed in the search box.
177 static v8::Handle<v8::Value> GetSessionContext(const v8::Arguments& args);
178
179 // Gets whether the search box currently has keyboard focus or not.
180 static v8::Handle<v8::Value> GetIsFocused(const v8::Arguments& args);
181
108 // Sets ordered suggestions. Valid for current |value|. 182 // Sets ordered suggestions. Valid for current |value|.
109 static v8::Handle<v8::Value> SetSuggestions(const v8::Arguments& args); 183 static v8::Handle<v8::Value> SetSuggestions(const v8::Arguments& args);
110 184
185 // Sets the text to be autocompleted into the search box.
186 static v8::Handle<v8::Value> SetAutocompleteText(const v8::Arguments& args);
187
188 // Like |SetAutocompleteText| but uses a restricted ID to identify the text.
189 static v8::Handle<v8::Value> SetRestrictedAutocompleteText(
190 const v8::Arguments& args);
191
192 // Sets the search box text, completely replacing what the user typed.
193 static v8::Handle<v8::Value> SetValue(const v8::Arguments& args);
194
195 // Like |SetValue| but uses a restricted ID to identify the text.
196 static v8::Handle<v8::Value> SetRestrictedValue(const v8::Arguments& args);
197
198 // Resize the preview to the given height.
199 static v8::Handle<v8::Value> SetNonNativeDropdownHeight(
200 const v8::Arguments& args);
201
202 // Navigate the window to the URL identified by a restricted ID.
203 static v8::Handle<v8::Value> NavigateContentWindow(const v8::Arguments& args);
sreeram 2012/08/09 22:13:51 Get rid of this also. Not needed in the near futur
Shishir 2012/08/10 18:16:57 Done.
204
111 private: 205 private:
112 DISALLOW_COPY_AND_ASSIGN(SearchBoxExtensionWrapper); 206 DISALLOW_COPY_AND_ASSIGN(SearchBoxExtensionWrapper);
113 }; 207 };
114 208
115 SearchBoxExtensionWrapper::SearchBoxExtensionWrapper( 209 SearchBoxExtensionWrapper::SearchBoxExtensionWrapper(
116 const base::StringPiece& code) 210 const base::StringPiece& code)
117 : v8::Extension(kSearchBoxExtensionName, code.data(), 0, 0, code.size()) { 211 : v8::Extension(kSearchBoxExtensionName, code.data(), 0, 0, code.size()) {
118 } 212 }
119 213
120 v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction( 214 v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction(
121 v8::Handle<v8::String> name) { 215 v8::Handle<v8::String> name) {
122 if (name->Equals(v8::String::New("GetValue"))) { 216 if (name->Equals(v8::String::New("GetValue"))) {
123 return v8::FunctionTemplate::New(GetValue); 217 return v8::FunctionTemplate::New(GetValue);
124 } else if (name->Equals(v8::String::New("GetVerbatim"))) { 218 } else if (name->Equals(v8::String::New("GetVerbatim"))) {
125 return v8::FunctionTemplate::New(GetVerbatim); 219 return v8::FunctionTemplate::New(GetVerbatim);
126 } else if (name->Equals(v8::String::New("GetSelectionStart"))) { 220 } else if (name->Equals(v8::String::New("GetSelectionStart"))) {
127 return v8::FunctionTemplate::New(GetSelectionStart); 221 return v8::FunctionTemplate::New(GetSelectionStart);
128 } else if (name->Equals(v8::String::New("GetSelectionEnd"))) { 222 } else if (name->Equals(v8::String::New("GetSelectionEnd"))) {
129 return v8::FunctionTemplate::New(GetSelectionEnd); 223 return v8::FunctionTemplate::New(GetSelectionEnd);
130 } else if (name->Equals(v8::String::New("GetX"))) { 224 } else if (name->Equals(v8::String::New("GetX"))) {
131 return v8::FunctionTemplate::New(GetX); 225 return v8::FunctionTemplate::New(GetX);
132 } else if (name->Equals(v8::String::New("GetY"))) { 226 } else if (name->Equals(v8::String::New("GetY"))) {
133 return v8::FunctionTemplate::New(GetY); 227 return v8::FunctionTemplate::New(GetY);
134 } else if (name->Equals(v8::String::New("GetWidth"))) { 228 } else if (name->Equals(v8::String::New("GetWidth"))) {
135 return v8::FunctionTemplate::New(GetWidth); 229 return v8::FunctionTemplate::New(GetWidth);
136 } else if (name->Equals(v8::String::New("GetHeight"))) { 230 } else if (name->Equals(v8::String::New("GetHeight"))) {
137 return v8::FunctionTemplate::New(GetHeight); 231 return v8::FunctionTemplate::New(GetHeight);
232 } else if (name->Equals(v8::String::New("GetNativeSuggestions"))) {
233 return v8::FunctionTemplate::New(GetNativeSuggestions);
234 } else if (name->Equals(v8::String::New("GetKeyCode"))) {
235 return v8::FunctionTemplate::New(GetKeyCode);
236 } else if (name->Equals(v8::String::New("GetSessionContext"))) {
237 return v8::FunctionTemplate::New(GetSessionContext);
238 } else if (name->Equals(v8::String::New("GetIsFocused"))) {
239 return v8::FunctionTemplate::New(GetIsFocused);
138 } else if (name->Equals(v8::String::New("SetSuggestions"))) { 240 } else if (name->Equals(v8::String::New("SetSuggestions"))) {
139 return v8::FunctionTemplate::New(SetSuggestions); 241 return v8::FunctionTemplate::New(SetSuggestions);
242 } else if (name->Equals(v8::String::New("SetAutocompleteText"))) {
243 return v8::FunctionTemplate::New(SetAutocompleteText);
244 } else if (name->Equals(v8::String::New("SetRestrictedAutocompleteText"))) {
245 return v8::FunctionTemplate::New(SetRestrictedAutocompleteText);
246 } else if (name->Equals(v8::String::New("SetValue"))) {
247 return v8::FunctionTemplate::New(SetValue);
248 } else if (name->Equals(v8::String::New("SetRestrictedValue"))) {
249 return v8::FunctionTemplate::New(SetRestrictedValue);
250 } else if (name->Equals(v8::String::New("SetNonNativeDropdownHeight"))) {
251 return v8::FunctionTemplate::New(SetNonNativeDropdownHeight);
252 } else if (name->Equals(v8::String::New("NavigateContentWindow"))) {
253 return v8::FunctionTemplate::New(NavigateContentWindow);
140 } 254 }
141 return v8::Handle<v8::FunctionTemplate>(); 255 return v8::Handle<v8::FunctionTemplate>();
142 } 256 }
143 257
144 // static 258 // static
145 content::RenderView* SearchBoxExtensionWrapper::GetRenderView() { 259 content::RenderView* SearchBoxExtensionWrapper::GetRenderView() {
146 WebKit::WebFrame* webframe = WebKit::WebFrame::frameForEnteredContext(); 260 WebKit::WebFrame* webframe = WebKit::WebFrame::frameForEnteredContext();
147 DCHECK(webframe) << "There should be an active frame since we just got " 261 DCHECK(webframe) << "There should be an active frame since we just got "
148 "a native function called."; 262 "a native function called.";
149 if (!webframe) return NULL; 263 if (!webframe) return NULL;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 329
216 // static 330 // static
217 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight( 331 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight(
218 const v8::Arguments& args) { 332 const v8::Arguments& args) {
219 content::RenderView* render_view = GetRenderView(); 333 content::RenderView* render_view = GetRenderView();
220 if (!render_view) return v8::Undefined(); 334 if (!render_view) return v8::Undefined();
221 return v8::Int32::New(SearchBox::Get(render_view)->GetRect().height()); 335 return v8::Int32::New(SearchBox::Get(render_view)->GetRect().height());
222 } 336 }
223 337
224 // static 338 // static
339 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetNativeSuggestions(
340 const v8::Arguments& args) {
341 content::RenderView* render_view = GetRenderView();
342 if (!render_view) return v8::Undefined();
343 const std::vector<InstantAutocompleteResult>& suggestions =
344 SearchBox::Get(render_view)->instant_autocomplete_results();
345 const int rid_base = SearchBox::Get(render_view)->rid_base();
346 v8::Handle<v8::Array> suggestions_array(v8::Array::New(suggestions.size()));
347 for (size_t i = 0; i < suggestions.size(); ++i) {
348 v8::Handle<v8::Object> suggestion(v8::Object::New());
349 suggestion->Set(v8::String::New("provider"),
350 v8::String::New(suggestions[i].provider.c_str()));
351 suggestion->Set(v8::String::New("contents"),
352 v8::String::New(suggestions[i].contents.c_str()));
353 suggestion->Set(v8::String::New("destination_url"),
354 v8::String::New(suggestions[i].destination_url.spec().c_str()));
355 suggestion->Set(v8::String::New("rid"), v8::Uint32::New(rid_base + i));
356
357 v8::Handle<v8::Object> ranking_data(v8::Object::New());
358 ranking_data->Set(v8::String::New("relevance"),
359 v8::Int32::New(suggestions[i].relevance));
360 suggestion->Set(v8::String::New("rankingData"), ranking_data);
361
362 suggestions_array->Set(i, suggestion);
363 }
364
365 return suggestions_array;
366 }
367
368 // static
369 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetKeyCode(
370 const v8::Arguments& args) {
371 content::RenderView* render_view = GetRenderView();
372 if (!render_view) return v8::Undefined();
373 return v8::Int32::New(SearchBox::Get(render_view)->key_code());
374 }
375
376 // static
377 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSessionContext(
378 const v8::Arguments& args) {
379 content::RenderView* render_view = GetRenderView();
380 if (!render_view) return v8::Undefined();
381 v8::Handle<v8::Object> session_context(v8::Object::New());
382 session_context->Set(v8::String::New("lastSearchQuery"),
383 v8::String::New(SearchBox::Get(render_view)->last_query().c_str()));
384 // NOTE: SECURITY RISK -- Providing the current url in this way is insecure.
385 session_context->Set(v8::String::New("currentUrl"),
386 v8::String::New(SearchBox::Get(render_view)->current_url().c_str()));
387 return session_context;
388 }
389
390 // static
391 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetIsFocused(
392 const v8::Arguments& args) {
393 content::RenderView* render_view = GetRenderView();
394 if (!render_view) return v8::Undefined();
395 return v8::Boolean::New(SearchBox::Get(render_view)->is_focused());
396 }
397
398 // static
225 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions( 399 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions(
226 const v8::Arguments& args) { 400 const v8::Arguments& args) {
227 std::vector<string16> suggestions; 401 std::vector<InstantSuggestion> suggestions;
228 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW;
229 402
230 if (args.Length() && args[0]->IsObject()) { 403 if (args.Length() && args[0]->IsObject()) {
231 v8::Local<v8::Object> suggestion_json = args[0]->ToObject(); 404 v8::Local<v8::Object> suggestion_json(args[0]->ToObject());
232 405
233 v8::Local<v8::Value> complete_value = 406 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW;
234 suggestion_json->Get(v8::String::New("complete_behavior")); 407 InstantSuggestionType type = INSTANT_SUGGESTION_SEARCH;
408 v8::Local<v8::Value> complete_value(
409 suggestion_json->Get(v8::String::New("complete_behavior")));
235 if (complete_value->IsString()) { 410 if (complete_value->IsString()) {
236 if (complete_value->Equals(v8::String::New("now"))) { 411 if (complete_value->Equals(v8::String::New("now"))) {
237 behavior = INSTANT_COMPLETE_NOW; 412 behavior = INSTANT_COMPLETE_NOW;
238 } else if (complete_value->Equals(v8::String::New("never"))) { 413 } else if (complete_value->Equals(v8::String::New("never"))) {
239 behavior = INSTANT_COMPLETE_NEVER; 414 behavior = INSTANT_COMPLETE_NEVER;
240 } else if (complete_value->Equals(v8::String::New("delayed"))) { 415 } else if (complete_value->Equals(v8::String::New("delayed"))) {
241 behavior = INSTANT_COMPLETE_DELAYED; 416 behavior = INSTANT_COMPLETE_DELAYED;
417 } else if (complete_value->Equals(v8::String::New("replace"))) {
418 behavior = INSTANT_COMPLETE_REPLACE;
242 } else { 419 } else {
243 VLOG(1) << "Unsupported complete behavior '" 420 VLOG(1) << "Unsupported complete behavior '"
244 << *v8::String::Utf8Value(complete_value) << "'"; 421 << *v8::String::Utf8Value(complete_value) << "'";
245 } 422 }
246 } 423 }
247 424 v8::Local<v8::Value> suggestions_field(
248 v8::Local<v8::Value> suggestions_field = 425 suggestion_json->Get(v8::String::New("suggestions")));
249 suggestion_json->Get(v8::String::New("suggestions"));
250
251 if (suggestions_field->IsArray()) { 426 if (suggestions_field->IsArray()) {
252 v8::Local<v8::Array> suggestions_array = 427 v8::Local<v8::Array> suggestions_array(
253 suggestions_field.As<v8::Array>(); 428 suggestions_field.As<v8::Array>());
254
255 size_t length = suggestions_array->Length(); 429 size_t length = suggestions_array->Length();
256 for (size_t i = 0; i < length; i++) { 430 for (size_t i = 0; i < length; i++) {
257 v8::Local<v8::Value> suggestion_value = suggestions_array->Get(i); 431 v8::Local<v8::Value> suggestion_value(suggestions_array->Get(i));
258 if (!suggestion_value->IsObject()) continue; 432 if (!suggestion_value->IsObject()) continue;
259 433
260 v8::Local<v8::Object> suggestion_object = suggestion_value->ToObject(); 434 v8::Local<v8::Object> suggestion_object(suggestion_value->ToObject());
261 v8::Local<v8::Value> suggestion_object_value = 435 v8::Local<v8::Value> suggestion_object_value(
262 suggestion_object->Get(v8::String::New("value")); 436 suggestion_object->Get(v8::String::New("value")));
263 if (!suggestion_object_value->IsString()) continue; 437 if (!suggestion_object_value->IsString()) continue;
264 438 string16 text = *v8::String::Value(suggestion_object_value);
265 string16 suggestion(reinterpret_cast<char16*>(*v8::String::Value( 439
266 suggestion_object_value->ToString()))); 440 suggestions.push_back(InstantSuggestion(text, behavior, type));
267 suggestions.push_back(suggestion);
268 } 441 }
269 } 442 }
270 } 443 }
271 444
272 if (content::RenderView* render_view = GetRenderView()) 445 if (content::RenderView* render_view = GetRenderView())
273 SearchBox::Get(render_view)->SetSuggestions(suggestions, behavior); 446 SearchBox::Get(render_view)->SetSuggestions(suggestions);
274 return v8::Undefined(); 447 return v8::Undefined();
275 } 448 }
276 449
450 // static
451 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetAutocompleteText(
452 const v8::Arguments& args) {
453 if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsString()) {
454 string16 text = *v8::String::Value(args[0]);
455 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW;
456 InstantSuggestionType type = INSTANT_SUGGESTION_URL;
457
458 if (args.Length() >= 2 && args[1]->Uint32Value() == 2) {
459 behavior = INSTANT_COMPLETE_NEVER;
460 // TODO(sreeram): The page should really set the type explicitly.
461 type = INSTANT_SUGGESTION_SEARCH;
462 }
463
464 if (content::RenderView* render_view = GetRenderView()) {
465 std::vector<InstantSuggestion> suggestions;
466 suggestions.push_back(InstantSuggestion(text, behavior, type));
467 SearchBox::Get(render_view)->SetSuggestions(suggestions);
468 }
469 }
470 return v8::Undefined();
471 }
472
473 // static
474 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetRestrictedAutocompleteText(
475 const v8::Arguments& args) {
476 content::RenderView* render_view = GetRenderView();
477 if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsNumber() &&
478 render_view) {
479 const int rid = args[0]->Uint32Value();
480 const int rid_base = SearchBox::Get(render_view)->rid_base();
481 // Note that stale rids, less than the current rid_base, will wrap.
482 const size_t index = rid - rid_base;
483 const std::vector<InstantAutocompleteResult>& suggestions =
484 SearchBox::Get(render_view)->instant_autocomplete_results();
485 if (index < suggestions.size()) {
486 string16 text = UTF8ToUTF16(suggestions[index].destination_url.spec());
487 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW;
488 InstantSuggestionType type = INSTANT_SUGGESTION_URL;
489
490 if (args.Length() >= 2 && args[1]->Uint32Value() == 2)
491 behavior = INSTANT_COMPLETE_NEVER;
492
493 if (suggestions[index].is_search) {
494 text = suggestions[index].contents;
495 type = INSTANT_SUGGESTION_SEARCH;
496 }
497
498 std::vector<InstantSuggestion> suggestions;
499 suggestions.push_back(InstantSuggestion(text, behavior, type));
500 SearchBox::Get(render_view)->SetSuggestions(suggestions);
501 } else {
502 VLOG(1) << "Invalid rid " << rid << "; "
503 << "rid_base is " << rid_base << ".";
504 }
505 }
506 return v8::Undefined();
507 }
508
509 // static
510 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetValue(
511 const v8::Arguments& args) {
512 // TODO(sreeram): Make the second argument (type) mandatory.
513 if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsString()) {
514 string16 text = *v8::String::Value(args[0]);
515 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE;
516 InstantSuggestionType type = INSTANT_SUGGESTION_SEARCH;
517
518 if (args.Length() >= 2 && args[1]->Uint32Value() == 1)
519 type = INSTANT_SUGGESTION_URL;
520
521 if (content::RenderView* render_view = GetRenderView()) {
522 std::vector<InstantSuggestion> suggestions;
523 suggestions.push_back(InstantSuggestion(text, behavior, type));
524 SearchBox::Get(render_view)->SetSuggestions(suggestions);
525 }
526 }
527 return v8::Undefined();
528 }
529
530 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetRestrictedValue(
531 const v8::Arguments& args) {
532 content::RenderView* render_view = GetRenderView();
533 if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsNumber() &&
534 render_view) {
535 const int rid = args[0]->Uint32Value();
536 const int rid_base = SearchBox::Get(render_view)->rid_base();
537 // Note that stale rids, less than the current rid_base, will wrap.
538 const size_t index = rid - rid_base;
539 const std::vector<InstantAutocompleteResult>& suggestions =
540 SearchBox::Get(render_view)->instant_autocomplete_results();
541 if (index < suggestions.size()) {
542 string16 text = UTF8ToUTF16(suggestions[index].destination_url.spec());
543 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE;
544 InstantSuggestionType type = INSTANT_SUGGESTION_URL;
545
546 if ((args.Length() >= 2 && args[1]->Uint32Value() == 0) ||
547 (args.Length() < 2 && suggestions[index].is_search)) {
548 text = suggestions[index].contents;
549 type = INSTANT_SUGGESTION_SEARCH;
550 }
551
552 std::vector<InstantSuggestion> suggestions;
553 suggestions.push_back(InstantSuggestion(text, behavior, type));
554 SearchBox::Get(render_view)->SetSuggestions(suggestions);
555 } else {
556 VLOG(1) << "Invalid rid " << rid << "; "
557 << "rid_base is " << rid_base << ".";
558 }
559 }
560 return v8::Undefined();
561 }
562
563 // static
564 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetNonNativeDropdownHeight(
565 const v8::Arguments& args) {
566 if (args.Length() == 1) {
567 int height = 0;
568 InstantSizeUnits units = INSTANT_SIZE_PIXELS;
569 if (args[0]->IsInt32()) {
570 height = args[0]->Int32Value();
571 } else if (args[0]->IsString()) {
572 std::string height_str = *v8::String::Utf8Value(args[0]);
573 std::string units_str;
574 SplitLeadingNumberToken(&height_str, &units_str);
575 if (!base::StringToInt(height_str, &height))
576 return v8::Undefined();
577 if (units_str == "%") {
578 units = INSTANT_SIZE_PERCENT;
579 } else if (!units_str.empty() && units_str != "px") {
580 return v8::Undefined();
581 }
582 } else {
583 return v8::Undefined();
584 }
585 content::RenderView* render_view = GetRenderView();
586 if (render_view && height >= 0)
587 SearchBox::Get(render_view)->SetInstantPreviewHeight(height, units);
588 }
589 return v8::Undefined();
590 }
591
592 // static
593 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateContentWindow(
594 const v8::Arguments& args) {
595 content::RenderView* render_view = GetRenderView();
596 if (args.Length() == 1 && args[0]->IsNumber() && render_view) {
597 const int rid = args[0]->Uint32Value();
598 const int rid_base = SearchBox::Get(render_view)->rid_base();
599 // Note that stale rids, less than the current rid_base, will wrap.
600 const size_t index = rid - rid_base;
601 const std::vector<InstantAutocompleteResult>& suggestions =
602 SearchBox::Get(render_view)->instant_autocomplete_results();
603 if (index < suggestions.size()) {
604 // Navigate directly to the selected URL.
605 // TODO(sreeram): SECURITY RISK! Disconnect the InstantLoader and call
606 // SearchBox::Reset to not leak sensitive data to the new page.
607 WebKit::WebURLRequest request(suggestions[index].destination_url);
608 render_view->GetWebView()->mainFrame()->loadRequest(request);
609 } else {
610 VLOG(1) << "Invalid rid " << rid << "; "
611 << "rid_base is " << rid_base << ".";
612 }
613 }
614 return v8::Undefined();
615 }
616
277 // static 617 // static
278 void Dispatch(WebKit::WebFrame* frame, WebKit::WebString script) { 618 void Dispatch(WebKit::WebFrame* frame, WebKit::WebString script) {
279 DCHECK(frame) << "Dispatch requires frame"; 619 DCHECK(frame) << "Dispatch requires frame";
280 if (!frame) return; 620 if (!frame) return;
281 frame->executeScript(WebKit::WebScriptSource(script)); 621 frame->executeScript(WebKit::WebScriptSource(script));
282 } 622 }
283 623
284 // static 624 // static
285 void SearchBoxExtension::DispatchChange(WebKit::WebFrame* frame) { 625 void SearchBoxExtension::DispatchChange(WebKit::WebFrame* frame) {
286 Dispatch(frame, kDispatchChangeEventScript); 626 Dispatch(frame, kDispatchChangeEventScript);
287 } 627 }
288 628
289 // static 629 // static
290 void SearchBoxExtension::DispatchSubmit(WebKit::WebFrame* frame) { 630 void SearchBoxExtension::DispatchSubmit(WebKit::WebFrame* frame) {
291 Dispatch(frame, kDispatchSubmitEventScript); 631 Dispatch(frame, kDispatchSubmitEventScript);
292 } 632 }
293 633
294 // static 634 // static
295 void SearchBoxExtension::DispatchCancel(WebKit::WebFrame* frame) { 635 void SearchBoxExtension::DispatchCancel(WebKit::WebFrame* frame) {
296 Dispatch(frame, kDispatchCancelEventScript); 636 Dispatch(frame, kDispatchCancelEventScript);
297 } 637 }
298 638
299 // static 639 // static
300 void SearchBoxExtension::DispatchResize(WebKit::WebFrame* frame) { 640 void SearchBoxExtension::DispatchResize(WebKit::WebFrame* frame) {
301 Dispatch(frame, kDispatchResizeEventScript); 641 Dispatch(frame, kDispatchResizeEventScript);
302 } 642 }
303 643
304 // static 644 // static
645 void SearchBoxExtension::DispatchNativeSuggestions(WebKit::WebFrame* frame) {
646 Dispatch(frame, kDispatchNativeSuggestionsEventScript);
647 }
648
649 // static
650 void SearchBoxExtension::DispatchKeyPress(WebKit::WebFrame* frame) {
651 Dispatch(frame, kDispatchKeyPressEventScript);
652 }
653
654 // static
655 void SearchBoxExtension::DispatchFocus(WebKit::WebFrame* frame) {
656 Dispatch(frame, kDispatchFocusEventScript);
657 }
658
659 // static
660 void SearchBoxExtension::DispatchBlur(WebKit::WebFrame* frame) {
661 Dispatch(frame, kDispatchBlurEventScript);
662 }
663
664 // static
305 bool SearchBoxExtension::PageSupportsInstant(WebKit::WebFrame* frame) { 665 bool SearchBoxExtension::PageSupportsInstant(WebKit::WebFrame* frame) {
306 DCHECK(frame) << "PageSupportsInstant requires frame"; 666 DCHECK(frame) << "PageSupportsInstant requires frame";
307 if (!frame) return false; 667 if (!frame) return false;
308 668
309 v8::Handle<v8::Value> v = frame->executeScriptAndReturnValue( 669 v8::Handle<v8::Value> v = frame->executeScriptAndReturnValue(
310 WebKit::WebScriptSource(kSupportsInstantScript)); 670 WebKit::WebScriptSource(kSupportsInstantScript));
311 bool supports_instant = !v.IsEmpty() && v->BooleanValue(); 671 bool supports_instant = !v.IsEmpty() && v->BooleanValue();
312 672
313 // Send a resize message to tell the page that Chrome is actively using the 673 // 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 674 // searchbox API with it. The page uses the message to transition from
315 // "homepage" mode to "search" mode. 675 // "homepage" mode to "search" mode.
316 if (supports_instant) 676 if (supports_instant)
317 DispatchResize(frame); 677 DispatchResize(frame);
318 678
319 return supports_instant; 679 return supports_instant;
320 } 680 }
321 681
322 // static 682 // static
323 v8::Extension* SearchBoxExtension::Get() { 683 v8::Extension* SearchBoxExtension::Get() {
324 const base::StringPiece code = 684 const base::StringPiece code =
325 ResourceBundle::GetSharedInstance().GetRawDataResource( 685 ResourceBundle::GetSharedInstance().GetRawDataResource(
326 IDR_SEARCHBOX_API, ui::SCALE_FACTOR_NONE); 686 IDR_SEARCHBOX_API, ui::SCALE_FACTOR_NONE);
327 return new SearchBoxExtensionWrapper(code); 687 return new SearchBoxExtensionWrapper(code);
328 } 688 }
329 689
330 } // namespace extensions_v8 690 } // namespace extensions_v8
OLDNEW
« chrome/renderer/searchbox_extension.h ('K') | « chrome/renderer/searchbox_extension.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698