Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Side by Side Diff: content/browser/accessibility/browser_accessibility_win.cc

Issue 10823073: Improve accessible name calculation on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | content/browser/accessibility/dump_accessibility_tree_browsertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 // The calculation of the accessible name of an element has been
2730 // standardized in the HTML to Platform Accessibility APIs Implementation
2731 // Guide (http://www.w3.org/TR/html-aapi/). In order to return the
2732 // appropriate accessible name on Windows, we need to apply some logic
2733 // to the fields we get from WebKit.
2734 //
2735 // TODO(dmazzoni): move most of this logic into WebKit.
2736 //
2737 // WebKit gives us:
2738 //
2739 // name: the default name, e.g. inner text
2740 // title ui element: a reference to a <label> element on the same
2741 // page that labels this node.
2742 // description: accessible labels that override the default name:
2743 // aria-label or aria-labelledby or aria-describedby
2744 // help: the value of the "title" attribute
2745 //
2746 // On Windows, the logic we apply lets some fields take precedence and
2747 // always returns the primary name in "name" and the secondary name,
2748 // if any, in "description".
2749
2750 string16 description, help, title_attr;
2751 int title_elem_id = 0;
2752 GetIntAttribute(AccessibilityNodeData::ATTR_TITLE_UI_ELEMENT, &title_elem_id);
2753 GetStringAttribute(AccessibilityNodeData::ATTR_DESCRIPTION, &description);
2754 GetStringAttribute(AccessibilityNodeData::ATTR_HELP, &help);
2755
2756 // WebKit annoyingly puts the title in the description if there's no other
2757 // description, which just confuses the rest of the logic. Put it back.
2758 // Now "help" is always the value of the "title" attribute, if present.
2759 if (GetHtmlAttribute("title", &title_attr) &&
2760 description == title_attr &&
2761 help.empty()) {
2762 help = description;
2763 description = L"";
2764 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = L"";
2765 string_attributes_[AccessibilityNodeData::ATTR_HELP] = help;
2766 }
2767
2768 // Now implement the main logic: the descripion should become the name if
2769 // it's nonempty, and the help should become the description if
2770 // there's no description - or the name if there's no name or description.
2771 if (!description.empty()) {
2772 name_ = description;
2773 description = L"";
2774 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = description;
2775 }
2776 if (!help.empty() && description.empty()) {
2777 description = help;
2778 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = help;
2779 string_attributes_[AccessibilityNodeData::ATTR_HELP] = L"";
2780 }
2781 if (!description.empty() && name_.empty() && !title_elem_id) {
2782 name_ = description;
2783 description = L"";
2784 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = L"";
2785 }
2786
2787 // If it's a text field, also consider the placeholder.
2788 string16 placeholder;
2789 if (role_ == AccessibilityNodeData::ROLE_TEXT_FIELD &&
2790 HasState(AccessibilityNodeData::STATE_FOCUSABLE) &&
2791 GetHtmlAttribute("placeholder", &placeholder)) {
2792 if (name_.empty() && !title_elem_id) {
2793 name_ = placeholder;
2794 } else if (description.empty()) {
2795 description = placeholder;
2796 string_attributes_[AccessibilityNodeData::ATTR_DESCRIPTION] = description;
2797 }
2798 }
2799
2800 // For certain roles (listbox option, static text, and list marker)
2801 // WebKit stores the main accessible text in the "value" - swap it so
2802 // that it's the "name".
2729 if (name_.empty() && 2803 if (name_.empty() &&
2730 (role_ == AccessibilityNodeData::ROLE_LISTBOX_OPTION || 2804 (role_ == AccessibilityNodeData::ROLE_LISTBOX_OPTION ||
2731 role_ == AccessibilityNodeData::ROLE_STATIC_TEXT || 2805 role_ == AccessibilityNodeData::ROLE_STATIC_TEXT ||
2732 role_ == AccessibilityNodeData::ROLE_LIST_MARKER)) { 2806 role_ == AccessibilityNodeData::ROLE_LIST_MARKER)) {
2733 name_.swap(value_); 2807 name_.swap(value_);
2734 } 2808 }
2735 2809
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 2810 // 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. 2811 // attribute. This allows screen readers to read an empty link's destination.
2744 string16 url; 2812 string16 url;
2745 if (value_.empty() && (ia_state_ & STATE_SYSTEM_LINKED)) 2813 if (value_.empty() && (ia_state_ & STATE_SYSTEM_LINKED))
2746 GetStringAttribute(AccessibilityNodeData::ATTR_URL, &value_); 2814 GetStringAttribute(AccessibilityNodeData::ATTR_URL, &value_);
2747 2815
2748 // Clear any old relationships between this node and other nodes. 2816 // Clear any old relationships between this node and other nodes.
2749 for (size_t i = 0; i < relations_.size(); ++i) 2817 for (size_t i = 0; i < relations_.size(); ++i)
2750 relations_[i]->Release(); 2818 relations_[i]->Release();
2751 relations_.clear(); 2819 relations_.clear();
2752 2820
2753 // Handle title UI element. 2821 // Handle title UI element.
2754 int title_elem_id; 2822 if (title_elem_id) {
2755 if (GetIntAttribute(AccessibilityNodeData::ATTR_TITLE_UI_ELEMENT,
2756 &title_elem_id)) {
2757 // Add a labelled by relationship. 2823 // Add a labelled by relationship.
2758 CComObject<BrowserAccessibilityRelation>* relation; 2824 CComObject<BrowserAccessibilityRelation>* relation;
2759 HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance( 2825 HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance(
2760 &relation); 2826 &relation);
2761 DCHECK(SUCCEEDED(hr)); 2827 DCHECK(SUCCEEDED(hr));
2762 relation->AddRef(); 2828 relation->AddRef();
2763 relation->Initialize(this, IA2_RELATION_LABELLED_BY); 2829 relation->Initialize(this, IA2_RELATION_LABELLED_BY);
2764 relation->AddTarget(title_elem_id); 2830 relation->AddTarget(title_elem_id);
2765 relations_.push_back(relation); 2831 relations_.push_back(relation);
2766 } 2832 }
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
3411 ia_state_ |= STATE_SYSTEM_READONLY; 3477 ia_state_ |= STATE_SYSTEM_READONLY;
3412 3478
3413 // The role should always be set. 3479 // The role should always be set.
3414 DCHECK(!role_name_.empty() || ia_role_); 3480 DCHECK(!role_name_.empty() || ia_role_);
3415 3481
3416 // If we didn't explicitly set the IAccessible2 role, make it the same 3482 // If we didn't explicitly set the IAccessible2 role, make it the same
3417 // as the MSAA role. 3483 // as the MSAA role.
3418 if (!ia2_role_) 3484 if (!ia2_role_)
3419 ia2_role_ = ia_role_; 3485 ia2_role_ = ia_role_;
3420 } 3486 }
OLDNEW
« no previous file with comments | « no previous file | content/browser/accessibility/dump_accessibility_tree_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698