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

Side by Side Diff: chrome/renderer/searchbox/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: Syncing to pickup moved searchbox code. 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/searchbox_extension.h" 5 #include "chrome/renderer/searchbox/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/searchbox.h" 13 #include "chrome/renderer/searchbox/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/13 16:37:08 We don't need this header.
Shishir 2012/08/13 18:11:12 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 kDispatchAutocompleteResultsEventScript[] =
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
66 // ---------------------------------------------------------------------------- 110 // ----------------------------------------------------------------------------
67 111
68 class SearchBoxExtensionWrapper : public v8::Extension { 112 class SearchBoxExtensionWrapper : public v8::Extension {
69 public: 113 public:
70 explicit SearchBoxExtensionWrapper(const base::StringPiece& code); 114 explicit SearchBoxExtensionWrapper(const base::StringPiece& code);
71 115
72 // Allows v8's javascript code to call the native functions defined 116 // Allows v8's javascript code to call the native functions defined
73 // in this class for window.chrome. 117 // in this class for window.chrome.
74 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( 118 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
75 v8::Handle<v8::String> name); 119 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 142 // Gets the y coordinate (relative to |window|) of the right edge of the
99 // region of the search box that overlaps the window. 143 // region of the search box that overlaps the window.
100 static v8::Handle<v8::Value> GetY(const v8::Arguments& args); 144 static v8::Handle<v8::Value> GetY(const v8::Arguments& args);
101 145
102 // Gets the width of the region of the search box that overlaps the window. 146 // 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); 147 static v8::Handle<v8::Value> GetWidth(const v8::Arguments& args);
104 148
105 // Gets the height of the region of the search box that overlaps the window. 149 // 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); 150 static v8::Handle<v8::Value> GetHeight(const v8::Arguments& args);
107 151
152 // Gets the autocomplete results from search box.
153 static v8::Handle<v8::Value> GetAutocompleteResults(
154 const v8::Arguments& args);
155
156 // Gets the last key code entered in search box.
157 static v8::Handle<v8::Value> GetKeyCode(const v8::Arguments& args);
158
108 // Sets ordered suggestions. Valid for current |value|. 159 // Sets ordered suggestions. Valid for current |value|.
109 static v8::Handle<v8::Value> SetSuggestions(const v8::Arguments& args); 160 static v8::Handle<v8::Value> SetSuggestions(const v8::Arguments& args);
110 161
162 // Sets the text to be autocompleted into the search box.
163 static v8::Handle<v8::Value> SetSuggestionInline(const v8::Arguments& args);
164
165 // Like |SetSuggestionInline| but uses a restricted ID to identify the text.
166 static v8::Handle<v8::Value> SetAutocompleteResultInline(
167 const v8::Arguments& args);
168
169 // Sets the search box text, completely replacing what the user typed.
170 static v8::Handle<v8::Value> SetSuggestionReplace(const v8::Arguments& args);
171
172 // Like |SetSuggestionReplace| but uses a restricted ID to identify the text.
173 static v8::Handle<v8::Value> SetAutocompleteResultReplace(
174 const v8::Arguments& args);
175
176 // Resize the preview to the given height.
177 static v8::Handle<v8::Value> SetNonNativeDropdownHeight(
178 const v8::Arguments& args);
179
111 private: 180 private:
112 DISALLOW_COPY_AND_ASSIGN(SearchBoxExtensionWrapper); 181 DISALLOW_COPY_AND_ASSIGN(SearchBoxExtensionWrapper);
113 }; 182 };
114 183
115 SearchBoxExtensionWrapper::SearchBoxExtensionWrapper( 184 SearchBoxExtensionWrapper::SearchBoxExtensionWrapper(
116 const base::StringPiece& code) 185 const base::StringPiece& code)
117 : v8::Extension(kSearchBoxExtensionName, code.data(), 0, 0, code.size()) { 186 : v8::Extension(kSearchBoxExtensionName, code.data(), 0, 0, code.size()) {
118 } 187 }
119 188
120 v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction( 189 v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction(
121 v8::Handle<v8::String> name) { 190 v8::Handle<v8::String> name) {
122 if (name->Equals(v8::String::New("GetValue"))) { 191 if (name->Equals(v8::String::New("GetValue"))) {
123 return v8::FunctionTemplate::New(GetValue); 192 return v8::FunctionTemplate::New(GetValue);
124 } else if (name->Equals(v8::String::New("GetVerbatim"))) { 193 } else if (name->Equals(v8::String::New("GetVerbatim"))) {
125 return v8::FunctionTemplate::New(GetVerbatim); 194 return v8::FunctionTemplate::New(GetVerbatim);
126 } else if (name->Equals(v8::String::New("GetSelectionStart"))) { 195 } else if (name->Equals(v8::String::New("GetSelectionStart"))) {
127 return v8::FunctionTemplate::New(GetSelectionStart); 196 return v8::FunctionTemplate::New(GetSelectionStart);
128 } else if (name->Equals(v8::String::New("GetSelectionEnd"))) { 197 } else if (name->Equals(v8::String::New("GetSelectionEnd"))) {
129 return v8::FunctionTemplate::New(GetSelectionEnd); 198 return v8::FunctionTemplate::New(GetSelectionEnd);
130 } else if (name->Equals(v8::String::New("GetX"))) { 199 } else if (name->Equals(v8::String::New("GetX"))) {
131 return v8::FunctionTemplate::New(GetX); 200 return v8::FunctionTemplate::New(GetX);
132 } else if (name->Equals(v8::String::New("GetY"))) { 201 } else if (name->Equals(v8::String::New("GetY"))) {
133 return v8::FunctionTemplate::New(GetY); 202 return v8::FunctionTemplate::New(GetY);
134 } else if (name->Equals(v8::String::New("GetWidth"))) { 203 } else if (name->Equals(v8::String::New("GetWidth"))) {
135 return v8::FunctionTemplate::New(GetWidth); 204 return v8::FunctionTemplate::New(GetWidth);
136 } else if (name->Equals(v8::String::New("GetHeight"))) { 205 } else if (name->Equals(v8::String::New("GetHeight"))) {
137 return v8::FunctionTemplate::New(GetHeight); 206 return v8::FunctionTemplate::New(GetHeight);
207 } else if (name->Equals(v8::String::New("GetAutocompleteResults"))) {
208 return v8::FunctionTemplate::New(GetAutocompleteResults);
209 } else if (name->Equals(v8::String::New("GetKeyCode"))) {
210 return v8::FunctionTemplate::New(GetKeyCode);
138 } else if (name->Equals(v8::String::New("SetSuggestions"))) { 211 } else if (name->Equals(v8::String::New("SetSuggestions"))) {
139 return v8::FunctionTemplate::New(SetSuggestions); 212 return v8::FunctionTemplate::New(SetSuggestions);
213 } else if (name->Equals(v8::String::New("SetSuggestionInline"))) {
214 return v8::FunctionTemplate::New(SetSuggestionInline);
215 } else if (name->Equals(v8::String::New("SetAutocompleteResultInline"))) {
216 return v8::FunctionTemplate::New(SetAutocompleteResultInline);
217 } else if (name->Equals(v8::String::New("SetSuggestionReplace"))) {
218 return v8::FunctionTemplate::New(SetSuggestionReplace);
219 } else if (name->Equals(v8::String::New("SetAutocompleteResultReplace"))) {
220 return v8::FunctionTemplate::New(SetAutocompleteResultReplace);
221 } else if (name->Equals(v8::String::New("SetNonNativeDropdownHeight"))) {
222 return v8::FunctionTemplate::New(SetNonNativeDropdownHeight);
140 } 223 }
141 return v8::Handle<v8::FunctionTemplate>(); 224 return v8::Handle<v8::FunctionTemplate>();
142 } 225 }
143 226
144 // static 227 // static
145 content::RenderView* SearchBoxExtensionWrapper::GetRenderView() { 228 content::RenderView* SearchBoxExtensionWrapper::GetRenderView() {
146 WebKit::WebFrame* webframe = WebKit::WebFrame::frameForEnteredContext(); 229 WebKit::WebFrame* webframe = WebKit::WebFrame::frameForEnteredContext();
147 DCHECK(webframe) << "There should be an active frame since we just got " 230 DCHECK(webframe) << "There should be an active frame since we just got "
148 "a native function called."; 231 "a native function called.";
149 if (!webframe) return NULL; 232 if (!webframe) return NULL;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 298
216 // static 299 // static
217 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight( 300 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight(
218 const v8::Arguments& args) { 301 const v8::Arguments& args) {
219 content::RenderView* render_view = GetRenderView(); 302 content::RenderView* render_view = GetRenderView();
220 if (!render_view) return v8::Undefined(); 303 if (!render_view) return v8::Undefined();
221 return v8::Int32::New(SearchBox::Get(render_view)->GetRect().height()); 304 return v8::Int32::New(SearchBox::Get(render_view)->GetRect().height());
222 } 305 }
223 306
224 // static 307 // static
308 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults(
309 const v8::Arguments& args) {
310 content::RenderView* render_view = GetRenderView();
311 if (!render_view) return v8::Undefined();
312 const std::vector<InstantAutocompleteResult>& suggestions =
313 SearchBox::Get(render_view)->autocomplete_results();
sreeram 2012/08/13 16:37:08 suggestions -> results, throughout this method.
Shishir 2012/08/13 18:11:12 Done.
314 const int results_base = SearchBox::Get(render_view)->results_base();
315 v8::Handle<v8::Array> suggestions_array(v8::Array::New(suggestions.size()));
316 for (size_t i = 0; i < suggestions.size(); ++i) {
317 v8::Handle<v8::Object> suggestion(v8::Object::New());
318 suggestion->Set(v8::String::New("provider"),
319 v8::String::New(suggestions[i].provider.c_str()));
320 suggestion->Set(v8::String::New("contents"),
321 v8::String::New(suggestions[i].contents.c_str()));
sreeram 2012/08/13 16:37:08 suggestions[i].provider/contents are string16s. .c
Shishir 2012/08/13 18:11:12 Done.
322 suggestion->Set(v8::String::New("destination_url"),
323 v8::String::New(suggestions[i].destination_url.spec().c_str()));
324 suggestion->Set(v8::String::New("rid"), v8::Uint32::New(results_base + i));
325
326 v8::Handle<v8::Object> ranking_data(v8::Object::New());
327 ranking_data->Set(v8::String::New("relevance"),
328 v8::Int32::New(suggestions[i].relevance));
329 suggestion->Set(v8::String::New("rankingData"), ranking_data);
330
331 suggestions_array->Set(i, suggestion);
332 }
333
334 return suggestions_array;
335 }
336
337 // static
338 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetKeyCode(
339 const v8::Arguments& args) {
340 content::RenderView* render_view = GetRenderView();
341 if (!render_view) return v8::Undefined();
342 return v8::Int32::New(SearchBox::Get(render_view)->key_code());
343 }
344
345 // static
225 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions( 346 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions(
226 const v8::Arguments& args) { 347 const v8::Arguments& args) {
227 std::vector<string16> suggestions; 348 std::vector<InstantSuggestion> suggestions;
228 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW;
229 349
230 if (args.Length() && args[0]->IsObject()) { 350 if (args.Length() && args[0]->IsObject()) {
231 v8::Local<v8::Object> suggestion_json = args[0]->ToObject(); 351 v8::Local<v8::Object> suggestion_json(args[0]->ToObject());
232 352
233 v8::Local<v8::Value> complete_value = 353 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW;
234 suggestion_json->Get(v8::String::New("complete_behavior")); 354 InstantSuggestionType type = INSTANT_SUGGESTION_SEARCH;
355 v8::Local<v8::Value> complete_value(
356 suggestion_json->Get(v8::String::New("complete_behavior")));
235 if (complete_value->IsString()) { 357 if (complete_value->IsString()) {
236 if (complete_value->Equals(v8::String::New("now"))) { 358 if (complete_value->Equals(v8::String::New("now"))) {
237 behavior = INSTANT_COMPLETE_NOW; 359 behavior = INSTANT_COMPLETE_NOW;
238 } else if (complete_value->Equals(v8::String::New("never"))) { 360 } else if (complete_value->Equals(v8::String::New("never"))) {
239 behavior = INSTANT_COMPLETE_NEVER; 361 behavior = INSTANT_COMPLETE_NEVER;
240 } else if (complete_value->Equals(v8::String::New("delayed"))) { 362 } else if (complete_value->Equals(v8::String::New("delayed"))) {
241 behavior = INSTANT_COMPLETE_DELAYED; 363 behavior = INSTANT_COMPLETE_DELAYED;
364 } else if (complete_value->Equals(v8::String::New("replace"))) {
365 behavior = INSTANT_COMPLETE_REPLACE;
242 } else { 366 } else {
243 VLOG(1) << "Unsupported complete behavior '" 367 VLOG(1) << "Unsupported complete behavior '"
244 << *v8::String::Utf8Value(complete_value) << "'"; 368 << *v8::String::Utf8Value(complete_value) << "'";
245 } 369 }
246 } 370 }
247 371 v8::Local<v8::Value> suggestions_field(
248 v8::Local<v8::Value> suggestions_field = 372 suggestion_json->Get(v8::String::New("suggestions")));
249 suggestion_json->Get(v8::String::New("suggestions"));
250
251 if (suggestions_field->IsArray()) { 373 if (suggestions_field->IsArray()) {
252 v8::Local<v8::Array> suggestions_array = 374 v8::Local<v8::Array> suggestions_array(
253 suggestions_field.As<v8::Array>(); 375 suggestions_field.As<v8::Array>());
254
255 size_t length = suggestions_array->Length(); 376 size_t length = suggestions_array->Length();
256 for (size_t i = 0; i < length; i++) { 377 for (size_t i = 0; i < length; i++) {
257 v8::Local<v8::Value> suggestion_value = suggestions_array->Get(i); 378 v8::Local<v8::Value> suggestion_value(suggestions_array->Get(i));
258 if (!suggestion_value->IsObject()) continue; 379 if (!suggestion_value->IsObject()) continue;
259 380
260 v8::Local<v8::Object> suggestion_object = suggestion_value->ToObject(); 381 v8::Local<v8::Object> suggestion_object(suggestion_value->ToObject());
261 v8::Local<v8::Value> suggestion_object_value = 382 v8::Local<v8::Value> suggestion_object_value(
262 suggestion_object->Get(v8::String::New("value")); 383 suggestion_object->Get(v8::String::New("value")));
sreeram 2012/08/13 16:37:08 Why replace all the "type foo = bar;" statements w
Shishir 2012/08/13 18:11:12 Done.
263 if (!suggestion_object_value->IsString()) continue; 384 if (!suggestion_object_value->IsString()) continue;
385 string16 text = *v8::String::Value(suggestion_object_value);
264 386
265 string16 suggestion(reinterpret_cast<char16*>(*v8::String::Value( 387 suggestions.push_back(InstantSuggestion(text, behavior, type));
266 suggestion_object_value->ToString())));
267 suggestions.push_back(suggestion);
268 } 388 }
269 } 389 }
270 } 390 }
271 391
272 if (content::RenderView* render_view = GetRenderView()) 392 if (content::RenderView* render_view = GetRenderView())
273 SearchBox::Get(render_view)->SetSuggestions(suggestions, behavior); 393 SearchBox::Get(render_view)->SetSuggestions(suggestions);
274 return v8::Undefined(); 394 return v8::Undefined();
275 } 395 }
276 396
397 // static
398 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestionInline(
399 const v8::Arguments& args) {
400 if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsString()) {
401 string16 text = *v8::String::Value(args[0]);
402 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW;
403 InstantSuggestionType type = INSTANT_SUGGESTION_URL;
404
405 if (args.Length() >= 2 && args[1]->Uint32Value() == 2) {
406 behavior = INSTANT_COMPLETE_NEVER;
407 // TODO(sreeram): The page should really set the type explicitly.
408 type = INSTANT_SUGGESTION_SEARCH;
409 }
410
411 if (content::RenderView* render_view = GetRenderView()) {
412 std::vector<InstantSuggestion> suggestions;
413 suggestions.push_back(InstantSuggestion(text, behavior, type));
414 SearchBox::Get(render_view)->SetSuggestions(suggestions);
415 }
416 }
417 return v8::Undefined();
418 }
419
420 // static
421 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetAutocompleteResultInline(
422 const v8::Arguments& args) {
423 content::RenderView* render_view = GetRenderView();
424 if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsNumber() &&
425 render_view) {
426 const int results_id = args[0]->Uint32Value();
427 const int results_base = SearchBox::Get(render_view)->results_base();
428 // Note that stale results_ids, less than the current results_base, will
429 // wrap.
430 const size_t index = results_id - results_base;
431 const std::vector<InstantAutocompleteResult>& suggestions =
432 SearchBox::Get(render_view)->autocomplete_results();
433 if (index < suggestions.size()) {
434 string16 text = UTF8ToUTF16(suggestions[index].destination_url.spec());
435 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW;
436 InstantSuggestionType type = INSTANT_SUGGESTION_URL;
437
438 if (args.Length() >= 2 && args[1]->Uint32Value() == 2)
439 behavior = INSTANT_COMPLETE_NEVER;
440
441 if (suggestions[index].is_search) {
442 text = suggestions[index].contents;
443 type = INSTANT_SUGGESTION_SEARCH;
444 }
445
446 std::vector<InstantSuggestion> suggestions;
447 suggestions.push_back(InstantSuggestion(text, behavior, type));
448 SearchBox::Get(render_view)->SetSuggestions(suggestions);
449 } else {
450 VLOG(1) << "Invalid results_id " << results_id << "; "
451 << "results_base is " << results_base << ".";
452 }
453 }
454 return v8::Undefined();
455 }
456
457 // static
458 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestionReplace(
459 const v8::Arguments& args) {
460 // TODO(sreeram): Make the second argument (type) mandatory.
461 if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsString()) {
462 string16 text = *v8::String::Value(args[0]);
463 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE;
464 InstantSuggestionType type = INSTANT_SUGGESTION_SEARCH;
465
466 if (args.Length() >= 2 && args[1]->Uint32Value() == 1)
467 type = INSTANT_SUGGESTION_URL;
468
469 if (content::RenderView* render_view = GetRenderView()) {
470 std::vector<InstantSuggestion> suggestions;
471 suggestions.push_back(InstantSuggestion(text, behavior, type));
472 SearchBox::Get(render_view)->SetSuggestions(suggestions);
473 }
474 }
475 return v8::Undefined();
476 }
477
478 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetAutocompleteResultReplace(
479 const v8::Arguments& args) {
480 content::RenderView* render_view = GetRenderView();
481 if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsNumber() &&
482 render_view) {
483 const int results_id = args[0]->Uint32Value();
484 const int results_base = SearchBox::Get(render_view)->results_base();
485 // Note that stale results_ids, less than the current results_base, will
486 // wrap.
487 const size_t index = results_id - results_base;
488 const std::vector<InstantAutocompleteResult>& suggestions =
489 SearchBox::Get(render_view)->autocomplete_results();
490 if (index < suggestions.size()) {
491 string16 text = UTF8ToUTF16(suggestions[index].destination_url.spec());
492 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE;
493 InstantSuggestionType type = INSTANT_SUGGESTION_URL;
494
495 if ((args.Length() >= 2 && args[1]->Uint32Value() == 0) ||
496 (args.Length() < 2 && suggestions[index].is_search)) {
497 text = suggestions[index].contents;
498 type = INSTANT_SUGGESTION_SEARCH;
499 }
500
501 std::vector<InstantSuggestion> suggestions;
502 suggestions.push_back(InstantSuggestion(text, behavior, type));
503 SearchBox::Get(render_view)->SetSuggestions(suggestions);
504 } else {
505 VLOG(1) << "Invalid results_id " << results_id << "; "
506 << "results_base is " << results_base << ".";
507 }
508 }
509 return v8::Undefined();
510 }
511
512 // static
513 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetNonNativeDropdownHeight(
514 const v8::Arguments& args) {
515 if (args.Length() == 1) {
516 int height = 0;
517 InstantSizeUnits units = INSTANT_SIZE_PIXELS;
518 if (args[0]->IsInt32()) {
519 height = args[0]->Int32Value();
520 } else if (args[0]->IsString()) {
521 std::string height_str = *v8::String::Utf8Value(args[0]);
522 std::string units_str;
523 SplitLeadingNumberToken(&height_str, &units_str);
524 if (!base::StringToInt(height_str, &height))
525 return v8::Undefined();
526 if (units_str == "%") {
527 units = INSTANT_SIZE_PERCENT;
528 } else if (!units_str.empty() && units_str != "px") {
529 return v8::Undefined();
530 }
531 } else {
532 return v8::Undefined();
533 }
534 content::RenderView* render_view = GetRenderView();
535 if (render_view && height >= 0)
536 SearchBox::Get(render_view)->SetInstantPreviewHeight(height, units);
537 }
538 return v8::Undefined();
539 }
540
277 // static 541 // static
278 void Dispatch(WebKit::WebFrame* frame, WebKit::WebString script) { 542 void Dispatch(WebKit::WebFrame* frame, WebKit::WebString script) {
279 DCHECK(frame) << "Dispatch requires frame"; 543 DCHECK(frame) << "Dispatch requires frame";
280 if (!frame) return; 544 if (!frame) return;
281 frame->executeScript(WebKit::WebScriptSource(script)); 545 frame->executeScript(WebKit::WebScriptSource(script));
282 } 546 }
283 547
284 // static 548 // static
285 void SearchBoxExtension::DispatchChange(WebKit::WebFrame* frame) { 549 void SearchBoxExtension::DispatchChange(WebKit::WebFrame* frame) {
286 Dispatch(frame, kDispatchChangeEventScript); 550 Dispatch(frame, kDispatchChangeEventScript);
287 } 551 }
288 552
289 // static 553 // static
290 void SearchBoxExtension::DispatchSubmit(WebKit::WebFrame* frame) { 554 void SearchBoxExtension::DispatchSubmit(WebKit::WebFrame* frame) {
291 Dispatch(frame, kDispatchSubmitEventScript); 555 Dispatch(frame, kDispatchSubmitEventScript);
292 } 556 }
293 557
294 // static 558 // static
295 void SearchBoxExtension::DispatchCancel(WebKit::WebFrame* frame) { 559 void SearchBoxExtension::DispatchCancel(WebKit::WebFrame* frame) {
296 Dispatch(frame, kDispatchCancelEventScript); 560 Dispatch(frame, kDispatchCancelEventScript);
297 } 561 }
298 562
299 // static 563 // static
300 void SearchBoxExtension::DispatchResize(WebKit::WebFrame* frame) { 564 void SearchBoxExtension::DispatchResize(WebKit::WebFrame* frame) {
301 Dispatch(frame, kDispatchResizeEventScript); 565 Dispatch(frame, kDispatchResizeEventScript);
302 } 566 }
303 567
304 // static 568 // static
569 void SearchBoxExtension::DispatchAutocompleteResults(WebKit::WebFrame* frame) {
570 Dispatch(frame, kDispatchAutocompleteResultsEventScript);
571 }
572
573 // static
574 void SearchBoxExtension::DispatchKeyPress(WebKit::WebFrame* frame) {
575 Dispatch(frame, kDispatchKeyPressEventScript);
576 }
577
578 // static
305 bool SearchBoxExtension::PageSupportsInstant(WebKit::WebFrame* frame) { 579 bool SearchBoxExtension::PageSupportsInstant(WebKit::WebFrame* frame) {
306 DCHECK(frame) << "PageSupportsInstant requires frame"; 580 DCHECK(frame) << "PageSupportsInstant requires frame";
307 if (!frame) return false; 581 if (!frame) return false;
308 582
309 v8::Handle<v8::Value> v = frame->executeScriptAndReturnValue( 583 v8::Handle<v8::Value> v = frame->executeScriptAndReturnValue(
310 WebKit::WebScriptSource(kSupportsInstantScript)); 584 WebKit::WebScriptSource(kSupportsInstantScript));
311 bool supports_instant = !v.IsEmpty() && v->BooleanValue(); 585 bool supports_instant = !v.IsEmpty() && v->BooleanValue();
312 586
313 // Send a resize message to tell the page that Chrome is actively using the 587 // 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 588 // searchbox API with it. The page uses the message to transition from
315 // "homepage" mode to "search" mode. 589 // "homepage" mode to "search" mode.
316 if (supports_instant) 590 if (supports_instant)
317 DispatchResize(frame); 591 DispatchResize(frame);
318 592
319 return supports_instant; 593 return supports_instant;
320 } 594 }
321 595
322 // static 596 // static
323 v8::Extension* SearchBoxExtension::Get() { 597 v8::Extension* SearchBoxExtension::Get() {
324 const base::StringPiece code = 598 const base::StringPiece code =
325 ResourceBundle::GetSharedInstance().GetRawDataResource( 599 ResourceBundle::GetSharedInstance().GetRawDataResource(
326 IDR_SEARCHBOX_API, ui::SCALE_FACTOR_NONE); 600 IDR_SEARCHBOX_API, ui::SCALE_FACTOR_NONE);
327 return new SearchBoxExtensionWrapper(code); 601 return new SearchBoxExtensionWrapper(code);
328 } 602 }
329 603
330 } // namespace extensions_v8 604 } // namespace extensions_v8
OLDNEW
« chrome/renderer/searchbox/searchbox.h ('K') | « chrome/renderer/searchbox/searchbox_extension.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698