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/browser/ui/omnibox/omnibox_edit_model.h" | 5 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 void OmniboxEditModel::SetUserText(const string16& text) { | 220 void OmniboxEditModel::SetUserText(const string16& text) { |
221 SetInputInProgress(true); | 221 SetInputInProgress(true); |
222 InternalSetUserText(text); | 222 InternalSetUserText(text); |
223 paste_state_ = NONE; | 223 paste_state_ = NONE; |
224 has_temporary_text_ = false; | 224 has_temporary_text_ = false; |
225 is_temporary_text_set_by_instant_ = false; | 225 is_temporary_text_set_by_instant_ = false; |
226 selected_instant_autocomplete_match_index_ = OmniboxPopupModel::kNoMatch; | 226 selected_instant_autocomplete_match_index_ = OmniboxPopupModel::kNoMatch; |
227 is_instant_temporary_text_a_search_query_ = false; | 227 is_instant_temporary_text_a_search_query_ = false; |
228 } | 228 } |
229 | 229 |
230 void OmniboxEditModel::FinalizeInstantQuery(const string16& input_text, | 230 void OmniboxEditModel::FinalizeInstantQuery( |
231 const InstantSuggestion& suggestion, | 231 const string16& input_text, |
232 bool skip_inline_autocomplete) { | 232 const InstantSuggestion& suggestion) { |
233 if (skip_inline_autocomplete) { | 233 if (popup_model()->IsOpen()) { |
234 const string16 final_text = input_text + suggestion.text; | |
235 view_->OnBeforePossibleChange(); | |
236 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, | |
237 false); | |
238 view_->OnAfterPossibleChange(); | |
239 } else if (popup_model()->IsOpen()) { | |
240 SearchProvider* search_provider = | 234 SearchProvider* search_provider = |
241 autocomplete_controller()->search_provider(); | 235 autocomplete_controller()->search_provider(); |
242 // There may be no providers during testing; guard against that. | 236 // There may be no providers during testing; guard against that. |
243 if (search_provider) | 237 if (search_provider) |
244 search_provider->FinalizeInstantQuery(input_text, suggestion); | 238 search_provider->FinalizeInstantQuery(input_text, suggestion); |
245 } | 239 } |
246 } | 240 } |
247 | 241 |
248 void OmniboxEditModel::SetInstantSuggestion( | 242 void OmniboxEditModel::SetInstantSuggestion( |
249 const InstantSuggestion& suggestion) { | 243 const InstantSuggestion& suggestion) { |
250 switch (suggestion.behavior) { | 244 switch (suggestion.behavior) { |
251 case INSTANT_COMPLETE_NOW: | 245 case INSTANT_COMPLETE_NOW: |
252 view_->SetInstantSuggestion(string16()); | 246 view_->SetInstantSuggestion(string16()); |
253 if (!suggestion.text.empty()) | 247 if (!suggestion.text.empty()) |
254 FinalizeInstantQuery(view_->GetText(), suggestion, false); | 248 FinalizeInstantQuery(view_->GetText(), suggestion); |
255 break; | 249 break; |
256 | 250 |
257 case INSTANT_COMPLETE_NEVER: { | 251 case INSTANT_COMPLETE_NEVER: { |
258 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); | 252 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); |
259 view_->SetInstantSuggestion(suggestion.text); | 253 view_->SetInstantSuggestion(suggestion.text); |
260 autocomplete_controller()->search_provider()->ClearInstantSuggestion(); | 254 SearchProvider* search_provider = |
255 autocomplete_controller()->search_provider(); | |
256 if (search_provider) | |
257 search_provider->ClearInstantSuggestion(); | |
sreeram
2013/05/29 15:40:24
As mentioned in a previous CL, I don't think there
beaudoin
2013/05/29 16:19:41
Sorry, probably a rebase issue.
Done.
| |
261 break; | 258 break; |
262 } | 259 } |
263 | 260 |
264 case INSTANT_COMPLETE_REPLACE: { | 261 case INSTANT_COMPLETE_REPLACE: { |
265 const bool save_original_selection = !has_temporary_text_; | 262 const bool save_original_selection = !has_temporary_text_; |
266 view_->SetInstantSuggestion(string16()); | 263 view_->SetInstantSuggestion(string16()); |
267 has_temporary_text_ = true; | 264 has_temporary_text_ = true; |
268 is_temporary_text_set_by_instant_ = true; | 265 is_temporary_text_set_by_instant_ = true; |
269 selected_instant_autocomplete_match_index_ = | 266 selected_instant_autocomplete_match_index_ = |
270 suggestion.autocomplete_match_index; | 267 suggestion.autocomplete_match_index; |
271 is_instant_temporary_text_a_search_query_ = | 268 is_instant_temporary_text_a_search_query_ = |
272 suggestion.type == INSTANT_SUGGESTION_SEARCH; | 269 suggestion.type == INSTANT_SUGGESTION_SEARCH; |
273 // Instant suggestions are never a keyword. | 270 // Instant suggestions are never a keyword. |
274 keyword_ = string16(); | 271 keyword_ = string16(); |
275 is_keyword_hint_ = false; | 272 is_keyword_hint_ = false; |
276 view_->OnTemporaryTextMaybeChanged(suggestion.text, | 273 view_->OnTemporaryTextMaybeChanged(suggestion.text, |
277 save_original_selection, true); | 274 save_original_selection, true); |
278 break; | 275 break; |
279 } | 276 } |
280 } | 277 } |
281 } | 278 } |
282 | 279 |
283 bool OmniboxEditModel::CommitSuggestedText(bool skip_inline_autocomplete) { | 280 bool OmniboxEditModel::CommitSuggestedText() { |
284 if (!controller_->GetInstant()) | 281 if (!GetInstantController()) |
285 return false; | 282 return false; |
sreeram
2013/05/29 15:40:24
We don't need this check, I think. (It wasn't need
beaudoin
2013/05/29 16:19:41
Done.
| |
286 | 283 |
287 const string16 suggestion = view_->GetInstantSuggestion(); | 284 const string16 suggestion = view_->GetInstantSuggestion(); |
288 if (suggestion.empty()) | 285 if (suggestion.empty()) |
289 return false; | 286 return false; |
290 | 287 |
291 // Assume that the gray text we are committing is a search suggestion. | 288 // Assume that the gray text we are committing is a search suggestion. |
292 FinalizeInstantQuery(view_->GetText(), | 289 const string16 final_text = view_->GetText() + suggestion; |
293 InstantSuggestion(suggestion, | 290 view_->OnBeforePossibleChange(); |
294 INSTANT_COMPLETE_NOW, | 291 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, |
295 INSTANT_SUGGESTION_SEARCH, | 292 false); |
296 string16(), | 293 view_->OnAfterPossibleChange(); |
297 OmniboxPopupModel::kNoMatch), | |
298 skip_inline_autocomplete); | |
299 return true; | 294 return true; |
300 } | 295 } |
301 | 296 |
302 void OmniboxEditModel::OnChanged() { | 297 void OmniboxEditModel::OnChanged() { |
303 // Don't call CurrentMatch() when there's no editing, as in this case we'll | 298 // Don't call CurrentMatch() when there's no editing, as in this case we'll |
304 // never actually use it. This avoids running the autocomplete providers (and | 299 // never actually use it. This avoids running the autocomplete providers (and |
305 // any systems they then spin up) during startup. | 300 // any systems they then spin up) during startup. |
306 const AutocompleteMatch& current_match = user_input_in_progress_ ? | 301 const AutocompleteMatch& current_match = user_input_in_progress_ ? |
307 CurrentMatch() : AutocompleteMatch(); | 302 CurrentMatch() : AutocompleteMatch(); |
308 | 303 |
(...skipping 11 matching lines...) Expand all Loading... | |
320 // before it's needed. Note: This event is triggered as part of startup when | 315 // before it's needed. Note: This event is triggered as part of startup when |
321 // the initial tab transitions to the start page. | 316 // the initial tab transitions to the start page. |
322 recommended_action = | 317 recommended_action = |
323 action_predictor->RecommendAction(user_text_, current_match); | 318 action_predictor->RecommendAction(user_text_, current_match); |
324 } | 319 } |
325 | 320 |
326 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.Action", | 321 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.Action", |
327 recommended_action, | 322 recommended_action, |
328 AutocompleteActionPredictor::LAST_PREDICT_ACTION); | 323 AutocompleteActionPredictor::LAST_PREDICT_ACTION); |
329 | 324 |
330 if (!DoInstant(current_match)) { | 325 // Do not perform instant if we're currently reverting or the change is the |
326 // result of an INSTANT_COMPLETE_REPLACE instant suggestion. | |
327 bool performed_instant = false; | |
328 if (!in_revert_ && !is_temporary_text_set_by_instant_) { | |
329 size_t start, end; | |
330 view_->GetSelectionBounds(&start, &end); | |
331 string16 user_text = has_temporary_text_ ? current_match.fill_into_edit : | |
332 DisplayTextFromUserText(user_text_); | |
333 performed_instant = omnibox_controller_->DoInstant( | |
334 current_match, user_text, view_->GetText(), start, end, | |
335 user_input_in_progress_, in_escape_handler_, | |
336 view_->DeleteAtEndPressed() || just_deleted_text_, | |
337 KeywordIsSelected()); | |
338 } | |
339 | |
340 if (!performed_instant) { | |
331 // Hide any suggestions we might be showing. | 341 // Hide any suggestions we might be showing. |
332 view_->SetInstantSuggestion(string16()); | 342 view_->SetInstantSuggestion(string16()); |
333 | 343 |
334 // No need to wait any longer for Instant. | 344 // No need to wait any longer for Instant. |
335 FinalizeInstantQuery(string16(), InstantSuggestion(), false); | 345 FinalizeInstantQuery(string16(), InstantSuggestion()); |
336 } | 346 } |
337 | 347 |
338 switch (recommended_action) { | 348 switch (recommended_action) { |
339 case AutocompleteActionPredictor::ACTION_PRERENDER: | 349 case AutocompleteActionPredictor::ACTION_PRERENDER: |
340 // It's possible that there is no current page, for instance if the tab | 350 // It's possible that there is no current page, for instance if the tab |
341 // has been closed or on return from a sleep state. | 351 // has been closed or on return from a sleep state. |
342 // (http://crbug.com/105689) | 352 // (http://crbug.com/105689) |
343 if (!delegate_->CurrentPageExists()) | 353 if (!delegate_->CurrentPageExists()) |
344 break; | 354 break; |
345 // Ask for prerendering if the destination URL is different than the | 355 // Ask for prerendering if the destination URL is different than the |
(...skipping 17 matching lines...) Expand all Loading... | |
363 AutocompleteMatch match; | 373 AutocompleteMatch match; |
364 GetInfoForCurrentText(&match, NULL); | 374 GetInfoForCurrentText(&match, NULL); |
365 *url = match.destination_url; | 375 *url = match.destination_url; |
366 if (*url == URLFixerUpper::FixupURL(UTF16ToUTF8(permanent_text_), | 376 if (*url == URLFixerUpper::FixupURL(UTF16ToUTF8(permanent_text_), |
367 std::string())) { | 377 std::string())) { |
368 *title = controller_->GetTitle(); | 378 *title = controller_->GetTitle(); |
369 *favicon = controller_->GetFavicon(); | 379 *favicon = controller_->GetFavicon(); |
370 } | 380 } |
371 } | 381 } |
372 | 382 |
373 bool OmniboxEditModel::UseVerbatimInstant() { | |
374 #if defined(OS_MACOSX) | |
375 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, | |
376 // so that we can display Instant suggest along with composition text. | |
377 const AutocompleteInput& input = autocomplete_controller()->input(); | |
378 if (input.prevent_inline_autocomplete()) | |
379 return true; | |
380 #endif | |
381 | |
382 // The value of input.prevent_inline_autocomplete() is determined by the | |
383 // following conditions: | |
384 // 1. If the caret is at the end of the text. | |
385 // 2. If it's in IME composition mode. | |
386 // We send the caret position to Instant (so it can determine #1 itself), and | |
387 // we use a separated widget for displaying the Instant suggest (so it doesn't | |
388 // interfere with #2). So, we don't need to care about the value of | |
389 // input.prevent_inline_autocomplete() here. | |
390 return view_->DeleteAtEndPressed() || popup_model()->selected_line() != 0 || | |
391 just_deleted_text_; | |
392 } | |
393 | |
394 bool OmniboxEditModel::CurrentTextIsURL() const { | 383 bool OmniboxEditModel::CurrentTextIsURL() const { |
395 if (view_->toolbar_model()->GetSearchTermsType() != | 384 if (view_->toolbar_model()->GetSearchTermsType() != |
396 ToolbarModel::NO_SEARCH_TERMS) | 385 ToolbarModel::NO_SEARCH_TERMS) |
397 return false; | 386 return false; |
398 | 387 |
399 // If current text is not composed of replaced search terms and | 388 // If current text is not composed of replaced search terms and |
400 // !user_input_in_progress_, then permanent text is showing and should be a | 389 // !user_input_in_progress_, then permanent text is showing and should be a |
401 // URL, so no further checking is needed. By avoiding checking in this case, | 390 // URL, so no further checking is needed. By avoiding checking in this case, |
402 // we avoid calling into the autocomplete providers, and thus initializing the | 391 // we avoid calling into the autocomplete providers, and thus initializing the |
403 // history system, as long as possible, which speeds startup. | 392 // history system, as long as possible, which speeds startup. |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
495 false, true); | 484 false, true); |
496 AutocompleteActionPredictor* action_predictor = | 485 AutocompleteActionPredictor* action_predictor = |
497 AutocompleteActionPredictorFactory::GetForProfile(profile_); | 486 AutocompleteActionPredictorFactory::GetForProfile(profile_); |
498 if (action_predictor) | 487 if (action_predictor) |
499 action_predictor->ClearTransitionalMatches(); | 488 action_predictor->ClearTransitionalMatches(); |
500 } | 489 } |
501 | 490 |
502 void OmniboxEditModel::StartAutocomplete( | 491 void OmniboxEditModel::StartAutocomplete( |
503 bool has_selected_text, | 492 bool has_selected_text, |
504 bool prevent_inline_autocomplete) const { | 493 bool prevent_inline_autocomplete) const { |
505 omnibox_controller_->ClearPopupKeywordMode(); | |
506 | |
507 bool keyword_is_selected = KeywordIsSelected(); | |
508 popup_model()->SetHoveredLine(OmniboxPopupModel::kNoMatch); | |
509 | |
510 size_t cursor_position; | 494 size_t cursor_position; |
511 if (inline_autocomplete_text_.empty()) { | 495 if (inline_autocomplete_text_.empty()) { |
512 // Cursor position is equivalent to the current selection's end. | 496 // Cursor position is equivalent to the current selection's end. |
513 size_t start; | 497 size_t start; |
514 view_->GetSelectionBounds(&start, &cursor_position); | 498 view_->GetSelectionBounds(&start, &cursor_position); |
515 // Adjust cursor position taking into account possible keyword in the user | 499 // Adjust cursor position taking into account possible keyword in the user |
516 // text. We rely on DisplayTextFromUserText() method which is consistent | 500 // text. We rely on DisplayTextFromUserText() method which is consistent |
517 // with keyword extraction done in KeywordProvider/SearchProvider. | 501 // with keyword extraction done in KeywordProvider/SearchProvider. |
518 const size_t cursor_offset = | 502 const size_t cursor_offset = |
519 user_text_.length() - DisplayTextFromUserText(user_text_).length(); | 503 user_text_.length() - DisplayTextFromUserText(user_text_).length(); |
520 cursor_position += cursor_offset; | 504 cursor_position += cursor_offset; |
521 } else { | 505 } else { |
522 // There are some cases where StartAutocomplete() may be called | 506 // There are some cases where StartAutocomplete() may be called |
523 // with non-empty |inline_autocomplete_text_|. In such cases, we cannot | 507 // with non-empty |inline_autocomplete_text_|. In such cases, we cannot |
524 // use the current selection, because it could result with the cursor | 508 // use the current selection, because it could result with the cursor |
525 // position past the last character from the user text. Instead, | 509 // position past the last character from the user text. Instead, |
526 // we assume that the cursor is simply at the end of input. | 510 // we assume that the cursor is simply at the end of input. |
527 // One example is when user presses Ctrl key while having a highlighted | 511 // One example is when user presses Ctrl key while having a highlighted |
528 // inline autocomplete text. | 512 // inline autocomplete text. |
529 // TODO: Rethink how we are going to handle this case to avoid | 513 // TODO: Rethink how we are going to handle this case to avoid |
530 // inconsistent behavior when user presses Ctrl key. | 514 // inconsistent behavior when user presses Ctrl key. |
531 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. | 515 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. |
532 cursor_position = user_text_.length(); | 516 cursor_position = user_text_.length(); |
533 } | 517 } |
534 | 518 |
535 InstantController* instant = controller_->GetInstant(); | 519 bool keyword_is_selected = KeywordIsSelected(); |
536 if (instant) { | 520 omnibox_controller_->StartAutocomplete( |
537 instant->OnAutocompleteStart(); | 521 user_text_, |
538 // If the embedded page for InstantExtended is fetching its own suggestions, | 522 cursor_position, |
539 // suppress search suggestions from SearchProvider. We still need | |
540 // SearchProvider to run for FinalizeInstantQuery. | |
541 // TODO(dcblack): Once we are done refactoring the omnibox so we don't need | |
542 // to use FinalizeInstantQuery anymore, we can take out this check and | |
543 // remove this provider from kInstantExtendedOmniboxProviders. | |
544 if (instant->WillFetchCompletions()) | |
545 autocomplete_controller()->search_provider()->SuppressSearchSuggestions(); | |
546 } | |
547 | |
548 // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as | |
549 // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. | |
550 autocomplete_controller()->Start(AutocompleteInput( | |
551 user_text_, cursor_position, string16(), GURL(), | |
552 prevent_inline_autocomplete || just_deleted_text_ || | 523 prevent_inline_autocomplete || just_deleted_text_ || |
553 (has_selected_text && inline_autocomplete_text_.empty()) || | 524 (has_selected_text && inline_autocomplete_text_.empty()) || |
554 (paste_state_ != NONE), keyword_is_selected, | 525 (paste_state_ != NONE), |
555 keyword_is_selected || allow_exact_keyword_match_, | 526 keyword_is_selected, |
556 AutocompleteInput::ALL_MATCHES)); | 527 keyword_is_selected || allow_exact_keyword_match_); |
557 } | 528 } |
558 | 529 |
559 void OmniboxEditModel::StopAutocomplete() { | 530 void OmniboxEditModel::StopAutocomplete() { |
560 autocomplete_controller()->Stop(true); | 531 autocomplete_controller()->Stop(true); |
561 } | 532 } |
562 | 533 |
563 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const { | 534 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const { |
564 if (!view_->command_updater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) | 535 if (!view_->command_updater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) |
565 return false; | 536 return false; |
566 | 537 |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
758 const GURL destination_url = autocomplete_controller()-> | 729 const GURL destination_url = autocomplete_controller()-> |
759 GetDestinationURL(match, query_formulation_time); | 730 GetDestinationURL(match, query_formulation_time); |
760 | 731 |
761 // If running with instant, notify the instant controller that a navigation | 732 // If running with instant, notify the instant controller that a navigation |
762 // is about to take place if we are navigating to a URL. This can be | 733 // is about to take place if we are navigating to a URL. This can be |
763 // determined by inspecting the transition type. To ensure that this is only | 734 // determined by inspecting the transition type. To ensure that this is only |
764 // done on Enter key press, check that the disposition is CURRENT_TAB. This | 735 // done on Enter key press, check that the disposition is CURRENT_TAB. This |
765 // is the same heuristic used by BrowserInstantController::OpenInstant | 736 // is the same heuristic used by BrowserInstantController::OpenInstant |
766 if (match.transition == content::PAGE_TRANSITION_TYPED && | 737 if (match.transition == content::PAGE_TRANSITION_TYPED && |
767 disposition == CURRENT_TAB) { | 738 disposition == CURRENT_TAB) { |
768 InstantController* instant = controller_->GetInstant(); | 739 InstantController* instant = GetInstantController(); |
769 if (instant) | 740 if (instant) |
sreeram
2013/05/29 15:40:24
Why not use the pattern as before:
if (GetInstan
beaudoin
2013/05/29 16:19:41
Reverted to this pattern everywhere, so it should
| |
770 instant->OmniboxNavigateToURL(); | 741 instant->OmniboxNavigateToURL(); |
771 } | 742 } |
772 | 743 |
773 // This calls RevertAll again. | 744 // This calls RevertAll again. |
774 base::AutoReset<bool> tmp(&in_revert_, true); | 745 base::AutoReset<bool> tmp(&in_revert_, true); |
775 controller_->OnAutocompleteAccept(destination_url, disposition, | 746 controller_->OnAutocompleteAccept(destination_url, disposition, |
776 match.transition, alternate_nav_url); | 747 match.transition, alternate_nav_url); |
777 } | 748 } |
778 | 749 |
779 if (match.starred) | 750 if (match.starred) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
870 | 841 |
871 void OmniboxEditModel::SetCaretVisibility(bool visible) { | 842 void OmniboxEditModel::SetCaretVisibility(bool visible) { |
872 // Caret visibility only matters if the omnibox has focus. | 843 // Caret visibility only matters if the omnibox has focus. |
873 if (focus_state_ != OMNIBOX_FOCUS_NONE) { | 844 if (focus_state_ != OMNIBOX_FOCUS_NONE) { |
874 SetFocusState(visible ? OMNIBOX_FOCUS_VISIBLE : OMNIBOX_FOCUS_INVISIBLE, | 845 SetFocusState(visible ? OMNIBOX_FOCUS_VISIBLE : OMNIBOX_FOCUS_INVISIBLE, |
875 OMNIBOX_FOCUS_CHANGE_EXPLICIT); | 846 OMNIBOX_FOCUS_CHANGE_EXPLICIT); |
876 } | 847 } |
877 } | 848 } |
878 | 849 |
879 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { | 850 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { |
880 InstantController* instant = controller_->GetInstant(); | 851 InstantController* instant = GetInstantController(); |
881 if (instant) { | 852 if (instant) { |
882 instant->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE, | 853 instant->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE, |
883 OMNIBOX_FOCUS_CHANGE_EXPLICIT, | 854 OMNIBOX_FOCUS_CHANGE_EXPLICIT, |
884 view_gaining_focus); | 855 view_gaining_focus); |
885 } | 856 } |
886 | 857 |
887 // TODO(jered): Rip this out along with StartZeroSuggest. | 858 // TODO(jered): Rip this out along with StartZeroSuggest. |
888 autocomplete_controller()->StopZeroSuggest(); | 859 autocomplete_controller()->StopZeroSuggest(); |
889 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_, | 860 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_, |
890 popup_model()->IsOpen(), user_text_.empty()); | 861 popup_model()->IsOpen(), user_text_.empty()); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
972 // TODO(pkasting): We should, in fact, force this particular query to open | 943 // TODO(pkasting): We should, in fact, force this particular query to open |
973 // the popup immediately. | 944 // the popup immediately. |
974 if (!user_input_in_progress_) | 945 if (!user_input_in_progress_) |
975 InternalSetUserText(permanent_text_); | 946 InternalSetUserText(permanent_text_); |
976 view_->UpdatePopup(); | 947 view_->UpdatePopup(); |
977 } else { | 948 } else { |
978 // TODO(pkasting): The popup is working on a query but is not open. We | 949 // TODO(pkasting): The popup is working on a query but is not open. We |
979 // should force it to open immediately. | 950 // should force it to open immediately. |
980 } | 951 } |
981 } else { | 952 } else { |
982 InstantController* instant = controller_->GetInstant(); | 953 InstantController* instant = GetInstantController(); |
983 if (instant && instant->OnUpOrDownKeyPressed(count)) { | 954 if (instant && instant->OnUpOrDownKeyPressed(count)) { |
984 // If Instant handles the key press, it's showing a list of suggestions | 955 // If Instant handles the key press, it's showing a list of suggestions |
985 // that it's stepping through. In that case, our popup model is | 956 // that it's stepping through. In that case, our popup model is |
986 // irrelevant, so don't process the key press ourselves. However, do stop | 957 // irrelevant, so don't process the key press ourselves. However, do stop |
987 // the autocomplete system from changing the results. | 958 // the autocomplete system from changing the results. |
988 autocomplete_controller()->Stop(false); | 959 autocomplete_controller()->Stop(false); |
989 } else { | 960 } else { |
990 // The popup is open, so the user should be able to interact with it | 961 // The popup is open, so the user should be able to interact with it |
991 // normally. | 962 // normally. |
992 popup_model()->Move(count); | 963 popup_model()->Move(count); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1173 // will have updated our state already, so in that case we don't also return | 1144 // will have updated our state already, so in that case we don't also return |
1174 // true from this function. | 1145 // true from this function. |
1175 return !(text_differs && allow_keyword_ui_change && !just_deleted_text && | 1146 return !(text_differs && allow_keyword_ui_change && !just_deleted_text && |
1176 no_selection && (selection_start == user_text_.length()) && | 1147 no_selection && (selection_start == user_text_.length()) && |
1177 MaybeAcceptKeywordBySpace(user_text_)); | 1148 MaybeAcceptKeywordBySpace(user_text_)); |
1178 } | 1149 } |
1179 | 1150 |
1180 void OmniboxEditModel::OnResultChanged(bool default_match_changed) { | 1151 void OmniboxEditModel::OnResultChanged(bool default_match_changed) { |
1181 } | 1152 } |
1182 | 1153 |
1154 InstantController* OmniboxEditModel::GetInstantController() const { | |
1155 return controller_->GetInstant(); | |
1156 } | |
1157 | |
1183 bool OmniboxEditModel::query_in_progress() const { | 1158 bool OmniboxEditModel::query_in_progress() const { |
1184 return !autocomplete_controller()->done(); | 1159 return !autocomplete_controller()->done(); |
1185 } | 1160 } |
1186 | 1161 |
1187 void OmniboxEditModel::InternalSetUserText(const string16& text) { | 1162 void OmniboxEditModel::InternalSetUserText(const string16& text) { |
1188 user_text_ = text; | 1163 user_text_ = text; |
1189 just_deleted_text_ = false; | 1164 just_deleted_text_ = false; |
1190 inline_autocomplete_text_.clear(); | 1165 inline_autocomplete_text_.clear(); |
1191 } | 1166 } |
1192 | 1167 |
1193 bool OmniboxEditModel::KeywordIsSelected() const { | 1168 bool OmniboxEditModel::KeywordIsSelected() const { |
1194 return !is_keyword_hint_ && !keyword_.empty(); | 1169 return !is_keyword_hint_ && !keyword_.empty(); |
1195 } | 1170 } |
1196 | 1171 |
1172 void OmniboxEditModel::ClearPopupKeywordMode() const { | |
1173 omnibox_controller_->ClearPopupKeywordMode(); | |
1174 } | |
1175 | |
1197 string16 OmniboxEditModel::DisplayTextFromUserText(const string16& text) const { | 1176 string16 OmniboxEditModel::DisplayTextFromUserText(const string16& text) const { |
1198 return KeywordIsSelected() ? | 1177 return KeywordIsSelected() ? |
1199 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 1178 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
1200 } | 1179 } |
1201 | 1180 |
1202 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const { | 1181 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const { |
1203 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; | 1182 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
1204 } | 1183 } |
1205 | 1184 |
1206 void OmniboxEditModel::GetInfoForCurrentText(AutocompleteMatch* match, | 1185 void OmniboxEditModel::GetInfoForCurrentText(AutocompleteMatch* match, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1301 // The user typed something, then selected a different item. Restore the | 1280 // The user typed something, then selected a different item. Restore the |
1302 // text they typed and change back to the default item. | 1281 // text they typed and change back to the default item. |
1303 // NOTE: This purposefully does not reset paste_state_. | 1282 // NOTE: This purposefully does not reset paste_state_. |
1304 bool notify_instant = is_temporary_text_set_by_instant_; | 1283 bool notify_instant = is_temporary_text_set_by_instant_; |
1305 just_deleted_text_ = false; | 1284 just_deleted_text_ = false; |
1306 has_temporary_text_ = false; | 1285 has_temporary_text_ = false; |
1307 is_temporary_text_set_by_instant_ = false; | 1286 is_temporary_text_set_by_instant_ = false; |
1308 selected_instant_autocomplete_match_index_ = OmniboxPopupModel::kNoMatch; | 1287 selected_instant_autocomplete_match_index_ = OmniboxPopupModel::kNoMatch; |
1309 is_instant_temporary_text_a_search_query_ = false; | 1288 is_instant_temporary_text_a_search_query_ = false; |
1310 | 1289 |
1311 InstantController* instant = controller_->GetInstant(); | 1290 InstantController* instant = GetInstantController(); |
1312 if (instant && notify_instant) { | 1291 if (instant && notify_instant) { |
1313 // Normally, popup_->ResetToDefaultMatch() will cause the view text to be | 1292 // Normally, popup_->ResetToDefaultMatch() will cause the view text to be |
1314 // updated. In Instant Extended mode however, the popup_ is not used, so it | 1293 // updated. In Instant Extended mode however, the popup_ is not used, so it |
1315 // won't do anything. So, update the view ourselves. Even if Instant is not | 1294 // won't do anything. So, update the view ourselves. Even if Instant is not |
1316 // in extended mode (i.e., it's enabled in non-extended mode, or disabled | 1295 // in extended mode (i.e., it's enabled in non-extended mode, or disabled |
1317 // altogether), this is okay to do, since the call to | 1296 // altogether), this is okay to do, since the call to |
1318 // popup_->ResetToDefaultMatch() will just override whatever we do here. | 1297 // popup_->ResetToDefaultMatch() will just override whatever we do here. |
1319 // | 1298 // |
1320 // The two "false" arguments make sure that our shenanigans don't cause any | 1299 // The two "false" arguments make sure that our shenanigans don't cause any |
1321 // previously saved selection to be erased nor OnChanged() to be called. | 1300 // previously saved selection to be erased nor OnChanged() to be called. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1365 // Then check if the text before the inserted space matches a keyword. | 1344 // Then check if the text before the inserted space matches a keyword. |
1366 string16 keyword; | 1345 string16 keyword; |
1367 TrimWhitespace(new_text.substr(0, space_position), TRIM_LEADING, &keyword); | 1346 TrimWhitespace(new_text.substr(0, space_position), TRIM_LEADING, &keyword); |
1368 // TODO(sreeram): Once the Instant extended API supports keywords properly, | 1347 // TODO(sreeram): Once the Instant extended API supports keywords properly, |
1369 // keyword_provider() should never be NULL. Remove that clause. | 1348 // keyword_provider() should never be NULL. Remove that clause. |
1370 return !keyword.empty() && autocomplete_controller()->keyword_provider() && | 1349 return !keyword.empty() && autocomplete_controller()->keyword_provider() && |
1371 !autocomplete_controller()->keyword_provider()-> | 1350 !autocomplete_controller()->keyword_provider()-> |
1372 GetKeywordForText(keyword).empty(); | 1351 GetKeywordForText(keyword).empty(); |
1373 } | 1352 } |
1374 | 1353 |
1375 bool OmniboxEditModel::DoInstant(const AutocompleteMatch& match) { | |
1376 InstantController* instant = controller_->GetInstant(); | |
1377 if (!instant || in_revert_) | |
1378 return false; | |
1379 | |
1380 // Don't call Update() if the change is the result of an | |
1381 // INSTANT_COMPLETE_REPLACE instant suggestion. | |
1382 if (is_temporary_text_set_by_instant_) | |
1383 return false; | |
1384 | |
1385 // The two pieces of text we want to send Instant, viz., what the user has | |
1386 // typed, and the full omnibox text including any inline autocompletion. | |
1387 string16 user_text = has_temporary_text_ ? | |
1388 match.fill_into_edit : DisplayTextFromUserText(user_text_); | |
1389 string16 full_text = view_->GetText(); | |
1390 | |
1391 // Remove "?" if we're in forced query mode. | |
1392 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | |
1393 autocomplete_controller()->input().type(), &user_text); | |
1394 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | |
1395 autocomplete_controller()->input().type(), &full_text); | |
1396 | |
1397 size_t start, end; | |
1398 view_->GetSelectionBounds(&start, &end); | |
1399 | |
1400 return instant->Update(match, user_text, full_text, start, end, | |
1401 UseVerbatimInstant(), user_input_in_progress_, popup_model()->IsOpen(), | |
1402 in_escape_handler_, KeywordIsSelected()); | |
1403 } | |
1404 | |
1405 // static | 1354 // static |
1406 bool OmniboxEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 1355 bool OmniboxEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
1407 switch (c) { | 1356 switch (c) { |
1408 case 0x0020: // Space | 1357 case 0x0020: // Space |
1409 case 0x3000: // Ideographic Space | 1358 case 0x3000: // Ideographic Space |
1410 return true; | 1359 return true; |
1411 default: | 1360 default: |
1412 return false; | 1361 return false; |
1413 } | 1362 } |
1414 } | 1363 } |
(...skipping 19 matching lines...) Expand all Loading... | |
1434 DCHECK(match); | 1383 DCHECK(match); |
1435 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify(text, | 1384 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify(text, |
1436 false, false, match, alternate_nav_url); | 1385 false, false, match, alternate_nav_url); |
1437 } | 1386 } |
1438 | 1387 |
1439 void OmniboxEditModel::SetFocusState(OmniboxFocusState state, | 1388 void OmniboxEditModel::SetFocusState(OmniboxFocusState state, |
1440 OmniboxFocusChangeReason reason) { | 1389 OmniboxFocusChangeReason reason) { |
1441 if (state == focus_state_) | 1390 if (state == focus_state_) |
1442 return; | 1391 return; |
1443 | 1392 |
1444 InstantController* instant = controller_->GetInstant(); | 1393 InstantController* instant = GetInstantController(); |
1445 if (instant) | 1394 if (instant) |
1446 instant->OmniboxFocusChanged(state, reason, NULL); | 1395 instant->OmniboxFocusChanged(state, reason, NULL); |
1447 | 1396 |
1448 // Update state and notify view if the omnibox has focus and the caret | 1397 // Update state and notify view if the omnibox has focus and the caret |
1449 // visibility changed. | 1398 // visibility changed. |
1450 const bool was_caret_visible = is_caret_visible(); | 1399 const bool was_caret_visible = is_caret_visible(); |
1451 focus_state_ = state; | 1400 focus_state_ = state; |
1452 if (focus_state_ != OMNIBOX_FOCUS_NONE && | 1401 if (focus_state_ != OMNIBOX_FOCUS_NONE && |
1453 is_caret_visible() != was_caret_visible) | 1402 is_caret_visible() != was_caret_visible) |
1454 view_->ApplyCaretVisibility(); | 1403 view_->ApplyCaretVisibility(); |
1455 } | 1404 } |
OLD | NEW |