Chromium Code Reviews| 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 |