OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "ui/views/controls/textfield/textfield.h" | 5 #include "ui/views/controls/textfield/textfield.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "ui/base/dragdrop/drag_drop_types.h" | 24 #include "ui/base/dragdrop/drag_drop_types.h" |
25 #include "ui/base/ime/text_input_client.h" | 25 #include "ui/base/ime/text_input_client.h" |
26 #include "ui/base/l10n/l10n_util.h" | 26 #include "ui/base/l10n/l10n_util.h" |
27 #include "ui/base/ui_base_switches.h" | 27 #include "ui/base/ui_base_switches.h" |
28 #include "ui/base/ui_base_switches_util.h" | 28 #include "ui/base/ui_base_switches_util.h" |
29 #include "ui/events/event.h" | 29 #include "ui/events/event.h" |
30 #include "ui/events/keycodes/keyboard_codes.h" | 30 #include "ui/events/keycodes/keyboard_codes.h" |
31 #include "ui/gfx/render_text.h" | 31 #include "ui/gfx/render_text.h" |
32 #include "ui/views/controls/textfield/textfield_controller.h" | 32 #include "ui/views/controls/textfield/textfield_controller.h" |
33 #include "ui/views/controls/textfield/textfield_model.h" | 33 #include "ui/views/controls/textfield/textfield_model.h" |
| 34 #include "ui/views/controls/textfield/textfield_test_api.h" |
34 #include "ui/views/focus/focus_manager.h" | 35 #include "ui/views/focus/focus_manager.h" |
35 #include "ui/views/ime/mock_input_method.h" | 36 #include "ui/views/ime/mock_input_method.h" |
36 #include "ui/views/test/test_views_delegate.h" | 37 #include "ui/views/test/test_views_delegate.h" |
37 #include "ui/views/test/views_test_base.h" | 38 #include "ui/views/test/views_test_base.h" |
38 #include "ui/views/widget/native_widget_private.h" | 39 #include "ui/views/widget/native_widget_private.h" |
39 #include "ui/views/widget/widget.h" | 40 #include "ui/views/widget/widget.h" |
40 #include "url/gurl.h" | 41 #include "url/gurl.h" |
41 | 42 |
42 #if defined(OS_WIN) | 43 #if defined(OS_WIN) |
43 #include "base/win/windows_version.h" | 44 #include "base/win/windows_version.h" |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 textfield_->set_controller(this); | 191 textfield_->set_controller(this); |
191 widget_ = new Widget(); | 192 widget_ = new Widget(); |
192 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 193 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
193 params.bounds = gfx::Rect(100, 100, 100, 100); | 194 params.bounds = gfx::Rect(100, 100, 100, 100); |
194 widget_->Init(params); | 195 widget_->Init(params); |
195 View* container = new View(); | 196 View* container = new View(); |
196 widget_->SetContentsView(container); | 197 widget_->SetContentsView(container); |
197 container->AddChildView(textfield_); | 198 container->AddChildView(textfield_); |
198 textfield_->SetBoundsRect(params.bounds); | 199 textfield_->SetBoundsRect(params.bounds); |
199 textfield_->set_id(1); | 200 textfield_->set_id(1); |
| 201 test_api_.reset(new TextfieldTestApi(textfield_)); |
200 | 202 |
201 for (int i = 1; i < count; i++) { | 203 for (int i = 1; i < count; i++) { |
202 Textfield* textfield = new Textfield(); | 204 Textfield* textfield = new Textfield(); |
203 container->AddChildView(textfield); | 205 container->AddChildView(textfield); |
204 textfield->set_id(i + 1); | 206 textfield->set_id(i + 1); |
205 } | 207 } |
206 | 208 |
207 model_ = textfield_->model_.get(); | 209 model_ = test_api_->model(); |
208 model_->ClearEditHistory(); | 210 model_->ClearEditHistory(); |
209 | 211 |
210 input_method_ = new MockInputMethod(); | 212 input_method_ = new MockInputMethod(); |
211 widget_->ReplaceInputMethod(input_method_); | 213 widget_->ReplaceInputMethod(input_method_); |
212 | 214 |
213 // Activate the widget and focus the textfield for input handling. | 215 // Activate the widget and focus the textfield for input handling. |
214 widget_->Activate(); | 216 widget_->Activate(); |
215 textfield_->RequestFocus(); | 217 textfield_->RequestFocus(); |
216 } | 218 } |
217 | 219 |
218 ui::MenuModel* GetContextMenuModel() { | 220 ui::MenuModel* GetContextMenuModel() { |
219 textfield_->UpdateContextMenu(); | 221 test_api_->UpdateContextMenu(); |
220 return textfield_->context_menu_contents_.get(); | 222 return test_api_->context_menu_contents(); |
221 } | |
222 | |
223 ui::TouchSelectionController* GetTouchSelectionController() { | |
224 return textfield_->touch_selection_controller_.get(); | |
225 } | 223 } |
226 | 224 |
227 protected: | 225 protected: |
228 void SendKeyEvent(ui::KeyboardCode key_code, | 226 void SendKeyEvent(ui::KeyboardCode key_code, |
229 bool alt, | 227 bool alt, |
230 bool shift, | 228 bool shift, |
231 bool control, | 229 bool control, |
232 bool caps_lock) { | 230 bool caps_lock) { |
233 int flags = (alt ? ui::EF_ALT_DOWN : 0) | | 231 int flags = (alt ? ui::EF_ALT_DOWN : 0) | |
234 (shift ? ui::EF_SHIFT_DOWN : 0) | | 232 (shift ? ui::EF_SHIFT_DOWN : 0) | |
(...skipping 22 matching lines...) Expand all Loading... |
257 event.set_character(ch); | 255 event.set_character(ch); |
258 input_method_->DispatchKeyEvent(event); | 256 input_method_->DispatchKeyEvent(event); |
259 } | 257 } |
260 } | 258 } |
261 | 259 |
262 View* GetFocusedView() { | 260 View* GetFocusedView() { |
263 return widget_->GetFocusManager()->GetFocusedView(); | 261 return widget_->GetFocusManager()->GetFocusedView(); |
264 } | 262 } |
265 | 263 |
266 int GetCursorPositionX(int cursor_pos) { | 264 int GetCursorPositionX(int cursor_pos) { |
267 return textfield_->GetRenderText()->GetCursorBounds( | 265 return test_api_->GetRenderText()->GetCursorBounds( |
268 gfx::SelectionModel(cursor_pos, gfx::CURSOR_FORWARD), false).x(); | 266 gfx::SelectionModel(cursor_pos, gfx::CURSOR_FORWARD), false).x(); |
269 } | 267 } |
270 | 268 |
271 // Get the current cursor bounds. | 269 // Get the current cursor bounds. |
272 gfx::Rect GetCursorBounds() { | 270 gfx::Rect GetCursorBounds() { |
273 return textfield_->GetRenderText()->GetUpdatedCursorBounds(); | 271 return test_api_->GetRenderText()->GetUpdatedCursorBounds(); |
274 } | 272 } |
275 | 273 |
276 // Get the cursor bounds of |sel|. | 274 // Get the cursor bounds of |sel|. |
277 gfx::Rect GetCursorBounds(const gfx::SelectionModel& sel) { | 275 gfx::Rect GetCursorBounds(const gfx::SelectionModel& sel) { |
278 return textfield_->GetRenderText()->GetCursorBounds(sel, true); | 276 return test_api_->GetRenderText()->GetCursorBounds(sel, true); |
279 } | 277 } |
280 | 278 |
281 gfx::Rect GetDisplayRect() { | 279 gfx::Rect GetDisplayRect() { |
282 return textfield_->GetRenderText()->display_rect(); | 280 return test_api_->GetRenderText()->display_rect(); |
283 } | 281 } |
284 | 282 |
285 // Mouse click on the point whose x-axis is |bound|'s x plus |x_offset| and | 283 // Mouse click on the point whose x-axis is |bound|'s x plus |x_offset| and |
286 // y-axis is in the middle of |bound|'s vertical range. | 284 // y-axis is in the middle of |bound|'s vertical range. |
287 void MouseClick(const gfx::Rect bound, int x_offset) { | 285 void MouseClick(const gfx::Rect bound, int x_offset) { |
288 gfx::Point point(bound.x() + x_offset, bound.y() + bound.height() / 2); | 286 gfx::Point point(bound.x() + x_offset, bound.y() + bound.height() / 2); |
289 ui::MouseEvent click(ui::ET_MOUSE_PRESSED, point, point, | 287 ui::MouseEvent click(ui::ET_MOUSE_PRESSED, point, point, |
290 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 288 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
291 textfield_->OnMousePressed(click); | 289 textfield_->OnMousePressed(click); |
292 ui::MouseEvent release(ui::ET_MOUSE_RELEASED, point, point, | 290 ui::MouseEvent release(ui::ET_MOUSE_RELEASED, point, point, |
(...skipping 24 matching lines...) Expand all Loading... |
317 menu->IsEnabledAt(4 /* PASTE */)); | 315 menu->IsEnabledAt(4 /* PASTE */)); |
318 EXPECT_EQ(textfield_has_selection, menu->IsEnabledAt(5 /* DELETE */)); | 316 EXPECT_EQ(textfield_has_selection, menu->IsEnabledAt(5 /* DELETE */)); |
319 EXPECT_TRUE(menu->IsEnabledAt(6 /* Separator */)); | 317 EXPECT_TRUE(menu->IsEnabledAt(6 /* Separator */)); |
320 EXPECT_TRUE(menu->IsEnabledAt(7 /* SELECT ALL */)); | 318 EXPECT_TRUE(menu->IsEnabledAt(7 /* SELECT ALL */)); |
321 } | 319 } |
322 | 320 |
323 // We need widget to populate wrapper class. | 321 // We need widget to populate wrapper class. |
324 Widget* widget_; | 322 Widget* widget_; |
325 | 323 |
326 TestTextfield* textfield_; | 324 TestTextfield* textfield_; |
| 325 scoped_ptr<TextfieldTestApi> test_api_; |
327 TextfieldModel* model_; | 326 TextfieldModel* model_; |
328 | 327 |
329 // The string from Controller::ContentsChanged callback. | 328 // The string from Controller::ContentsChanged callback. |
330 base::string16 last_contents_; | 329 base::string16 last_contents_; |
331 | 330 |
332 // For testing input method related behaviors. | 331 // For testing input method related behaviors. |
333 MockInputMethod* input_method_; | 332 MockInputMethod* input_method_; |
334 | 333 |
335 // Indicates how many times OnBeforeUserAction() is called. | 334 // Indicates how many times OnBeforeUserAction() is called. |
336 int on_before_user_action_; | 335 int on_before_user_action_; |
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1896 EXPECT_STR_EQ("other", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION)); | 1895 EXPECT_STR_EQ("other", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION)); |
1897 EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard()); | 1896 EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard()); |
1898 } | 1897 } |
1899 #endif | 1898 #endif |
1900 | 1899 |
1901 // Touch selection and dragging currently only works for chromeos. | 1900 // Touch selection and dragging currently only works for chromeos. |
1902 #if defined(OS_CHROMEOS) | 1901 #if defined(OS_CHROMEOS) |
1903 TEST_F(TextfieldTest, TouchSelectionAndDraggingTest) { | 1902 TEST_F(TextfieldTest, TouchSelectionAndDraggingTest) { |
1904 InitTextfield(); | 1903 InitTextfield(); |
1905 textfield_->SetText(ASCIIToUTF16("hello world")); | 1904 textfield_->SetText(ASCIIToUTF16("hello world")); |
1906 EXPECT_FALSE(GetTouchSelectionController()); | 1905 EXPECT_FALSE(test_api_->touch_selection_controller()); |
1907 const int x = GetCursorPositionX(2); | 1906 const int x = GetCursorPositionX(2); |
1908 GestureEventForTest tap(ui::ET_GESTURE_TAP, x, 0, 1.0f, 0.0f); | 1907 GestureEventForTest tap(ui::ET_GESTURE_TAP, x, 0, 1.0f, 0.0f); |
1909 GestureEventForTest tap_down(ui::ET_GESTURE_TAP_DOWN, x, 0, 0.0f, 0.0f); | 1908 GestureEventForTest tap_down(ui::ET_GESTURE_TAP_DOWN, x, 0, 0.0f, 0.0f); |
1910 GestureEventForTest long_press(ui::ET_GESTURE_LONG_PRESS, x, 0, 0.0f, 0.0f); | 1909 GestureEventForTest long_press(ui::ET_GESTURE_LONG_PRESS, x, 0, 0.0f, 0.0f); |
1911 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing); | 1910 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing); |
1912 | 1911 |
1913 // Tapping on the textfield should turn on the TouchSelectionController. | 1912 // Tapping on the textfield should turn on the TouchSelectionController. |
1914 textfield_->OnGestureEvent(&tap); | 1913 textfield_->OnGestureEvent(&tap); |
1915 EXPECT_TRUE(GetTouchSelectionController()); | 1914 EXPECT_TRUE(test_api_->touch_selection_controller()); |
1916 | 1915 |
1917 // Un-focusing the textfield should reset the TouchSelectionController | 1916 // Un-focusing the textfield should reset the TouchSelectionController |
1918 textfield_->GetFocusManager()->ClearFocus(); | 1917 textfield_->GetFocusManager()->ClearFocus(); |
1919 EXPECT_FALSE(GetTouchSelectionController()); | 1918 EXPECT_FALSE(test_api_->touch_selection_controller()); |
1920 | 1919 |
1921 // With touch editing enabled, long press should not show context menu. | 1920 // With touch editing enabled, long press should not show context menu. |
1922 // Instead, select word and invoke TouchSelectionController. | 1921 // Instead, select word and invoke TouchSelectionController. |
1923 textfield_->OnGestureEvent(&tap_down); | 1922 textfield_->OnGestureEvent(&tap_down); |
1924 textfield_->OnGestureEvent(&long_press); | 1923 textfield_->OnGestureEvent(&long_press); |
1925 EXPECT_STR_EQ("hello", textfield_->GetSelectedText()); | 1924 EXPECT_STR_EQ("hello", textfield_->GetSelectedText()); |
1926 EXPECT_TRUE(GetTouchSelectionController()); | 1925 EXPECT_TRUE(test_api_->touch_selection_controller()); |
1927 | 1926 |
1928 // With touch drag drop enabled, long pressing in the selected region should | 1927 // With touch drag drop enabled, long pressing in the selected region should |
1929 // start a drag and remove TouchSelectionController. | 1928 // start a drag and remove TouchSelectionController. |
1930 ASSERT_TRUE(switches::IsTouchDragDropEnabled()); | 1929 ASSERT_TRUE(switches::IsTouchDragDropEnabled()); |
1931 textfield_->OnGestureEvent(&tap_down); | 1930 textfield_->OnGestureEvent(&tap_down); |
1932 textfield_->OnGestureEvent(&long_press); | 1931 textfield_->OnGestureEvent(&long_press); |
1933 EXPECT_STR_EQ("hello", textfield_->GetSelectedText()); | 1932 EXPECT_STR_EQ("hello", textfield_->GetSelectedText()); |
1934 EXPECT_FALSE(GetTouchSelectionController()); | 1933 EXPECT_FALSE(test_api_->touch_selection_controller()); |
1935 | 1934 |
1936 // After disabling touch drag drop, long pressing again in the selection | 1935 // After disabling touch drag drop, long pressing again in the selection |
1937 // region should not do anything. | 1936 // region should not do anything. |
1938 CommandLine::ForCurrentProcess()->AppendSwitch( | 1937 CommandLine::ForCurrentProcess()->AppendSwitch( |
1939 switches::kDisableTouchDragDrop); | 1938 switches::kDisableTouchDragDrop); |
1940 ASSERT_FALSE(switches::IsTouchDragDropEnabled()); | 1939 ASSERT_FALSE(switches::IsTouchDragDropEnabled()); |
1941 textfield_->OnGestureEvent(&tap_down); | 1940 textfield_->OnGestureEvent(&tap_down); |
1942 textfield_->OnGestureEvent(&long_press); | 1941 textfield_->OnGestureEvent(&long_press); |
1943 EXPECT_STR_EQ("hello", textfield_->GetSelectedText()); | 1942 EXPECT_STR_EQ("hello", textfield_->GetSelectedText()); |
1944 EXPECT_TRUE(GetTouchSelectionController()); | 1943 EXPECT_TRUE(test_api_->touch_selection_controller()); |
1945 EXPECT_TRUE(long_press.handled()); | 1944 EXPECT_TRUE(long_press.handled()); |
1946 } | 1945 } |
1947 | 1946 |
1948 TEST_F(TextfieldTest, TouchScrubbingSelection) { | 1947 TEST_F(TextfieldTest, TouchScrubbingSelection) { |
1949 InitTextfield(); | 1948 InitTextfield(); |
1950 textfield_->SetText(ASCIIToUTF16("hello world")); | 1949 textfield_->SetText(ASCIIToUTF16("hello world")); |
1951 EXPECT_FALSE(GetTouchSelectionController()); | 1950 EXPECT_FALSE(test_api_->touch_selection_controller()); |
1952 | 1951 |
1953 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing); | 1952 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing); |
1954 | 1953 |
1955 // Simulate touch-scrubbing. | 1954 // Simulate touch-scrubbing. |
1956 int scrubbing_start = GetCursorPositionX(1); | 1955 int scrubbing_start = GetCursorPositionX(1); |
1957 int scrubbing_end = GetCursorPositionX(6); | 1956 int scrubbing_end = GetCursorPositionX(6); |
1958 | 1957 |
1959 GestureEventForTest tap_down(ui::ET_GESTURE_TAP_DOWN, scrubbing_start, 0, | 1958 GestureEventForTest tap_down(ui::ET_GESTURE_TAP_DOWN, scrubbing_start, 0, |
1960 0.0f, 0.0f); | 1959 0.0f, 0.0f); |
1961 textfield_->OnGestureEvent(&tap_down); | 1960 textfield_->OnGestureEvent(&tap_down); |
(...skipping 13 matching lines...) Expand all Loading... |
1975 GestureEventForTest scroll_end(ui::ET_GESTURE_SCROLL_END, scrubbing_end, 0, | 1974 GestureEventForTest scroll_end(ui::ET_GESTURE_SCROLL_END, scrubbing_end, 0, |
1976 0.0f, 0.0f); | 1975 0.0f, 0.0f); |
1977 textfield_->OnGestureEvent(&scroll_end); | 1976 textfield_->OnGestureEvent(&scroll_end); |
1978 | 1977 |
1979 GestureEventForTest end(ui::ET_GESTURE_END, scrubbing_end, 0, 0.0f, 0.0f); | 1978 GestureEventForTest end(ui::ET_GESTURE_END, scrubbing_end, 0, 0.0f, 0.0f); |
1980 textfield_->OnGestureEvent(&end); | 1979 textfield_->OnGestureEvent(&end); |
1981 | 1980 |
1982 // In the end, part of text should have been selected and handles should have | 1981 // In the end, part of text should have been selected and handles should have |
1983 // appeared. | 1982 // appeared. |
1984 EXPECT_STR_EQ("ello ", textfield_->GetSelectedText()); | 1983 EXPECT_STR_EQ("ello ", textfield_->GetSelectedText()); |
1985 EXPECT_TRUE(GetTouchSelectionController()); | 1984 EXPECT_TRUE(test_api_->touch_selection_controller()); |
1986 } | 1985 } |
1987 #endif | 1986 #endif |
1988 | 1987 |
1989 // Long_Press gesture in Textfield can initiate a drag and drop now. | 1988 // Long_Press gesture in Textfield can initiate a drag and drop now. |
1990 TEST_F(TextfieldTest, TestLongPressInitiatesDragDrop) { | 1989 TEST_F(TextfieldTest, TestLongPressInitiatesDragDrop) { |
1991 InitTextfield(); | 1990 InitTextfield(); |
1992 textfield_->SetText(ASCIIToUTF16("Hello string world")); | 1991 textfield_->SetText(ASCIIToUTF16("Hello string world")); |
1993 | 1992 |
1994 // Ensure the textfield will provide selected text for drag data. | 1993 // Ensure the textfield will provide selected text for drag data. |
1995 textfield_->SelectRange(gfx::Range(6, 12)); | 1994 textfield_->SelectRange(gfx::Range(6, 12)); |
(...skipping 19 matching lines...) Expand all Loading... |
2015 // Set text which may fall back to a font which has taller baseline than | 2014 // Set text which may fall back to a font which has taller baseline than |
2016 // the default font. | 2015 // the default font. |
2017 textfield_->SetText(UTF8ToUTF16("\xE0\xB9\x91")); | 2016 textfield_->SetText(UTF8ToUTF16("\xE0\xB9\x91")); |
2018 const int new_baseline = textfield_->GetBaseline(); | 2017 const int new_baseline = textfield_->GetBaseline(); |
2019 | 2018 |
2020 // Regardless of the text, the baseline must be the same. | 2019 // Regardless of the text, the baseline must be the same. |
2021 EXPECT_EQ(new_baseline, old_baseline); | 2020 EXPECT_EQ(new_baseline, old_baseline); |
2022 } | 2021 } |
2023 | 2022 |
2024 } // namespace views | 2023 } // namespace views |
OLD | NEW |