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 "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
6 #include "base/strings/utf_string_conversions.h" | 6 #include "base/strings/utf_string_conversions.h" |
7 #include "base/win/scoped_bstr.h" | 7 #include "base/win/scoped_bstr.h" |
8 #include "base/win/scoped_comptr.h" | 8 #include "base/win/scoped_comptr.h" |
9 #include "base/win/scoped_variant.h" | 9 #include "base/win/scoped_variant.h" |
10 #include "content/browser/accessibility/browser_accessibility_manager.h" | 10 #include "content/browser/accessibility/browser_accessibility_manager.h" |
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
805 EXPECT_NE(nullptr, static_cast<BSTR>(attributes)); | 805 EXPECT_NE(nullptr, static_cast<BSTR>(attributes)); |
806 std::wstring attributes_str(attributes, attributes.Length()); | 806 std::wstring attributes_str(attributes, attributes.Length()); |
807 EXPECT_EQ(L"checkable:true;", attributes_str); | 807 EXPECT_EQ(L"checkable:true;", attributes_str); |
808 | 808 |
809 manager.reset(); | 809 manager.reset(); |
810 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances()); | 810 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances()); |
811 } | 811 } |
812 | 812 |
813 /** | 813 /** |
814 * Ensures that ui::AX_ATTR_TEXT_SEL_START/END attributes are correctly used to | 814 * Ensures that ui::AX_ATTR_TEXT_SEL_START/END attributes are correctly used to |
815 * determine caret position and text selection in various types of editable | 815 * determine caret position and text selection in simple form fields. |
816 * elements. | |
817 */ | 816 */ |
818 TEST_F(BrowserAccessibilityTest, TestCaretAndTextSelection) { | 817 TEST_F(BrowserAccessibilityTest, TestCaretAndSelectionInSimpleFields) { |
819 ui::AXNodeData root; | 818 ui::AXNodeData root; |
820 root.id = 1; | 819 root.id = 1; |
821 root.role = ui::AX_ROLE_ROOT_WEB_AREA; | 820 root.role = ui::AX_ROLE_ROOT_WEB_AREA; |
822 root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE); | 821 root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE); |
823 | 822 |
824 ui::AXNodeData combo_box; | 823 ui::AXNodeData combo_box; |
825 combo_box.id = 2; | 824 combo_box.id = 2; |
826 combo_box.role = ui::AX_ROLE_COMBO_BOX; | 825 combo_box.role = ui::AX_ROLE_COMBO_BOX; |
827 combo_box.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_FOCUSED); | 826 combo_box.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_FOCUSED); |
828 combo_box.SetValue("Test1"); | 827 combo_box.SetValue("Test1"); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
868 // -2 is never a valid offset. | 867 // -2 is never a valid offset. |
869 LONG caret_offset = -2; | 868 LONG caret_offset = -2; |
870 LONG n_selections = -2; | 869 LONG n_selections = -2; |
871 LONG selection_start = -2; | 870 LONG selection_start = -2; |
872 LONG selection_end = -2; | 871 LONG selection_end = -2; |
873 | 872 |
874 // Test get_caretOffset. | 873 // Test get_caretOffset. |
875 HRESULT hr = combo_box_accessible->get_caretOffset(&caret_offset);; | 874 HRESULT hr = combo_box_accessible->get_caretOffset(&caret_offset);; |
876 EXPECT_EQ(S_OK, hr); | 875 EXPECT_EQ(S_OK, hr); |
877 EXPECT_EQ(1L, caret_offset); | 876 EXPECT_EQ(1L, caret_offset); |
878 // caret_offset should be -1 when the object is not focused. | 877 // The caret should be at the start of the selection. |
879 hr = text_field_accessible->get_caretOffset(&caret_offset);; | 878 hr = text_field_accessible->get_caretOffset(&caret_offset);; |
880 EXPECT_EQ(S_FALSE, hr); | 879 EXPECT_EQ(S_OK, hr); |
881 EXPECT_EQ(-1L, caret_offset); | 880 EXPECT_EQ(1L, caret_offset); |
882 | 881 |
883 // Move the focus to the text field. | 882 // Move the focus to the text field. |
884 combo_box.state &= ~(1 << ui::AX_STATE_FOCUSED); | 883 combo_box.state &= ~(1 << ui::AX_STATE_FOCUSED); |
885 text_field.state |= 1 << ui::AX_STATE_FOCUSED; | 884 text_field.state |= 1 << ui::AX_STATE_FOCUSED; |
886 manager->SetFocus(text_field_accessible, false /* notify */); | 885 manager->SetFocus(text_field_accessible, false /* notify */); |
887 ASSERT_EQ(text_field_accessible, | 886 ASSERT_EQ(text_field_accessible, |
888 manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin()); | 887 manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin()); |
889 | 888 |
890 // The caret should be at the start of the selection. | 889 // The caret should not have moved. |
891 hr = text_field_accessible->get_caretOffset(&caret_offset);; | 890 hr = text_field_accessible->get_caretOffset(&caret_offset);; |
892 EXPECT_EQ(S_OK, hr); | 891 EXPECT_EQ(S_OK, hr); |
893 EXPECT_EQ(1L, caret_offset); | 892 EXPECT_EQ(1L, caret_offset); |
894 | 893 |
895 // Test get_nSelections. | 894 // Test get_nSelections. |
896 hr = combo_box_accessible->get_nSelections(&n_selections);; | 895 hr = combo_box_accessible->get_nSelections(&n_selections);; |
897 EXPECT_EQ(S_OK, hr); | 896 EXPECT_EQ(S_OK, hr); |
898 EXPECT_EQ(0L, n_selections); | 897 EXPECT_EQ(0L, n_selections); |
899 hr = text_field_accessible->get_nSelections(&n_selections);; | 898 hr = text_field_accessible->get_nSelections(&n_selections);; |
900 EXPECT_EQ(S_OK, hr); | 899 EXPECT_EQ(S_OK, hr); |
901 EXPECT_EQ(1L, n_selections); | 900 EXPECT_EQ(1L, n_selections); |
902 | 901 |
903 // Test get_selection. | 902 // Test get_selection. |
904 hr = combo_box_accessible->get_selection( | 903 hr = combo_box_accessible->get_selection( |
905 0L /* selection_index */, &selection_start, &selection_end);; | 904 0L /* selection_index */, &selection_start, &selection_end);; |
906 EXPECT_EQ(E_INVALIDARG, hr); // No selections available. | 905 EXPECT_EQ(E_INVALIDARG, hr); // No selections available. |
907 // Invalid in_args should not modify out_args. | 906 // Invalid in_args should not modify out_args. |
908 EXPECT_EQ(-2L, selection_start); | 907 EXPECT_EQ(-2L, selection_start); |
909 EXPECT_EQ(-2L, selection_end); | 908 EXPECT_EQ(-2L, selection_end); |
910 hr = text_field_accessible->get_selection( | 909 hr = text_field_accessible->get_selection( |
911 0L /* selection_index */, &selection_start, &selection_end);; | 910 0L /* selection_index */, &selection_start, &selection_end);; |
912 EXPECT_EQ(S_OK, hr); | 911 EXPECT_EQ(S_OK, hr); |
913 EXPECT_EQ(1L, selection_start); | 912 EXPECT_EQ(1L, selection_start); |
914 EXPECT_EQ(2L, selection_end); | 913 EXPECT_EQ(2L, selection_end); |
915 | 914 |
916 manager.reset(); | 915 manager.reset(); |
917 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances()); | 916 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances()); |
918 } | 917 } |
919 | 918 |
919 TEST_F(BrowserAccessibilityTest, TestCaretInContentEditables) { | |
920 ui::AXNodeData root; | |
921 root.id = 1; | |
922 root.role = ui::AX_ROLE_ROOT_WEB_AREA; | |
923 root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE); | |
924 | |
925 ui::AXNodeData div_editable; | |
926 div_editable.id = 2; | |
927 div_editable.role = ui::AX_ROLE_DIV; | |
928 div_editable.state = (1 << ui::AX_STATE_FOCUSABLE); | |
929 | |
930 ui::AXNodeData text; | |
931 text.id = 3; | |
932 text.role = ui::AX_ROLE_STATIC_TEXT; | |
933 text.SetName("Click "); | |
934 | |
935 ui::AXNodeData link; | |
936 link.id = 4; | |
937 link.role = ui::AX_ROLE_LINK; | |
938 link.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED); | |
939 link.SetName("here"); | |
940 | |
941 ui::AXNodeData link_text; | |
942 link_text.id = 5; | |
943 link_text.role = ui::AX_ROLE_STATIC_TEXT; | |
944 link_text.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED); | |
945 link_text.SetName("here"); | |
946 | |
947 // Place the caret between 'h' and 'e'. | |
948 root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, 4); | |
949 root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, 1); | |
950 root.AddIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, 4); | |
951 root.AddIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, 1); | |
952 | |
953 root.child_ids.push_back(2); | |
954 div_editable.child_ids.push_back(3); | |
955 div_editable.child_ids.push_back(4); | |
956 link.child_ids.push_back(5); | |
957 | |
958 CountedBrowserAccessibility::reset(); | |
959 scoped_ptr<BrowserAccessibilityManager> manager( | |
960 BrowserAccessibilityManager::Create( | |
961 MakeAXTreeUpdate(root, div_editable, link, link_text, text), | |
962 nullptr, new CountedBrowserAccessibilityFactory())); | |
963 ASSERT_EQ(5, CountedBrowserAccessibility::num_instances()); | |
964 | |
965 ASSERT_NE(nullptr, manager->GetRoot()); | |
966 BrowserAccessibilityWin* root_accessible = | |
967 manager->GetRoot()->ToBrowserAccessibilityWin(); | |
968 ASSERT_NE(nullptr, root_accessible); | |
969 ASSERT_EQ(1, root_accessible->PlatformChildCount()); | |
970 | |
971 BrowserAccessibilityWin* div_editable_accessible = | |
972 root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); | |
973 ASSERT_NE(nullptr, div_editable_accessible); | |
974 ASSERT_EQ(2, div_editable_accessible->PlatformChildCount()); | |
975 | |
976 // -2 is never a valid offset. | |
977 LONG caret_offset = -2; | |
978 | |
979 // The caret should be on the embedded object character. | |
980 HRESULT hr = div_editable_accessible->get_caretOffset(&caret_offset);; | |
981 EXPECT_EQ(S_OK, hr); | |
982 EXPECT_EQ(6L, caret_offset); | |
983 | |
984 // Move the focus to the content editable. | |
985 div_editable.state |= 1 << ui::AX_STATE_FOCUSED; | |
dmazzoni
2015/07/16 19:50:23
I don't think this line is doing anything, you're
| |
986 manager->SetFocus(div_editable_accessible, false /* notify */); | |
987 ASSERT_EQ(div_editable_accessible, | |
988 manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin()); | |
989 | |
990 BrowserAccessibilityWin* text_accessible = | |
991 div_editable_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); | |
992 ASSERT_NE(nullptr, text_accessible); | |
993 BrowserAccessibilityWin* link_accessible = | |
994 div_editable_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); | |
995 ASSERT_NE(nullptr, link_accessible); | |
996 ASSERT_EQ(1, link_accessible->PlatformChildCount()); | |
997 | |
998 BrowserAccessibilityWin* link_text_accessible = | |
999 link_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); | |
1000 ASSERT_NE(nullptr, link_text_accessible); | |
1001 | |
1002 // The caret should not have moved. | |
1003 hr = div_editable_accessible->get_caretOffset(&caret_offset);; | |
1004 EXPECT_EQ(S_OK, hr); | |
1005 EXPECT_EQ(6L, caret_offset); | |
1006 | |
1007 hr = link_accessible->get_caretOffset(&caret_offset);; | |
1008 EXPECT_EQ(S_OK, hr); | |
1009 EXPECT_EQ(1L, caret_offset); | |
1010 hr = link_text_accessible->get_caretOffset(&caret_offset);; | |
1011 EXPECT_EQ(S_OK, hr); | |
1012 EXPECT_EQ(1L, caret_offset); | |
1013 | |
1014 manager.reset(); | |
1015 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances()); | |
1016 } | |
1017 | |
1018 TEST_F(BrowserAccessibilityTest, TestSelectionInContentEditables) { | |
1019 ui::AXNodeData root; | |
1020 root.id = 1; | |
1021 root.role = ui::AX_ROLE_ROOT_WEB_AREA; | |
1022 root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE); | |
1023 | |
1024 ui::AXNodeData div_editable; | |
1025 div_editable.id = 2; | |
1026 div_editable.role = ui::AX_ROLE_DIV; | |
1027 div_editable.state = (1 << ui::AX_STATE_FOCUSABLE); | |
1028 | |
1029 ui::AXNodeData text; | |
1030 text.id = 3; | |
1031 text.role = ui::AX_ROLE_STATIC_TEXT; | |
1032 text.SetName("Click "); | |
1033 | |
1034 ui::AXNodeData link; | |
1035 link.id = 4; | |
1036 link.role = ui::AX_ROLE_LINK; | |
1037 link.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED); | |
1038 link.SetName("here"); | |
1039 | |
1040 ui::AXNodeData link_text; | |
1041 link_text.id = 5; | |
1042 link_text.role = ui::AX_ROLE_STATIC_TEXT; | |
1043 link_text.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED); | |
1044 link_text.SetName("here"); | |
1045 | |
1046 // Select the part of the text "lick here". | |
1047 root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, 3); | |
1048 root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, 1); | |
1049 root.AddIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, 5); | |
1050 root.AddIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, 4); | |
1051 | |
1052 root.child_ids.push_back(2); | |
1053 div_editable.child_ids.push_back(3); | |
1054 div_editable.child_ids.push_back(4); | |
1055 link.child_ids.push_back(5); | |
1056 | |
1057 CountedBrowserAccessibility::reset(); | |
1058 scoped_ptr<BrowserAccessibilityManager> manager( | |
1059 BrowserAccessibilityManager::Create( | |
1060 MakeAXTreeUpdate(root, div_editable, link, link_text, text), | |
1061 nullptr, new CountedBrowserAccessibilityFactory())); | |
1062 ASSERT_EQ(5, CountedBrowserAccessibility::num_instances()); | |
1063 | |
1064 ASSERT_NE(nullptr, manager->GetRoot()); | |
1065 BrowserAccessibilityWin* root_accessible = | |
1066 manager->GetRoot()->ToBrowserAccessibilityWin(); | |
1067 ASSERT_NE(nullptr, root_accessible); | |
1068 ASSERT_EQ(1, root_accessible->PlatformChildCount()); | |
1069 | |
1070 BrowserAccessibilityWin* div_editable_accessible = | |
1071 root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); | |
1072 ASSERT_NE(nullptr, div_editable_accessible); | |
1073 ASSERT_EQ(2, div_editable_accessible->PlatformChildCount()); | |
1074 | |
1075 // -2 is never a valid offset. | |
1076 LONG caret_offset = -2; | |
1077 LONG n_selections = -2; | |
1078 LONG selection_start = -2; | |
1079 LONG selection_end = -2; | |
1080 | |
1081 BrowserAccessibilityWin* text_accessible = | |
1082 div_editable_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); | |
1083 ASSERT_NE(nullptr, text_accessible); | |
1084 BrowserAccessibilityWin* link_accessible = | |
1085 div_editable_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); | |
1086 ASSERT_NE(nullptr, link_accessible); | |
1087 ASSERT_EQ(1, link_accessible->PlatformChildCount()); | |
1088 | |
1089 BrowserAccessibilityWin* link_text_accessible = | |
1090 link_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); | |
1091 ASSERT_NE(nullptr, link_text_accessible); | |
1092 | |
1093 // get_nSelections should work on all objects. | |
1094 HRESULT hr = div_editable_accessible->get_nSelections(&n_selections);; | |
1095 EXPECT_EQ(S_OK, hr); | |
1096 EXPECT_EQ(1L, n_selections); | |
1097 hr = text_accessible->get_nSelections(&n_selections);; | |
1098 EXPECT_EQ(S_OK, hr); | |
1099 EXPECT_EQ(1L, n_selections); | |
1100 hr = link_accessible->get_nSelections(&n_selections);; | |
1101 EXPECT_EQ(S_OK, hr); | |
1102 EXPECT_EQ(1L, n_selections); | |
1103 hr = link_text_accessible->get_nSelections(&n_selections);; | |
1104 EXPECT_EQ(S_OK, hr); | |
1105 EXPECT_EQ(1L, n_selections); | |
1106 | |
1107 // get_selection should be unaffected by focus placement. | |
1108 hr = div_editable_accessible->get_selection( | |
1109 0L /* selection_index */, &selection_start, &selection_end);; | |
1110 EXPECT_EQ(S_OK, hr); | |
1111 EXPECT_EQ(1L, selection_start); | |
1112 // selection_end should be after embedded object character. | |
1113 EXPECT_EQ(7L, selection_end); | |
1114 | |
1115 hr = text_accessible->get_selection( | |
1116 0L /* selection_index */, &selection_start, &selection_end);; | |
1117 EXPECT_EQ(S_OK, hr); | |
1118 EXPECT_EQ(1L, selection_start); | |
1119 // No embedded character on this object, only the first part of the text. | |
1120 EXPECT_EQ(6L, selection_end); | |
1121 hr = link_accessible->get_selection( | |
1122 0L /* selection_index */, &selection_start, &selection_end);; | |
1123 EXPECT_EQ(S_OK, hr); | |
1124 EXPECT_EQ(0L, selection_start); | |
1125 EXPECT_EQ(4L, selection_end); | |
1126 hr = link_text_accessible->get_selection( | |
1127 0L /* selection_index */, &selection_start, &selection_end);; | |
1128 EXPECT_EQ(S_OK, hr); | |
1129 EXPECT_EQ(0L, selection_start); | |
1130 EXPECT_EQ(4L, selection_end); | |
1131 | |
1132 // The caret should be at the anchor (the start) of the selection. | |
1133 hr = div_editable_accessible->get_caretOffset(&caret_offset);; | |
1134 EXPECT_EQ(S_OK, hr); | |
1135 EXPECT_EQ(1L, caret_offset); | |
1136 | |
1137 // Move the focus to the content editable. | |
1138 div_editable.state |= 1 << ui::AX_STATE_FOCUSED; | |
1139 manager->SetFocus(div_editable_accessible, false /* notify */); | |
1140 ASSERT_EQ(div_editable_accessible, | |
1141 manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin()); | |
1142 | |
1143 // The caret should not have moved. | |
1144 hr = div_editable_accessible->get_caretOffset(&caret_offset);; | |
1145 EXPECT_EQ(S_OK, hr); | |
1146 EXPECT_EQ(1L, caret_offset); | |
1147 | |
1148 // The HRESULT should be S_FALSE if the caret is not in the given object. | |
1149 hr = link_accessible->get_caretOffset(&caret_offset);; | |
1150 EXPECT_EQ(S_FALSE, hr); | |
1151 EXPECT_EQ(-1L, caret_offset); | |
1152 hr = link_text_accessible->get_caretOffset(&caret_offset);; | |
1153 EXPECT_EQ(S_FALSE, hr); | |
1154 EXPECT_EQ(-1L, caret_offset); | |
1155 | |
1156 hr = div_editable_accessible->get_selection( | |
1157 0L /* selection_index */, &selection_start, &selection_end);; | |
1158 EXPECT_EQ(S_OK, hr); | |
1159 EXPECT_EQ(1L, selection_start); | |
1160 EXPECT_EQ(7L, selection_end); | |
1161 | |
1162 manager.reset(); | |
1163 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances()); | |
1164 } | |
1165 | |
920 } // namespace content | 1166 } // namespace content |
OLD | NEW |