OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/accessibility/browser_accessibility_android.h" | 5 #include "content/browser/accessibility/browser_accessibility_android.h" |
6 | 6 |
7 #include "base/i18n/break_iterator.h" | 7 #include "base/i18n/break_iterator.h" |
8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 } | 365 } |
366 | 366 |
367 if (text.empty()) | 367 if (text.empty()) |
368 text = value; | 368 text = value; |
369 | 369 |
370 // This is called from PlatformIsLeaf, so don't call PlatformChildCount | 370 // This is called from PlatformIsLeaf, so don't call PlatformChildCount |
371 // from within this! | 371 // from within this! |
372 if (text.empty() && | 372 if (text.empty() && |
373 (HasOnlyStaticTextChildren() || | 373 (HasOnlyStaticTextChildren() || |
374 (IsFocusable() && HasOnlyTextAndImageChildren()))) { | 374 (IsFocusable() && HasOnlyTextAndImageChildren()))) { |
375 for (uint32 i = 0; i < InternalChildCount(); i++) { | 375 for (uint32_t i = 0; i < InternalChildCount(); i++) { |
376 BrowserAccessibility* child = InternalGetChild(i); | 376 BrowserAccessibility* child = InternalGetChild(i); |
377 text += static_cast<BrowserAccessibilityAndroid*>(child)->GetText(); | 377 text += static_cast<BrowserAccessibilityAndroid*>(child)->GetText(); |
378 } | 378 } |
379 } | 379 } |
380 | 380 |
381 if (text.empty() && (IsLink() || GetRole() == ui::AX_ROLE_IMAGE)) { | 381 if (text.empty() && (IsLink() || GetRole() == ui::AX_ROLE_IMAGE)) { |
382 base::string16 url = GetString16Attribute(ui::AX_ATTR_URL); | 382 base::string16 url = GetString16Attribute(ui::AX_ATTR_URL); |
383 // Given a url like http://foo.com/bar/baz.png, just return the | 383 // Given a url like http://foo.com/bar/baz.png, just return the |
384 // base text, e.g., "baz". | 384 // base text, e.g., "baz". |
385 int trailing_slashes = 0; | 385 int trailing_slashes = 0; |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 float BrowserAccessibilityAndroid::RangeMax() const { | 765 float BrowserAccessibilityAndroid::RangeMax() const { |
766 return GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE); | 766 return GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE); |
767 } | 767 } |
768 | 768 |
769 float BrowserAccessibilityAndroid::RangeCurrentValue() const { | 769 float BrowserAccessibilityAndroid::RangeCurrentValue() const { |
770 return GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE); | 770 return GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE); |
771 } | 771 } |
772 | 772 |
773 void BrowserAccessibilityAndroid::GetGranularityBoundaries( | 773 void BrowserAccessibilityAndroid::GetGranularityBoundaries( |
774 int granularity, | 774 int granularity, |
775 std::vector<int32>* starts, | 775 std::vector<int32_t>* starts, |
776 std::vector<int32>* ends, | 776 std::vector<int32_t>* ends, |
777 int offset) { | 777 int offset) { |
778 switch (granularity) { | 778 switch (granularity) { |
779 case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_LINE: | 779 case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_LINE: |
780 GetLineBoundaries(starts, ends, offset); | 780 GetLineBoundaries(starts, ends, offset); |
781 break; | 781 break; |
782 case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_WORD: | 782 case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_WORD: |
783 GetWordBoundaries(starts, ends, offset); | 783 GetWordBoundaries(starts, ends, offset); |
784 break; | 784 break; |
785 default: | 785 default: |
786 NOTREACHED(); | 786 NOTREACHED(); |
787 } | 787 } |
788 } | 788 } |
789 | 789 |
790 void BrowserAccessibilityAndroid::GetLineBoundaries( | 790 void BrowserAccessibilityAndroid::GetLineBoundaries( |
791 std::vector<int32>* line_starts, | 791 std::vector<int32_t>* line_starts, |
792 std::vector<int32>* line_ends, | 792 std::vector<int32_t>* line_ends, |
793 int offset) { | 793 int offset) { |
794 // If this node has no children, treat it as all one line. | 794 // If this node has no children, treat it as all one line. |
795 if (GetText().size() > 0 && !InternalChildCount()) { | 795 if (GetText().size() > 0 && !InternalChildCount()) { |
796 line_starts->push_back(offset); | 796 line_starts->push_back(offset); |
797 line_ends->push_back(offset + GetText().size()); | 797 line_ends->push_back(offset + GetText().size()); |
798 } | 798 } |
799 | 799 |
800 // If this is a static text node, get the line boundaries from the | 800 // If this is a static text node, get the line boundaries from the |
801 // inline text boxes if possible. | 801 // inline text boxes if possible. |
802 if (GetRole() == ui::AX_ROLE_STATIC_TEXT) { | 802 if (GetRole() == ui::AX_ROLE_STATIC_TEXT) { |
803 int last_y = 0; | 803 int last_y = 0; |
804 for (uint32 i = 0; i < InternalChildCount(); i++) { | 804 for (uint32_t i = 0; i < InternalChildCount(); i++) { |
805 BrowserAccessibilityAndroid* child = | 805 BrowserAccessibilityAndroid* child = |
806 static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i)); | 806 static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i)); |
807 CHECK_EQ(ui::AX_ROLE_INLINE_TEXT_BOX, child->GetRole()); | 807 CHECK_EQ(ui::AX_ROLE_INLINE_TEXT_BOX, child->GetRole()); |
808 // TODO(dmazzoni): replace this with a proper API to determine | 808 // TODO(dmazzoni): replace this with a proper API to determine |
809 // if two inline text boxes are on the same line. http://crbug.com/421771 | 809 // if two inline text boxes are on the same line. http://crbug.com/421771 |
810 int y = child->GetLocation().y(); | 810 int y = child->GetLocation().y(); |
811 if (i == 0) { | 811 if (i == 0) { |
812 line_starts->push_back(offset); | 812 line_starts->push_back(offset); |
813 } else if (y != last_y) { | 813 } else if (y != last_y) { |
814 line_ends->push_back(offset); | 814 line_ends->push_back(offset); |
815 line_starts->push_back(offset); | 815 line_starts->push_back(offset); |
816 } | 816 } |
817 offset += child->GetText().size(); | 817 offset += child->GetText().size(); |
818 last_y = y; | 818 last_y = y; |
819 } | 819 } |
820 line_ends->push_back(offset); | 820 line_ends->push_back(offset); |
821 return; | 821 return; |
822 } | 822 } |
823 | 823 |
824 // Otherwise, call GetLineBoundaries recursively on the children. | 824 // Otherwise, call GetLineBoundaries recursively on the children. |
825 for (uint32 i = 0; i < InternalChildCount(); i++) { | 825 for (uint32_t i = 0; i < InternalChildCount(); i++) { |
826 BrowserAccessibilityAndroid* child = | 826 BrowserAccessibilityAndroid* child = |
827 static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i)); | 827 static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i)); |
828 child->GetLineBoundaries(line_starts, line_ends, offset); | 828 child->GetLineBoundaries(line_starts, line_ends, offset); |
829 offset += child->GetText().size(); | 829 offset += child->GetText().size(); |
830 } | 830 } |
831 } | 831 } |
832 | 832 |
833 void BrowserAccessibilityAndroid::GetWordBoundaries( | 833 void BrowserAccessibilityAndroid::GetWordBoundaries( |
834 std::vector<int32>* word_starts, | 834 std::vector<int32_t>* word_starts, |
835 std::vector<int32>* word_ends, | 835 std::vector<int32_t>* word_ends, |
836 int offset) { | 836 int offset) { |
837 if (GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) { | 837 if (GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) { |
838 const std::vector<int32>& starts = GetIntListAttribute( | 838 const std::vector<int32_t>& starts = |
839 ui::AX_ATTR_WORD_STARTS); | 839 GetIntListAttribute(ui::AX_ATTR_WORD_STARTS); |
840 const std::vector<int32>& ends = GetIntListAttribute( | 840 const std::vector<int32_t>& ends = |
841 ui::AX_ATTR_WORD_ENDS); | 841 GetIntListAttribute(ui::AX_ATTR_WORD_ENDS); |
842 for (size_t i = 0; i < starts.size(); ++i) { | 842 for (size_t i = 0; i < starts.size(); ++i) { |
843 word_starts->push_back(offset + starts[i]); | 843 word_starts->push_back(offset + starts[i]); |
844 word_ends->push_back(offset + ends[i]); | 844 word_ends->push_back(offset + ends[i]); |
845 } | 845 } |
846 return; | 846 return; |
847 } | 847 } |
848 | 848 |
849 base::string16 concatenated_text; | 849 base::string16 concatenated_text; |
850 for (uint32 i = 0; i < InternalChildCount(); i++) { | 850 for (uint32_t i = 0; i < InternalChildCount(); i++) { |
851 BrowserAccessibilityAndroid* child = | 851 BrowserAccessibilityAndroid* child = |
852 static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i)); | 852 static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i)); |
853 base::string16 child_text = child->GetText(); | 853 base::string16 child_text = child->GetText(); |
854 concatenated_text += child->GetText(); | 854 concatenated_text += child->GetText(); |
855 } | 855 } |
856 | 856 |
857 base::string16 text = GetText(); | 857 base::string16 text = GetText(); |
858 if (text.empty() || concatenated_text == text) { | 858 if (text.empty() || concatenated_text == text) { |
859 // Great - this node is just the concatenation of its children, so | 859 // Great - this node is just the concatenation of its children, so |
860 // we can get the word boundaries recursively. | 860 // we can get the word boundaries recursively. |
861 for (uint32 i = 0; i < InternalChildCount(); i++) { | 861 for (uint32_t i = 0; i < InternalChildCount(); i++) { |
862 BrowserAccessibilityAndroid* child = | 862 BrowserAccessibilityAndroid* child = |
863 static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i)); | 863 static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i)); |
864 child->GetWordBoundaries(word_starts, word_ends, offset); | 864 child->GetWordBoundaries(word_starts, word_ends, offset); |
865 offset += child->GetText().size(); | 865 offset += child->GetText().size(); |
866 } | 866 } |
867 } else { | 867 } else { |
868 // This node has its own accessible text that doesn't match its | 868 // This node has its own accessible text that doesn't match its |
869 // visible text - like alt text for an image or something with an | 869 // visible text - like alt text for an image or something with an |
870 // aria-label, so split the text into words locally. | 870 // aria-label, so split the text into words locally. |
871 base::i18n::BreakIterator iter(text, base::i18n::BreakIterator::BREAK_WORD); | 871 base::i18n::BreakIterator iter(text, base::i18n::BreakIterator::BREAK_WORD); |
872 if (!iter.Init()) | 872 if (!iter.Init()) |
873 return; | 873 return; |
874 while (iter.Advance()) { | 874 while (iter.Advance()) { |
875 if (iter.IsWord()) { | 875 if (iter.IsWord()) { |
876 word_starts->push_back(iter.prev()); | 876 word_starts->push_back(iter.prev()); |
877 word_ends->push_back(iter.pos()); | 877 word_ends->push_back(iter.pos()); |
878 } | 878 } |
879 } | 879 } |
880 } | 880 } |
881 } | 881 } |
882 | 882 |
883 bool BrowserAccessibilityAndroid::HasFocusableChild() const { | 883 bool BrowserAccessibilityAndroid::HasFocusableChild() const { |
884 // This is called from PlatformIsLeaf, so don't call PlatformChildCount | 884 // This is called from PlatformIsLeaf, so don't call PlatformChildCount |
885 // from within this! | 885 // from within this! |
886 for (uint32 i = 0; i < InternalChildCount(); i++) { | 886 for (uint32_t i = 0; i < InternalChildCount(); i++) { |
887 BrowserAccessibility* child = InternalGetChild(i); | 887 BrowserAccessibility* child = InternalGetChild(i); |
888 if (child->HasState(ui::AX_STATE_FOCUSABLE)) | 888 if (child->HasState(ui::AX_STATE_FOCUSABLE)) |
889 return true; | 889 return true; |
890 if (static_cast<BrowserAccessibilityAndroid*>(child)->HasFocusableChild()) | 890 if (static_cast<BrowserAccessibilityAndroid*>(child)->HasFocusableChild()) |
891 return true; | 891 return true; |
892 } | 892 } |
893 return false; | 893 return false; |
894 } | 894 } |
895 | 895 |
896 bool BrowserAccessibilityAndroid::HasOnlyStaticTextChildren() const { | 896 bool BrowserAccessibilityAndroid::HasOnlyStaticTextChildren() const { |
897 // This is called from PlatformIsLeaf, so don't call PlatformChildCount | 897 // This is called from PlatformIsLeaf, so don't call PlatformChildCount |
898 // from within this! | 898 // from within this! |
899 for (uint32 i = 0; i < InternalChildCount(); i++) { | 899 for (uint32_t i = 0; i < InternalChildCount(); i++) { |
900 BrowserAccessibility* child = InternalGetChild(i); | 900 BrowserAccessibility* child = InternalGetChild(i); |
901 if (child->GetRole() != ui::AX_ROLE_STATIC_TEXT) | 901 if (child->GetRole() != ui::AX_ROLE_STATIC_TEXT) |
902 return false; | 902 return false; |
903 } | 903 } |
904 return true; | 904 return true; |
905 } | 905 } |
906 | 906 |
907 bool BrowserAccessibilityAndroid::HasOnlyTextAndImageChildren() const { | 907 bool BrowserAccessibilityAndroid::HasOnlyTextAndImageChildren() const { |
908 // This is called from PlatformIsLeaf, so don't call PlatformChildCount | 908 // This is called from PlatformIsLeaf, so don't call PlatformChildCount |
909 // from within this! | 909 // from within this! |
910 for (uint32 i = 0; i < InternalChildCount(); i++) { | 910 for (uint32_t i = 0; i < InternalChildCount(); i++) { |
911 BrowserAccessibility* child = InternalGetChild(i); | 911 BrowserAccessibility* child = InternalGetChild(i); |
912 if (child->GetRole() != ui::AX_ROLE_STATIC_TEXT && | 912 if (child->GetRole() != ui::AX_ROLE_STATIC_TEXT && |
913 child->GetRole() != ui::AX_ROLE_IMAGE) { | 913 child->GetRole() != ui::AX_ROLE_IMAGE) { |
914 return false; | 914 return false; |
915 } | 915 } |
916 } | 916 } |
917 return true; | 917 return true; |
918 } | 918 } |
919 | 919 |
920 bool BrowserAccessibilityAndroid::IsIframe() const { | 920 bool BrowserAccessibilityAndroid::IsIframe() const { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 if (!text.empty()) { | 957 if (!text.empty()) { |
958 manager()->NotifyAccessibilityEvent(ui::AX_EVENT_SHOW, | 958 manager()->NotifyAccessibilityEvent(ui::AX_EVENT_SHOW, |
959 this); | 959 this); |
960 } | 960 } |
961 cached_text_ = text; | 961 cached_text_ = text; |
962 } | 962 } |
963 } | 963 } |
964 | 964 |
965 int BrowserAccessibilityAndroid::CountChildrenWithRole(ui::AXRole role) const { | 965 int BrowserAccessibilityAndroid::CountChildrenWithRole(ui::AXRole role) const { |
966 int count = 0; | 966 int count = 0; |
967 for (uint32 i = 0; i < PlatformChildCount(); i++) { | 967 for (uint32_t i = 0; i < PlatformChildCount(); i++) { |
968 if (PlatformGetChild(i)->GetRole() == role) | 968 if (PlatformGetChild(i)->GetRole() == role) |
969 count++; | 969 count++; |
970 } | 970 } |
971 return count; | 971 return count; |
972 } | 972 } |
973 | 973 |
974 } // namespace content | 974 } // namespace content |
OLD | NEW |