| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "base/i18n/rtl.h" | 7 #include "chrome/common/instant_types.h" |
| 8 #include "base/stringprintf.h" | |
| 9 #include "base/strings/string_number_conversions.h" | |
| 10 #include "base/utf_string_conversions.h" | |
| 11 #include "chrome/common/extensions/extension.h" | |
| 12 #include "chrome/renderer/searchbox/searchbox.h" | 8 #include "chrome/renderer/searchbox/searchbox.h" |
| 13 #include "content/public/renderer/render_view.h" | 9 #include "content/public/renderer/render_view.h" |
| 14 #include "grit/renderer_resources.h" | 10 #include "grit/renderer_resources.h" |
| 15 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h" | |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h" | 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h" |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
| 19 #include "ui/base/keycodes/keyboard_codes.h" | |
| 20 #include "ui/base/resource/resource_bundle.h" | 14 #include "ui/base/resource/resource_bundle.h" |
| 21 #include "ui/base/window_open_disposition.h" | |
| 22 #include "v8/include/v8.h" | 15 #include "v8/include/v8.h" |
| 23 | 16 |
| 24 namespace { | 17 namespace { |
| 25 | 18 |
| 26 const char kCSSBackgroundImageFormat[] = | 19 const char kSearchBoxExtensionName[] = "v8/SearchBox"; |
| 27 "-webkit-image-set(url(chrome://theme/IDR_THEME_BACKGROUND?%s) 1x)"; | |
| 28 | 20 |
| 29 const char kCSSBackgroundColorFormat[] = "rgba(%d,%d,%d,%s)"; | 21 const char kDetermineInstantSupportScript[] = |
| 22 "chrome &&" |
| 23 "chrome.searchBox &&" |
| 24 "chrome.searchBox.onsubmit &&" |
| 25 "typeof chrome.searchBox.onsubmit == 'function';"; |
| 30 | 26 |
| 31 const char kCSSBackgroundPositionCenter[] = "center"; | 27 const char kOnChangeScript[] = |
| 32 const char kCSSBackgroundPositionLeft[] = "left"; | 28 "if (chrome &&" |
| 33 const char kCSSBackgroundPositionTop[] = "top"; | 29 " chrome.searchBox &&" |
| 34 const char kCSSBackgroundPositionRight[] = "right"; | 30 " chrome.searchBox.onchange &&" |
| 35 const char kCSSBackgroundPositionBottom[] = "bottom"; | 31 " typeof chrome.searchBox.onchange == 'function')" |
| 32 " chrome.searchBox.onchange();"; |
| 36 | 33 |
| 37 const char kCSSBackgroundRepeatNo[] = "no-repeat"; | 34 const char kOnSubmitScript[] = |
| 38 const char kCSSBackgroundRepeatX[] = "repeat-x"; | 35 "if (chrome &&" |
| 39 const char kCSSBackgroundRepeatY[] = "repeat-y"; | 36 " chrome.searchBox &&" |
| 40 const char kCSSBackgroundRepeat[] = "repeat"; | 37 " chrome.searchBox.onsubmit &&" |
| 38 " typeof chrome.searchBox.onsubmit == 'function')" |
| 39 " chrome.searchBox.onsubmit();"; |
| 41 | 40 |
| 42 // Converts a V8 value to a string16. | 41 const char kOnBlurScript[] = |
| 42 "if (chrome &&" |
| 43 " chrome.searchBox &&" |
| 44 " chrome.searchBox.oncancel &&" |
| 45 " typeof chrome.searchBox.oncancel == 'function')" |
| 46 " chrome.searchBox.oncancel();"; |
| 47 |
| 48 const char kOnPopupBoundsScript[] = |
| 49 "if (chrome &&" |
| 50 " chrome.searchBox &&" |
| 51 " chrome.searchBox.onresize &&" |
| 52 " typeof chrome.searchBox.onresize == 'function')" |
| 53 " chrome.searchBox.onresize();"; |
| 54 |
| 43 string16 V8ValueToUTF16(v8::Handle<v8::Value> v) { | 55 string16 V8ValueToUTF16(v8::Handle<v8::Value> v) { |
| 44 v8::String::Value s(v); | 56 v8::String::Value s(v); |
| 45 return string16(reinterpret_cast<const char16*>(*s), s.length()); | 57 return string16(reinterpret_cast<const char16*>(*s), s.length()); |
| 46 } | 58 } |
| 47 | 59 |
| 48 // Converts string16 to V8 String. | |
| 49 v8::Handle<v8::String> UTF16ToV8String(const string16& s) { | 60 v8::Handle<v8::String> UTF16ToV8String(const string16& s) { |
| 50 return v8::String::New(reinterpret_cast<const uint16_t*>(s.data()), s.size()); | 61 return v8::String::New(reinterpret_cast<const uint16_t*>(s.data()), s.size()); |
| 51 } | 62 } |
| 52 | 63 |
| 53 // Converts std::string to V8 String. | 64 SearchBox* GetSearchBox() { |
| 54 v8::Handle<v8::String> UTF8ToV8String(const std::string& s) { | 65 WebKit::WebFrame* frame = WebKit::WebFrame::frameForCurrentContext(); |
| 55 return v8::String::New(s.data(), s.size()); | 66 // The WebView may be NULL during closing. |
| 67 if (!frame || !frame->view()) |
| 68 return NULL; |
| 69 |
| 70 content::RenderView* render_view = |
| 71 content::RenderView::FromWebView(frame->view()); |
| 72 if (!render_view) |
| 73 return NULL; |
| 74 |
| 75 return SearchBox::Get(render_view); |
| 56 } | 76 } |
| 57 | 77 |
| 58 void Dispatch(WebKit::WebFrame* frame, const WebKit::WebString& script) { | 78 WebKit::WebFrame* GetFrame(content::RenderView* render_view) { |
| 59 if (!frame) return; | 79 return render_view->GetWebView() ? render_view->GetWebView()->mainFrame() : |
| 60 frame->executeScript(WebKit::WebScriptSource(script)); | 80 NULL; |
| 81 } |
| 82 |
| 83 void Dispatch(content::RenderView* render_view, |
| 84 const WebKit::WebString& script) { |
| 85 WebKit::WebFrame* frame = GetFrame(render_view); |
| 86 if (frame) |
| 87 frame->executeScript(WebKit::WebScriptSource(script)); |
| 61 } | 88 } |
| 62 | 89 |
| 63 } // namespace | 90 } // namespace |
| 64 | 91 |
| 65 namespace extensions_v8 { | 92 namespace extensions_v8 { |
| 66 | 93 |
| 67 static const char kSearchBoxExtensionName[] = "v8/EmbeddedSearch"; | 94 // SearchBoxExtensionWrapper -------------------------------------------------- |
| 68 | |
| 69 static const char kDispatchChangeEventScript[] = | |
| 70 "if (window.chrome &&" | |
| 71 " window.chrome.embeddedSearch &&" | |
| 72 " window.chrome.embeddedSearch.searchBox &&" | |
| 73 " window.chrome.embeddedSearch.searchBox.onchange &&" | |
| 74 " typeof window.chrome.embeddedSearch.searchBox.onchange ==" | |
| 75 " 'function') {" | |
| 76 " window.chrome.embeddedSearch.searchBox.onchange();" | |
| 77 " true;" | |
| 78 "}"; | |
| 79 | |
| 80 static const char kDispatchSubmitEventScript[] = | |
| 81 "if (window.chrome &&" | |
| 82 " window.chrome.embeddedSearch &&" | |
| 83 " window.chrome.embeddedSearch.searchBox &&" | |
| 84 " window.chrome.embeddedSearch.searchBox.onsubmit &&" | |
| 85 " typeof window.chrome.embeddedSearch.searchBox.onsubmit ==" | |
| 86 " 'function') {" | |
| 87 " window.chrome.embeddedSearch.searchBox.onsubmit();" | |
| 88 " true;" | |
| 89 "}"; | |
| 90 | |
| 91 static const char kDispatchCancelEventScript[] = | |
| 92 "if (window.chrome &&" | |
| 93 " window.chrome.embeddedSearch &&" | |
| 94 " window.chrome.embeddedSearch.searchBox &&" | |
| 95 " window.chrome.embeddedSearch.searchBox.oncancel &&" | |
| 96 " typeof window.chrome.embeddedSearch.searchBox.oncancel ==" | |
| 97 " 'function') {" | |
| 98 " window.chrome.embeddedSearch.searchBox.oncancel();" | |
| 99 " true;" | |
| 100 "}"; | |
| 101 | |
| 102 static const char kDispatchResizeEventScript[] = | |
| 103 "if (window.chrome &&" | |
| 104 " window.chrome.embeddedSearch &&" | |
| 105 " window.chrome.embeddedSearch.searchBox &&" | |
| 106 " window.chrome.embeddedSearch.searchBox.onresize &&" | |
| 107 " typeof window.chrome.embeddedSearch.searchBox.onresize ==" | |
| 108 " 'function') {" | |
| 109 " window.chrome.embeddedSearch.searchBox.onresize();" | |
| 110 " true;" | |
| 111 "}"; | |
| 112 | |
| 113 // We first send this script down to determine if the page supports instant. | |
| 114 static const char kSupportsInstantScript[] = | |
| 115 "if (window.chrome &&" | |
| 116 " window.chrome.embeddedSearch &&" | |
| 117 " window.chrome.embeddedSearch.searchBox &&" | |
| 118 " window.chrome.embeddedSearch.searchBox.onsubmit &&" | |
| 119 " typeof window.chrome.embeddedSearch.searchBox.onsubmit ==" | |
| 120 " 'function') {" | |
| 121 " true;" | |
| 122 "} else {" | |
| 123 " false;" | |
| 124 "}"; | |
| 125 | |
| 126 // Extended API. | |
| 127 | |
| 128 // Per-context initialization. | |
| 129 static const char kDispatchOnWindowReady[] = | |
| 130 "if (window.chrome &&" | |
| 131 " window.chrome.embeddedSearchOnWindowReady &&" | |
| 132 " typeof window.chrome.embeddedSearchOnWindowReady == 'function') {" | |
| 133 " window.chrome.embeddedSearchOnWindowReady();" | |
| 134 "}"; | |
| 135 | |
| 136 static const char kDispatchAutocompleteResultsEventScript[] = | |
| 137 "if (window.chrome &&" | |
| 138 " window.chrome.embeddedSearch &&" | |
| 139 " window.chrome.embeddedSearch.searchBox &&" | |
| 140 " window.chrome.embeddedSearch.searchBox.onnativesuggestions &&" | |
| 141 " typeof window.chrome.embeddedSearch.searchBox.onnativesuggestions ==" | |
| 142 " 'function') {" | |
| 143 " window.chrome.embeddedSearch.searchBox.onnativesuggestions();" | |
| 144 " true;" | |
| 145 "}"; | |
| 146 | |
| 147 // Takes two printf-style replaceable values: count, key_code. | |
| 148 static const char kDispatchUpOrDownKeyPressEventScript[] = | |
| 149 "if (window.chrome &&" | |
| 150 " window.chrome.embeddedSearch &&" | |
| 151 " window.chrome.embeddedSearch.searchBox &&" | |
| 152 " window.chrome.embeddedSearch.searchBox.onkeypress &&" | |
| 153 " typeof window.chrome.embeddedSearch.searchBox.onkeypress ==" | |
| 154 " 'function') {" | |
| 155 " for (var i = 0; i < %d; ++i)" | |
| 156 " window.chrome.embeddedSearch.searchBox.onkeypress({keyCode: %d});" | |
| 157 " true;" | |
| 158 "}"; | |
| 159 | |
| 160 // Takes one printf-style replaceable value: key_code. | |
| 161 static const char kDispatchEscKeyPressEventScript[] = | |
| 162 "if (window.chrome &&" | |
| 163 " window.chrome.embeddedSearch &&" | |
| 164 " window.chrome.embeddedSearch.searchBox &&" | |
| 165 " window.chrome.embeddedSearch.searchBox.onkeypress &&" | |
| 166 " typeof window.chrome.embeddedSearch.searchBox.onkeypress ==" | |
| 167 " 'function') {" | |
| 168 " window.chrome.embeddedSearch.searchBox.onkeypress({keyCode: %d});" | |
| 169 " true;" | |
| 170 "}"; | |
| 171 | |
| 172 static const char kDispatchKeyCaptureChangeScript[] = | |
| 173 "if (window.chrome &&" | |
| 174 " window.chrome.embeddedSearch &&" | |
| 175 " window.chrome.embeddedSearch.searchBox &&" | |
| 176 " window.chrome.embeddedSearch.searchBox.onkeycapturechange &&" | |
| 177 " typeof window.chrome.embeddedSearch.searchBox.onkeycapturechange ==" | |
| 178 " 'function') {" | |
| 179 " window.chrome.embeddedSearch.searchBox.onkeycapturechange();" | |
| 180 " true;" | |
| 181 "}"; | |
| 182 | |
| 183 static const char kDispatchThemeChangeEventScript[] = | |
| 184 "if (window.chrome &&" | |
| 185 " window.chrome.embeddedSearch &&" | |
| 186 " window.chrome.embeddedSearch.newTabPage &&" | |
| 187 " window.chrome.embeddedSearch.newTabPage.onthemechange &&" | |
| 188 " typeof window.chrome.embeddedSearch.newTabPage.onthemechange ==" | |
| 189 " 'function') {" | |
| 190 " window.chrome.embeddedSearch.newTabPage.onthemechange();" | |
| 191 " true;" | |
| 192 "}"; | |
| 193 | |
| 194 static const char kDispatchMarginChangeEventScript[] = | |
| 195 "if (window.chrome &&" | |
| 196 " window.chrome.embeddedSearch &&" | |
| 197 " window.chrome.embeddedSearch.searchBox &&" | |
| 198 " window.chrome.embeddedSearch.searchBox.onmarginchange &&" | |
| 199 " typeof window.chrome.embeddedSearch.searchBox.onmarginchange ==" | |
| 200 " 'function') {" | |
| 201 " window.chrome.embeddedSearch.searchBox.onmarginchange();" | |
| 202 " true;" | |
| 203 "}"; | |
| 204 | |
| 205 static const char kDispatchMostVisitedChangedScript[] = | |
| 206 "if (window.chrome &&" | |
| 207 " window.chrome.embeddedSearch &&" | |
| 208 " window.chrome.embeddedSearch.newTabPage &&" | |
| 209 " window.chrome.embeddedSearch.newTabPage.onmostvisitedchange &&" | |
| 210 " typeof window.chrome.embeddedSearch.newTabPage.onmostvisitedchange ==" | |
| 211 " 'function') {" | |
| 212 " window.chrome.embeddedSearch.newTabPage.onmostvisitedchange();" | |
| 213 " true;" | |
| 214 "}"; | |
| 215 | |
| 216 // ---------------------------------------------------------------------------- | |
| 217 | 95 |
| 218 class SearchBoxExtensionWrapper : public v8::Extension { | 96 class SearchBoxExtensionWrapper : public v8::Extension { |
| 219 public: | 97 public: |
| 220 explicit SearchBoxExtensionWrapper(const base::StringPiece& code); | 98 explicit SearchBoxExtensionWrapper(const base::StringPiece& code); |
| 221 | 99 |
| 222 // Allows v8's javascript code to call the native functions defined | 100 // Allows v8's JavaScript code to call the native functions defined in this |
| 223 // in this class for window.chrome. | 101 // class for window.chrome.searchBox. |
| 224 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( | 102 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( |
| 225 v8::Handle<v8::String> name) OVERRIDE; | 103 v8::Handle<v8::String> name) OVERRIDE; |
| 226 | 104 |
| 227 // Helper function to find the RenderView. May return NULL. | 105 // Gets the user's search query. |
| 228 static content::RenderView* GetRenderView(); | |
| 229 | |
| 230 // Deletes a Most Visited item. | |
| 231 static v8::Handle<v8::Value> DeleteMostVisitedItem(const v8::Arguments& args); | |
| 232 | |
| 233 // Gets the value of the user's search query. | |
| 234 static v8::Handle<v8::Value> GetQuery(const v8::Arguments& args); | 106 static v8::Handle<v8::Value> GetQuery(const v8::Arguments& args); |
| 235 | 107 |
| 236 // Gets whether the |value| should be considered final -- as opposed to a | 108 // Gets whether the search query should be considered final -- as opposed to |
| 237 // partial match. This may be set if the user clicks a suggestion, presses | 109 // a partial match. This may be set if the user clicks a suggestion, presses |
| 238 // forward delete, or in other cases where Chrome overrides. | 110 // forward delete, or in other cases where Chrome overrides. |
| 239 static v8::Handle<v8::Value> GetVerbatim(const v8::Arguments& args); | 111 static v8::Handle<v8::Value> GetVerbatim(const v8::Arguments& args); |
| 240 | 112 |
| 241 // Gets the start of the selection in the search box. | 113 // Gets the start of the selection in the searchbox. |
| 242 static v8::Handle<v8::Value> GetSelectionStart(const v8::Arguments& args); | 114 static v8::Handle<v8::Value> GetSelectionStart(const v8::Arguments& args); |
| 243 | 115 |
| 244 // Gets the end of the selection in the search box. | 116 // Gets the end of the selection in the searchbox. |
| 245 static v8::Handle<v8::Value> GetSelectionEnd(const v8::Arguments& args); | 117 static v8::Handle<v8::Value> GetSelectionEnd(const v8::Arguments& args); |
| 246 | 118 |
| 247 // Gets the x coordinate (relative to |window|) of the left edge of the | 119 // Gets the x coordinate (relative to the window) of the left edge of the |
| 248 // region of the search box that overlaps the window. | 120 // region of the searchbox popup that overlaps the window. |
| 249 static v8::Handle<v8::Value> GetX(const v8::Arguments& args); | 121 static v8::Handle<v8::Value> GetX(const v8::Arguments& args); |
| 250 | 122 |
| 251 // Gets the y coordinate (relative to |window|) of the right edge of the | 123 // Gets the y coordinate (relative to the window) of the right edge of the |
| 252 // region of the search box that overlaps the window. | 124 // region of the searchbox popup that overlaps the window. |
| 253 static v8::Handle<v8::Value> GetY(const v8::Arguments& args); | 125 static v8::Handle<v8::Value> GetY(const v8::Arguments& args); |
| 254 | 126 |
| 255 // Gets the width of the region of the search box that overlaps the window, | 127 // Gets the width of the searchbox popup region that overlaps the window. |
| 256 // i.e., the width of the omnibox. | |
| 257 static v8::Handle<v8::Value> GetWidth(const v8::Arguments& args); | 128 static v8::Handle<v8::Value> GetWidth(const v8::Arguments& args); |
| 258 | 129 |
| 259 // Gets the height of the region of the search box that overlaps the window. | 130 // Gets the height of the searchbox popup region that overlaps the window. |
| 260 static v8::Handle<v8::Value> GetHeight(const v8::Arguments& args); | 131 static v8::Handle<v8::Value> GetHeight(const v8::Arguments& args); |
| 261 | 132 |
| 262 // Gets Most Visited Items. | 133 // Suggests an autocompletion for the current query. |
| 263 static v8::Handle<v8::Value> GetMostVisitedItems(const v8::Arguments& args); | 134 static v8::Handle<v8::Value> SetSuggestion(const v8::Arguments& args); |
| 264 | |
| 265 // Gets the start-edge margin to use with extended Instant. | |
| 266 static v8::Handle<v8::Value> GetStartMargin(const v8::Arguments& args); | |
| 267 | |
| 268 // Returns true if the Searchbox itself is oriented right-to-left. | |
| 269 static v8::Handle<v8::Value> GetRightToLeft(const v8::Arguments& args); | |
| 270 | |
| 271 // Gets the autocomplete results from search box. | |
| 272 static v8::Handle<v8::Value> GetAutocompleteResults( | |
| 273 const v8::Arguments& args); | |
| 274 | |
| 275 // Gets whether to display Instant results. | |
| 276 static v8::Handle<v8::Value> GetDisplayInstantResults( | |
| 277 const v8::Arguments& args); | |
| 278 | |
| 279 // Gets the background info of the theme currently adopted by browser. | |
| 280 // Call only when overlay is showing NTP page. | |
| 281 static v8::Handle<v8::Value> GetThemeBackgroundInfo( | |
| 282 const v8::Arguments& args); | |
| 283 | |
| 284 // Gets whether the browser is capturing key strokes. | |
| 285 static v8::Handle<v8::Value> IsKeyCaptureEnabled(const v8::Arguments& args); | |
| 286 | |
| 287 // Gets the font family of the text in the omnibox. | |
| 288 static v8::Handle<v8::Value> GetFont(const v8::Arguments& args); | |
| 289 | |
| 290 // Gets the font size of the text in the omnibox. | |
| 291 static v8::Handle<v8::Value> GetFontSize(const v8::Arguments& args); | |
| 292 | |
| 293 // Navigates the window to a URL represented by either a URL string or a | |
| 294 // restricted ID. | |
| 295 static v8::Handle<v8::Value> NavigateContentWindow(const v8::Arguments& args); | |
| 296 | |
| 297 // Sets ordered suggestions. Valid for current |value|. | |
| 298 static v8::Handle<v8::Value> SetSuggestions(const v8::Arguments& args); | |
| 299 | |
| 300 // Sets the text to be autocompleted into the search box. | |
| 301 static v8::Handle<v8::Value> SetQuerySuggestion(const v8::Arguments& args); | |
| 302 | |
| 303 // Like |SetQuerySuggestion| but uses a restricted ID to identify the text. | |
| 304 static v8::Handle<v8::Value> SetQuerySuggestionFromAutocompleteResult( | |
| 305 const v8::Arguments& args); | |
| 306 | |
| 307 // Sets the search box text, completely replacing what the user typed. | |
| 308 static v8::Handle<v8::Value> SetQuery(const v8::Arguments& args); | |
| 309 | |
| 310 // Like |SetQuery| but uses a restricted ID to identify the text. | |
| 311 static v8::Handle<v8::Value> SetQueryFromAutocompleteResult( | |
| 312 const v8::Arguments& args); | |
| 313 | |
| 314 // Requests the overlay be shown with the specified contents and height. | |
| 315 static v8::Handle<v8::Value> ShowOverlay(const v8::Arguments& args); | |
| 316 | |
| 317 // Start capturing user key strokes. | |
| 318 static v8::Handle<v8::Value> StartCapturingKeyStrokes( | |
| 319 const v8::Arguments& args); | |
| 320 | |
| 321 // Stop capturing user key strokes. | |
| 322 static v8::Handle<v8::Value> StopCapturingKeyStrokes( | |
| 323 const v8::Arguments& args); | |
| 324 | |
| 325 // Undoes the deletion of all Most Visited itens. | |
| 326 static v8::Handle<v8::Value> UndoAllMostVisitedDeletions( | |
| 327 const v8::Arguments& args); | |
| 328 | |
| 329 // Undoes the deletion of a Most Visited item. | |
| 330 static v8::Handle<v8::Value> UndoMostVisitedDeletion( | |
| 331 const v8::Arguments& args); | |
| 332 | 135 |
| 333 private: | 136 private: |
| 334 DISALLOW_COPY_AND_ASSIGN(SearchBoxExtensionWrapper); | 137 DISALLOW_COPY_AND_ASSIGN(SearchBoxExtensionWrapper); |
| 335 }; | 138 }; |
| 336 | 139 |
| 337 SearchBoxExtensionWrapper::SearchBoxExtensionWrapper( | 140 SearchBoxExtensionWrapper::SearchBoxExtensionWrapper( |
| 338 const base::StringPiece& code) | 141 const base::StringPiece& code) |
| 339 : v8::Extension(kSearchBoxExtensionName, code.data(), 0, 0, code.size()) { | 142 : v8::Extension(kSearchBoxExtensionName, code.data(), 0, 0, code.size()) { |
| 340 } | 143 } |
| 341 | 144 |
| 342 v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction( | 145 v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction( |
| 343 v8::Handle<v8::String> name) { | 146 v8::Handle<v8::String> name) { |
| 344 if (name->Equals(v8::String::New("DeleteMostVisitedItem"))) | 147 const struct { |
| 345 return v8::FunctionTemplate::New(DeleteMostVisitedItem); | 148 const char* const name; |
| 346 if (name->Equals(v8::String::New("GetQuery"))) | 149 v8::Handle<v8::Value> (*function)(const v8::Arguments& args); |
| 347 return v8::FunctionTemplate::New(GetQuery); | 150 } kFunctions[] = { |
| 348 if (name->Equals(v8::String::New("GetVerbatim"))) | 151 {"GetQuery", GetQuery}, |
| 349 return v8::FunctionTemplate::New(GetVerbatim); | 152 {"GetVerbatim", GetVerbatim}, |
| 350 if (name->Equals(v8::String::New("GetSelectionStart"))) | 153 {"GetSelectionStart", GetSelectionStart}, |
| 351 return v8::FunctionTemplate::New(GetSelectionStart); | 154 {"GetSelectionEnd", GetSelectionEnd}, |
| 352 if (name->Equals(v8::String::New("GetSelectionEnd"))) | 155 {"GetX", GetX}, |
| 353 return v8::FunctionTemplate::New(GetSelectionEnd); | 156 {"GetY", GetY}, |
| 354 if (name->Equals(v8::String::New("GetX"))) | 157 {"GetWidth", GetWidth}, |
| 355 return v8::FunctionTemplate::New(GetX); | 158 {"GetHeight", GetHeight}, |
| 356 if (name->Equals(v8::String::New("GetY"))) | 159 {"SetSuggestion", SetSuggestion}, |
| 357 return v8::FunctionTemplate::New(GetY); | 160 }; |
| 358 if (name->Equals(v8::String::New("GetWidth"))) | 161 |
| 359 return v8::FunctionTemplate::New(GetWidth); | 162 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kFunctions); ++i) { |
| 360 if (name->Equals(v8::String::New("GetHeight"))) | 163 if (name->Equals(v8::String::New(kFunctions[i].name))) |
| 361 return v8::FunctionTemplate::New(GetHeight); | 164 return v8::FunctionTemplate::New(kFunctions[i].function); |
| 362 if (name->Equals(v8::String::New("GetMostVisitedItems"))) | 165 } |
| 363 return v8::FunctionTemplate::New(GetMostVisitedItems); | |
| 364 if (name->Equals(v8::String::New("GetStartMargin"))) | |
| 365 return v8::FunctionTemplate::New(GetStartMargin); | |
| 366 if (name->Equals(v8::String::New("GetRightToLeft"))) | |
| 367 return v8::FunctionTemplate::New(GetRightToLeft); | |
| 368 if (name->Equals(v8::String::New("GetAutocompleteResults"))) | |
| 369 return v8::FunctionTemplate::New(GetAutocompleteResults); | |
| 370 if (name->Equals(v8::String::New("GetDisplayInstantResults"))) | |
| 371 return v8::FunctionTemplate::New(GetDisplayInstantResults); | |
| 372 if (name->Equals(v8::String::New("GetThemeBackgroundInfo"))) | |
| 373 return v8::FunctionTemplate::New(GetThemeBackgroundInfo); | |
| 374 if (name->Equals(v8::String::New("IsKeyCaptureEnabled"))) | |
| 375 return v8::FunctionTemplate::New(IsKeyCaptureEnabled); | |
| 376 if (name->Equals(v8::String::New("GetFont"))) | |
| 377 return v8::FunctionTemplate::New(GetFont); | |
| 378 if (name->Equals(v8::String::New("GetFontSize"))) | |
| 379 return v8::FunctionTemplate::New(GetFontSize); | |
| 380 if (name->Equals(v8::String::New("NavigateContentWindow"))) | |
| 381 return v8::FunctionTemplate::New(NavigateContentWindow); | |
| 382 if (name->Equals(v8::String::New("SetSuggestions"))) | |
| 383 return v8::FunctionTemplate::New(SetSuggestions); | |
| 384 if (name->Equals(v8::String::New("SetQuerySuggestion"))) | |
| 385 return v8::FunctionTemplate::New(SetQuerySuggestion); | |
| 386 if (name->Equals(v8::String::New("SetQuerySuggestionFromAutocompleteResult"))) | |
| 387 return v8::FunctionTemplate::New(SetQuerySuggestionFromAutocompleteResult); | |
| 388 if (name->Equals(v8::String::New("SetQuery"))) | |
| 389 return v8::FunctionTemplate::New(SetQuery); | |
| 390 if (name->Equals(v8::String::New("SetQueryFromAutocompleteResult"))) | |
| 391 return v8::FunctionTemplate::New(SetQueryFromAutocompleteResult); | |
| 392 if (name->Equals(v8::String::New("ShowOverlay"))) | |
| 393 return v8::FunctionTemplate::New(ShowOverlay); | |
| 394 if (name->Equals(v8::String::New("StartCapturingKeyStrokes"))) | |
| 395 return v8::FunctionTemplate::New(StartCapturingKeyStrokes); | |
| 396 if (name->Equals(v8::String::New("StopCapturingKeyStrokes"))) | |
| 397 return v8::FunctionTemplate::New(StopCapturingKeyStrokes); | |
| 398 if (name->Equals(v8::String::New("UndoAllMostVisitedDeletions"))) | |
| 399 return v8::FunctionTemplate::New(UndoAllMostVisitedDeletions); | |
| 400 if (name->Equals(v8::String::New("UndoMostVisitedDeletion"))) | |
| 401 return v8::FunctionTemplate::New(UndoMostVisitedDeletion); | |
| 402 return v8::Handle<v8::FunctionTemplate>(); | 166 return v8::Handle<v8::FunctionTemplate>(); |
| 403 } | 167 } |
| 404 | 168 |
| 405 // static | 169 // static |
| 406 content::RenderView* SearchBoxExtensionWrapper::GetRenderView() { | |
| 407 WebKit::WebFrame* webframe = WebKit::WebFrame::frameForCurrentContext(); | |
| 408 if (!webframe) return NULL; | |
| 409 | |
| 410 WebKit::WebView* webview = webframe->view(); | |
| 411 if (!webview) return NULL; // can happen during closing | |
| 412 | |
| 413 return content::RenderView::FromWebView(webview); | |
| 414 } | |
| 415 | |
| 416 // static | |
| 417 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetQuery( | 170 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetQuery( |
| 418 const v8::Arguments& args) { | 171 const v8::Arguments& args) { |
| 419 content::RenderView* render_view = GetRenderView(); | 172 SearchBox* searchbox = GetSearchBox(); |
| 420 if (!render_view) return v8::Undefined(); | 173 if (!searchbox) return v8::Undefined(); |
| 421 | 174 |
| 422 DVLOG(1) << render_view << " GetQuery: '" | 175 return UTF16ToV8String(searchbox->query()); |
| 423 << SearchBox::Get(render_view)->query() << "'"; | |
| 424 return UTF16ToV8String(SearchBox::Get(render_view)->query()); | |
| 425 } | 176 } |
| 426 | 177 |
| 427 // static | 178 // static |
| 428 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetVerbatim( | 179 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetVerbatim( |
| 429 const v8::Arguments& args) { | 180 const v8::Arguments& args) { |
| 430 content::RenderView* render_view = GetRenderView(); | 181 SearchBox* searchbox = GetSearchBox(); |
| 431 if (!render_view) return v8::Undefined(); | 182 if (!searchbox) return v8::Undefined(); |
| 432 | 183 |
| 433 DVLOG(1) << render_view << " GetVerbatim: " | 184 return v8::Boolean::New(searchbox->verbatim()); |
| 434 << SearchBox::Get(render_view)->verbatim(); | |
| 435 return v8::Boolean::New(SearchBox::Get(render_view)->verbatim()); | |
| 436 } | 185 } |
| 437 | 186 |
| 438 // static | 187 // static |
| 439 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSelectionStart( | 188 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSelectionStart( |
| 440 const v8::Arguments& args) { | 189 const v8::Arguments& args) { |
| 441 content::RenderView* render_view = GetRenderView(); | 190 SearchBox* searchbox = GetSearchBox(); |
| 442 if (!render_view) return v8::Undefined(); | 191 if (!searchbox) return v8::Undefined(); |
| 443 | 192 |
| 444 return v8::Uint32::New(SearchBox::Get(render_view)->selection_start()); | 193 return v8::Uint32::New(searchbox->selection_start()); |
| 445 } | 194 } |
| 446 | 195 |
| 447 // static | 196 // static |
| 448 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSelectionEnd( | 197 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSelectionEnd( |
| 449 const v8::Arguments& args) { | 198 const v8::Arguments& args) { |
| 450 content::RenderView* render_view = GetRenderView(); | 199 SearchBox* searchbox = GetSearchBox(); |
| 451 if (!render_view) return v8::Undefined(); | 200 if (!searchbox) return v8::Undefined(); |
| 452 | 201 |
| 453 return v8::Uint32::New(SearchBox::Get(render_view)->selection_end()); | 202 return v8::Uint32::New(searchbox->selection_end()); |
| 454 } | 203 } |
| 455 | 204 |
| 456 // static | 205 // static |
| 457 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetX( | 206 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetX( |
| 458 const v8::Arguments& args) { | 207 const v8::Arguments& args) { |
| 459 content::RenderView* render_view = GetRenderView(); | 208 SearchBox* searchbox = GetSearchBox(); |
| 460 if (!render_view) return v8::Undefined(); | 209 if (!searchbox) return v8::Undefined(); |
| 461 | 210 |
| 462 return v8::Int32::New(SearchBox::Get(render_view)->GetPopupBounds().x()); | 211 return v8::Int32::New(searchbox->GetPopupBounds().x()); |
| 463 } | 212 } |
| 464 | 213 |
| 465 // static | 214 // static |
| 466 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetY( | 215 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetY( |
| 467 const v8::Arguments& args) { | 216 const v8::Arguments& args) { |
| 468 content::RenderView* render_view = GetRenderView(); | 217 SearchBox* searchbox = GetSearchBox(); |
| 469 if (!render_view) return v8::Undefined(); | 218 if (!searchbox) return v8::Undefined(); |
| 470 | 219 |
| 471 return v8::Int32::New(SearchBox::Get(render_view)->GetPopupBounds().y()); | 220 return v8::Int32::New(searchbox->GetPopupBounds().y()); |
| 472 } | 221 } |
| 473 | 222 |
| 474 // static | 223 // static |
| 475 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetWidth( | 224 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetWidth( |
| 476 const v8::Arguments& args) { | 225 const v8::Arguments& args) { |
| 477 content::RenderView* render_view = GetRenderView(); | 226 SearchBox* searchbox = GetSearchBox(); |
| 478 if (!render_view) return v8::Undefined(); | 227 if (!searchbox) return v8::Undefined(); |
| 479 return v8::Int32::New(SearchBox::Get(render_view)->GetPopupBounds().width()); | 228 |
| 229 return v8::Int32::New(searchbox->GetPopupBounds().width()); |
| 480 } | 230 } |
| 481 | 231 |
| 482 // static | 232 // static |
| 483 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight( | 233 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight( |
| 484 const v8::Arguments& args) { | 234 const v8::Arguments& args) { |
| 485 content::RenderView* render_view = GetRenderView(); | 235 SearchBox* searchbox = GetSearchBox(); |
| 486 if (!render_view) return v8::Undefined(); | 236 if (!searchbox) return v8::Undefined(); |
| 487 | 237 |
| 488 return v8::Int32::New(SearchBox::Get(render_view)->GetPopupBounds().height()); | 238 return v8::Int32::New(searchbox->GetPopupBounds().height()); |
| 489 } | 239 } |
| 490 | 240 |
| 491 // static | 241 // static |
| 492 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetStartMargin( | 242 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestion( |
| 493 const v8::Arguments& args) { | 243 const v8::Arguments& args) { |
| 494 content::RenderView* render_view = GetRenderView(); | 244 SearchBox* searchbox = GetSearchBox(); |
| 495 if (!render_view) return v8::Undefined(); | 245 if (!searchbox || !args.Length()) return v8::Undefined(); |
| 496 return v8::Int32::New(SearchBox::Get(render_view)->GetStartMargin()); | |
| 497 } | |
| 498 | 246 |
| 499 // static | 247 InstantSuggestion suggestion; |
| 500 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetRightToLeft( | |
| 501 const v8::Arguments& args) { | |
| 502 return v8::Boolean::New(base::i18n::IsRTL()); | |
| 503 } | |
| 504 | 248 |
| 505 // static | |
| 506 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( | |
| 507 const v8::Arguments& args) { | |
| 508 content::RenderView* render_view = GetRenderView(); | |
| 509 if (!render_view) return v8::Undefined(); | |
| 510 | |
| 511 DVLOG(1) << render_view << " GetAutocompleteResults"; | |
| 512 const std::vector<InstantAutocompleteResult>& results = | |
| 513 SearchBox::Get(render_view)->GetAutocompleteResults(); | |
| 514 size_t results_base = SearchBox::Get(render_view)->results_base(); | |
| 515 | |
| 516 v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); | |
| 517 for (size_t i = 0; i < results.size(); ++i) { | |
| 518 v8::Handle<v8::Object> result = v8::Object::New(); | |
| 519 result->Set(v8::String::New("provider"), | |
| 520 UTF16ToV8String(results[i].provider)); | |
| 521 result->Set(v8::String::New("type"), UTF16ToV8String(results[i].type)); | |
| 522 result->Set(v8::String::New("contents"), | |
| 523 UTF16ToV8String(results[i].description)); | |
| 524 result->Set(v8::String::New("destination_url"), | |
| 525 UTF16ToV8String(results[i].destination_url)); | |
| 526 result->Set(v8::String::New("rid"), v8::Uint32::New(results_base + i)); | |
| 527 | |
| 528 v8::Handle<v8::Object> ranking_data = v8::Object::New(); | |
| 529 ranking_data->Set(v8::String::New("relevance"), | |
| 530 v8::Int32::New(results[i].relevance)); | |
| 531 result->Set(v8::String::New("rankingData"), ranking_data); | |
| 532 | |
| 533 results_array->Set(i, result); | |
| 534 } | |
| 535 return results_array; | |
| 536 } | |
| 537 | |
| 538 // static | |
| 539 v8::Handle<v8::Value> SearchBoxExtensionWrapper::IsKeyCaptureEnabled( | |
| 540 const v8::Arguments& args) { | |
| 541 content::RenderView* render_view = GetRenderView(); | |
| 542 if (!render_view) return v8::Undefined(); | |
| 543 | |
| 544 return v8::Boolean::New(SearchBox::Get(render_view)-> | |
| 545 is_key_capture_enabled()); | |
| 546 } | |
| 547 | |
| 548 // static | |
| 549 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetDisplayInstantResults( | |
| 550 const v8::Arguments& args) { | |
| 551 content::RenderView* render_view = GetRenderView(); | |
| 552 if (!render_view) return v8::Undefined(); | |
| 553 | |
| 554 bool display_instant_results = | |
| 555 SearchBox::Get(render_view)->display_instant_results(); | |
| 556 DVLOG(1) << render_view << " " | |
| 557 << "GetDisplayInstantResults: " << display_instant_results; | |
| 558 return v8::Boolean::New(display_instant_results); | |
| 559 } | |
| 560 | |
| 561 // static | |
| 562 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetThemeBackgroundInfo( | |
| 563 const v8::Arguments& args) { | |
| 564 content::RenderView* render_view = GetRenderView(); | |
| 565 if (!render_view) return v8::Undefined(); | |
| 566 | |
| 567 DVLOG(1) << render_view << " GetThemeBackgroundInfo"; | |
| 568 const ThemeBackgroundInfo& theme_info = | |
| 569 SearchBox::Get(render_view)->GetThemeBackgroundInfo(); | |
| 570 v8::Handle<v8::Object> info = v8::Object::New(); | |
| 571 | |
| 572 // The theme background color is in RGBA format "rgba(R,G,B,A)" where R, G and | |
| 573 // B are between 0 and 255 inclusive, and A is a double between 0 and 1 | |
| 574 // inclusive. | |
| 575 // This is the CSS "background-color" format. | |
| 576 // Value is always valid. | |
| 577 info->Set(v8::String::New("colorRgba"), UTF8ToV8String( | |
| 578 // Convert the alpha using DoubleToString because StringPrintf will use | |
| 579 // locale specific formatters (e.g., use , instead of . in German). | |
| 580 base::StringPrintf( | |
| 581 kCSSBackgroundColorFormat, | |
| 582 theme_info.color_r, | |
| 583 theme_info.color_g, | |
| 584 theme_info.color_b, | |
| 585 base::DoubleToString(theme_info.color_a / 255.0).c_str()))); | |
| 586 | |
| 587 // The theme background image url is of format | |
| 588 // "-webkit-image-set(url(chrome://theme/IDR_THEME_BACKGROUND?<theme_id>) 1x)" | |
| 589 // where <theme_id> is the id that identifies the theme. | |
| 590 // This is the CSS "background-image" format. | |
| 591 // Value is only valid if there's a custom theme background image. | |
| 592 if (extensions::Extension::IdIsValid(theme_info.theme_id)) { | |
| 593 info->Set(v8::String::New("imageUrl"), UTF8ToV8String( | |
| 594 base::StringPrintf(kCSSBackgroundImageFormat, | |
| 595 theme_info.theme_id.c_str()))); | |
| 596 | |
| 597 // The theme background image horizontal alignment is one of "left", | |
| 598 // "right", "center". | |
| 599 // This is the horizontal component of the CSS "background-position" format. | |
| 600 // Value is only valid if |imageUrl| is not empty. | |
| 601 std::string alignment = kCSSBackgroundPositionCenter; | |
| 602 if (theme_info.image_horizontal_alignment == | |
| 603 THEME_BKGRND_IMAGE_ALIGN_LEFT) { | |
| 604 alignment = kCSSBackgroundPositionLeft; | |
| 605 } else if (theme_info.image_horizontal_alignment == | |
| 606 THEME_BKGRND_IMAGE_ALIGN_RIGHT) { | |
| 607 alignment = kCSSBackgroundPositionRight; | |
| 608 } | |
| 609 info->Set(v8::String::New("imageHorizontalAlignment"), | |
| 610 UTF8ToV8String(alignment)); | |
| 611 | |
| 612 // The theme background image vertical alignment is one of "bottom", | |
| 613 // "center" or, for top-aligned image, "top" or "$x px" where $x is an | |
| 614 // integer to offset top of image by. | |
| 615 // This is the vertical component of the CSS "background-position" format. | |
| 616 // Value is only valid if |image_url| is not empty. | |
| 617 if (theme_info.image_vertical_alignment == THEME_BKGRND_IMAGE_ALIGN_TOP) { | |
| 618 if (theme_info.image_top_offset != 0) | |
| 619 alignment = base::IntToString(theme_info.image_top_offset) + "px"; | |
| 620 else | |
| 621 alignment = kCSSBackgroundPositionTop; | |
| 622 } else if (theme_info.image_vertical_alignment == | |
| 623 THEME_BKGRND_IMAGE_ALIGN_BOTTOM) { | |
| 624 alignment = kCSSBackgroundPositionBottom; | |
| 625 } else { | |
| 626 alignment = kCSSBackgroundPositionCenter; | |
| 627 } | |
| 628 info->Set(v8::String::New("imageVerticalAlignment"), | |
| 629 UTF8ToV8String(alignment)); | |
| 630 | |
| 631 // The tiling of the theme background image is one of "no-repeat", | |
| 632 // "repeat-x", "repeat-y", "repeat". | |
| 633 // This is the CSS "background-repeat" format. | |
| 634 // Value is only valid if |image_url| is not empty. | |
| 635 std::string tiling = kCSSBackgroundRepeatNo; | |
| 636 switch (theme_info.image_tiling) { | |
| 637 case THEME_BKGRND_IMAGE_NO_REPEAT: | |
| 638 tiling = kCSSBackgroundRepeatNo; | |
| 639 break; | |
| 640 case THEME_BKGRND_IMAGE_REPEAT_X: | |
| 641 tiling = kCSSBackgroundRepeatX; | |
| 642 break; | |
| 643 case THEME_BKGRND_IMAGE_REPEAT_Y: | |
| 644 tiling = kCSSBackgroundRepeatY; | |
| 645 break; | |
| 646 case THEME_BKGRND_IMAGE_REPEAT: | |
| 647 tiling = kCSSBackgroundRepeat; | |
| 648 break; | |
| 649 } | |
| 650 info->Set(v8::String::New("imageTiling"), UTF8ToV8String(tiling)); | |
| 651 | |
| 652 // The theme background image height is only valid if |imageUrl| is valid. | |
| 653 info->Set(v8::String::New("imageHeight"), | |
| 654 v8::Int32::New(theme_info.image_height)); | |
| 655 } | |
| 656 | |
| 657 return info; | |
| 658 } | |
| 659 | |
| 660 // static | |
| 661 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetFont( | |
| 662 const v8::Arguments& args) { | |
| 663 content::RenderView* render_view = GetRenderView(); | |
| 664 if (!render_view) return v8::Undefined(); | |
| 665 | |
| 666 return UTF16ToV8String(SearchBox::Get(render_view)->omnibox_font()); | |
| 667 } | |
| 668 | |
| 669 // static | |
| 670 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetFontSize( | |
| 671 const v8::Arguments& args) { | |
| 672 content::RenderView* render_view = GetRenderView(); | |
| 673 if (!render_view) return v8::Undefined(); | |
| 674 | |
| 675 return v8::Uint32::New(SearchBox::Get(render_view)->omnibox_font_size()); | |
| 676 } | |
| 677 | |
| 678 // static | |
| 679 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateContentWindow( | |
| 680 const v8::Arguments& args) { | |
| 681 content::RenderView* render_view = GetRenderView(); | |
| 682 if (!render_view || !args.Length()) return v8::Undefined(); | |
| 683 | |
| 684 GURL destination_url; | |
| 685 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; | |
| 686 if (args[0]->IsNumber()) { | |
| 687 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | |
| 688 GetAutocompleteResultWithId(args[0]->Uint32Value()); | |
| 689 if (result) { | |
| 690 destination_url = GURL(result->destination_url); | |
| 691 transition = result->transition; | |
| 692 } | |
| 693 } else { | |
| 694 destination_url = GURL(V8ValueToUTF16(args[0])); | |
| 695 } | |
| 696 | |
| 697 // Navigate the main frame. | |
| 698 if (destination_url.is_valid()) { | |
| 699 WindowOpenDisposition disposition = CURRENT_TAB; | |
| 700 if (args[1]->Uint32Value() == 2) | |
| 701 disposition = NEW_BACKGROUND_TAB; | |
| 702 SearchBox::Get(render_view)->NavigateToURL( | |
| 703 destination_url, transition, disposition); | |
| 704 } | |
| 705 return v8::Undefined(); | |
| 706 } | |
| 707 | |
| 708 // static | |
| 709 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions( | |
| 710 const v8::Arguments& args) { | |
| 711 content::RenderView* render_view = GetRenderView(); | |
| 712 if (!render_view || !args.Length()) return v8::Undefined(); | |
| 713 | |
| 714 DVLOG(1) << render_view << " SetSuggestions"; | |
| 715 v8::Handle<v8::Object> suggestion_json = args[0]->ToObject(); | 249 v8::Handle<v8::Object> suggestion_json = args[0]->ToObject(); |
| 716 | 250 |
| 717 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; | |
| 718 InstantSuggestionType type = INSTANT_SUGGESTION_SEARCH; | |
| 719 v8::Handle<v8::Value> complete_value = | |
| 720 suggestion_json->Get(v8::String::New("complete_behavior")); | |
| 721 if (complete_value->Equals(v8::String::New("now"))) { | |
| 722 behavior = INSTANT_COMPLETE_NOW; | |
| 723 } else if (complete_value->Equals(v8::String::New("never"))) { | |
| 724 behavior = INSTANT_COMPLETE_NEVER; | |
| 725 } else if (complete_value->Equals(v8::String::New("replace"))) { | |
| 726 behavior = INSTANT_COMPLETE_REPLACE; | |
| 727 } | |
| 728 | |
| 729 std::vector<InstantSuggestion> suggestions; | |
| 730 | |
| 731 v8::Handle<v8::Value> suggestions_field = | 251 v8::Handle<v8::Value> suggestions_field = |
| 732 suggestion_json->Get(v8::String::New("suggestions")); | 252 suggestion_json->Get(v8::String::New("suggestions")); |
| 733 if (suggestions_field->IsArray()) { | 253 if (suggestions_field->IsArray()) { |
| 734 v8::Handle<v8::Array> suggestions_array = suggestions_field.As<v8::Array>(); | 254 v8::Handle<v8::Array> suggestions_array = suggestions_field.As<v8::Array>(); |
| 735 for (size_t i = 0; i < suggestions_array->Length(); i++) { | 255 if (suggestions_array->Length() > 0) { |
| 736 string16 text = V8ValueToUTF16( | 256 suggestion.text = V8ValueToUTF16( |
| 737 suggestions_array->Get(i)->ToObject()->Get(v8::String::New("value"))); | 257 suggestions_array->Get(0)->ToObject()->Get(v8::String::New("value"))); |
| 738 suggestions.push_back(InstantSuggestion(text, behavior, type)); | |
| 739 } | 258 } |
| 740 } | 259 } |
| 741 | 260 |
| 742 SearchBox::Get(render_view)->SetSuggestions(suggestions); | 261 searchbox->SetSuggestion(suggestion); |
| 743 | 262 |
| 744 return v8::Undefined(); | 263 return v8::Undefined(); |
| 745 } | 264 } |
| 746 | 265 |
| 747 // static | 266 // SearchBoxExtension --------------------------------------------------------- |
| 748 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetQuerySuggestion( | |
| 749 const v8::Arguments& args) { | |
| 750 content::RenderView* render_view = GetRenderView(); | |
| 751 if (!render_view || args.Length() < 2) return v8::Undefined(); | |
| 752 | |
| 753 DVLOG(1) << render_view << " SetQuerySuggestion"; | |
| 754 string16 text = V8ValueToUTF16(args[0]); | |
| 755 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; | |
| 756 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | |
| 757 | |
| 758 if (args[1]->Uint32Value() == 2) { | |
| 759 behavior = INSTANT_COMPLETE_NEVER; | |
| 760 type = INSTANT_SUGGESTION_SEARCH; | |
| 761 } | |
| 762 | |
| 763 std::vector<InstantSuggestion> suggestions; | |
| 764 suggestions.push_back(InstantSuggestion(text, behavior, type)); | |
| 765 SearchBox::Get(render_view)->SetSuggestions(suggestions); | |
| 766 | |
| 767 return v8::Undefined(); | |
| 768 } | |
| 769 | |
| 770 // static | |
| 771 v8::Handle<v8::Value> | |
| 772 SearchBoxExtensionWrapper::SetQuerySuggestionFromAutocompleteResult( | |
| 773 const v8::Arguments& args) { | |
| 774 content::RenderView* render_view = GetRenderView(); | |
| 775 if (!render_view || !args.Length()) return v8::Undefined(); | |
| 776 | |
| 777 DVLOG(1) << render_view << " SetQuerySuggestionFromAutocompleteResult"; | |
| 778 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | |
| 779 GetAutocompleteResultWithId(args[0]->Uint32Value()); | |
| 780 if (!result) return v8::Undefined(); | |
| 781 | |
| 782 // We only support selecting autocomplete results that are URLs. | |
| 783 string16 text = result->destination_url; | |
| 784 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; | |
| 785 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | |
| 786 | |
| 787 std::vector<InstantSuggestion> suggestions; | |
| 788 suggestions.push_back(InstantSuggestion(text, behavior, type)); | |
| 789 SearchBox::Get(render_view)->SetSuggestions(suggestions); | |
| 790 | |
| 791 return v8::Undefined(); | |
| 792 } | |
| 793 | |
| 794 // static | |
| 795 v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetQuery( | |
| 796 const v8::Arguments& args) { | |
| 797 content::RenderView* render_view = GetRenderView(); | |
| 798 if (!render_view || args.Length() < 2) return v8::Undefined(); | |
| 799 | |
| 800 DVLOG(1) << render_view << " SetQuery"; | |
| 801 string16 text = V8ValueToUTF16(args[0]); | |
| 802 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; | |
| 803 InstantSuggestionType type = INSTANT_SUGGESTION_SEARCH; | |
| 804 | |
| 805 if (args[1]->Uint32Value() == 1) | |
| 806 type = INSTANT_SUGGESTION_URL; | |
| 807 | |
| 808 std::vector<InstantSuggestion> suggestions; | |
| 809 suggestions.push_back(InstantSuggestion(text, behavior, type)); | |
| 810 SearchBox::Get(render_view)->SetSuggestions(suggestions); | |
| 811 | |
| 812 return v8::Undefined(); | |
| 813 } | |
| 814 | |
| 815 v8::Handle<v8::Value> | |
| 816 SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( | |
| 817 const v8::Arguments& args) { | |
| 818 content::RenderView* render_view = GetRenderView(); | |
| 819 if (!render_view || !args.Length()) return v8::Undefined(); | |
| 820 | |
| 821 DVLOG(1) << render_view << " SetQueryFromAutocompleteResult"; | |
| 822 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | |
| 823 GetAutocompleteResultWithId(args[0]->Uint32Value()); | |
| 824 if (!result) return v8::Undefined(); | |
| 825 | |
| 826 // We only support selecting autocomplete results that are URLs. | |
| 827 string16 text = result->destination_url; | |
| 828 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; | |
| 829 // TODO(jered): Distinguish between history URLs and search provider | |
| 830 // navsuggest URLs so that we can do proper accounting on history URLs. | |
| 831 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | |
| 832 | |
| 833 std::vector<InstantSuggestion> suggestions; | |
| 834 suggestions.push_back(InstantSuggestion(text, behavior, type)); | |
| 835 SearchBox::Get(render_view)->SetSuggestions(suggestions); | |
| 836 | |
| 837 return v8::Undefined(); | |
| 838 } | |
| 839 | |
| 840 // static | |
| 841 v8::Handle<v8::Value> SearchBoxExtensionWrapper::ShowOverlay( | |
| 842 const v8::Arguments& args) { | |
| 843 content::RenderView* render_view = GetRenderView(); | |
| 844 if (!render_view || args.Length() < 2) return v8::Undefined(); | |
| 845 | |
| 846 DVLOG(1) << render_view << " ShowOverlay"; | |
| 847 InstantShownReason reason = INSTANT_SHOWN_NOT_SPECIFIED; | |
| 848 switch (args[0]->Uint32Value()) { | |
| 849 case 1: reason = INSTANT_SHOWN_CUSTOM_NTP_CONTENT; break; | |
| 850 case 2: reason = INSTANT_SHOWN_QUERY_SUGGESTIONS; break; | |
| 851 case 3: reason = INSTANT_SHOWN_ZERO_SUGGESTIONS; break; | |
| 852 case 4: reason = INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION; break; | |
| 853 } | |
| 854 | |
| 855 int height = 100; | |
| 856 InstantSizeUnits units = INSTANT_SIZE_PERCENT; | |
| 857 if (args[1]->IsInt32()) { | |
| 858 height = args[1]->Int32Value(); | |
| 859 units = INSTANT_SIZE_PIXELS; | |
| 860 } | |
| 861 | |
| 862 SearchBox::Get(render_view)->ShowInstantOverlay(reason, height, units); | |
| 863 | |
| 864 return v8::Undefined(); | |
| 865 } | |
| 866 | |
| 867 // static | |
| 868 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( | |
| 869 const v8::Arguments& args) { | |
| 870 content::RenderView* render_view = GetRenderView(); | |
| 871 if (!render_view) return v8::Undefined(); | |
| 872 | |
| 873 DVLOG(1) << render_view << " GetMostVisitedItems"; | |
| 874 | |
| 875 const std::vector<MostVisitedItem>& items = | |
| 876 SearchBox::Get(render_view)->GetMostVisitedItems(); | |
| 877 v8::Handle<v8::Array> items_array = v8::Array::New(items.size()); | |
| 878 for (size_t i = 0; i < items.size(); ++i) { | |
| 879 | |
| 880 const string16 url = UTF8ToUTF16(items[i].url.spec()); | |
| 881 const string16 host = UTF8ToUTF16(items[i].url.host()); | |
| 882 int restrict_id = | |
| 883 SearchBox::Get(render_view)->UrlToRestrictedId(url); | |
| 884 | |
| 885 v8::Handle<v8::Object> item = v8::Object::New(); | |
| 886 item->Set(v8::String::New("rid"), | |
| 887 v8::Int32::New(restrict_id)); | |
| 888 item->Set(v8::String::New("thumbnailUrl"), | |
| 889 UTF16ToV8String(SearchBox::Get(render_view)-> | |
| 890 GenerateThumbnailUrl(restrict_id))); | |
| 891 item->Set(v8::String::New("faviconUrl"), | |
| 892 UTF16ToV8String(SearchBox::Get(render_view)-> | |
| 893 GenerateFaviconUrl(restrict_id))); | |
| 894 item->Set(v8::String::New("title"), | |
| 895 UTF16ToV8String(items[i].title)); | |
| 896 item->Set(v8::String::New("domain"), UTF16ToV8String(host)); | |
| 897 | |
| 898 items_array->Set(i, item); | |
| 899 } | |
| 900 return items_array; | |
| 901 } | |
| 902 | |
| 903 // static | |
| 904 v8::Handle<v8::Value> SearchBoxExtensionWrapper::DeleteMostVisitedItem( | |
| 905 const v8::Arguments& args) { | |
| 906 content::RenderView* render_view = GetRenderView(); | |
| 907 if (!render_view || !args.Length()) return v8::Undefined(); | |
| 908 | |
| 909 DVLOG(1) << render_view << " DeleteMostVisitedItem"; | |
| 910 SearchBox::Get(render_view)->DeleteMostVisitedItem(args[0]->IntegerValue()); | |
| 911 return v8::Undefined(); | |
| 912 } | |
| 913 | |
| 914 // static | |
| 915 v8::Handle<v8::Value> SearchBoxExtensionWrapper::UndoMostVisitedDeletion( | |
| 916 const v8::Arguments& args) { | |
| 917 content::RenderView* render_view = GetRenderView(); | |
| 918 if (!render_view || !args.Length()) return v8::Undefined(); | |
| 919 | |
| 920 DVLOG(1) << render_view << " UndoMostVisitedDeletion"; | |
| 921 SearchBox::Get(render_view)->UndoMostVisitedDeletion(args[0]->IntegerValue()); | |
| 922 return v8::Undefined(); | |
| 923 } | |
| 924 | |
| 925 // static | |
| 926 v8::Handle<v8::Value> SearchBoxExtensionWrapper::UndoAllMostVisitedDeletions( | |
| 927 const v8::Arguments& args) { | |
| 928 content::RenderView* render_view = GetRenderView(); | |
| 929 if (!render_view) return v8::Undefined(); | |
| 930 | |
| 931 DVLOG(1) << render_view << " UndoAllMostVisitedDeletions"; | |
| 932 SearchBox::Get(render_view)->UndoAllMostVisitedDeletions(); | |
| 933 return v8::Undefined(); | |
| 934 } | |
| 935 | |
| 936 // static | |
| 937 v8::Handle<v8::Value> SearchBoxExtensionWrapper::StartCapturingKeyStrokes( | |
| 938 const v8::Arguments& args) { | |
| 939 content::RenderView* render_view = GetRenderView(); | |
| 940 if (!render_view) return v8::Undefined(); | |
| 941 | |
| 942 DVLOG(1) << render_view << " StartCapturingKeyStrokes"; | |
| 943 SearchBox::Get(render_view)->StartCapturingKeyStrokes(); | |
| 944 return v8::Undefined(); | |
| 945 } | |
| 946 | |
| 947 // static | |
| 948 v8::Handle<v8::Value> SearchBoxExtensionWrapper::StopCapturingKeyStrokes( | |
| 949 const v8::Arguments& args) { | |
| 950 content::RenderView* render_view = GetRenderView(); | |
| 951 if (!render_view) return v8::Undefined(); | |
| 952 | |
| 953 DVLOG(1) << render_view << " StopCapturingKeyStrokes"; | |
| 954 SearchBox::Get(render_view)->StopCapturingKeyStrokes(); | |
| 955 return v8::Undefined(); | |
| 956 } | |
| 957 | 267 |
| 958 // static | 268 // static |
| 959 v8::Extension* SearchBoxExtension::Get() { | 269 v8::Extension* SearchBoxExtension::Get() { |
| 960 return new SearchBoxExtensionWrapper(ResourceBundle::GetSharedInstance(). | 270 return new SearchBoxExtensionWrapper(ResourceBundle::GetSharedInstance(). |
| 961 GetRawDataResource(IDR_SEARCHBOX_API)); | 271 GetRawDataResource(IDR_SEARCHBOX_API)); |
| 962 } | 272 } |
| 963 | 273 |
| 964 // static | 274 // static |
| 965 bool SearchBoxExtension::PageSupportsInstant(WebKit::WebFrame* frame) { | 275 bool SearchBoxExtension::DetermineInstantSupport( |
| 966 if (!frame) return false; | 276 content::RenderView* render_view) { |
| 277 WebKit::WebFrame* frame = GetFrame(render_view); |
| 278 if (!frame) |
| 279 return false; |
| 280 |
| 967 v8::HandleScope handle_scope; | 281 v8::HandleScope handle_scope; |
| 968 v8::Handle<v8::Value> v = frame->executeScriptAndReturnValue( | 282 v8::Handle<v8::Value> v = frame->executeScriptAndReturnValue( |
| 969 WebKit::WebScriptSource(kSupportsInstantScript)); | 283 WebKit::WebScriptSource(kDetermineInstantSupportScript)); |
| 970 return !v.IsEmpty() && v->BooleanValue(); | 284 return !v.IsEmpty() && v->BooleanValue(); |
| 971 } | 285 } |
| 972 | 286 |
| 973 // static | 287 // static |
| 974 void SearchBoxExtension::DispatchChange(WebKit::WebFrame* frame) { | 288 void SearchBoxExtension::Change(content::RenderView* render_view) { |
| 975 Dispatch(frame, kDispatchChangeEventScript); | 289 Dispatch(render_view, kOnChangeScript); |
| 976 } | 290 } |
| 977 | 291 |
| 978 // static | 292 // static |
| 979 void SearchBoxExtension::DispatchSubmit(WebKit::WebFrame* frame) { | 293 void SearchBoxExtension::Submit(content::RenderView* render_view) { |
| 980 Dispatch(frame, kDispatchSubmitEventScript); | 294 Dispatch(render_view, kOnSubmitScript); |
| 981 } | 295 } |
| 982 | 296 |
| 983 // static | 297 // static |
| 984 void SearchBoxExtension::DispatchCancel(WebKit::WebFrame* frame) { | 298 void SearchBoxExtension::Blur(content::RenderView* render_view) { |
| 985 Dispatch(frame, kDispatchCancelEventScript); | 299 Dispatch(render_view, kOnBlurScript); |
| 986 } | 300 } |
| 987 | 301 |
| 988 // static | 302 // static |
| 989 void SearchBoxExtension::DispatchResize(WebKit::WebFrame* frame) { | 303 void SearchBoxExtension::PopupBounds(content::RenderView* render_view) { |
| 990 Dispatch(frame, kDispatchResizeEventScript); | 304 Dispatch(render_view, kOnPopupBoundsScript); |
| 991 } | 305 } |
| 992 | 306 |
| 993 // static | |
| 994 void SearchBoxExtension::DispatchOnWindowReady(WebKit::WebFrame* frame) { | |
| 995 Dispatch(frame, kDispatchOnWindowReady); | |
| 996 } | |
| 997 | |
| 998 // static | |
| 999 void SearchBoxExtension::DispatchAutocompleteResults(WebKit::WebFrame* frame) { | |
| 1000 Dispatch(frame, kDispatchAutocompleteResultsEventScript); | |
| 1001 } | |
| 1002 | |
| 1003 // static | |
| 1004 void SearchBoxExtension::DispatchUpOrDownKeyPress(WebKit::WebFrame* frame, | |
| 1005 int count) { | |
| 1006 Dispatch(frame, WebKit::WebString::fromUTF8( | |
| 1007 base::StringPrintf(kDispatchUpOrDownKeyPressEventScript, abs(count), | |
| 1008 count < 0 ? ui::VKEY_UP : ui::VKEY_DOWN))); | |
| 1009 } | |
| 1010 | |
| 1011 // static | |
| 1012 void SearchBoxExtension::DispatchEscKeyPress(WebKit::WebFrame* frame) { | |
| 1013 Dispatch(frame, WebKit::WebString::fromUTF8( | |
| 1014 base::StringPrintf(kDispatchEscKeyPressEventScript, ui::VKEY_ESCAPE))); | |
| 1015 } | |
| 1016 | |
| 1017 // static | |
| 1018 void SearchBoxExtension::DispatchKeyCaptureChange(WebKit::WebFrame* frame) { | |
| 1019 Dispatch(frame, kDispatchKeyCaptureChangeScript); | |
| 1020 } | |
| 1021 | |
| 1022 // static | |
| 1023 void SearchBoxExtension::DispatchMarginChange(WebKit::WebFrame* frame) { | |
| 1024 Dispatch(frame, kDispatchMarginChangeEventScript); | |
| 1025 } | |
| 1026 | |
| 1027 // static | |
| 1028 void SearchBoxExtension::DispatchThemeChange(WebKit::WebFrame* frame) { | |
| 1029 Dispatch(frame, kDispatchThemeChangeEventScript); | |
| 1030 } | |
| 1031 | |
| 1032 // static | |
| 1033 void SearchBoxExtension::DispatchMostVisitedChanged( | |
| 1034 WebKit::WebFrame* frame) { | |
| 1035 Dispatch(frame, kDispatchMostVisitedChangedScript); | |
| 1036 } | |
| 1037 } // namespace extensions_v8 | 307 } // namespace extensions_v8 |
| OLD | NEW |