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

Side by Side Diff: chrome/browser/ui/omnibox/omnibox_edit_model.cc

Issue 1060613004: Fix a variety of omnibox bugs around zerosuggest, the escape key, or both. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Safer escape handling method Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 base::string16* text, 456 base::string16* text,
457 GURL* url, 457 GURL* url,
458 bool* write_url) { 458 bool* write_url) {
459 *write_url = false; 459 *write_url = false;
460 460
461 // Do not adjust if selection did not start at the beginning of the field, or 461 // Do not adjust if selection did not start at the beginning of the field, or
462 // if the URL was omitted. 462 // if the URL was omitted.
463 if ((sel_min != 0) || controller_->GetToolbarModel()->WouldReplaceURL()) 463 if ((sel_min != 0) || controller_->GetToolbarModel()->WouldReplaceURL())
464 return; 464 return;
465 465
466 if (!user_input_in_progress_ && is_all_selected) { 466 // Check whether the user is trying to copy the current page's URL by
467 // The user selected all the text and has not edited it. Use the url as the 467 // selecting the whole thing without editing it.
468 // text so that if the scheme was stripped it's added back, and the url 468 //
469 // is unescaped (we escape parts of the url for display). 469 // This is complicated by ZeroSuggest. When ZeroSuggest is active, the user
470 // may be selecting different items and thus changing the address bar text,
471 // even though !user_input_in_progress_; and the permanent URL may change
472 // without updating the visible text, just like when user input is in
473 // progress. In these cases, we don't want to copy the underlying URL, we
474 // want to copy what the user actually sees. However, if we simply never do
475 // this block when !popup_model()->IsOpen(), then just clicking into the
476 // address bar and trying to copy will always bypass this block on pages that
477 // trigger ZeroSuggest, which is too conservative. Instead, in the
478 // ZeroSuggest case, we check that (a) the user hasn't selected one of the
479 // other suggestions, and (b) the selected text is still the same as the
480 // permanent text. ((b) probably implies (a), but it doesn't hurt to be
481 // sure.) If these hold, then it's safe to copy the underlying URL.
482 if (!user_input_in_progress_ && is_all_selected &&
483 (!popup_model() || !popup_model()->IsOpen() ||
484 ((popup_model()->selected_line() == 0) && (*text == permanent_text_)))) {
485 // It's safe to copy the underlying URL. These lines ensure that if the
486 // scheme was stripped it's added back, and the URL is unescaped (we escape
487 // parts of it for display).
470 *url = PermanentURL(); 488 *url = PermanentURL();
471 *text = base::UTF8ToUTF16(url->spec()); 489 *text = base::UTF8ToUTF16(url->spec());
472 *write_url = true; 490 *write_url = true;
473 return; 491 return;
474 } 492 }
475 493
476 // We can't use CurrentTextIsURL() or GetDataForURLExport() because right now 494 // We can't use CurrentTextIsURL() or GetDataForURLExport() because right now
477 // the user is probably holding down control to cause the copy, which will 495 // the user is probably holding down control to cause the copy, which will
478 // screw up our calculation of the desired_tld. 496 // screw up our calculation of the desired_tld.
479 AutocompleteMatch match; 497 AutocompleteMatch match;
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 delegate_->OnInputStateChanged(); 996 delegate_->OnInputStateChanged();
979 } 997 }
980 998
981 void OmniboxEditModel::OnKillFocus() { 999 void OmniboxEditModel::OnKillFocus() {
982 SetFocusState(OMNIBOX_FOCUS_NONE, OMNIBOX_FOCUS_CHANGE_EXPLICIT); 1000 SetFocusState(OMNIBOX_FOCUS_NONE, OMNIBOX_FOCUS_CHANGE_EXPLICIT);
983 focus_source_ = INVALID; 1001 focus_source_ = INVALID;
984 control_key_state_ = UP; 1002 control_key_state_ = UP;
985 paste_state_ = NONE; 1003 paste_state_ = NONE;
986 } 1004 }
987 1005
1006 bool OmniboxEditModel::WillHandleEscapeKey() const {
1007 return user_input_in_progress_ ||
1008 (has_temporary_text_ &&
1009 (CurrentMatch(NULL).destination_url != original_url_));
1010 }
1011
988 bool OmniboxEditModel::OnEscapeKeyPressed() { 1012 bool OmniboxEditModel::OnEscapeKeyPressed() {
989 const AutocompleteMatch& match = CurrentMatch(NULL); 1013 if (has_temporary_text_ &&
990 if (has_temporary_text_) { 1014 (CurrentMatch(NULL).destination_url != original_url_)) {
991 if (match.destination_url != original_url_) { 1015 RevertTemporaryText(true);
992 RevertTemporaryText(true); 1016 return true;
993 return true;
994 }
995 } 1017 }
996 1018
997 // We do not clear the pending entry from the omnibox when a load is first 1019 // We do not clear the pending entry from the omnibox when a load is first
998 // stopped. If the user presses Escape while stopped, we clear it. 1020 // stopped. If the user presses Escape while stopped, whether editing or not,
1021 // we clear it.
999 if (delegate_->CurrentPageExists() && !delegate_->IsLoading()) { 1022 if (delegate_->CurrentPageExists() && !delegate_->IsLoading()) {
1000 delegate_->GetNavigationController().DiscardNonCommittedEntries(); 1023 delegate_->GetNavigationController().DiscardNonCommittedEntries();
1001 view_->Update(); 1024 view_->Update();
1002 } 1025 }
1003 1026
1004 // If the user wasn't editing, but merely had focus in the edit, allow <esc>
1005 // to be processed as an accelerator, so it can still be used to stop a load.
1006 // When the permanent text isn't all selected we still fall through to the
1007 // SelectAll() call below so users can arrow around in the text and then hit
1008 // <esc> to quickly replace all the text; this matches IE.
1009 const bool has_zero_suggest_match = match.provider &&
1010 (match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST);
1011 if (!has_zero_suggest_match && !user_input_in_progress_ &&
1012 view_->IsSelectAll())
1013 return false;
1014
1015 if (!user_text_.empty()) { 1027 if (!user_text_.empty()) {
1016 UMA_HISTOGRAM_ENUMERATION(kOmniboxUserTextClearedHistogram, 1028 UMA_HISTOGRAM_ENUMERATION(kOmniboxUserTextClearedHistogram,
1017 OMNIBOX_USER_TEXT_CLEARED_WITH_ESCAPE, 1029 OMNIBOX_USER_TEXT_CLEARED_WITH_ESCAPE,
1018 OMNIBOX_USER_TEXT_CLEARED_NUM_OF_ITEMS); 1030 OMNIBOX_USER_TEXT_CLEARED_NUM_OF_ITEMS);
1019 } 1031 }
1020 1032
1033 // Unconditionally revert/select all. This ensures any popup, whether due to
1034 // normal editing or zerosuggest, is closed, and the full text is selected.
H Fung 2015/04/07 00:38:23 ZeroSuggest to be consistent with earlier comments
Peter Kasting 2015/04/07 02:18:16 Done.
1035 // This latter allows the user to hit escape to quickly select all for ease of
H Fung 2015/04/07 00:38:23 This->The (I'm assuming you're referring to select
Peter Kasting 2015/04/07 02:18:16 I tweaked the comment slightly to read better.
1036 // replacement, and matches other browsers.
1037 bool user_input_was_in_progress = user_input_in_progress_;
1021 view_->RevertAll(); 1038 view_->RevertAll();
1022 view_->SelectAll(true); 1039 view_->SelectAll(true);
1023 return true; 1040
1041 // If the user was in the midst of editing, don't cancel any underlying page
1042 // load. This doesn't match IE or Firefox, but seems more correct. Note that
1043 // we do allow the page load to be stopped in the case where zerosuggest was
1044 // visible; this is so that it's still possible to focus the address bar and
1045 // hit escape once to stop a load even if the address being loaded triggers
1046 // the zerosuggest popup.
1047 return user_input_was_in_progress;
1024 } 1048 }
1025 1049
1026 void OmniboxEditModel::OnControlKeyChanged(bool pressed) { 1050 void OmniboxEditModel::OnControlKeyChanged(bool pressed) {
1027 if (pressed == (control_key_state_ == UP)) 1051 if (pressed == (control_key_state_ == UP))
1028 control_key_state_ = pressed ? DOWN_WITHOUT_CHANGE : UP; 1052 control_key_state_ = pressed ? DOWN_WITHOUT_CHANGE : UP;
1029 } 1053 }
1030 1054
1031 void OmniboxEditModel::OnPaste() { 1055 void OmniboxEditModel::OnPaste() {
1032 UMA_HISTOGRAM_COUNTS("Omnibox.Paste", 1); 1056 UMA_HISTOGRAM_COUNTS("Omnibox.Paste", 1);
1033 paste_state_ = PASTING; 1057 paste_state_ = PASTING;
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 // Update state and notify view if the omnibox has focus and the caret 1493 // Update state and notify view if the omnibox has focus and the caret
1470 // visibility changed. 1494 // visibility changed.
1471 const bool was_caret_visible = is_caret_visible(); 1495 const bool was_caret_visible = is_caret_visible();
1472 focus_state_ = state; 1496 focus_state_ = state;
1473 if (focus_state_ != OMNIBOX_FOCUS_NONE && 1497 if (focus_state_ != OMNIBOX_FOCUS_NONE &&
1474 is_caret_visible() != was_caret_visible) 1498 is_caret_visible() != was_caret_visible)
1475 view_->ApplyCaretVisibility(); 1499 view_->ApplyCaretVisibility();
1476 1500
1477 delegate_->OnFocusChanged(focus_state_, reason); 1501 delegate_->OnFocusChanged(focus_state_, reason);
1478 } 1502 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/omnibox/omnibox_edit_model.h ('k') | chrome/browser/ui/omnibox/omnibox_view_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698