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 <execinfo.h> | 5 #include <execinfo.h> |
6 #include <stddef.h> | 6 #include <stddef.h> |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #import "content/browser/accessibility/browser_accessibility_cocoa.h" | 9 #import "content/browser/accessibility/browser_accessibility_cocoa.h" |
10 | 10 |
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 } | 765 } |
766 | 766 |
767 - (NSString*)description { | 767 - (NSString*)description { |
768 if (![self instanceActive]) | 768 if (![self instanceActive]) |
769 return nil; | 769 return nil; |
770 | 770 |
771 // Mac OS X wants static text exposed in AXValue. | 771 // Mac OS X wants static text exposed in AXValue. |
772 if ([self shouldExposeNameInAXValue]) | 772 if ([self shouldExposeNameInAXValue]) |
773 return @""; | 773 return @""; |
774 | 774 |
775 // If the name came from a single related element and it's present in the | 775 // If we're exposing the title in TitleUIElement, don't also redundantly |
776 // tree, it will be exposed in AXTitleUIElement. | 776 // expose it in AXDescription. |
777 std::vector<int32_t> labelledby_ids = | 777 if ([self shouldExposeTitleUIElement]) |
778 browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS); | 778 return @""; |
| 779 |
779 ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>( | 780 ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>( |
780 browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM)); | 781 browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM)); |
781 std::string name = browserAccessibility_->GetStringAttribute( | 782 std::string name = browserAccessibility_->GetStringAttribute( |
782 ui::AX_ATTR_NAME); | 783 ui::AX_ATTR_NAME); |
783 | |
784 // VoiceOver ignores titleUIElement on non-control AX nodes, so this special | |
785 // case expressly returns a nonempty text name for these nodes. | |
786 if (nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT && | |
787 labelledby_ids.size() == 1 && | |
788 browserAccessibility_->manager()->GetFromID(labelledby_ids[0]) && | |
789 !browserAccessibility_->IsControl()) { | |
790 return base::SysUTF8ToNSString(name); | |
791 } | |
792 | |
793 if (!name.empty()) { | 784 if (!name.empty()) { |
794 // On Mac OS X, the accessible name of an object is exposed as its | 785 // On Mac OS X, the accessible name of an object is exposed as its |
795 // title if it comes from visible text, and as its description | 786 // title if it comes from visible text, and as its description |
796 // otherwise, but never both. | 787 // otherwise, but never both. |
797 if (nameFrom == ui::AX_NAME_FROM_CONTENTS || | 788 if (nameFrom == ui::AX_NAME_FROM_CONTENTS || |
798 nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT || | 789 nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT || |
799 nameFrom == ui::AX_NAME_FROM_VALUE) { | 790 nameFrom == ui::AX_NAME_FROM_VALUE) { |
800 return @""; | 791 return @""; |
801 } else { | 792 } else { |
802 return base::SysUTF8ToNSString(name); | 793 return base::SysUTF8ToNSString(name); |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 case ui::AX_ROLE_LIST_BOX_OPTION: | 1221 case ui::AX_ROLE_LIST_BOX_OPTION: |
1231 case ui::AX_ROLE_LIST_MARKER: | 1222 case ui::AX_ROLE_LIST_MARKER: |
1232 case ui::AX_ROLE_MENU_LIST_OPTION: | 1223 case ui::AX_ROLE_MENU_LIST_OPTION: |
1233 case ui::AX_ROLE_STATIC_TEXT: | 1224 case ui::AX_ROLE_STATIC_TEXT: |
1234 return true; | 1225 return true; |
1235 default: | 1226 default: |
1236 return false; | 1227 return false; |
1237 } | 1228 } |
1238 } | 1229 } |
1239 | 1230 |
| 1231 // Returns true if this object should expose its accessible name using |
| 1232 // AXTitleUIElement rather than AXTitle or AXDescription. We only do |
| 1233 // this if it's a control, if there's a single label, and the label has |
| 1234 // nonempty text. |
| 1235 // internal |
| 1236 - (BOOL)shouldExposeTitleUIElement { |
| 1237 // VoiceOver ignores TitleUIElement if the element isn't a control. |
| 1238 if (!browserAccessibility_->IsControl()) |
| 1239 return false; |
| 1240 |
| 1241 ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>( |
| 1242 browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM)); |
| 1243 if (nameFrom != ui::AX_NAME_FROM_RELATED_ELEMENT) |
| 1244 return false; |
| 1245 |
| 1246 std::vector<int32_t> labelledby_ids = |
| 1247 browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS); |
| 1248 if (labelledby_ids.size() != 1) |
| 1249 return false; |
| 1250 |
| 1251 BrowserAccessibility* label = |
| 1252 browserAccessibility_->manager()->GetFromID(labelledby_ids[0]); |
| 1253 if (!label) |
| 1254 return false; |
| 1255 |
| 1256 std::string labelName = label->GetStringAttribute(ui::AX_ATTR_NAME); |
| 1257 return !labelName.empty(); |
| 1258 } |
| 1259 |
1240 // internal | 1260 // internal |
1241 - (content::BrowserAccessibilityDelegate*)delegate { | 1261 - (content::BrowserAccessibilityDelegate*)delegate { |
1242 return [self instanceActive] ? browserAccessibility_->manager()->delegate() | 1262 return [self instanceActive] ? browserAccessibility_->manager()->delegate() |
1243 : nil; | 1263 : nil; |
1244 } | 1264 } |
1245 | 1265 |
1246 - (content::BrowserAccessibility*)browserAccessibility { | 1266 - (content::BrowserAccessibility*)browserAccessibility { |
1247 return browserAccessibility_; | 1267 return browserAccessibility_; |
1248 } | 1268 } |
1249 | 1269 |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1709 return tabSubtree; | 1729 return tabSubtree; |
1710 } | 1730 } |
1711 | 1731 |
1712 - (NSString*)title { | 1732 - (NSString*)title { |
1713 if (![self instanceActive]) | 1733 if (![self instanceActive]) |
1714 return nil; | 1734 return nil; |
1715 // Mac OS X wants static text exposed in AXValue. | 1735 // Mac OS X wants static text exposed in AXValue. |
1716 if ([self shouldExposeNameInAXValue]) | 1736 if ([self shouldExposeNameInAXValue]) |
1717 return @""; | 1737 return @""; |
1718 | 1738 |
1719 // If the name came from a single related element and it's present in the | 1739 // If we're exposing the title in TitleUIElement, don't also redundantly |
1720 // tree, it will be exposed in AXTitleUIElement. | 1740 // expose it in AXDescription. |
1721 std::vector<int32_t> labelledby_ids = | 1741 if ([self shouldExposeTitleUIElement]) |
1722 browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS); | |
1723 ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>( | |
1724 browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM)); | |
1725 if (nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT && | |
1726 labelledby_ids.size() == 1 && | |
1727 browserAccessibility_->manager()->GetFromID(labelledby_ids[0])) { | |
1728 return @""; | 1742 return @""; |
1729 } | |
1730 | 1743 |
1731 // On Mac OS X, the accessible name of an object is exposed as its | 1744 // On Mac OS X, the accessible name of an object is exposed as its |
1732 // title if it comes from visible text, and as its description | 1745 // title if it comes from visible text, and as its description |
1733 // otherwise, but never both. | 1746 // otherwise, but never both. |
| 1747 ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>( |
| 1748 browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM)); |
1734 if (nameFrom == ui::AX_NAME_FROM_CONTENTS || | 1749 if (nameFrom == ui::AX_NAME_FROM_CONTENTS || |
1735 nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT || | 1750 nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT || |
1736 nameFrom == ui::AX_NAME_FROM_VALUE) { | 1751 nameFrom == ui::AX_NAME_FROM_VALUE) { |
1737 return NSStringForStringAttribute( | 1752 return NSStringForStringAttribute( |
1738 browserAccessibility_, ui::AX_ATTR_NAME); | 1753 browserAccessibility_, ui::AX_ATTR_NAME); |
1739 } | 1754 } |
1740 | 1755 |
1741 return nil; | 1756 return nil; |
1742 } | 1757 } |
1743 | 1758 |
1744 - (id)titleUIElement { | 1759 - (id)titleUIElement { |
1745 if (![self instanceActive]) | 1760 if (![self instanceActive]) |
1746 return nil; | 1761 return nil; |
| 1762 if (![self shouldExposeTitleUIElement]) |
| 1763 return nil; |
| 1764 |
1747 std::vector<int32_t> labelledby_ids = | 1765 std::vector<int32_t> labelledby_ids = |
1748 browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS); | 1766 browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS); |
1749 ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>( | 1767 ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>( |
1750 browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM)); | 1768 browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM)); |
1751 if (nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT && | 1769 if (nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT && |
1752 labelledby_ids.size() == 1) { | 1770 labelledby_ids.size() == 1) { |
1753 BrowserAccessibility* titleElement = | 1771 BrowserAccessibility* titleElement = |
1754 browserAccessibility_->manager()->GetFromID(labelledby_ids[0]); | 1772 browserAccessibility_->manager()->GetFromID(labelledby_ids[0]); |
1755 if (titleElement) | 1773 if (titleElement) |
1756 return ToBrowserAccessibilityCocoa(titleElement); | 1774 return ToBrowserAccessibilityCocoa(titleElement); |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2860 if (![self instanceActive]) | 2878 if (![self instanceActive]) |
2861 return [super hash]; | 2879 return [super hash]; |
2862 return browserAccessibility_->GetId(); | 2880 return browserAccessibility_->GetId(); |
2863 } | 2881 } |
2864 | 2882 |
2865 - (BOOL)accessibilityShouldUseUniqueId { | 2883 - (BOOL)accessibilityShouldUseUniqueId { |
2866 return YES; | 2884 return YES; |
2867 } | 2885 } |
2868 | 2886 |
2869 @end | 2887 @end |
OLD | NEW |