Commit c9781f04 authored by Nektarios Paisios's avatar Nektarios Paisios Committed by Commit Bot

Adding a tabindex to a span element should expose the span to accessibility

R=dmazzoni@chromium.org, aleventhal@chromium.org

Tested: Manually with Jaws, layout test
Change-Id: Iddc30de6ad10825dd9f99af059d89032cba5af98
Reviewed-on: https://chromium-review.googlesource.com/990537
Commit-Queue: Nektarios Paisios <nektar@chromium.org>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Reviewed-by: default avatarAaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548452}
parent 42a1454b
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<p id="p"><span tabindex="0">hello</span>there</p>
<script>
test(() => {
let axParagraph = accessibilityController.accessibleElementById('p');
assert_not_equals(axParagraph, null);
let axSpan = axParagraph.childAtIndex(0);
assert_not_equals(axSpan, null);
assert_equals(axSpan.role, "AXRole: AXGenericContainer");
assert_true(axSpan.isFocusable);
}, 'Ensure that spans with a tabindex get a focusable state.');
</script>
......@@ -566,6 +566,9 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (layout_object_->IsBR())
return false;
if (CanSetFocusAttribute())
return false;
if (IsLink())
return false;
......@@ -660,28 +663,13 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (RoleValue() == kTimeRole)
return false;
if (RoleValue() == kProgressIndicatorRole) {
if (RoleValue() == kProgressIndicatorRole)
return false;
}
// if this element has aria attributes on it, it should not be ignored.
if (SupportsARIAAttributes())
return false;
// <span> tags are inline tags and not meant to convey information if they
// have no other aria information on them. If we don't ignore them, they may
// emit signals expected to come from their parent. In addition, because
// included spans are GroupRole objects, and GroupRole objects are often
// containers with meaningful information, the inclusion of a span can have
// the side effect of causing the immediate parent accessible to be ignored.
// This is especially problematic for platforms which have distinct roles for
// textual block elements.
if (IsHTMLSpanElement(node)) {
if (ignored_reasons)
ignored_reasons->push_back(IgnoredReason(kAXUninteresting));
return true;
}
if (IsImage())
return false;
......@@ -714,10 +702,14 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
!GetAttribute(altAttr).IsEmpty() || !GetAttribute(titleAttr).IsEmpty())
return false;
// Don't ignore generic focusable elements like <div tabindex=0>
// unless they're completely empty, with no children.
if (IsGenericFocusableElement() && node->hasChildren())
return false;
// <span> tags are inline tags and not meant to convey information if they
// have no other ARIA information on them. If we don't ignore them, they may
// emit signals expected to come from their parent.
if (IsHTMLSpanElement(node)) {
if (ignored_reasons)
ignored_reasons->push_back(IgnoredReason(kAXUninteresting));
return true;
}
// Positioned elements and scrollable containers are important for
// determining bounding boxes.
......
......@@ -606,41 +606,6 @@ bool AXNodeObject::IsTextControl() const {
}
}
bool AXNodeObject::IsGenericFocusableElement() const {
if (!CanSetFocusAttribute())
return false;
// If it's a control, it's not generic.
if (IsControl())
return false;
// If it has an aria role, it's not generic.
if (aria_role_ != kUnknownRole)
return false;
// If the content editable attribute is set on this element, that's the reason
// it's focusable, and existing logic should handle this case already - so
// it's not a generic focusable element.
if (HasContentEditableAttributeSet())
return false;
// The web area and body element are both focusable, but existing logic
// handles these cases already, so we don't need to include them here.
if (RoleValue() == kWebAreaRole)
return false;
if (IsHTMLBodyElement(GetNode()))
return false;
// An SVG root is focusable by default, but it's probably not interactive, so
// don't include it. It can still be made accessible by giving it an ARIA
// role.
if (RoleValue() == kSVGRootRole)
return false;
return true;
}
AXObject* AXNodeObject::MenuButtonForMenu() const {
Element* menu_item = MenuItemElementForMenu();
......
......@@ -70,9 +70,6 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
bool HasContentEditableAttributeSet() const;
bool IsTextControl() const override;
// This returns true if it's focusable but it's not content editable and it's
// not a control or ARIA control.
bool IsGenericFocusableElement() const;
AXObject* MenuButtonForMenu() const;
AXObject* MenuButtonForMenuIfExists() const;
Element* MenuItemElementForMenu() const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment