searchbox.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 3// found in the LICENSE file. 4 5#include "chrome/renderer/searchbox/searchbox.h" 6 7#include "chrome/common/render_messages.h" 8#include "chrome/renderer/searchbox/searchbox_extension.h" 9#include "content/public/renderer/render_view.h" 10#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 11 12SearchBox::SearchBox(content::RenderView* render_view) 13 : content::RenderViewObserver(render_view), 14 content::RenderViewObserverTracker<SearchBox>(render_view), 15 verbatim_(false), 16 selection_start_(0), 17 selection_end_(0), 18 results_base_(0), 19 last_results_base_(0), 20 is_focused_(false), 21 active_tab_is_ntp_(false) { 22} 23 24SearchBox::~SearchBox() { 25} 26 27void SearchBox::SetSuggestions( 28 const std::vector<InstantSuggestion>& suggestions) { 29 if (!suggestions.empty() && 30 suggestions[0].behavior == INSTANT_COMPLETE_REPLACE) { 31 query_ = suggestions[0].text; 32 verbatim_ = true; 33 selection_start_ = selection_end_ = query_.size(); 34 } 35 // Explicitly allow empty vector to be sent to the browser. 36 render_view()->Send(new ChromeViewHostMsg_SetSuggestions( 37 render_view()->GetRoutingID(), render_view()->GetPageId(), suggestions)); 38} 39 40void SearchBox::ShowInstantPreview(InstantShownReason reason, 41 int height, 42 InstantSizeUnits units) { 43 render_view()->Send(new ChromeViewHostMsg_ShowInstantPreview( 44 render_view()->GetRoutingID(), render_view()->GetPageId(), reason, 45 height, units)); 46} 47 48gfx::Rect SearchBox::GetRect() { 49 // Need to adjust for scale. 50 if (rect_.IsEmpty()) 51 return rect_; 52 WebKit::WebView* web_view = render_view()->GetWebView(); 53 if (!web_view) 54 return rect_; 55 double zoom = WebKit::WebView::zoomLevelToZoomFactor(web_view->zoomLevel()); 56 if (zoom == 0) 57 return rect_; 58 return gfx::Rect(static_cast<int>(static_cast<float>(rect_.x()) / zoom), 59 static_cast<int>(static_cast<float>(rect_.y()) / zoom), 60 static_cast<int>(static_cast<float>(rect_.width()) / zoom), 61 static_cast<int>(static_cast<float>(rect_.height()) / zoom)); 62} 63 64const std::vector<InstantAutocompleteResult>& 65 SearchBox::GetAutocompleteResults() { 66 // Remember the last requested autocomplete_results to account for race 67 // conditions between autocomplete providers returning new data and the user 68 // clicking on a suggestion. 69 last_autocomplete_results_ = autocomplete_results_; 70 last_results_base_ = results_base_; 71 return autocomplete_results_; 72} 73 74const InstantAutocompleteResult* SearchBox::GetAutocompleteResultWithId( 75 size_t restricted_id) const { 76 if (restricted_id < last_results_base_ || 77 restricted_id >= last_results_base_ + last_autocomplete_results_.size()) 78 return NULL; 79 return &last_autocomplete_results_[restricted_id - last_results_base_]; 80} 81 82bool SearchBox::OnMessageReceived(const IPC::Message& message) { 83 bool handled = true; 84 IPC_BEGIN_MESSAGE_MAP(SearchBox, message) 85 IPC_MESSAGE_HANDLER(ChromeViewMsg_SearchBoxChange, OnChange) 86 IPC_MESSAGE_HANDLER(ChromeViewMsg_SearchBoxSubmit, OnSubmit) 87 IPC_MESSAGE_HANDLER(ChromeViewMsg_SearchBoxCancel, OnCancel) 88 IPC_MESSAGE_HANDLER(ChromeViewMsg_SearchBoxResize, OnResize) 89 IPC_MESSAGE_HANDLER(ChromeViewMsg_DetermineIfPageSupportsInstant, 90 OnDetermineIfPageSupportsInstant) 91 IPC_MESSAGE_HANDLER(ChromeViewMsg_SearchBoxAutocompleteResults, 92 OnAutocompleteResults) 93 IPC_MESSAGE_HANDLER(ChromeViewMsg_SearchBoxUpOrDownKeyPressed, 94 OnUpOrDownKeyPressed) 95 IPC_MESSAGE_HANDLER(ChromeViewMsg_SearchBoxFocus, OnFocus) 96 IPC_MESSAGE_HANDLER(ChromeViewMsg_SearchBoxBlur, OnBlur) 97 IPC_MESSAGE_HANDLER(ChromeViewMsg_SearchBoxActiveTabModeChanged, 98 OnActiveTabModeChanged) 99 IPC_MESSAGE_UNHANDLED(handled = false) 100 IPC_END_MESSAGE_MAP() 101 return handled; 102} 103 104void SearchBox::OnChange(const string16& query, 105 bool verbatim, 106 size_t selection_start, 107 size_t selection_end) { 108 query_ = query; 109 verbatim_ = verbatim; 110 selection_start_ = selection_start; 111 selection_end_ = selection_end; 112 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 113 extensions_v8::SearchBoxExtension::DispatchChange( 114 render_view()->GetWebView()->mainFrame()); 115 } 116} 117 118void SearchBox::OnSubmit(const string16& query) { 119 query_ = query; 120 verbatim_ = true; 121 selection_start_ = selection_end_ = query_.size(); 122 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 123 extensions_v8::SearchBoxExtension::DispatchSubmit( 124 render_view()->GetWebView()->mainFrame()); 125 } 126 Reset(); 127} 128 129void SearchBox::OnCancel(const string16& query) { 130 query_ = query; 131 verbatim_ = true; 132 selection_start_ = selection_end_ = query_.size(); 133 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 134 extensions_v8::SearchBoxExtension::DispatchCancel( 135 render_view()->GetWebView()->mainFrame()); 136 } 137 Reset(); 138} 139 140void SearchBox::OnResize(const gfx::Rect& bounds) { 141 rect_ = bounds; 142 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 143 extensions_v8::SearchBoxExtension::DispatchResize( 144 render_view()->GetWebView()->mainFrame()); 145 } 146} 147 148void SearchBox::OnDetermineIfPageSupportsInstant() { 149 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 150 bool result = extensions_v8::SearchBoxExtension::PageSupportsInstant( 151 render_view()->GetWebView()->mainFrame()); 152 render_view()->Send(new ChromeViewHostMsg_InstantSupportDetermined( 153 render_view()->GetRoutingID(), render_view()->GetPageId(), result)); 154 } 155} 156 157void SearchBox::OnAutocompleteResults( 158 const std::vector<InstantAutocompleteResult>& results) { 159 results_base_ += autocomplete_results_.size(); 160 autocomplete_results_ = results; 161 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 162 extensions_v8::SearchBoxExtension::DispatchAutocompleteResults( 163 render_view()->GetWebView()->mainFrame()); 164 } 165} 166 167void SearchBox::OnUpOrDownKeyPressed(int count) { 168 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 169 extensions_v8::SearchBoxExtension::DispatchUpOrDownKeyPress( 170 render_view()->GetWebView()->mainFrame(), count); 171 } 172} 173 174void SearchBox::OnFocus() { 175 is_focused_ = true; 176 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 177 extensions_v8::SearchBoxExtension::DispatchFocus( 178 render_view()->GetWebView()->mainFrame()); 179 } 180} 181 182void SearchBox::OnBlur() { 183 is_focused_ = false; 184 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 185 extensions_v8::SearchBoxExtension::DispatchBlur( 186 render_view()->GetWebView()->mainFrame()); 187 } 188} 189 190void SearchBox::OnActiveTabModeChanged(bool active_tab_is_ntp) { 191 active_tab_is_ntp_ = active_tab_is_ntp; 192 if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { 193 extensions_v8::SearchBoxExtension::DispatchContextChange( 194 render_view()->GetWebView()->mainFrame()); 195 } 196} 197 198void SearchBox::Reset() { 199 query_.clear(); 200 verbatim_ = false; 201 selection_start_ = selection_end_ = 0; 202 results_base_ = 0; 203 rect_ = gfx::Rect(); 204 autocomplete_results_.clear(); 205 is_focused_ = false; 206} 207