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( ...@@ -396,6 +396,60 @@ void FindBarView::ButtonPressed(
void FindBarView::ContentsChanged(views::Textfield* sender, void FindBarView::ContentsChanged(views::Textfield* sender,
const string16& new_contents) { 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(); FindBarController* controller = find_bar_host()->GetFindBarController();
DCHECK(controller); DCHECK(controller);
content::WebContents* web_contents = controller->web_contents(); content::WebContents* web_contents = controller->web_contents();
...@@ -406,12 +460,14 @@ void FindBarView::ContentsChanged(views::Textfield* sender, ...@@ -406,12 +460,14 @@ void FindBarView::ContentsChanged(views::Textfield* sender,
return; return;
FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents); 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 // 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 // if the textbox contains something we set it as the new search string and
// initiate search (even though old searches might be in progress). // 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). // 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 { } else {
find_tab_helper->StopFinding(FindBarController::kClearSelectionOnPage); find_tab_helper->StopFinding(FindBarController::kClearSelectionOnPage);
UpdateForResult(find_tab_helper->find_result(), string16()); UpdateForResult(find_tab_helper->find_result(), string16());
...@@ -429,33 +485,6 @@ void FindBarView::ContentsChanged(views::Textfield* sender, ...@@ -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) { void FindBarView::UpdateMatchCountAppearance(bool no_match) {
if (no_match) { if (no_match) {
match_count_text_->SetBackgroundColor(kBackgroundColorNoMatch); match_count_text_->SetBackgroundColor(kBackgroundColorNoMatch);
......
...@@ -80,9 +80,14 @@ class FindBarView : public DropdownBarView, ...@@ -80,9 +80,14 @@ class FindBarView : public DropdownBarView,
const string16& new_contents) OVERRIDE; const string16& new_contents) OVERRIDE;
virtual bool HandleKeyEvent(views::Textfield* sender, virtual bool HandleKeyEvent(views::Textfield* sender,
const ui::KeyEvent& key_event) OVERRIDE; const ui::KeyEvent& key_event) OVERRIDE;
virtual void OnAfterUserAction(views::Textfield* sender) OVERRIDE;
virtual void OnAfterPaste() OVERRIDE;
private: 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); void UpdateMatchCountAppearance(bool no_match);
// views::View: // views::View:
...@@ -132,6 +137,10 @@ class FindBarView : public DropdownBarView, ...@@ -132,6 +137,10 @@ class FindBarView : public DropdownBarView,
// between us and the WebContentsView. // between us and the WebContentsView.
FindBarHost* find_bar_host() const; 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. // The controls in the window.
SearchTextfieldView* find_text_; SearchTextfieldView* find_text_;
views::Label* match_count_text_; views::Label* match_count_text_;
......
...@@ -1397,13 +1397,9 @@ bool NativeTextfieldViews::Paste() { ...@@ -1397,13 +1397,9 @@ bool NativeTextfieldViews::Paste() {
string16 new_text = GetTextForDisplay(GetText()); string16 new_text = GetTextForDisplay(GetText());
model_->SetText(new_text); model_->SetText(new_text);
// Calls TextfieldController::ContentsChanged() explicitly if the paste TextfieldController* controller = textfield_->GetController();
// action did not change the content at all. See http://crbug.com/79002 if (controller)
if (new_text == original_text) { controller->OnAfterPaste();
TextfieldController* controller = textfield_->GetController();
if (controller)
controller->ContentsChanged(textfield_, textfield_->text());
}
} }
return success; return success;
} }
......
...@@ -1063,6 +1063,8 @@ void NativeTextfieldWin::OnPaste() { ...@@ -1063,6 +1063,8 @@ void NativeTextfieldWin::OnPaste() {
textfield_->SyncText(); textfield_->SyncText();
text_before_change_.clear(); text_before_change_.clear();
ReplaceSel(collapsed.c_str(), true); ReplaceSel(collapsed.c_str(), true);
if (TextfieldController* controller = textfield_->GetController())
controller->OnAfterPaste();
} }
} }
......
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
namespace views { namespace views {
bool TextfieldController::HandleKeyEvent(Textfield* sender,
const ui::KeyEvent& key_event) {
return false;
}
bool TextfieldController::HandleMouseEvent(Textfield* sender, bool TextfieldController::HandleMouseEvent(Textfield* sender,
const ui::MouseEvent& mouse_event) { const ui::MouseEvent& mouse_event) {
return false; return false;
......
...@@ -29,13 +29,13 @@ class VIEWS_EXPORT TextfieldController { ...@@ -29,13 +29,13 @@ class VIEWS_EXPORT TextfieldController {
// user. It won't be called if the text is changed by calling // user. It won't be called if the text is changed by calling
// Textfield::SetText() or Textfield::AppendText(). // Textfield::SetText() or Textfield::AppendText().
virtual void ContentsChanged(Textfield* sender, 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. // This method is called to get notified about keystrokes in the edit.
// Returns true if the message was handled and should not be processed // Returns true if the message was handled and should not be processed
// further. If it returns false the processing continues. // further. If it returns false the processing continues.
virtual bool HandleKeyEvent(Textfield* sender, 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. // 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 // Returns true if the message was handled and should not be processed
...@@ -54,6 +54,9 @@ class VIEWS_EXPORT TextfieldController { ...@@ -54,6 +54,9 @@ class VIEWS_EXPORT TextfieldController {
// Called after performing a Cut or Copy operation. // Called after performing a Cut or Copy operation.
virtual void OnAfterCutOrCopy() {} 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 // Called after the textfield has written drag data to give the controller a
// chance to modify the drag data. // chance to modify the drag data.
virtual void OnWriteDragData(ui::OSExchangeData* 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