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 "content/browser/accessibility/browser_accessibility_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_win.h" |
6 | 6 |
7 #include <UIAutomationClient.h> | 7 #include <UIAutomationClient.h> |
8 #include <UIAutomationCoreApi.h> | 8 #include <UIAutomationCoreApi.h> |
9 | 9 |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
(...skipping 2708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2719 } | 2719 } |
2720 if (index >= 0) { | 2720 if (index >= 0) { |
2721 ia2_attributes_.push_back(string16(L"table-cell-index:") + | 2721 ia2_attributes_.push_back(string16(L"table-cell-index:") + |
2722 base::IntToString16(index)); | 2722 base::IntToString16(index)); |
2723 } | 2723 } |
2724 } else { | 2724 } else { |
2725 NOTREACHED(); | 2725 NOTREACHED(); |
2726 } | 2726 } |
2727 } | 2727 } |
2728 | 2728 |
2729 // WebKit computes accessible name, description and help strings from the | |
2730 // html source, but on Windows, the help should become the description if | |
2731 // there's no description, and then the description should become the name | |
2732 // if there's no name. | |
2733 string16 description, help; | |
2734 int title_elem_id = 0; | |
2735 GetIntAttribute(AccessibilityNodeData::ATTR_TITLE_UI_ELEMENT, &title_elem_id); | |
2736 GetStringAttribute(AccessibilityNodeData::ATTR_DESCRIPTION, &description); | |
2737 GetStringAttribute(AccessibilityNodeData::ATTR_HELP, &help); | |
2738 if (!description.empty()) { | |
2739 name_ = description; | |
aboxhall
2012/08/06 01:55:49
I'm confused by this line. Is name_ always empty a
| |
2740 description = L""; | |
2741 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = description; | |
2742 } | |
2743 if (!help.empty() && description.empty()) { | |
2744 description = help; | |
2745 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = help; | |
2746 string_attributes_[AccessibilityNodeData::ATTR_HELP] = L""; | |
2747 } | |
2748 if (!description.empty() && name_.empty() && !title_elem_id) { | |
2749 name_ = description; | |
2750 description = L""; | |
2751 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = L""; | |
2752 } | |
2753 | |
2754 // If it's a text field, also consider the placeholder. | |
2755 string16 placeholder; | |
2756 if (role_ == AccessibilityNodeData::ROLE_TEXT_FIELD && | |
2757 HasState(AccessibilityNodeData::STATE_FOCUSABLE) && | |
2758 GetHtmlAttribute("placeholder", &placeholder)) { | |
2759 if (name_.empty() && !title_elem_id) { | |
2760 name_ = placeholder; | |
2761 } else if (description.empty()) { | |
2762 description = placeholder; | |
2763 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = description; | |
2764 } else { | |
2765 description = description + L" " + placeholder; | |
aboxhall
2012/08/06 01:55:49
As I said elsewhere, I'm not sure this is the best
| |
2766 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = description; | |
2767 } | |
2768 } | |
2769 | |
2729 if (name_.empty() && | 2770 if (name_.empty() && |
2730 (role_ == AccessibilityNodeData::ROLE_LISTBOX_OPTION || | 2771 (role_ == AccessibilityNodeData::ROLE_LISTBOX_OPTION || |
2731 role_ == AccessibilityNodeData::ROLE_STATIC_TEXT || | 2772 role_ == AccessibilityNodeData::ROLE_STATIC_TEXT || |
2732 role_ == AccessibilityNodeData::ROLE_LIST_MARKER)) { | 2773 role_ == AccessibilityNodeData::ROLE_LIST_MARKER)) { |
2733 name_.swap(value_); | 2774 name_.swap(value_); |
2734 } | 2775 } |
2735 | 2776 |
2736 // If this object doesn't have a name but it does have a description, | |
2737 // use the description as its name - because some screen readers only | |
2738 // announce the name. | |
2739 if (name_.empty()) | |
2740 GetStringAttribute(AccessibilityNodeData::ATTR_DESCRIPTION, &name_); | |
2741 | |
2742 // If this doesn't have a value and is linked then set its value to the url | 2777 // If this doesn't have a value and is linked then set its value to the url |
2743 // attribute. This allows screen readers to read an empty link's destination. | 2778 // attribute. This allows screen readers to read an empty link's destination. |
2744 string16 url; | 2779 string16 url; |
2745 if (value_.empty() && (ia_state_ & STATE_SYSTEM_LINKED)) | 2780 if (value_.empty() && (ia_state_ & STATE_SYSTEM_LINKED)) |
2746 GetStringAttribute(AccessibilityNodeData::ATTR_URL, &value_); | 2781 GetStringAttribute(AccessibilityNodeData::ATTR_URL, &value_); |
2747 | 2782 |
2748 // Clear any old relationships between this node and other nodes. | 2783 // Clear any old relationships between this node and other nodes. |
2749 for (size_t i = 0; i < relations_.size(); ++i) | 2784 for (size_t i = 0; i < relations_.size(); ++i) |
2750 relations_[i]->Release(); | 2785 relations_[i]->Release(); |
2751 relations_.clear(); | 2786 relations_.clear(); |
2752 | 2787 |
2753 // Handle title UI element. | 2788 // Handle title UI element. |
2754 int title_elem_id; | 2789 if (title_elem_id) { |
2755 if (GetIntAttribute(AccessibilityNodeData::ATTR_TITLE_UI_ELEMENT, | |
2756 &title_elem_id)) { | |
2757 // Add a labelled by relationship. | 2790 // Add a labelled by relationship. |
2758 CComObject<BrowserAccessibilityRelation>* relation; | 2791 CComObject<BrowserAccessibilityRelation>* relation; |
2759 HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance( | 2792 HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance( |
2760 &relation); | 2793 &relation); |
2761 DCHECK(SUCCEEDED(hr)); | 2794 DCHECK(SUCCEEDED(hr)); |
2762 relation->AddRef(); | 2795 relation->AddRef(); |
2763 relation->Initialize(this, IA2_RELATION_LABELLED_BY); | 2796 relation->Initialize(this, IA2_RELATION_LABELLED_BY); |
2764 relation->AddTarget(title_elem_id); | 2797 relation->AddTarget(title_elem_id); |
2765 relations_.push_back(relation); | 2798 relations_.push_back(relation); |
2766 } | 2799 } |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3411 ia_state_ |= STATE_SYSTEM_READONLY; | 3444 ia_state_ |= STATE_SYSTEM_READONLY; |
3412 | 3445 |
3413 // The role should always be set. | 3446 // The role should always be set. |
3414 DCHECK(!role_name_.empty() || ia_role_); | 3447 DCHECK(!role_name_.empty() || ia_role_); |
3415 | 3448 |
3416 // If we didn't explicitly set the IAccessible2 role, make it the same | 3449 // If we didn't explicitly set the IAccessible2 role, make it the same |
3417 // as the MSAA role. | 3450 // as the MSAA role. |
3418 if (!ia2_role_) | 3451 if (!ia2_role_) |
3419 ia2_role_ = ia_role_; | 3452 ia2_role_ = ia_role_; |
3420 } | 3453 } |
OLD | NEW |