Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "ui/views/controls/label.h" | 5 #include "ui/views/controls/label.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/command_line.h" | |
| 9 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 11 #include "build/build_config.h" | 12 #include "build/build_config.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "ui/accessibility/ax_node_data.h" | 14 #include "ui/accessibility/ax_node_data.h" |
| 14 #include "ui/base/clipboard/clipboard.h" | 15 #include "ui/base/clipboard/clipboard.h" |
| 15 #include "ui/base/l10n/l10n_util.h" | 16 #include "ui/base/l10n/l10n_util.h" |
| 16 #include "ui/compositor/canvas_painter.h" | 17 #include "ui/compositor/canvas_painter.h" |
| 17 #include "ui/events/base_event_utils.h" | 18 #include "ui/events/base_event_utils.h" |
| 18 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
| 19 #include "ui/gfx/render_text.h" | 20 #include "ui/gfx/render_text.h" |
| 21 #include "ui/gfx/switches.h" | |
| 20 #include "ui/views/border.h" | 22 #include "ui/views/border.h" |
| 21 #include "ui/views/test/focus_manager_test.h" | 23 #include "ui/views/test/focus_manager_test.h" |
| 22 #include "ui/views/test/views_test_base.h" | 24 #include "ui/views/test/views_test_base.h" |
| 23 #include "ui/views/widget/widget.h" | 25 #include "ui/views/widget/widget.h" |
| 24 | 26 |
| 25 using base::ASCIIToUTF16; | 27 using base::ASCIIToUTF16; |
| 26 | 28 |
| 27 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16) | 29 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16) |
| 28 | 30 |
| 29 namespace views { | 31 namespace views { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 53 void TearDown() override { | 55 void TearDown() override { |
| 54 widget_.Close(); | 56 widget_.Close(); |
| 55 ViewsTestBase::TearDown(); | 57 ViewsTestBase::TearDown(); |
| 56 } | 58 } |
| 57 | 59 |
| 58 protected: | 60 protected: |
| 59 Label* label() { return label_; } | 61 Label* label() { return label_; } |
| 60 | 62 |
| 61 Widget* widget() { return &widget_; } | 63 Widget* widget() { return &widget_; } |
| 62 | 64 |
| 65 private: | |
| 66 Label* label_ = nullptr; | |
| 67 Widget widget_; | |
| 68 | |
| 69 DISALLOW_COPY_AND_ASSIGN(LabelTest); | |
| 70 }; | |
| 71 | |
| 72 // Test fixture for text selection related tests. | |
| 73 class LabelSelectionTest : public LabelTest { | |
| 74 public: | |
| 75 LabelSelectionTest() {} | |
| 76 | |
| 77 // LabelTest overrides: | |
| 78 void SetUp() override { | |
| 79 #if defined(OS_MACOSX) | |
| 80 // On Mac, by default RenderTextMac is used for labels which does not | |
|
sky
2016/11/09 16:23:10
Is there a reason not to promoted this to LabelTes
karandeepb
2016/11/10 00:00:03
For non text selection related tests, I wanted to
| |
| 81 // support text selection. Instead use RenderTextHarfBuzz for selection | |
| 82 // related tests. TODO(crbug.com/661394): Remove this once Mac also uses | |
| 83 // RenderTextHarfBuzz for Labels. | |
| 84 base::CommandLine::ForCurrentProcess()->AppendSwitch( | |
| 85 switches::kEnableHarfBuzzRenderText); | |
| 86 #endif | |
| 87 LabelTest::SetUp(); | |
| 88 } | |
| 89 | |
| 90 protected: | |
| 63 View* GetFocusedView() { | 91 View* GetFocusedView() { |
| 64 return widget()->GetFocusManager()->GetFocusedView(); | 92 return widget()->GetFocusManager()->GetFocusedView(); |
| 65 } | 93 } |
| 66 | 94 |
| 67 void PerformMousePress(const gfx::Point& point, int extra_flags = 0) { | 95 void PerformMousePress(const gfx::Point& point, int extra_flags = 0) { |
| 68 ui::MouseEvent pressed_event = ui::MouseEvent( | 96 ui::MouseEvent pressed_event = ui::MouseEvent( |
| 69 ui::ET_MOUSE_PRESSED, point, point, ui::EventTimeForNow(), | 97 ui::ET_MOUSE_PRESSED, point, point, ui::EventTimeForNow(), |
| 70 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON | extra_flags); | 98 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON | extra_flags); |
| 71 label()->OnMousePressed(pressed_event); | 99 label()->OnMousePressed(pressed_event); |
| 72 } | 100 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 97 .origin(); | 125 .origin(); |
| 98 } | 126 } |
| 99 | 127 |
| 100 base::string16 GetSelectedText() { | 128 base::string16 GetSelectedText() { |
| 101 const gfx::RenderText* render_text = | 129 const gfx::RenderText* render_text = |
| 102 label()->GetRenderTextForSelectionController(); | 130 label()->GetRenderTextForSelectionController(); |
| 103 return render_text->GetTextFromRange(render_text->selection()); | 131 return render_text->GetTextFromRange(render_text->selection()); |
| 104 } | 132 } |
| 105 | 133 |
| 106 private: | 134 private: |
| 107 Label* label_ = nullptr; | 135 DISALLOW_COPY_AND_ASSIGN(LabelSelectionTest); |
| 108 Widget widget_; | |
| 109 | |
| 110 DISALLOW_COPY_AND_ASSIGN(LabelTest); | |
| 111 }; | 136 }; |
| 112 | 137 |
| 113 namespace { | 138 namespace { |
| 114 | 139 |
| 115 // All text sizing measurements (width and height) should be greater than this. | 140 // All text sizing measurements (width and height) should be greater than this. |
| 116 const int kMinTextDimension = 4; | 141 const int kMinTextDimension = 4; |
| 117 | 142 |
| 118 class TestLabel : public Label { | 143 class TestLabel : public Label { |
| 119 public: | 144 public: |
| 120 TestLabel() : Label(ASCIIToUTF16("TestLabel")) { SizeToPreferredSize(); } | 145 TestLabel() : Label(ASCIIToUTF16("TestLabel")) { SizeToPreferredSize(); } |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 766 TEST_F(LabelTest, EmptyLabel) { | 791 TEST_F(LabelTest, EmptyLabel) { |
| 767 label()->SetFocusBehavior(View::FocusBehavior::ALWAYS); | 792 label()->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 768 label()->RequestFocus(); | 793 label()->RequestFocus(); |
| 769 label()->SizeToPreferredSize(); | 794 label()->SizeToPreferredSize(); |
| 770 | 795 |
| 771 gfx::Rect focus_bounds = label()->GetFocusBounds(); | 796 gfx::Rect focus_bounds = label()->GetFocusBounds(); |
| 772 EXPECT_FALSE(focus_bounds.IsEmpty()); | 797 EXPECT_FALSE(focus_bounds.IsEmpty()); |
| 773 EXPECT_LT(label()->font_list().GetHeight(), focus_bounds.height()); | 798 EXPECT_LT(label()->font_list().GetHeight(), focus_bounds.height()); |
| 774 } | 799 } |
| 775 | 800 |
| 776 // Disabled on Mac since it uses RenderTextMac, which does not support text | 801 TEST_F(LabelSelectionTest, Selectable) { |
| 777 // selection. | |
| 778 // TODO(crbug.com/661394): Re-enable these once Mac uses RenderTextHarfBuzz for | |
| 779 // Labels. | |
| 780 #if !defined(OS_MACOSX) | |
| 781 TEST_F(LabelTest, Selectable) { | |
| 782 // By default, labels don't support text selection. | 802 // By default, labels don't support text selection. |
| 783 EXPECT_FALSE(label()->selectable()); | 803 EXPECT_FALSE(label()->selectable()); |
| 784 | 804 |
| 785 ASSERT_TRUE(label()->SetSelectable(true)); | 805 ASSERT_TRUE(label()->SetSelectable(true)); |
| 786 EXPECT_TRUE(label()->selectable()); | 806 EXPECT_TRUE(label()->selectable()); |
| 787 | 807 |
| 788 // Verify that making a label multiline causes the label to not support text | 808 // Verify that making a label multiline causes the label to not support text |
| 789 // selection. | 809 // selection. |
| 790 label()->SetMultiLine(true); | 810 label()->SetMultiLine(true); |
| 791 EXPECT_FALSE(label()->selectable()); | 811 EXPECT_FALSE(label()->selectable()); |
| 792 } | 812 } |
| 793 | 813 |
| 794 // Verify that labels supporting text selection get focus on clicks. | 814 // Verify that labels supporting text selection get focus on clicks. |
| 795 TEST_F(LabelTest, FocusOnClick) { | 815 TEST_F(LabelSelectionTest, FocusOnClick) { |
| 796 label()->SetText(ASCIIToUTF16("text")); | 816 label()->SetText(ASCIIToUTF16("text")); |
| 797 label()->SizeToPreferredSize(); | 817 label()->SizeToPreferredSize(); |
| 798 | 818 |
| 799 // By default, labels don't get focus on click. | 819 // By default, labels don't get focus on click. |
| 800 PerformClick(gfx::Point()); | 820 PerformClick(gfx::Point()); |
| 801 EXPECT_NE(label(), GetFocusedView()); | 821 EXPECT_NE(label(), GetFocusedView()); |
| 802 | 822 |
| 803 ASSERT_TRUE(label()->SetSelectable(true)); | 823 ASSERT_TRUE(label()->SetSelectable(true)); |
| 804 PerformClick(gfx::Point()); | 824 PerformClick(gfx::Point()); |
| 805 EXPECT_EQ(label(), GetFocusedView()); | 825 EXPECT_EQ(label(), GetFocusedView()); |
| 806 } | 826 } |
| 807 | 827 |
| 808 // Verify that labels supporting text selection do not get focus on tab | 828 // Verify that labels supporting text selection do not get focus on tab |
| 809 // traversal by default. | 829 // traversal by default. |
| 810 TEST_F(LabelTest, FocusTraversal) { | 830 TEST_F(LabelSelectionTest, FocusTraversal) { |
| 811 // Add another view before |label()|. | 831 // Add another view before |label()|. |
| 812 View* view = new View(); | 832 View* view = new View(); |
| 813 view->SetFocusBehavior(View::FocusBehavior::ALWAYS); | 833 view->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 814 widget()->GetContentsView()->AddChildViewAt(view, 0); | 834 widget()->GetContentsView()->AddChildViewAt(view, 0); |
| 815 | 835 |
| 816 // By default, labels are not focusable. | 836 // By default, labels are not focusable. |
| 817 view->RequestFocus(); | 837 view->RequestFocus(); |
| 818 EXPECT_EQ(view, GetFocusedView()); | 838 EXPECT_EQ(view, GetFocusedView()); |
| 819 widget()->GetFocusManager()->AdvanceFocus(false); | 839 widget()->GetFocusManager()->AdvanceFocus(false); |
| 820 EXPECT_NE(label(), GetFocusedView()); | 840 EXPECT_NE(label(), GetFocusedView()); |
| 821 | 841 |
| 822 // On enabling text selection, labels can get focus on clicks but not via tab | 842 // On enabling text selection, labels can get focus on clicks but not via tab |
| 823 // traversal. | 843 // traversal. |
| 824 view->RequestFocus(); | 844 view->RequestFocus(); |
| 825 EXPECT_EQ(view, GetFocusedView()); | 845 EXPECT_EQ(view, GetFocusedView()); |
| 826 EXPECT_TRUE(label()->SetSelectable(true)); | 846 EXPECT_TRUE(label()->SetSelectable(true)); |
| 827 widget()->GetFocusManager()->AdvanceFocus(false); | 847 widget()->GetFocusManager()->AdvanceFocus(false); |
| 828 EXPECT_NE(label(), GetFocusedView()); | 848 EXPECT_NE(label(), GetFocusedView()); |
| 829 | 849 |
| 830 // A label with FocusBehavior::ALWAYS should get focus via tab traversal. | 850 // A label with FocusBehavior::ALWAYS should get focus via tab traversal. |
| 831 view->RequestFocus(); | 851 view->RequestFocus(); |
| 832 EXPECT_EQ(view, GetFocusedView()); | 852 EXPECT_EQ(view, GetFocusedView()); |
| 833 EXPECT_TRUE(label()->SetSelectable(false)); | 853 EXPECT_TRUE(label()->SetSelectable(false)); |
| 834 label()->SetFocusBehavior(View::FocusBehavior::ALWAYS); | 854 label()->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 835 widget()->GetFocusManager()->AdvanceFocus(false); | 855 widget()->GetFocusManager()->AdvanceFocus(false); |
| 836 EXPECT_EQ(label(), GetFocusedView()); | 856 EXPECT_EQ(label(), GetFocusedView()); |
| 837 } | 857 } |
| 838 | 858 |
| 839 // Verify label text selection behavior on double and triple clicks. | 859 // Verify label text selection behavior on double and triple clicks. |
| 840 TEST_F(LabelTest, DoubleTripleClick) { | 860 TEST_F(LabelSelectionTest, DoubleTripleClick) { |
| 841 label()->SetText(ASCIIToUTF16("Label double click")); | 861 label()->SetText(ASCIIToUTF16("Label double click")); |
| 842 label()->SizeToPreferredSize(); | 862 label()->SizeToPreferredSize(); |
| 843 ASSERT_TRUE(label()->SetSelectable(true)); | 863 ASSERT_TRUE(label()->SetSelectable(true)); |
| 844 | 864 |
| 845 PerformClick(gfx::Point()); | 865 PerformClick(gfx::Point()); |
| 846 EXPECT_TRUE(GetSelectedText().empty()); | 866 EXPECT_TRUE(GetSelectedText().empty()); |
| 847 | 867 |
| 848 // Double clicking should select the word under cursor. | 868 // Double clicking should select the word under cursor. |
| 849 PerformClick(gfx::Point(), ui::EF_IS_DOUBLE_CLICK); | 869 PerformClick(gfx::Point(), ui::EF_IS_DOUBLE_CLICK); |
| 850 EXPECT_STR_EQ("Label", GetSelectedText()); | 870 EXPECT_STR_EQ("Label", GetSelectedText()); |
| 851 | 871 |
| 852 // Triple clicking should select all the text. | 872 // Triple clicking should select all the text. |
| 853 PerformClick(gfx::Point()); | 873 PerformClick(gfx::Point()); |
| 854 EXPECT_EQ(label()->text(), GetSelectedText()); | 874 EXPECT_EQ(label()->text(), GetSelectedText()); |
| 855 | 875 |
| 856 // Clicking again should alternate to double click. | 876 // Clicking again should alternate to double click. |
| 857 PerformClick(gfx::Point()); | 877 PerformClick(gfx::Point()); |
| 858 EXPECT_STR_EQ("Label", GetSelectedText()); | 878 EXPECT_STR_EQ("Label", GetSelectedText()); |
| 859 | 879 |
| 860 // Clicking at another location should clear the selection. | 880 // Clicking at another location should clear the selection. |
| 861 PerformClick(GetCursorPoint(8)); | 881 PerformClick(GetCursorPoint(8)); |
| 862 EXPECT_TRUE(GetSelectedText().empty()); | 882 EXPECT_TRUE(GetSelectedText().empty()); |
| 863 PerformClick(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK); | 883 PerformClick(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK); |
| 864 EXPECT_STR_EQ("double", GetSelectedText()); | 884 EXPECT_STR_EQ("double", GetSelectedText()); |
| 865 } | 885 } |
| 866 | 886 |
| 867 // Verify label text selection behavior on mouse drag. | 887 // Verify label text selection behavior on mouse drag. |
| 868 TEST_F(LabelTest, MouseDrag) { | 888 TEST_F(LabelSelectionTest, MouseDrag) { |
| 869 label()->SetText(ASCIIToUTF16("Label mouse drag")); | 889 label()->SetText(ASCIIToUTF16("Label mouse drag")); |
| 870 label()->SizeToPreferredSize(); | 890 label()->SizeToPreferredSize(); |
| 871 ASSERT_TRUE(label()->SetSelectable(true)); | 891 ASSERT_TRUE(label()->SetSelectable(true)); |
| 872 | 892 |
| 873 PerformMousePress(GetCursorPoint(5)); | 893 PerformMousePress(GetCursorPoint(5)); |
| 874 PerformMouseDragTo(gfx::Point()); | 894 PerformMouseDragTo(gfx::Point()); |
| 875 EXPECT_STR_EQ("Label", GetSelectedText()); | 895 EXPECT_STR_EQ("Label", GetSelectedText()); |
| 876 | 896 |
| 877 PerformMouseDragTo(GetCursorPoint(8)); | 897 PerformMouseDragTo(GetCursorPoint(8)); |
| 878 EXPECT_STR_EQ(" mo", GetSelectedText()); | 898 EXPECT_STR_EQ(" mo", GetSelectedText()); |
| 879 | 899 |
| 880 PerformMouseDragTo(gfx::Point(200, 0)); | 900 PerformMouseDragTo(gfx::Point(200, 0)); |
| 881 PerformMouseRelease(gfx::Point(200, 0)); | 901 PerformMouseRelease(gfx::Point(200, 0)); |
| 882 EXPECT_STR_EQ(" mouse drag", GetSelectedText()); | 902 EXPECT_STR_EQ(" mouse drag", GetSelectedText()); |
| 883 } | 903 } |
| 884 | 904 |
| 885 // Verify the initially selected word on a double click, remains selected on | 905 // Verify the initially selected word on a double click, remains selected on |
| 886 // mouse dragging. | 906 // mouse dragging. |
| 887 TEST_F(LabelTest, MouseDragWord) { | 907 TEST_F(LabelSelectionTest, MouseDragWord) { |
| 888 label()->SetText(ASCIIToUTF16("Label drag word")); | 908 label()->SetText(ASCIIToUTF16("Label drag word")); |
| 889 label()->SizeToPreferredSize(); | 909 label()->SizeToPreferredSize(); |
| 890 ASSERT_TRUE(label()->SetSelectable(true)); | 910 ASSERT_TRUE(label()->SetSelectable(true)); |
| 891 | 911 |
| 892 PerformClick(GetCursorPoint(8)); | 912 PerformClick(GetCursorPoint(8)); |
| 893 PerformMousePress(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK); | 913 PerformMousePress(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK); |
| 894 EXPECT_STR_EQ("drag", GetSelectedText()); | 914 EXPECT_STR_EQ("drag", GetSelectedText()); |
| 895 | 915 |
| 896 PerformMouseDragTo(gfx::Point()); | 916 PerformMouseDragTo(gfx::Point()); |
| 897 EXPECT_STR_EQ("Label drag", GetSelectedText()); | 917 EXPECT_STR_EQ("Label drag", GetSelectedText()); |
| 898 | 918 |
| 899 PerformMouseDragTo(gfx::Point(200, 0)); | 919 PerformMouseDragTo(gfx::Point(200, 0)); |
| 900 PerformMouseRelease(gfx::Point(200, 0)); | 920 PerformMouseRelease(gfx::Point(200, 0)); |
| 901 EXPECT_STR_EQ("drag word", GetSelectedText()); | 921 EXPECT_STR_EQ("drag word", GetSelectedText()); |
| 902 } | 922 } |
| 903 #endif // OS_MACOSX | |
| 904 | 923 |
| 905 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 924 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 906 // Verify selection clipboard behavior on text selection. Disabled due to | 925 // Verify selection clipboard behavior on text selection. Disabled due to |
| 907 // http://crbug.com/396477. | 926 // http://crbug.com/396477. |
| 908 TEST_F(LabelTest, DISABLED_SelectionClipboard) { | 927 TEST_F(LabelSelectionTest, DISABLED_SelectionClipboard) { |
| 909 label()->SetText(ASCIIToUTF16("Label selection clipboard")); | 928 label()->SetText(ASCIIToUTF16("Label selection clipboard")); |
| 910 label()->SizeToPreferredSize(); | 929 label()->SizeToPreferredSize(); |
| 911 ASSERT_TRUE(label()->SetSelectable(true)); | 930 ASSERT_TRUE(label()->SetSelectable(true)); |
| 912 | 931 |
| 913 // Verify programmatic modification of selection, does not modify the | 932 // Verify programmatic modification of selection, does not modify the |
| 914 // selection clipboard. | 933 // selection clipboard. |
| 915 label()->SelectRange(gfx::Range(2, 5)); | 934 label()->SelectRange(gfx::Range(2, 5)); |
| 916 EXPECT_STR_EQ("bel", GetSelectedText()); | 935 EXPECT_STR_EQ("bel", GetSelectedText()); |
| 917 EXPECT_TRUE(GetSelectionClipboardText().empty()); | 936 EXPECT_TRUE(GetSelectionClipboardText().empty()); |
| 918 | 937 |
| 919 // Verify text selection using the mouse updates the selection clipboard. | 938 // Verify text selection using the mouse updates the selection clipboard. |
| 920 PerformMousePress(GetCursorPoint(5)); | 939 PerformMousePress(GetCursorPoint(5)); |
| 921 PerformMouseDragTo(gfx::Point()); | 940 PerformMouseDragTo(gfx::Point()); |
| 922 PerformMouseRelease(gfx::Point()); | 941 PerformMouseRelease(gfx::Point()); |
| 923 EXPECT_STR_EQ("Label", GetSelectedText()); | 942 EXPECT_STR_EQ("Label", GetSelectedText()); |
| 924 EXPECT_STR_EQ("Label", GetSelectionClipboardText()); | 943 EXPECT_STR_EQ("Label", GetSelectionClipboardText()); |
| 925 } | 944 } |
| 926 #endif | 945 #endif |
| 927 | 946 |
| 928 } // namespace views | 947 } // namespace views |
| OLD | NEW |