OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/browser/autocomplete/autocomplete_edit.h" | 5 #include "chrome/browser/autocomplete/autocomplete_edit.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 /////////////////////////////////////////////////////////////////////////////// | 36 /////////////////////////////////////////////////////////////////////////////// |
37 // AutocompleteEditController | 37 // AutocompleteEditController |
38 | 38 |
39 AutocompleteEditController::~AutocompleteEditController() { | 39 AutocompleteEditController::~AutocompleteEditController() { |
40 } | 40 } |
41 | 41 |
42 /////////////////////////////////////////////////////////////////////////////// | 42 /////////////////////////////////////////////////////////////////////////////// |
43 // AutocompleteEditModel::State | 43 // AutocompleteEditModel::State |
44 | 44 |
45 AutocompleteEditModel::State::State(bool user_input_in_progress, | 45 AutocompleteEditModel::State::State(bool user_input_in_progress, |
46 const std::wstring& user_text, | 46 const string16& user_text, |
47 const std::wstring& keyword, | 47 const string16& keyword, |
48 bool is_keyword_hint) | 48 bool is_keyword_hint) |
49 : user_input_in_progress(user_input_in_progress), | 49 : user_input_in_progress(user_input_in_progress), |
50 user_text(user_text), | 50 user_text(user_text), |
51 keyword(keyword), | 51 keyword(keyword), |
52 is_keyword_hint(is_keyword_hint) { | 52 is_keyword_hint(is_keyword_hint) { |
53 } | 53 } |
54 | 54 |
55 AutocompleteEditModel::State::~State() { | 55 AutocompleteEditModel::State::~State() { |
56 } | 56 } |
57 | 57 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 | 94 |
95 const AutocompleteEditModel::State | 95 const AutocompleteEditModel::State |
96 AutocompleteEditModel::GetStateForTabSwitch() { | 96 AutocompleteEditModel::GetStateForTabSwitch() { |
97 // Like typing, switching tabs "accepts" the temporary text as the user | 97 // Like typing, switching tabs "accepts" the temporary text as the user |
98 // text, because it makes little sense to have temporary text when the | 98 // text, because it makes little sense to have temporary text when the |
99 // popup is closed. | 99 // popup is closed. |
100 if (user_input_in_progress_) { | 100 if (user_input_in_progress_) { |
101 // Weird edge case to match other browsers: if the edit is empty, revert to | 101 // Weird edge case to match other browsers: if the edit is empty, revert to |
102 // the permanent text (so the user can get it back easily) but select it (so | 102 // the permanent text (so the user can get it back easily) but select it (so |
103 // on switching back, typing will "just work"). | 103 // on switching back, typing will "just work"). |
104 const std::wstring user_text(UserTextFromDisplayText(view_->GetText())); | 104 const string16 user_text(UserTextFromDisplayText(view_->GetText())); |
105 if (user_text.empty()) { | 105 if (user_text.empty()) { |
106 view_->RevertAll(); | 106 view_->RevertAll(); |
107 view_->SelectAll(true); | 107 view_->SelectAll(true); |
108 } else { | 108 } else { |
109 InternalSetUserText(user_text); | 109 InternalSetUserText(user_text); |
110 } | 110 } |
111 } | 111 } |
112 | 112 |
113 return State(user_input_in_progress_, user_text_, keyword_, is_keyword_hint_); | 113 return State(user_input_in_progress_, user_text_, keyword_, is_keyword_hint_); |
114 } | 114 } |
(...skipping 10 matching lines...) Expand all Loading... |
125 } | 125 } |
126 } | 126 } |
127 | 127 |
128 AutocompleteMatch AutocompleteEditModel::CurrentMatch() { | 128 AutocompleteMatch AutocompleteEditModel::CurrentMatch() { |
129 AutocompleteMatch match; | 129 AutocompleteMatch match; |
130 GetInfoForCurrentText(&match, NULL); | 130 GetInfoForCurrentText(&match, NULL); |
131 return match; | 131 return match; |
132 } | 132 } |
133 | 133 |
134 bool AutocompleteEditModel::UpdatePermanentText( | 134 bool AutocompleteEditModel::UpdatePermanentText( |
135 const std::wstring& new_permanent_text) { | 135 const string16& new_permanent_text) { |
136 // When there's a new URL, and the user is not editing anything or the edit | 136 // When there's a new URL, and the user is not editing anything or the edit |
137 // doesn't have focus, we want to revert the edit to show the new URL. (The | 137 // doesn't have focus, we want to revert the edit to show the new URL. (The |
138 // common case where the edit doesn't have focus is when the user has started | 138 // common case where the edit doesn't have focus is when the user has started |
139 // an edit and then abandoned it and clicked a link on the page.) | 139 // an edit and then abandoned it and clicked a link on the page.) |
140 const bool visibly_changed_permanent_text = | 140 const bool visibly_changed_permanent_text = |
141 (permanent_text_ != new_permanent_text) && | 141 (permanent_text_ != new_permanent_text) && |
142 (!user_input_in_progress_ || !has_focus_); | 142 (!user_input_in_progress_ || !has_focus_); |
143 | 143 |
144 permanent_text_ = new_permanent_text; | 144 permanent_text_ = new_permanent_text; |
145 return visibly_changed_permanent_text; | 145 return visibly_changed_permanent_text; |
146 } | 146 } |
147 | 147 |
148 void AutocompleteEditModel::SetUserText(const std::wstring& text) { | 148 void AutocompleteEditModel::SetUserText(const string16& text) { |
149 SetInputInProgress(true); | 149 SetInputInProgress(true); |
150 InternalSetUserText(text); | 150 InternalSetUserText(text); |
151 paste_state_ = NONE; | 151 paste_state_ = NONE; |
152 has_temporary_text_ = false; | 152 has_temporary_text_ = false; |
153 } | 153 } |
154 | 154 |
155 void AutocompleteEditModel::FinalizeInstantQuery( | 155 void AutocompleteEditModel::FinalizeInstantQuery( |
156 const std::wstring& input_text, | 156 const string16& input_text, |
157 const std::wstring& suggest_text) { | 157 const string16& suggest_text) { |
158 popup_->FinalizeInstantQuery(input_text, suggest_text); | 158 popup_->FinalizeInstantQuery(input_text, suggest_text); |
159 } | 159 } |
160 | 160 |
161 void AutocompleteEditModel::GetDataForURLExport(GURL* url, | 161 void AutocompleteEditModel::GetDataForURLExport(GURL* url, |
162 std::wstring* title, | 162 string16* title, |
163 SkBitmap* favicon) { | 163 SkBitmap* favicon) { |
164 AutocompleteMatch match; | 164 AutocompleteMatch match; |
165 GetInfoForCurrentText(&match, NULL); | 165 GetInfoForCurrentText(&match, NULL); |
166 *url = match.destination_url; | 166 *url = match.destination_url; |
167 if (*url == URLFixerUpper::FixupURL(WideToUTF8(permanent_text_), | 167 if (*url == URLFixerUpper::FixupURL(UTF16ToUTF8(permanent_text_), |
168 std::string())) { | 168 std::string())) { |
169 *title = controller_->GetTitle(); | 169 *title = controller_->GetTitle(); |
170 *favicon = controller_->GetFavIcon(); | 170 *favicon = controller_->GetFavIcon(); |
171 } | 171 } |
172 } | 172 } |
173 | 173 |
174 bool AutocompleteEditModel::UseVerbatimInstant() { | 174 bool AutocompleteEditModel::UseVerbatimInstant() { |
175 #if defined(OS_MACOSX) | 175 #if defined(OS_MACOSX) |
176 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, | 176 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, |
177 // so that we can display instant suggest along with composition text. | 177 // so that we can display instant suggest along with composition text. |
178 const AutocompleteInput& input = popup_->autocomplete_controller()->input(); | 178 const AutocompleteInput& input = popup_->autocomplete_controller()->input(); |
179 if (input.initial_prevent_inline_autocomplete()) | 179 if (input.initial_prevent_inline_autocomplete()) |
180 return true; | 180 return true; |
181 #endif | 181 #endif |
182 | 182 |
183 // The value of input.initial_prevent_inline_autocomplete() is determined by | 183 // The value of input.initial_prevent_inline_autocomplete() is determined by |
184 // following conditions: | 184 // following conditions: |
185 // 1. If the caret is at the end of the text (checked below). | 185 // 1. If the caret is at the end of the text (checked below). |
186 // 2. If it's in IME composition mode. | 186 // 2. If it's in IME composition mode. |
187 // As we use a separated widget for displaying the instant suggest, it won't | 187 // As we use a separated widget for displaying the instant suggest, it won't |
188 // interfere with IME composition, so we don't need to care about the value of | 188 // interfere with IME composition, so we don't need to care about the value of |
189 // input.initial_prevent_inline_autocomplete() here. | 189 // input.initial_prevent_inline_autocomplete() here. |
190 if (view_->DeleteAtEndPressed() || (popup_->selected_line() != 0) || | 190 if (view_->DeleteAtEndPressed() || (popup_->selected_line() != 0) || |
191 just_deleted_text_) | 191 just_deleted_text_) |
192 return true; | 192 return true; |
193 | 193 |
194 std::wstring::size_type start, end; | 194 string16::size_type start, end; |
195 view_->GetSelectionBounds(&start, &end); | 195 view_->GetSelectionBounds(&start, &end); |
196 return (start != end) || (start != view_->GetText().size()); | 196 return (start != end) || (start != view_->GetText().size()); |
197 } | 197 } |
198 | 198 |
199 std::wstring AutocompleteEditModel::GetDesiredTLD() const { | 199 string16 AutocompleteEditModel::GetDesiredTLD() const { |
200 // Tricky corner case: The user has typed "foo" and currently sees an inline | 200 // Tricky corner case: The user has typed "foo" and currently sees an inline |
201 // autocomplete suggestion of "foo.net". He now presses ctrl-a (e.g. to | 201 // autocomplete suggestion of "foo.net". He now presses ctrl-a (e.g. to |
202 // select all, on Windows). If we treat the ctrl press as potentially for the | 202 // select all, on Windows). If we treat the ctrl press as potentially for the |
203 // sake of ctrl-enter, then we risk "www.foo.com" being promoted as the best | 203 // sake of ctrl-enter, then we risk "www.foo.com" being promoted as the best |
204 // match. This would make the autocompleted text disappear, leaving our user | 204 // match. This would make the autocompleted text disappear, leaving our user |
205 // feeling very confused when the wrong text gets highlighted. | 205 // feeling very confused when the wrong text gets highlighted. |
206 // | 206 // |
207 // Thus, we only treat the user as pressing ctrl-enter when the user presses | 207 // Thus, we only treat the user as pressing ctrl-enter when the user presses |
208 // ctrl without any fragile state built up in the omnibox: | 208 // ctrl without any fragile state built up in the omnibox: |
209 // * the contents of the omnibox have not changed since the keypress, | 209 // * the contents of the omnibox have not changed since the keypress, |
210 // * there is no autocompleted text visible, and | 210 // * there is no autocompleted text visible, and |
211 // * the user is not typing a keyword query. | 211 // * the user is not typing a keyword query. |
212 return (control_key_state_ == DOWN_WITHOUT_CHANGE && | 212 return (control_key_state_ == DOWN_WITHOUT_CHANGE && |
213 inline_autocomplete_text_.empty() && !KeywordIsSelected())? | 213 inline_autocomplete_text_.empty() && !KeywordIsSelected())? |
214 std::wstring(L"com") : std::wstring(); | 214 ASCIIToUTF16("com") : string16(); |
215 } | 215 } |
216 | 216 |
217 bool AutocompleteEditModel::CurrentTextIsURL() const { | 217 bool AutocompleteEditModel::CurrentTextIsURL() const { |
218 // If !user_input_in_progress_, the permanent text is showing, which should | 218 // If !user_input_in_progress_, the permanent text is showing, which should |
219 // always be a URL, so no further checking is needed. By avoiding checking in | 219 // always be a URL, so no further checking is needed. By avoiding checking in |
220 // this case, we avoid calling into the autocomplete providers, and thus | 220 // this case, we avoid calling into the autocomplete providers, and thus |
221 // initializing the history system, as long as possible, which speeds startup. | 221 // initializing the history system, as long as possible, which speeds startup. |
222 if (!user_input_in_progress_) | 222 if (!user_input_in_progress_) |
223 return true; | 223 return true; |
224 | 224 |
225 AutocompleteMatch match; | 225 AutocompleteMatch match; |
226 GetInfoForCurrentText(&match, NULL); | 226 GetInfoForCurrentText(&match, NULL); |
227 return match.transition == PageTransition::TYPED; | 227 return match.transition == PageTransition::TYPED; |
228 } | 228 } |
229 | 229 |
230 AutocompleteMatch::Type AutocompleteEditModel::CurrentTextType() const { | 230 AutocompleteMatch::Type AutocompleteEditModel::CurrentTextType() const { |
231 AutocompleteMatch match; | 231 AutocompleteMatch match; |
232 GetInfoForCurrentText(&match, NULL); | 232 GetInfoForCurrentText(&match, NULL); |
233 return match.type; | 233 return match.type; |
234 } | 234 } |
235 | 235 |
236 void AutocompleteEditModel::AdjustTextForCopy(int sel_min, | 236 void AutocompleteEditModel::AdjustTextForCopy(int sel_min, |
237 bool is_all_selected, | 237 bool is_all_selected, |
238 std::wstring* text, | 238 string16* text, |
239 GURL* url, | 239 GURL* url, |
240 bool* write_url) { | 240 bool* write_url) { |
241 *write_url = false; | 241 *write_url = false; |
242 | 242 |
243 if (sel_min != 0) | 243 if (sel_min != 0) |
244 return; | 244 return; |
245 | 245 |
246 // We can't use CurrentTextIsURL() or GetDataForURLExport() because right now | 246 // We can't use CurrentTextIsURL() or GetDataForURLExport() because right now |
247 // the user is probably holding down control to cause the copy, which will | 247 // the user is probably holding down control to cause the copy, which will |
248 // screw up our calculation of the desired_tld. | 248 // screw up our calculation of the desired_tld. |
249 if (!GetURLForText(*text, url)) | 249 if (!GetURLForText(*text, url)) |
250 return; // Can't be parsed as a url, no need to adjust text. | 250 return; // Can't be parsed as a url, no need to adjust text. |
251 | 251 |
252 if (!user_input_in_progress() && is_all_selected) { | 252 if (!user_input_in_progress() && is_all_selected) { |
253 // The user selected all the text and has not edited it. Use the url as the | 253 // The user selected all the text and has not edited it. Use the url as the |
254 // text so that if the scheme was stripped it's added back, and the url | 254 // text so that if the scheme was stripped it's added back, and the url |
255 // is unescaped (we escape parts of the url for display). | 255 // is unescaped (we escape parts of the url for display). |
256 *text = UTF8ToWide(url->spec()); | 256 *text = UTF8ToUTF16(url->spec()); |
257 *write_url = true; | 257 *write_url = true; |
258 return; | 258 return; |
259 } | 259 } |
260 | 260 |
261 // Prefix the text with 'http://' if the text doesn't start with 'http://', | 261 // Prefix the text with 'http://' if the text doesn't start with 'http://', |
262 // the text parses as a url with a scheme of http, the user selected the | 262 // the text parses as a url with a scheme of http, the user selected the |
263 // entire host, and the user hasn't edited the host or manually removed the | 263 // entire host, and the user hasn't edited the host or manually removed the |
264 // scheme. | 264 // scheme. |
265 GURL perm_url; | 265 GURL perm_url; |
266 if (GetURLForText(permanent_text_, &perm_url) && | 266 if (GetURLForText(permanent_text_, &perm_url) && |
267 perm_url.SchemeIs(chrome::kHttpScheme) && | 267 perm_url.SchemeIs(chrome::kHttpScheme) && |
268 url->SchemeIs(chrome::kHttpScheme) && | 268 url->SchemeIs(chrome::kHttpScheme) && |
269 perm_url.host() == url->host()) { | 269 perm_url.host() == url->host()) { |
270 *write_url = true; | 270 *write_url = true; |
271 | 271 |
272 std::wstring http = ASCIIToWide(chrome::kHttpScheme) + | 272 string16 http = ASCIIToUTF16(chrome::kHttpScheme) + |
273 ASCIIToWide(chrome::kStandardSchemeSeparator); | 273 ASCIIToUTF16(chrome::kStandardSchemeSeparator); |
274 if (text->compare(0, http.length(), http) != 0) | 274 if (text->compare(0, http.length(), http) != 0) |
275 *text = http + *text; | 275 *text = http + *text; |
276 } | 276 } |
277 } | 277 } |
278 | 278 |
279 void AutocompleteEditModel::SetInputInProgress(bool in_progress) { | 279 void AutocompleteEditModel::SetInputInProgress(bool in_progress) { |
280 if (user_input_in_progress_ == in_progress) | 280 if (user_input_in_progress_ == in_progress) |
281 return; | 281 return; |
282 | 282 |
283 user_input_in_progress_ = in_progress; | 283 user_input_in_progress_ = in_progress; |
284 controller_->OnInputInProgress(in_progress); | 284 controller_->OnInputInProgress(in_progress); |
285 } | 285 } |
286 | 286 |
287 void AutocompleteEditModel::Revert() { | 287 void AutocompleteEditModel::Revert() { |
288 SetInputInProgress(false); | 288 SetInputInProgress(false); |
289 paste_state_ = NONE; | 289 paste_state_ = NONE; |
290 InternalSetUserText(std::wstring()); | 290 InternalSetUserText(string16()); |
291 keyword_.clear(); | 291 keyword_.clear(); |
292 is_keyword_hint_ = false; | 292 is_keyword_hint_ = false; |
293 has_temporary_text_ = false; | 293 has_temporary_text_ = false; |
294 view_->SetWindowTextAndCaretPos(permanent_text_, | 294 view_->SetWindowTextAndCaretPos(permanent_text_, |
295 has_focus_ ? permanent_text_.length() : 0); | 295 has_focus_ ? permanent_text_.length() : 0); |
296 } | 296 } |
297 | 297 |
298 void AutocompleteEditModel::StartAutocomplete( | 298 void AutocompleteEditModel::StartAutocomplete( |
299 bool has_selected_text, | 299 bool has_selected_text, |
300 bool prevent_inline_autocomplete) const { | 300 bool prevent_inline_autocomplete) const { |
301 bool keyword_is_selected = KeywordIsSelected(); | 301 bool keyword_is_selected = KeywordIsSelected(); |
302 popup_->StartAutocomplete(user_text_, GetDesiredTLD(), | 302 popup_->StartAutocomplete(user_text_, GetDesiredTLD(), |
303 prevent_inline_autocomplete || just_deleted_text_ || | 303 prevent_inline_autocomplete || just_deleted_text_ || |
304 (has_selected_text && inline_autocomplete_text_.empty()) || | 304 (has_selected_text && inline_autocomplete_text_.empty()) || |
305 (paste_state_ != NONE), keyword_is_selected, keyword_is_selected); | 305 (paste_state_ != NONE), keyword_is_selected, keyword_is_selected); |
306 } | 306 } |
307 | 307 |
308 bool AutocompleteEditModel::CanPasteAndGo(const std::wstring& text) const { | 308 bool AutocompleteEditModel::CanPasteAndGo(const string16& text) const { |
309 if (!view_->GetCommandUpdater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) | 309 if (!view_->GetCommandUpdater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) |
310 return false; | 310 return false; |
311 | 311 |
312 AutocompleteMatch match; | 312 AutocompleteMatch match; |
313 profile_->GetAutocompleteClassifier()->Classify(text, std::wstring(), false, | 313 profile_->GetAutocompleteClassifier()->Classify(text, string16(), false, |
314 &match, &paste_and_go_alternate_nav_url_); | 314 &match, &paste_and_go_alternate_nav_url_); |
315 paste_and_go_url_ = match.destination_url; | 315 paste_and_go_url_ = match.destination_url; |
316 paste_and_go_transition_ = match.transition; | 316 paste_and_go_transition_ = match.transition; |
317 return paste_and_go_url_.is_valid(); | 317 return paste_and_go_url_.is_valid(); |
318 } | 318 } |
319 | 319 |
320 void AutocompleteEditModel::PasteAndGo() { | 320 void AutocompleteEditModel::PasteAndGo() { |
321 // The final parameter to OpenURL, keyword, is not quite correct here: it's | 321 // The final parameter to OpenURL, keyword, is not quite correct here: it's |
322 // possible to "paste and go" a string that contains a keyword. This is | 322 // possible to "paste and go" a string that contains a keyword. This is |
323 // enough of an edge case that we ignore this possibility. | 323 // enough of an edge case that we ignore this possibility. |
324 view_->RevertAll(); | 324 view_->RevertAll(); |
325 view_->OpenURL(paste_and_go_url_, CURRENT_TAB, paste_and_go_transition_, | 325 view_->OpenURL(paste_and_go_url_, CURRENT_TAB, paste_and_go_transition_, |
326 paste_and_go_alternate_nav_url_, AutocompletePopupModel::kNoMatch, | 326 paste_and_go_alternate_nav_url_, AutocompletePopupModel::kNoMatch, |
327 std::wstring()); | 327 string16()); |
328 } | 328 } |
329 | 329 |
330 void AutocompleteEditModel::AcceptInput(WindowOpenDisposition disposition, | 330 void AutocompleteEditModel::AcceptInput(WindowOpenDisposition disposition, |
331 bool for_drop) { | 331 bool for_drop) { |
332 // Get the URL and transition type for the selected entry. | 332 // Get the URL and transition type for the selected entry. |
333 AutocompleteMatch match; | 333 AutocompleteMatch match; |
334 GURL alternate_nav_url; | 334 GURL alternate_nav_url; |
335 GetInfoForCurrentText(&match, &alternate_nav_url); | 335 GetInfoForCurrentText(&match, &alternate_nav_url); |
336 | 336 |
337 if (!match.destination_url.is_valid()) | 337 if (!match.destination_url.is_valid()) |
338 return; | 338 return; |
339 | 339 |
340 if ((match.transition == PageTransition::TYPED) && (match.destination_url == | 340 if ((match.transition == PageTransition::TYPED) && (match.destination_url == |
341 URLFixerUpper::FixupURL(WideToUTF8(permanent_text_), std::string()))) { | 341 URLFixerUpper::FixupURL(UTF16ToUTF8(permanent_text_), std::string()))) { |
342 // When the user hit enter on the existing permanent URL, treat it like a | 342 // When the user hit enter on the existing permanent URL, treat it like a |
343 // reload for scoring purposes. We could detect this by just checking | 343 // reload for scoring purposes. We could detect this by just checking |
344 // user_input_in_progress_, but it seems better to treat "edits" that end | 344 // user_input_in_progress_, but it seems better to treat "edits" that end |
345 // up leaving the URL unchanged (e.g. deleting the last character and then | 345 // up leaving the URL unchanged (e.g. deleting the last character and then |
346 // retyping it) as reloads too. We exclude non-TYPED transitions because if | 346 // retyping it) as reloads too. We exclude non-TYPED transitions because if |
347 // the transition is GENERATED, the user input something that looked | 347 // the transition is GENERATED, the user input something that looked |
348 // different from the current URL, even if it wound up at the same place | 348 // different from the current URL, even if it wound up at the same place |
349 // (e.g. manually retyping the same search query), and it seems wrong to | 349 // (e.g. manually retyping the same search query), and it seems wrong to |
350 // treat this as a reload. | 350 // treat this as a reload. |
351 match.transition = PageTransition::RELOAD; | 351 match.transition = PageTransition::RELOAD; |
352 } else if (for_drop || ((paste_state_ != NONE) && | 352 } else if (for_drop || ((paste_state_ != NONE) && |
353 match.is_history_what_you_typed_match)) { | 353 match.is_history_what_you_typed_match)) { |
354 // When the user pasted in a URL and hit enter, score it like a link click | 354 // When the user pasted in a URL and hit enter, score it like a link click |
355 // rather than a normal typed URL, so it doesn't get inline autocompleted | 355 // rather than a normal typed URL, so it doesn't get inline autocompleted |
356 // as aggressively later. | 356 // as aggressively later. |
357 match.transition = PageTransition::LINK; | 357 match.transition = PageTransition::LINK; |
358 } | 358 } |
359 | 359 |
360 if (match.type == AutocompleteMatch::SEARCH_WHAT_YOU_TYPED || | 360 if (match.type == AutocompleteMatch::SEARCH_WHAT_YOU_TYPED || |
361 match.type == AutocompleteMatch::SEARCH_HISTORY || | 361 match.type == AutocompleteMatch::SEARCH_HISTORY || |
362 match.type == AutocompleteMatch::SEARCH_SUGGEST) { | 362 match.type == AutocompleteMatch::SEARCH_SUGGEST) { |
363 const TemplateURL* default_provider = | 363 const TemplateURL* default_provider = |
364 profile_->GetTemplateURLModel()->GetDefaultSearchProvider(); | 364 profile_->GetTemplateURLModel()->GetDefaultSearchProvider(); |
365 if (default_provider && default_provider->url() && | 365 if (default_provider && default_provider->url() && |
366 default_provider->url()->HasGoogleBaseURLs()) | 366 default_provider->url()->HasGoogleBaseURLs()) |
367 GoogleURLTracker::GoogleURLSearchCommitted(); | 367 GoogleURLTracker::GoogleURLSearchCommitted(); |
368 } | 368 } |
369 view_->OpenURL(match.destination_url, disposition, match.transition, | 369 view_->OpenURL(match.destination_url, disposition, match.transition, |
370 alternate_nav_url, AutocompletePopupModel::kNoMatch, | 370 alternate_nav_url, AutocompletePopupModel::kNoMatch, |
371 is_keyword_hint_ ? std::wstring() : keyword_); | 371 is_keyword_hint_ ? string16() : keyword_); |
372 } | 372 } |
373 | 373 |
374 void AutocompleteEditModel::OpenURL(const GURL& url, | 374 void AutocompleteEditModel::OpenURL(const GURL& url, |
375 WindowOpenDisposition disposition, | 375 WindowOpenDisposition disposition, |
376 PageTransition::Type transition, | 376 PageTransition::Type transition, |
377 const GURL& alternate_nav_url, | 377 const GURL& alternate_nav_url, |
378 size_t index, | 378 size_t index, |
379 const std::wstring& keyword) { | 379 const string16& keyword) { |
380 // We only care about cases where there is a selection (i.e. the popup is | 380 // We only care about cases where there is a selection (i.e. the popup is |
381 // open). | 381 // open). |
382 if (popup_->IsOpen()) { | 382 if (popup_->IsOpen()) { |
383 scoped_ptr<AutocompleteLog> log(popup_->GetAutocompleteLog()); | 383 scoped_ptr<AutocompleteLog> log(popup_->GetAutocompleteLog()); |
384 if (index != AutocompletePopupModel::kNoMatch) | 384 if (index != AutocompletePopupModel::kNoMatch) |
385 log->selected_index = index; | 385 log->selected_index = index; |
386 else if (!has_temporary_text_) | 386 else if (!has_temporary_text_) |
387 log->inline_autocompleted_length = inline_autocomplete_text_.length(); | 387 log->inline_autocompleted_length = inline_autocomplete_text_.length(); |
388 NotificationService::current()->Notify( | 388 NotificationService::current()->Notify( |
389 NotificationType::OMNIBOX_OPENED_URL, Source<Profile>(profile_), | 389 NotificationType::OMNIBOX_OPENED_URL, Source<Profile>(profile_), |
390 Details<AutocompleteLog>(log.get())); | 390 Details<AutocompleteLog>(log.get())); |
391 } | 391 } |
392 | 392 |
393 TemplateURLModel* template_url_model = profile_->GetTemplateURLModel(); | 393 TemplateURLModel* template_url_model = profile_->GetTemplateURLModel(); |
394 if (template_url_model && !keyword.empty()) { | 394 if (template_url_model && !keyword.empty()) { |
395 const TemplateURL* const template_url = | 395 const TemplateURL* const template_url = |
396 template_url_model->GetTemplateURLForKeyword(WideToUTF16Hack(keyword)); | 396 template_url_model->GetTemplateURLForKeyword(keyword); |
397 | 397 |
398 // Special case for extension keywords. Don't increment usage count for | 398 // Special case for extension keywords. Don't increment usage count for |
399 // these. | 399 // these. |
400 if (template_url && template_url->IsExtensionKeyword()) { | 400 if (template_url && template_url->IsExtensionKeyword()) { |
401 AutocompleteMatch current_match; | 401 AutocompleteMatch current_match; |
402 GetInfoForCurrentText(¤t_match, NULL); | 402 GetInfoForCurrentText(¤t_match, NULL); |
403 | 403 |
404 const AutocompleteMatch& match = | 404 const AutocompleteMatch& match = |
405 index == AutocompletePopupModel::kNoMatch ? | 405 index == AutocompletePopupModel::kNoMatch ? |
406 current_match : result().match_at(index); | 406 current_match : result().match_at(index); |
407 | 407 |
408 // Strip the keyword + leading space off the input. | 408 // Strip the keyword + leading space off the input. |
409 size_t prefix_length = match.template_url->keyword().size() + 1; | 409 size_t prefix_length = match.template_url->keyword().size() + 1; |
410 ExtensionOmniboxEventRouter::OnInputEntered( | 410 ExtensionOmniboxEventRouter::OnInputEntered( |
411 profile_, match.template_url->GetExtensionId(), | 411 profile_, match.template_url->GetExtensionId(), |
412 WideToUTF8(match.fill_into_edit.substr(prefix_length))); | 412 UTF16ToUTF8(match.fill_into_edit.substr(prefix_length))); |
413 view_->RevertAll(); | 413 view_->RevertAll(); |
414 return; | 414 return; |
415 } | 415 } |
416 | 416 |
417 if (template_url) { | 417 if (template_url) { |
418 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeyword"), profile_); | 418 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeyword"), profile_); |
419 template_url_model->IncrementUsageCount(template_url); | 419 template_url_model->IncrementUsageCount(template_url); |
420 } | 420 } |
421 | 421 |
422 // NOTE: We purposefully don't increment the usage count of the default | 422 // NOTE: We purposefully don't increment the usage count of the default |
423 // search engine, if applicable; see comments in template_url.h. | 423 // search engine, if applicable; see comments in template_url.h. |
424 } | 424 } |
425 | 425 |
426 if (disposition != NEW_BACKGROUND_TAB) { | 426 if (disposition != NEW_BACKGROUND_TAB) { |
427 controller_->OnAutocompleteWillAccept(); | 427 controller_->OnAutocompleteWillAccept(); |
428 view_->RevertAll(); // Revert the box to its unedited state | 428 view_->RevertAll(); // Revert the box to its unedited state |
429 } | 429 } |
430 controller_->OnAutocompleteAccept(url, disposition, transition, | 430 controller_->OnAutocompleteAccept(url, disposition, transition, |
431 alternate_nav_url); | 431 alternate_nav_url); |
432 } | 432 } |
433 | 433 |
434 bool AutocompleteEditModel::AcceptKeyword() { | 434 bool AutocompleteEditModel::AcceptKeyword() { |
435 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 435 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
436 | 436 |
437 view_->OnBeforePossibleChange(); | 437 view_->OnBeforePossibleChange(); |
438 view_->SetWindowTextAndCaretPos(std::wstring(), 0); | 438 view_->SetWindowTextAndCaretPos(string16(), 0); |
439 is_keyword_hint_ = false; | 439 is_keyword_hint_ = false; |
440 view_->OnAfterPossibleChange(); | 440 view_->OnAfterPossibleChange(); |
441 just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this | 441 just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this |
442 // since the edit contents have disappeared. It | 442 // since the edit contents have disappeared. It |
443 // doesn't really matter, but we clear it to be | 443 // doesn't really matter, but we clear it to be |
444 // consistent. | 444 // consistent. |
445 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint"), profile_); | 445 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint"), profile_); |
446 return true; | 446 return true; |
447 } | 447 } |
448 | 448 |
449 void AutocompleteEditModel::ClearKeyword(const std::wstring& visible_text) { | 449 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { |
450 view_->OnBeforePossibleChange(); | 450 view_->OnBeforePossibleChange(); |
451 const std::wstring window_text(keyword_ + visible_text); | 451 const string16 window_text(keyword_ + visible_text); |
452 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); | 452 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); |
453 keyword_.clear(); | 453 keyword_.clear(); |
454 is_keyword_hint_ = false; | 454 is_keyword_hint_ = false; |
455 view_->OnAfterPossibleChange(); | 455 view_->OnAfterPossibleChange(); |
456 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | 456 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this |
457 // since the edit contents have actually grown | 457 // since the edit contents have actually grown |
458 // longer. | 458 // longer. |
459 } | 459 } |
460 | 460 |
461 bool AutocompleteEditModel::query_in_progress() const { | 461 bool AutocompleteEditModel::query_in_progress() const { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 // should force it to open immediately. | 559 // should force it to open immediately. |
560 } | 560 } |
561 } else { | 561 } else { |
562 // The popup is open, so the user should be able to interact with it | 562 // The popup is open, so the user should be able to interact with it |
563 // normally. | 563 // normally. |
564 popup_->Move(count); | 564 popup_->Move(count); |
565 } | 565 } |
566 } | 566 } |
567 | 567 |
568 void AutocompleteEditModel::OnPopupDataChanged( | 568 void AutocompleteEditModel::OnPopupDataChanged( |
569 const std::wstring& text, | 569 const string16& text, |
570 GURL* destination_for_temporary_text_change, | 570 GURL* destination_for_temporary_text_change, |
571 const std::wstring& keyword, | 571 const string16& keyword, |
572 bool is_keyword_hint) { | 572 bool is_keyword_hint) { |
573 // Update keyword/hint-related local state. | 573 // Update keyword/hint-related local state. |
574 bool keyword_state_changed = (keyword_ != keyword) || | 574 bool keyword_state_changed = (keyword_ != keyword) || |
575 ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); | 575 ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); |
576 if (keyword_state_changed) { | 576 if (keyword_state_changed) { |
577 keyword_ = keyword; | 577 keyword_ = keyword; |
578 is_keyword_hint_ = is_keyword_hint; | 578 is_keyword_hint_ = is_keyword_hint; |
579 | 579 |
580 // |is_keyword_hint_| should always be false if |keyword_| is empty. | 580 // |is_keyword_hint_| should always be false if |keyword_| is empty. |
581 DCHECK(!keyword_.empty() || !is_keyword_hint_); | 581 DCHECK(!keyword_.empty() || !is_keyword_hint_); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 DisplayTextFromUserText(user_text_).length())) | 615 DisplayTextFromUserText(user_text_).length())) |
616 return; | 616 return; |
617 | 617 |
618 // All other code paths that return invoke OnChanged. We need to invoke | 618 // All other code paths that return invoke OnChanged. We need to invoke |
619 // OnChanged in case the destination url changed (as could happen when control | 619 // OnChanged in case the destination url changed (as could happen when control |
620 // is toggled). | 620 // is toggled). |
621 controller_->OnChanged(); | 621 controller_->OnChanged(); |
622 } | 622 } |
623 | 623 |
624 bool AutocompleteEditModel::OnAfterPossibleChange( | 624 bool AutocompleteEditModel::OnAfterPossibleChange( |
625 const std::wstring& new_text, | 625 const string16& new_text, |
626 bool selection_differs, | 626 bool selection_differs, |
627 bool text_differs, | 627 bool text_differs, |
628 bool just_deleted_text, | 628 bool just_deleted_text, |
629 bool allow_keyword_ui_change) { | 629 bool allow_keyword_ui_change) { |
630 // Update the paste state as appropriate: if we're just finishing a paste | 630 // Update the paste state as appropriate: if we're just finishing a paste |
631 // that replaced all the text, preserve that information; otherwise, if we've | 631 // that replaced all the text, preserve that information; otherwise, if we've |
632 // made some other edit, clear paste tracking. | 632 // made some other edit, clear paste tracking. |
633 if (paste_state_ == PASTING) | 633 if (paste_state_ == PASTING) |
634 paste_state_ = PASTED; | 634 paste_state_ = PASTED; |
635 else if (text_differs) | 635 else if (text_differs) |
(...skipping 12 matching lines...) Expand all Loading... |
648 if (!text_differs && !popup_->IsOpen()) | 648 if (!text_differs && !popup_->IsOpen()) |
649 return false; // Don't open the popup for no reason. | 649 return false; // Don't open the popup for no reason. |
650 } else if (!user_text_changed) { | 650 } else if (!user_text_changed) { |
651 return false; | 651 return false; |
652 } | 652 } |
653 | 653 |
654 // If the user text has not changed, we do not want to change the model's | 654 // If the user text has not changed, we do not want to change the model's |
655 // state associated with the text. Otherwise, we can get surprising behavior | 655 // state associated with the text. Otherwise, we can get surprising behavior |
656 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 | 656 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 |
657 if (user_text_changed) { | 657 if (user_text_changed) { |
658 const std::wstring new_user_text = UserTextFromDisplayText(new_text); | 658 const string16 new_user_text = UserTextFromDisplayText(new_text); |
659 | 659 |
660 // Try to accept the current keyword if the user only typed a space at the | 660 // Try to accept the current keyword if the user only typed a space at the |
661 // end of content. Model's state and popup will be updated when the keyword | 661 // end of content. Model's state and popup will be updated when the keyword |
662 // is accepted. So we just need to return false here. | 662 // is accepted. So we just need to return false here. |
663 if (allow_keyword_ui_change && !selection_differs && | 663 if (allow_keyword_ui_change && !selection_differs && |
664 MaybeAcceptKeywordBySpace(new_user_text)) | 664 MaybeAcceptKeywordBySpace(new_user_text)) |
665 return false; | 665 return false; |
666 | 666 |
667 InternalSetUserText(new_user_text); | 667 InternalSetUserText(new_user_text); |
668 has_temporary_text_ = false; | 668 has_temporary_text_ = false; |
(...skipping 29 matching lines...) Expand all Loading... |
698 return false; | 698 return false; |
699 } | 699 } |
700 } | 700 } |
701 | 701 |
702 void AutocompleteEditModel::Observe(NotificationType type, | 702 void AutocompleteEditModel::Observe(NotificationType type, |
703 const NotificationSource& source, | 703 const NotificationSource& source, |
704 const NotificationDetails& details) { | 704 const NotificationDetails& details) { |
705 DCHECK_EQ(NotificationType::AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED, | 705 DCHECK_EQ(NotificationType::AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED, |
706 type.value); | 706 type.value); |
707 | 707 |
708 std::wstring inline_autocomplete_text; | 708 string16 inline_autocomplete_text; |
709 std::wstring keyword; | 709 string16 keyword; |
710 bool is_keyword_hint = false; | 710 bool is_keyword_hint = false; |
711 const AutocompleteResult* result = | 711 const AutocompleteResult* result = |
712 Details<const AutocompleteResult>(details).ptr(); | 712 Details<const AutocompleteResult>(details).ptr(); |
713 const AutocompleteResult::const_iterator match(result->default_match()); | 713 const AutocompleteResult::const_iterator match(result->default_match()); |
714 if (match != result->end()) { | 714 if (match != result->end()) { |
715 if ((match->inline_autocomplete_offset != std::wstring::npos) && | 715 if ((match->inline_autocomplete_offset != string16::npos) && |
716 (match->inline_autocomplete_offset < match->fill_into_edit.length())) { | 716 (match->inline_autocomplete_offset < match->fill_into_edit.length())) { |
717 inline_autocomplete_text = | 717 inline_autocomplete_text = |
718 match->fill_into_edit.substr(match->inline_autocomplete_offset); | 718 match->fill_into_edit.substr(match->inline_autocomplete_offset); |
719 } | 719 } |
720 | 720 |
721 if (!match->destination_url.SchemeIs(chrome::kExtensionScheme)) { | 721 if (!match->destination_url.SchemeIs(chrome::kExtensionScheme)) { |
722 // Warm up DNS Prefetch cache, or preconnect to a search service. | 722 // Warm up DNS Prefetch cache, or preconnect to a search service. |
723 chrome_browser_net::AnticipateOmniboxUrl(match->destination_url, | 723 chrome_browser_net::AnticipateOmniboxUrl(match->destination_url, |
724 IsPreconnectable(match->type)); | 724 IsPreconnectable(match->type)); |
725 } | 725 } |
726 | 726 |
727 // We could prefetch the alternate nav URL, if any, but because there | 727 // We could prefetch the alternate nav URL, if any, but because there |
728 // can be many of these as a user types an initial series of characters, | 728 // can be many of these as a user types an initial series of characters, |
729 // the OS DNS cache could suffer eviction problems for minimal gain. | 729 // the OS DNS cache could suffer eviction problems for minimal gain. |
730 | 730 |
731 is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); | 731 is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); |
732 } | 732 } |
733 | 733 |
734 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, is_keyword_hint); | 734 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, is_keyword_hint); |
735 } | 735 } |
736 | 736 |
737 void AutocompleteEditModel::InternalSetUserText(const std::wstring& text) { | 737 void AutocompleteEditModel::InternalSetUserText(const string16& text) { |
738 user_text_ = text; | 738 user_text_ = text; |
739 just_deleted_text_ = false; | 739 just_deleted_text_ = false; |
740 inline_autocomplete_text_.clear(); | 740 inline_autocomplete_text_.clear(); |
741 } | 741 } |
742 | 742 |
743 bool AutocompleteEditModel::KeywordIsSelected() const { | 743 bool AutocompleteEditModel::KeywordIsSelected() const { |
744 return !is_keyword_hint_ && !keyword_.empty(); | 744 return !is_keyword_hint_ && !keyword_.empty(); |
745 } | 745 } |
746 | 746 |
747 std::wstring AutocompleteEditModel::DisplayTextFromUserText( | 747 string16 AutocompleteEditModel::DisplayTextFromUserText( |
748 const std::wstring& text) const { | 748 const string16& text) const { |
749 return KeywordIsSelected() ? | 749 return KeywordIsSelected() ? |
750 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 750 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
751 } | 751 } |
752 | 752 |
753 std::wstring AutocompleteEditModel::UserTextFromDisplayText( | 753 string16 AutocompleteEditModel::UserTextFromDisplayText( |
754 const std::wstring& text) const { | 754 const string16& text) const { |
755 return KeywordIsSelected() ? (keyword_ + L" " + text) : text; | 755 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
756 } | 756 } |
757 | 757 |
758 void AutocompleteEditModel::GetInfoForCurrentText( | 758 void AutocompleteEditModel::GetInfoForCurrentText( |
759 AutocompleteMatch* match, | 759 AutocompleteMatch* match, |
760 GURL* alternate_nav_url) const { | 760 GURL* alternate_nav_url) const { |
761 if (popup_->IsOpen() || query_in_progress()) { | 761 if (popup_->IsOpen() || query_in_progress()) { |
762 popup_->InfoForCurrentSelection(match, alternate_nav_url); | 762 popup_->InfoForCurrentSelection(match, alternate_nav_url); |
763 } else { | 763 } else { |
764 profile_->GetAutocompleteClassifier()->Classify( | 764 profile_->GetAutocompleteClassifier()->Classify( |
765 UserTextFromDisplayText(view_->GetText()), GetDesiredTLD(), true, | 765 UserTextFromDisplayText(view_->GetText()), GetDesiredTLD(), true, |
766 match, alternate_nav_url); | 766 match, alternate_nav_url); |
767 } | 767 } |
768 } | 768 } |
769 | 769 |
770 bool AutocompleteEditModel::GetURLForText(const std::wstring& text, | 770 bool AutocompleteEditModel::GetURLForText(const string16& text, |
771 GURL* url) const { | 771 GURL* url) const { |
772 GURL parsed_url; | 772 GURL parsed_url; |
773 const AutocompleteInput::Type type = AutocompleteInput::Parse( | 773 const AutocompleteInput::Type type = AutocompleteInput::Parse( |
774 UserTextFromDisplayText(text), std::wstring(), NULL, NULL, &parsed_url); | 774 UserTextFromDisplayText(text), string16(), NULL, NULL, &parsed_url); |
775 if (type != AutocompleteInput::URL) | 775 if (type != AutocompleteInput::URL) |
776 return false; | 776 return false; |
777 | 777 |
778 *url = parsed_url; | 778 *url = parsed_url; |
779 return true; | 779 return true; |
780 } | 780 } |
781 | 781 |
782 bool AutocompleteEditModel::MaybeAcceptKeywordBySpace( | 782 bool AutocompleteEditModel::MaybeAcceptKeywordBySpace( |
783 const std::wstring& new_user_text) { | 783 const string16& new_user_text) { |
784 return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() && | 784 return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() && |
785 inline_autocomplete_text_.empty() && !user_text_.empty() && | 785 inline_autocomplete_text_.empty() && !user_text_.empty() && |
786 (new_user_text.length() == user_text_.length() + 1) && | 786 (new_user_text.length() == user_text_.length() + 1) && |
787 !new_user_text.compare(0, user_text_.length(), user_text_) && | 787 !new_user_text.compare(0, user_text_.length(), user_text_) && |
788 IsSpaceCharForAcceptingKeyword(new_user_text[user_text_.length()]) && | 788 IsSpaceCharForAcceptingKeyword(new_user_text[user_text_.length()]) && |
789 !IsWhitespace(user_text_[user_text_.length() - 1]) && | 789 !IsWhitespace(user_text_[user_text_.length() - 1]) && |
790 AcceptKeyword(); | 790 AcceptKeyword(); |
791 } | 791 } |
792 | 792 |
793 // static | 793 // static |
794 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 794 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
795 switch (c) { | 795 switch (c) { |
796 case 0x0020: // Space | 796 case 0x0020: // Space |
797 case 0x3000: // Ideographic Space | 797 case 0x3000: // Ideographic Space |
798 return true; | 798 return true; |
799 default: | 799 default: |
800 return false; | 800 return false; |
801 } | 801 } |
802 } | 802 } |
OLD | NEW |