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

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

Powered by Google App Engine
This is Rietveld 408576698