Commit 973842b7 authored by msw's avatar msw Committed by Commit bot

Focus and trail cursor on Views Textfield selection clipboard paste.

Focus the textfield as needed (even with an empty clipboard).

Leave the cursor trailing the newly pasted text.
(don't restore and offset the prior cursor/selection)

Update and expand tests.

BUG=456581
TEST=Linux textfield/omnibox middle-click behaves as expected.
R=pkasting@chromium.org

Review URL: https://codereview.chromium.org/927743002

Cr-Commit-Position: refs/heads/master@{#316374}
parent c4a76234
...@@ -28,6 +28,14 @@ ...@@ -28,6 +28,14 @@
#include "ui/events/test/event_generator.h" #include "ui/events/test/event_generator.h"
#include "ui/views/controls/textfield/textfield_test_api.h" #include "ui/views/controls/textfield/textfield_test_api.h"
namespace {
void SetClipboardText(ui::ClipboardType type, const std::string& text) {
ui::ScopedClipboardWriter(type).WriteText(base::ASCIIToUTF16(text));
}
} // namespace
class OmniboxViewViewsTest : public InProcessBrowserTest { class OmniboxViewViewsTest : public InProcessBrowserTest {
protected: protected:
OmniboxViewViewsTest() {} OmniboxViewViewsTest() {}
...@@ -106,10 +114,7 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, PasteAndGoDoesNotLeavePopupOpen) { ...@@ -106,10 +114,7 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, PasteAndGoDoesNotLeavePopupOpen) {
OmniboxViewViews* omnibox_view_views = static_cast<OmniboxViewViews*>(view); OmniboxViewViews* omnibox_view_views = static_cast<OmniboxViewViews*>(view);
// Put an URL on the clipboard. // Put an URL on the clipboard.
{ SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "http://www.example.com/");
ui::ScopedClipboardWriter clipboard_writer(ui::CLIPBOARD_TYPE_COPY_PASTE);
clipboard_writer.WriteURL(base::ASCIIToUTF16("http://www.example.com/"));
}
// Paste and go. // Paste and go.
omnibox_view_views->ExecuteCommand(IDS_PASTE_AND_GO, ui::EF_NONE); omnibox_view_views->ExecuteCommand(IDS_PASTE_AND_GO, ui::EF_NONE);
...@@ -165,14 +170,65 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnClick) { ...@@ -165,14 +170,65 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnClick) {
EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
EXPECT_FALSE(omnibox_view->IsSelectAll()); EXPECT_FALSE(omnibox_view->IsSelectAll());
// Middle-clicking should not be handled by the omnibox. // Middle-click is only handled on Linux, by pasting the selection clipboard
// and moving the cursor after the pasted text instead of selecting-all.
ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter()); ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter());
ASSERT_NO_FATAL_FAILURE(Click(ui_controls::MIDDLE, ASSERT_NO_FATAL_FAILURE(Click(ui_controls::MIDDLE,
click_location, click_location)); click_location, click_location));
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
EXPECT_FALSE(omnibox_view->IsSelectAll());
#else
EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
EXPECT_FALSE(omnibox_view->IsSelectAll()); EXPECT_FALSE(omnibox_view->IsSelectAll());
#endif // OS_LINUX && !OS_CHROMEOS
} }
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectionClipboard) {
OmniboxView* omnibox_view = NULL;
ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view));
omnibox_view->SetUserText(base::ASCIIToUTF16("http://www.google.com/"));
OmniboxViewViews* omnibox_view_views =
static_cast<OmniboxViewViews*>(omnibox_view);
ASSERT_TRUE(omnibox_view_views);
gfx::RenderText* render_text = omnibox_view_views->GetRenderText();
// Take the focus away from the omnibox.
ASSERT_NO_FATAL_FAILURE(TapBrowserWindowCenter());
EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
EXPECT_FALSE(omnibox_view->IsSelectAll());
size_t cursor_position = 14;
int cursor_x = render_text->GetCursorBounds(
gfx::SelectionModel(cursor_position, gfx::CURSOR_FORWARD), false).x();
gfx::Point click_location = omnibox_view_views->GetBoundsInScreen().origin();
click_location.Offset(cursor_x + render_text->display_rect().x(),
omnibox_view_views->height() / 2);
// Middle click focuses the omnibox, pastes, and sets a trailing cursor.
// Select-all on focus shouldn't alter the selection clipboard or cursor.
SetClipboardText(ui::CLIPBOARD_TYPE_SELECTION, "123");
ASSERT_NO_FATAL_FAILURE(Click(ui_controls::MIDDLE,
click_location, click_location));
EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
EXPECT_FALSE(omnibox_view->IsSelectAll());
EXPECT_EQ(base::ASCIIToUTF16("http://www.goo123gle.com/"),
omnibox_view->GetText());
EXPECT_EQ(17U, omnibox_view_views->GetCursorPosition());
// Middle clicking again, with focus, pastes and updates the cursor.
SetClipboardText(ui::CLIPBOARD_TYPE_SELECTION, "4567");
ASSERT_NO_FATAL_FAILURE(Click(ui_controls::MIDDLE,
click_location, click_location));
EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
EXPECT_FALSE(omnibox_view->IsSelectAll());
EXPECT_EQ(base::ASCIIToUTF16("http://www.goo4567123gle.com/"),
omnibox_view->GetText());
EXPECT_EQ(18U, omnibox_view_views->GetCursorPosition());
}
#endif // OS_LINUX && !OS_CHROMEOS
IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnTap) { IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnTap) {
OmniboxView* omnibox_view = NULL; OmniboxView* omnibox_view = NULL;
ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view)); ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view));
...@@ -302,13 +358,8 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, ...@@ -302,13 +358,8 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest,
OmniboxViewViews* omnibox_view_views = static_cast<OmniboxViewViews*>(view); OmniboxViewViews* omnibox_view_views = static_cast<OmniboxViewViews*>(view);
views::TextfieldTestApi textfield_test_api(omnibox_view_views); views::TextfieldTestApi textfield_test_api(omnibox_view_views);
// Put a URL on the clipboard. It is written to the clipboard upon destruction // Put a URL on the clipboard.
// of the writer. SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "http://www.example.com/");
{
ui::ScopedClipboardWriter clipboard_writer(
ui::CLIPBOARD_TYPE_COPY_PASTE);
clipboard_writer.WriteURL(base::ASCIIToUTF16("http://www.example.com/"));
}
// Tap to activate touch editing. // Tap to activate touch editing.
gfx::Point omnibox_center = gfx::Point omnibox_center =
......
...@@ -1858,23 +1858,17 @@ void Textfield::PasteSelectionClipboard(const ui::MouseEvent& event) { ...@@ -1858,23 +1858,17 @@ void Textfield::PasteSelectionClipboard(const ui::MouseEvent& event) {
DCHECK(event.IsOnlyMiddleMouseButton()); DCHECK(event.IsOnlyMiddleMouseButton());
DCHECK(!read_only()); DCHECK(!read_only());
base::string16 selection_clipboard_text = GetSelectionClipboardText(); base::string16 selection_clipboard_text = GetSelectionClipboardText();
OnBeforeUserAction();
const gfx::SelectionModel mouse =
GetRenderText()->FindCursorPosition(event.location());
if (!HasFocus())
RequestFocus();
model_->MoveCursorTo(mouse);
if (!selection_clipboard_text.empty()) { if (!selection_clipboard_text.empty()) {
OnBeforeUserAction();
gfx::Range range = GetSelectionModel().selection();
gfx::LogicalCursorDirection affinity = GetSelectionModel().caret_affinity();
const gfx::SelectionModel mouse =
GetRenderText()->FindCursorPosition(event.location());
model_->MoveCursorTo(mouse);
model_->InsertText(selection_clipboard_text); model_->InsertText(selection_clipboard_text);
// Update the new selection range as needed.
if (range.GetMin() >= mouse.caret_pos()) {
const size_t length = selection_clipboard_text.length();
range = gfx::Range(range.start() + length, range.end() + length);
}
model_->MoveCursorTo(gfx::SelectionModel(range, affinity));
UpdateAfterChange(true, true); UpdateAfterChange(true, true);
OnAfterUserAction();
} }
OnAfterUserAction();
} }
} // namespace views } // namespace views
...@@ -1956,29 +1956,38 @@ TEST_F(TextfieldTest, DISABLED_SelectionClipboard) { ...@@ -1956,29 +1956,38 @@ TEST_F(TextfieldTest, DISABLED_SelectionClipboard) {
EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard()); EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard());
// Middle clicking should paste at the mouse (not cursor) location. // Middle clicking should paste at the mouse (not cursor) location.
// The cursor should be placed at the end of the pasted text.
ui::MouseEvent middle(ui::ET_MOUSE_PRESSED, point_4, point_4, ui::MouseEvent middle(ui::ET_MOUSE_PRESSED, point_4, point_4,
ui::EF_MIDDLE_MOUSE_BUTTON, ui::EF_MIDDLE_MOUSE_BUTTON); ui::EF_MIDDLE_MOUSE_BUTTON, ui::EF_MIDDLE_MOUSE_BUTTON);
textfield_->OnMousePressed(middle); textfield_->OnMousePressed(middle);
EXPECT_STR_EQ("01230123", textfield_->text()); EXPECT_STR_EQ("01230123", textfield_->text());
EXPECT_EQ(gfx::Range(0, 0), textfield_->GetSelectedRange()); EXPECT_EQ(gfx::Range(8, 8), textfield_->GetSelectedRange());
EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION)); EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
// Middle click pasting should adjust trailing cursors. // Middle clicking on an unfocused textfield should focus it and paste.
textfield_->SelectRange(gfx::Range(5, 5)); textfield_->GetFocusManager()->ClearFocus();
EXPECT_FALSE(textfield_->HasFocus());
textfield_->OnMousePressed(middle); textfield_->OnMousePressed(middle);
EXPECT_TRUE(textfield_->HasFocus());
EXPECT_STR_EQ("012301230123", textfield_->text()); EXPECT_STR_EQ("012301230123", textfield_->text());
EXPECT_EQ(gfx::Range(9, 9), textfield_->GetSelectedRange()); EXPECT_EQ(gfx::Range(8, 8), textfield_->GetSelectedRange());
EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
// Middle click pasting should adjust trailing selections. // Middle clicking with an empty selection clipboard should still focus.
textfield_->SelectRange(gfx::Range(7, 9)); SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, std::string());
textfield_->GetFocusManager()->ClearFocus();
EXPECT_FALSE(textfield_->HasFocus());
textfield_->OnMousePressed(middle); textfield_->OnMousePressed(middle);
EXPECT_STR_EQ("0123012301230123", textfield_->text()); EXPECT_TRUE(textfield_->HasFocus());
EXPECT_EQ(gfx::Range(11, 13), textfield_->GetSelectedRange()); EXPECT_STR_EQ("012301230123", textfield_->text());
EXPECT_EQ(gfx::Range(4, 4), textfield_->GetSelectedRange());
EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty());
// Middle clicking in the selection should clear the clipboard and selection. // Middle clicking in the selection should clear the clipboard and selection.
SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "foo");
textfield_->SelectRange(gfx::Range(2, 6)); textfield_->SelectRange(gfx::Range(2, 6));
textfield_->OnMousePressed(middle); textfield_->OnMousePressed(middle);
EXPECT_STR_EQ("0123012301230123", textfield_->text()); EXPECT_STR_EQ("012301230123", textfield_->text());
EXPECT_EQ(gfx::Range(6, 6), textfield_->GetSelectedRange()); EXPECT_EQ(gfx::Range(6, 6), textfield_->GetSelectedRange());
EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty()); EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty());
......
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