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

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