Delays find-in-page until IME composition is committed.

We shouldn't do find-in-page while a IME is composing.  This CL delays the actual search until the IME composition is committed.

BUG=158911
TEST=Test manually.

Review URL: https://chromiumcodereview.appspot.com/15841009

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203936 0039d316-1c4b-4281-b951-d872f2087c98
parent 5d7dc513
......@@ -396,6 +396,60 @@ void FindBarView::ButtonPressed(
void FindBarView::ContentsChanged(views::Textfield* sender,
const string16& new_contents) {
// TextfieldController::OnAfterUserAction() is supported only by Views
// implementation, and NativeTextfieldWin doesn't call OnAfterUserAction().
// Call Find() here.
// TODO(yukishiino): Remove this code after the migration to Views.
if (!views::Textfield::IsViewsTextfieldEnabled())
Find(new_contents);
}
bool FindBarView::HandleKeyEvent(views::Textfield* sender,
const ui::KeyEvent& key_event) {
// If the dialog is not visible, there is no reason to process keyboard input.
if (!host()->IsVisible())
return false;
if (find_bar_host()->MaybeForwardKeyEventToWebpage(key_event))
return true; // Handled, we are done!
if (key_event.key_code() == ui::VKEY_RETURN) {
// Pressing Return/Enter starts the search (unless text box is empty).
string16 find_string = find_text_->text();
if (!find_string.empty()) {
FindBarController* controller = find_bar_host()->GetFindBarController();
FindTabHelper* find_tab_helper =
FindTabHelper::FromWebContents(controller->web_contents());
// Search forwards for enter, backwards for shift-enter.
find_tab_helper->StartFinding(find_string,
!key_event.IsShiftDown(),
false); // Not case sensitive.
}
return true;
}
return false;
}
void FindBarView::OnAfterUserAction(views::Textfield* sender) {
// The composition text wouldn't be what the user is really looking for.
// We delay the search until the user commits the composition text.
if (sender->IsIMEComposing() || sender->text() == last_searched_text_)
return;
// TODO(yukishiino): Remove this condition check after the migration to Views.
if (views::Textfield::IsViewsTextfieldEnabled())
Find(sender->text());
}
void FindBarView::OnAfterPaste() {
// Clear the last search text so we always search for the user input after
// a paste operation, even if the pasted text is the same as before.
// See http://crbug.com/79002
last_searched_text_.clear();
}
void FindBarView::Find(const string16& search_text) {
FindBarController* controller = find_bar_host()->GetFindBarController();
DCHECK(controller);
content::WebContents* web_contents = controller->web_contents();
......@@ -406,12 +460,14 @@ void FindBarView::ContentsChanged(views::Textfield* sender,
return;
FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents);
last_searched_text_ = search_text;
// When the user changes something in the text box we check the contents and
// if the textbox contains something we set it as the new search string and
// initiate search (even though old searches might be in progress).
if (!new_contents.empty()) {
if (!search_text.empty()) {
// The last two params here are forward (true) and case sensitive (false).
find_tab_helper->StartFinding(new_contents, true, false);
find_tab_helper->StartFinding(search_text, true, false);
} else {
find_tab_helper->StopFinding(FindBarController::kClearSelectionOnPage);
UpdateForResult(find_tab_helper->find_result(), string16());
......@@ -429,33 +485,6 @@ void FindBarView::ContentsChanged(views::Textfield* sender,
}
}
bool FindBarView::HandleKeyEvent(views::Textfield* sender,
const ui::KeyEvent& key_event) {
// If the dialog is not visible, there is no reason to process keyboard input.
if (!host()->IsVisible())
return false;
if (find_bar_host()->MaybeForwardKeyEventToWebpage(key_event))
return true; // Handled, we are done!
if (key_event.key_code() == ui::VKEY_RETURN) {
// Pressing Return/Enter starts the search (unless text box is empty).
string16 find_string = find_text_->text();
if (!find_string.empty()) {
FindBarController* controller = find_bar_host()->GetFindBarController();
FindTabHelper* find_tab_helper =
FindTabHelper::FromWebContents(controller->web_contents());
// Search forwards for enter, backwards for shift-enter.
find_tab_helper->StartFinding(find_string,
!key_event.IsShiftDown(),
false); // Not case sensitive.
}
return true;
}
return false;
}
void FindBarView::UpdateMatchCountAppearance(bool no_match) {
if (no_match) {
match_count_text_->SetBackgroundColor(kBackgroundColorNoMatch);
......
......@@ -80,9 +80,14 @@ class FindBarView : public DropdownBarView,
const string16& new_contents) OVERRIDE;
virtual bool HandleKeyEvent(views::Textfield* sender,
const ui::KeyEvent& key_event) OVERRIDE;
virtual void OnAfterUserAction(views::Textfield* sender) OVERRIDE;
virtual void OnAfterPaste() OVERRIDE;
private:
// Update the appearance for the match count label.
// Starts finding |search_text|. If the text is empty, stops finding.
void Find(const string16& search_text);
// Updates the appearance for the match count label.
void UpdateMatchCountAppearance(bool no_match);
// views::View:
......@@ -132,6 +137,10 @@ class FindBarView : public DropdownBarView,
// between us and the WebContentsView.
FindBarHost* find_bar_host() const;
// Used to detect if the input text, not including the IME composition text,
// has changed or not.
string16 last_searched_text_;
// The controls in the window.
SearchTextfieldView* find_text_;
views::Label* match_count_text_;
......
......@@ -1397,13 +1397,9 @@ bool NativeTextfieldViews::Paste() {
string16 new_text = GetTextForDisplay(GetText());
model_->SetText(new_text);
// Calls TextfieldController::ContentsChanged() explicitly if the paste
// action did not change the content at all. See http://crbug.com/79002
if (new_text == original_text) {
TextfieldController* controller = textfield_->GetController();
if (controller)
controller->ContentsChanged(textfield_, textfield_->text());
}
TextfieldController* controller = textfield_->GetController();
if (controller)
controller->OnAfterPaste();
}
return success;
}
......
......@@ -1063,6 +1063,8 @@ void NativeTextfieldWin::OnPaste() {
textfield_->SyncText();
text_before_change_.clear();
ReplaceSel(collapsed.c_str(), true);
if (TextfieldController* controller = textfield_->GetController())
controller->OnAfterPaste();
}
}
......
......@@ -9,6 +9,11 @@
namespace views {
bool TextfieldController::HandleKeyEvent(Textfield* sender,
const ui::KeyEvent& key_event) {
return false;
}
bool TextfieldController::HandleMouseEvent(Textfield* sender,
const ui::MouseEvent& mouse_event) {
return false;
......
......@@ -29,13 +29,13 @@ class VIEWS_EXPORT TextfieldController {
// user. It won't be called if the text is changed by calling
// Textfield::SetText() or Textfield::AppendText().
virtual void ContentsChanged(Textfield* sender,
const string16& new_contents) = 0;
const string16& new_contents) {}
// This method is called to get notified about keystrokes in the edit.
// Returns true if the message was handled and should not be processed
// further. If it returns false the processing continues.
virtual bool HandleKeyEvent(Textfield* sender,
const ui::KeyEvent& key_event) = 0;
const ui::KeyEvent& key_event);
// This method is called to get notified about mouse events in the edit.
// Returns true if the message was handled and should not be processed
......@@ -54,6 +54,9 @@ class VIEWS_EXPORT TextfieldController {
// Called after performing a Cut or Copy operation.
virtual void OnAfterCutOrCopy() {}
// Called after performing a Paste operation.
virtual void OnAfterPaste() {}
// Called after the textfield has written drag data to give the controller a
// chance to modify the drag data.
virtual void OnWriteDragData(ui::OSExchangeData* data) {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment