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/command_line.h" |
10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 return clipboard_text; | 92 return clipboard_text; |
93 } | 93 } |
94 | 94 |
95 enum class SecondaryUiMode { NON_MD, MD }; | 95 enum class SecondaryUiMode { NON_MD, MD }; |
96 | 96 |
97 std::string SecondaryUiModeToString( | 97 std::string SecondaryUiModeToString( |
98 const ::testing::TestParamInfo<SecondaryUiMode>& info) { | 98 const ::testing::TestParamInfo<SecondaryUiMode>& info) { |
99 return info.param == SecondaryUiMode::MD ? "MD" : "NonMD"; | 99 return info.param == SecondaryUiMode::MD ? "MD" : "NonMD"; |
100 } | 100 } |
101 | 101 |
102 // Makes an RTL string by mapping 0..6 to [א,ב,ג,ד,ה,ו,ז]. | |
103 base::string16 ToRTL(const char* ascii) { | |
104 base::string16 rtl; | |
105 for (const char* c = ascii; *c; ++c) { | |
106 if (*c >= '0' && *c <= '6') | |
107 rtl += L'\x5d0' + (*c - '0'); | |
108 else | |
109 rtl += static_cast<base::string16::value_type>(*c); | |
msw
2017/05/25 18:11:55
q: can you really just cast ascii chars to string1
tapted
2017/05/26 06:53:40
yup - the first 255 codepoints of utf-16 is just t
| |
110 } | |
111 return rtl; | |
112 } | |
113 | |
102 } // namespace | 114 } // namespace |
103 | 115 |
104 class LabelTest : public ViewsTestBase { | 116 class LabelTest : public ViewsTestBase { |
105 public: | 117 public: |
106 LabelTest() {} | 118 LabelTest() {} |
107 | 119 |
108 // Called after ViewsTestBase is set up. ViewsTestBase initializes the | 120 // Called after ViewsTestBase is set up. ViewsTestBase initializes the |
109 // MaterialDesignController, so this allows a subclass to influence settings | 121 // MaterialDesignController, so this allows a subclass to influence settings |
110 // used for the remainder of SetUp(). | 122 // used for the remainder of SetUp(). |
111 virtual void OnBaseSetUp() {} | 123 virtual void OnBaseSetUp() {} |
(...skipping 30 matching lines...) Expand all Loading... | |
142 private: | 154 private: |
143 Label* label_ = nullptr; | 155 Label* label_ = nullptr; |
144 Widget widget_; | 156 Widget widget_; |
145 | 157 |
146 DISALLOW_COPY_AND_ASSIGN(LabelTest); | 158 DISALLOW_COPY_AND_ASSIGN(LabelTest); |
147 }; | 159 }; |
148 | 160 |
149 // Test fixture for text selection related tests. | 161 // Test fixture for text selection related tests. |
150 class LabelSelectionTest : public LabelTest { | 162 class LabelSelectionTest : public LabelTest { |
151 public: | 163 public: |
164 // Alias this long identifier for more readable tests. | |
165 static constexpr bool kExtends = | |
166 gfx::RenderText::kDragToEndIfOutsideVerticalBounds; | |
167 | |
168 // Some tests use cardinal directions to index an array of points above and | |
msw
2017/05/25 18:11:55
Please inline the array values and comment on each
tapted
2017/05/26 06:53:40
I'll reorder the steps.
I meant to leave a commen
| |
169 // below the label in either visual direction. | |
170 enum { NW, NORTH, NE, SE, SOUTH, SW }; | |
171 | |
152 LabelSelectionTest() {} | 172 LabelSelectionTest() {} |
153 | 173 |
154 // LabelTest overrides: | 174 // LabelTest overrides: |
155 void SetUp() override { | 175 void SetUp() override { |
156 #if defined(OS_MACOSX) | 176 #if defined(OS_MACOSX) |
157 // On Mac, by default RenderTextMac is used for labels which does not | 177 // On Mac, by default RenderTextMac is used for labels which does not |
158 // support text selection. Instead use RenderTextHarfBuzz for selection | 178 // support text selection. Instead use RenderTextHarfBuzz for selection |
159 // related tests. TODO(crbug.com/661394): Remove this once Mac also uses | 179 // related tests. TODO(crbug.com/661394): Remove this once Mac also uses |
160 // RenderTextHarfBuzz for Labels. | 180 // RenderTextHarfBuzz for Labels. |
161 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 181 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1027 | 1047 |
1028 PerformMouseDragTo(GetCursorPoint(7)); | 1048 PerformMouseDragTo(GetCursorPoint(7)); |
1029 EXPECT_STR_EQ("cd\nef", GetSelectedText()); | 1049 EXPECT_STR_EQ("cd\nef", GetSelectedText()); |
1030 | 1050 |
1031 PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6).y())); | 1051 PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6).y())); |
1032 EXPECT_STR_EQ("cd\n", GetSelectedText()); | 1052 EXPECT_STR_EQ("cd\n", GetSelectedText()); |
1033 | 1053 |
1034 PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6).y())); | 1054 PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6).y())); |
1035 EXPECT_STR_EQ("cd\nefgh", GetSelectedText()); | 1055 EXPECT_STR_EQ("cd\nefgh", GetSelectedText()); |
1036 | 1056 |
1037 PerformMouseDragTo(gfx::Point(GetCursorPoint(3).x(), -5)); | 1057 const gfx::Point points[] = { |
1038 EXPECT_STR_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? "ab" : "c", | 1058 {GetCursorPoint(1).x(), -5}, // NW. |
1039 GetSelectedText()); | 1059 {GetCursorPoint(2).x(), -5}, // NORTH. |
1060 {GetCursorPoint(3).x(), -5}, // NE. | |
1061 {GetCursorPoint(8).x(), 100}, // SE. | |
1062 {GetCursorPoint(7).x(), 100}, // SOUTH. | |
1063 {GetCursorPoint(6).x(), 100}, // SW. | |
1064 }; | |
1065 constexpr const char* kExtendLeft = "ab"; | |
1066 constexpr const char* kExtendRight = "cd\nefgh"; | |
1040 | 1067 |
1041 PerformMouseDragTo(gfx::Point(GetCursorPoint(7).x(), 100)); | 1068 // For multiline, N* extends right, S* extends left. |
msw
2017/05/25 18:11:55
I think you have this backwards?
tapted
2017/05/26 06:53:40
Whoops - yes. Thanks.
| |
1042 EXPECT_STR_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? "cd\nefgh" | 1069 PerformMouseDragTo(points[NE]); |
1043 : "cd\nef", | 1070 EXPECT_STR_EQ(kExtends ? kExtendLeft : "c", GetSelectedText()); |
1044 GetSelectedText()); | 1071 PerformMouseDragTo(points[SOUTH]); |
1072 EXPECT_STR_EQ(kExtends ? kExtendRight : "cd\nef", GetSelectedText()); | |
1073 PerformMouseDragTo(points[NW]); | |
1074 EXPECT_STR_EQ(kExtends ? kExtendLeft : "b", GetSelectedText()); | |
1075 PerformMouseDragTo(points[NORTH]); | |
1076 EXPECT_STR_EQ(kExtends ? kExtendLeft : "", GetSelectedText()); | |
msw
2017/05/25 18:11:55
good test case
| |
1077 PerformMouseDragTo(points[SE]); | |
1078 EXPECT_STR_EQ(kExtends ? kExtendRight : "cd\nefg", GetSelectedText()); | |
1079 PerformMouseDragTo(points[SW]); | |
1080 EXPECT_STR_EQ(kExtends ? kExtendRight : "cd\ne", GetSelectedText()); | |
1081 } | |
1082 | |
1083 // Single line fields consider the x offset as well. Ties go to the right. | |
1084 TEST_F(LabelSelectionTest, MouseDragSingleLineLTR) { | |
1085 label()->SetText(ASCIIToUTF16("abcdnefgh")); | |
msw
2017/05/25 18:11:55
nit: shorten to 5 or 6 (like rtl) chars and remove
tapted
2017/05/26 06:53:40
Done.
| |
1086 label()->SizeToPreferredSize(); | |
1087 ASSERT_TRUE(label()->SetSelectable(true)); | |
1088 PerformMousePress(GetCursorPoint(2)); | |
1089 const gfx::Point points[] = { | |
1090 {GetCursorPoint(1).x(), -5}, // NW. | |
1091 {GetCursorPoint(2).x(), -5}, // NORTH. | |
1092 {GetCursorPoint(3).x(), -5}, // NE. | |
1093 {GetCursorPoint(3).x(), 100}, // SE. | |
1094 {GetCursorPoint(2).x(), 100}, // SOUTH. | |
1095 {GetCursorPoint(1).x(), 100}, // SW. | |
1096 }; | |
1097 constexpr const char* kExtendLeft = "ab"; | |
1098 constexpr const char* kExtendRight = "cdnefgh"; | |
1099 | |
1100 // For single line, extends right unless west. | |
msw
2017/05/25 18:11:55
nit: // For single line, western directions extend
tapted
2017/05/26 06:53:40
Done.
| |
1101 PerformMouseDragTo(points[NE]); | |
1102 EXPECT_STR_EQ(kExtends ? kExtendRight : "c", GetSelectedText()); | |
1103 PerformMouseDragTo(points[SOUTH]); | |
1104 EXPECT_STR_EQ(kExtends ? kExtendRight : "", GetSelectedText()); | |
1105 PerformMouseDragTo(points[NW]); | |
1106 EXPECT_STR_EQ(kExtends ? kExtendLeft : "b", GetSelectedText()); | |
1107 PerformMouseDragTo(points[NORTH]); | |
1108 EXPECT_STR_EQ(kExtends ? kExtendRight : "", GetSelectedText()); | |
1109 PerformMouseDragTo(points[SE]); | |
1110 EXPECT_STR_EQ(kExtends ? kExtendRight : "c", GetSelectedText()); | |
1111 PerformMouseDragTo(points[SW]); | |
1112 EXPECT_STR_EQ(kExtends ? kExtendLeft : "b", GetSelectedText()); | |
1045 } | 1113 } |
1046 | 1114 |
1047 TEST_F(LabelSelectionTest, MouseDragMultilineRTL) { | 1115 TEST_F(LabelSelectionTest, MouseDragMultilineRTL) { |
1048 label()->SetMultiLine(true); | 1116 label()->SetMultiLine(true); |
1049 label()->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\n\x5d3\x5d4\x5d5")); | 1117 label()->SetText(ToRTL("012\n345")); |
1118 // Sanity check. | |
1119 EXPECT_EQ(WideToUTF16(L"\x5d0\x5d1\x5d2\n\x5d3\x5d4\x5d5"), label()->text()); | |
1120 | |
1050 label()->SizeToPreferredSize(); | 1121 label()->SizeToPreferredSize(); |
1051 ASSERT_TRUE(label()->SetSelectable(true)); | 1122 ASSERT_TRUE(label()->SetSelectable(true)); |
1052 ASSERT_EQ(2u, GetLineCount()); | 1123 ASSERT_EQ(2u, GetLineCount()); |
1053 | 1124 |
1054 PerformMousePress(GetCursorPoint(1)); | 1125 PerformMousePress(GetCursorPoint(1)); // Note: RTL drag starts at 1, not 2. |
1055 PerformMouseDragTo(GetCursorPoint(0)); | 1126 PerformMouseDragTo(GetCursorPoint(0)); |
1056 EXPECT_EQ(WideToUTF16(L"\x5d0"), GetSelectedText()); | 1127 EXPECT_EQ(ToRTL("0"), GetSelectedText()); |
1057 | 1128 |
1058 PerformMouseDragTo(GetCursorPoint(6)); | 1129 PerformMouseDragTo(GetCursorPoint(6)); |
1059 EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4"), GetSelectedText()); | 1130 EXPECT_EQ(ToRTL("12\n34"), GetSelectedText()); |
1060 | 1131 |
1061 PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6).y())); | 1132 PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6).y())); |
1062 EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4\x5d5"), GetSelectedText()); | 1133 EXPECT_EQ(ToRTL("12\n345"), GetSelectedText()); |
1063 | 1134 |
1064 PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6).y())); | 1135 PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6).y())); |
1065 EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n"), GetSelectedText()); | 1136 EXPECT_EQ(ToRTL("12\n"), GetSelectedText()); |
1066 | 1137 |
1067 PerformMouseDragTo(gfx::Point(GetCursorPoint(2).x(), -5)); | 1138 const gfx::Point points[] = { |
1068 EXPECT_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds | 1139 {GetCursorPoint(2).x(), -5}, // NW: Now towards the end of the string. |
1069 ? WideToUTF16(L"\x5d0") | 1140 {GetCursorPoint(1).x(), -5}, // NORTH, |
1070 : WideToUTF16(L"\x5d1"), | 1141 {GetCursorPoint(0).x(), -5}, // NE: Towards the start. |
1071 GetSelectedText()); | 1142 {GetCursorPoint(4).x(), 100}, // SE. |
1143 {GetCursorPoint(5).x(), 100}, // SOUTH. | |
1144 {GetCursorPoint(6).x(), 100}, // SW. | |
1145 }; | |
1072 | 1146 |
1073 PerformMouseDragTo(gfx::Point(GetCursorPoint(6).x(), 100)); | 1147 // Visual right, so to the beginning of the string for RTL. |
1074 EXPECT_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds | 1148 const base::string16 extend_right = ToRTL("0"); |
1075 ? WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4\x5d5") | 1149 const base::string16 extend_left = ToRTL("12\n345"); |
1076 : WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4"), | 1150 |
1077 GetSelectedText()); | 1151 // For multiline, N* extends right, S* extends left. |
1152 PerformMouseDragTo(points[NW]); | |
1153 EXPECT_EQ(kExtends ? extend_right : ToRTL("1"), GetSelectedText()); | |
1154 PerformMouseDragTo(points[SW]); | |
1155 EXPECT_EQ(kExtends ? extend_left : ToRTL("12\n34"), GetSelectedText()); | |
1156 PerformMouseDragTo(points[NORTH]); | |
1157 EXPECT_EQ(kExtends ? extend_right : ToRTL(""), GetSelectedText()); | |
1158 PerformMouseDragTo(points[NE]); | |
1159 EXPECT_EQ(kExtends ? extend_right : ToRTL("0"), GetSelectedText()); | |
1160 PerformMouseDragTo(points[SE]); | |
1161 EXPECT_EQ(kExtends ? extend_left : ToRTL("12\n"), GetSelectedText()); | |
1162 PerformMouseDragTo(points[SOUTH]); | |
1163 EXPECT_EQ(kExtends ? extend_left : ToRTL("12\n3"), GetSelectedText()); | |
1164 } | |
1165 | |
1166 TEST_F(LabelSelectionTest, MouseDragSingleLineRTL) { | |
1167 label()->SetText(ToRTL("0123456")); | |
1168 label()->SizeToPreferredSize(); | |
1169 ASSERT_TRUE(label()->SetSelectable(true)); | |
1170 | |
1171 PerformMousePress(GetCursorPoint(1)); | |
1172 const gfx::Point points[] = { | |
1173 {GetCursorPoint(2).x(), -5}, // NW. | |
1174 {GetCursorPoint(1).x(), -5}, // NORTH. | |
1175 {GetCursorPoint(0).x(), -5}, // NE. | |
1176 {GetCursorPoint(0).x(), 100}, // SE. | |
1177 {GetCursorPoint(1).x(), 100}, // SOUTH. | |
1178 {GetCursorPoint(2).x(), 100}, // SW. | |
1179 }; | |
1180 | |
1181 // Visual right, so to the beginning of the string for RTL. | |
1182 const base::string16 extend_right = ToRTL("0"); | |
1183 const base::string16 extend_left = ToRTL("123456"); | |
1184 | |
1185 // For single line, extends right unless west. | |
msw
2017/05/25 18:11:55
ditto rephrasing
tapted
2017/05/26 06:53:40
Done.
| |
1186 PerformMouseDragTo(points[NW]); | |
1187 EXPECT_EQ(kExtends ? extend_left : ToRTL("1"), GetSelectedText()); | |
1188 PerformMouseDragTo(points[SW]); | |
1189 EXPECT_EQ(kExtends ? extend_left : ToRTL("1"), GetSelectedText()); | |
1190 PerformMouseDragTo(points[NORTH]); | |
1191 EXPECT_EQ(kExtends ? extend_right : ToRTL(""), GetSelectedText()); | |
1192 PerformMouseDragTo(points[NE]); | |
1193 EXPECT_EQ(kExtends ? extend_right : ToRTL("0"), GetSelectedText()); | |
1194 PerformMouseDragTo(points[SE]); | |
1195 EXPECT_EQ(kExtends ? extend_right : ToRTL("0"), GetSelectedText()); | |
1196 PerformMouseDragTo(points[SOUTH]); | |
1197 EXPECT_EQ(kExtends ? extend_right : ToRTL(""), GetSelectedText()); | |
1078 } | 1198 } |
1079 | 1199 |
1080 // Verify the initially selected word on a double click, remains selected on | 1200 // Verify the initially selected word on a double click, remains selected on |
1081 // mouse dragging. | 1201 // mouse dragging. |
1082 TEST_F(LabelSelectionTest, MouseDragWord) { | 1202 TEST_F(LabelSelectionTest, MouseDragWord) { |
1083 label()->SetText(ASCIIToUTF16("Label drag word")); | 1203 label()->SetText(ASCIIToUTF16("Label drag word")); |
1084 label()->SizeToPreferredSize(); | 1204 label()->SizeToPreferredSize(); |
1085 ASSERT_TRUE(label()->SetSelectable(true)); | 1205 ASSERT_TRUE(label()->SetSelectable(true)); |
1086 | 1206 |
1087 PerformClick(GetCursorPoint(8)); | 1207 PerformClick(GetCursorPoint(8)); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1188 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_SELECT_ALL)); | 1308 EXPECT_FALSE(IsMenuCommandEnabled(IDS_APP_SELECT_ALL)); |
1189 } | 1309 } |
1190 | 1310 |
1191 INSTANTIATE_TEST_CASE_P(, | 1311 INSTANTIATE_TEST_CASE_P(, |
1192 MDLabelTest, | 1312 MDLabelTest, |
1193 ::testing::Values(SecondaryUiMode::MD, | 1313 ::testing::Values(SecondaryUiMode::MD, |
1194 SecondaryUiMode::NON_MD), | 1314 SecondaryUiMode::NON_MD), |
1195 &SecondaryUiModeToString); | 1315 &SecondaryUiModeToString); |
1196 | 1316 |
1197 } // namespace views | 1317 } // namespace views |
OLD | NEW |