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

Unified Diff: Source/modules/accessibility/AXLayoutObject.cpp

Issue 1039873002: AX presentation role should be inherited to its required owned elements. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: Source/modules/accessibility/AXLayoutObject.cpp
diff --git a/Source/modules/accessibility/AXLayoutObject.cpp b/Source/modules/accessibility/AXLayoutObject.cpp
index 7f100c1271312000019fbb27417d78c37303d96d..b1f9e6de07da523a46259d2171ab9238f475f61e 100644
--- a/Source/modules/accessibility/AXLayoutObject.cpp
+++ b/Source/modules/accessibility/AXLayoutObject.cpp
@@ -45,6 +45,10 @@
#include "core/html/HTMLLabelElement.h"
#include "core/html/HTMLOptionElement.h"
#include "core/html/HTMLSelectElement.h"
+#include "core/html/HTMLTableCellElement.h"
+#include "core/html/HTMLTableElement.h"
+#include "core/html/HTMLTableRowElement.h"
+#include "core/html/HTMLTableSectionElement.h"
#include "core/html/HTMLTextAreaElement.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/layout/HitTestResult.h"
@@ -171,6 +175,7 @@ AXLayoutObject::AXLayoutObject(LayoutObject* layoutObject, AXObjectCacheImpl* ax
: AXNodeObject(layoutObject->node(), axObjectCache)
, m_layoutObject(layoutObject)
, m_cachedElementRectDirty(true)
+ , m_hasInheritedPresentationRole(false)
{
#if ENABLE(ASSERT)
m_layoutObject->setHasAXObject(true);
@@ -546,6 +551,7 @@ bool AXLayoutObject::computeAccessibilityIsIgnored() const
#if ENABLE(ASSERT)
ASSERT(m_initialized);
#endif
+ m_hasInheritedPresentationRole = false;
// Check first if any of the common reasons cause this element to be ignored.
// Then process other use cases that need to be applied to all the various roles
@@ -563,7 +569,12 @@ bool AXLayoutObject::computeAccessibilityIsIgnored() const
if (roleValue() == IgnoredRole)
return true;
- if ((roleValue() == NoneRole || roleValue() == PresentationalRole) || inheritsPresentationalRole())
+ if (roleValue() == NoneRole || roleValue() == PresentationalRole) {
+ m_hasInheritedPresentationRole = true;
dmazzoni 2015/03/29 07:46:22 I don't want to compute this inside computeAccessi
je_julie(Not used) 2015/03/31 16:14:27 I added computeHasInheritedPresentationRole.
+ return true;
+ }
+
+ if (inheritsPresentationalRole())
return true;
// An ARIA tree can only have tree items and static text as children.
@@ -2328,27 +2339,90 @@ bool AXLayoutObject::inheritsPresentationalRole() const
if (canSetFocusAttribute())
return false;
- // ARIA spec says that when a parent object is presentational, and it has required child elements,
- // those child elements are also presentational. For example, <li> becomes presentational from <ul>.
- // http://www.w3.org/WAI/PF/aria/complete#presentation
- if (roleValue() != ListItemRole && roleValue() != ListMarkerRole)
+ // http://www.w3.org/TR/wai-aria/complete#presentation
+ // ARIA spec says that the user agent MUST apply an inherited role of presentation
+ // to any owned elements that do not have an explicit role defined.
+ if (ariaRoleAttribute() != UnknownRole)
return false;
AXObject* parent = parentObject();
- if (!parent->isAXLayoutObject())
+ if (!parent)
return false;
- Node* elementNode = toAXLayoutObject(parent)->node();
- if (!elementNode || !elementNode->isElementNode())
+ // The parent should have presentationalRole.
+ if (!isPresentationRole(parent) && !isPresentationRoleInTable(parent))
+ return false;
+
+ // ARIA spec says that when a parent object is presentational, and it has required owned elements,
+ // those elements are also presentational. For example, <li> becomes presentational from <ul>.
+ return m_hasInheritedPresentationRole = isRequiredOwnedElement(parent);
+}
+
+bool AXLayoutObject::isRequiredOwnedElement(AXObject* parent) const
+{
+ if (!parent->isAXLayoutObject())
return false;
- QualifiedName tagName = toElement(elementNode)->tagQName();
- if (tagName != ulTag && tagName != olTag && tagName != dlTag)
+ Node* parentNode = toAXLayoutObject(parent)->node();
+ if (!parentNode || !parentNode->isElementNode())
return false;
- if (parent->roleValue() == NoneRole || parent->roleValue() == PresentationalRole)
- return ariaRoleAttribute() == UnknownRole;
+ AccessibilityRole role = roleValue();
+
+ if (role == ListItemRole)
+ return isListElement(parentNode);
+ if (role == ListMarkerRole)
+ return isHTMLLIElement(*parentNode);
+ if (role == MenuItemCheckBoxRole || role == MenuItemRole || role == MenuItemRadioRole)
+ return isHTMLMenuElement(*parentNode);
+
+ Node* curNode = node();
+ if (isHTMLTableCellElement(curNode))
+ return isHTMLTableRowElement(*parentNode);
+ if (isHTMLTableRowElement(curNode))
+ return isHTMLTableSectionElement(*parentNode);
+
+ // In case of ListboxRole and it's child, ListBoxOptionRole,
+ // Inheritance of presentation role is handled in AXListBoxOption
+ // Because ListBoxOption Role doesn't have any child.
+ // If it's just ignored because of presentation, we can't see any AX tree related to ListBoxOption.
+ return false;
+}
+
+bool AXLayoutObject::isListElement(Node* node) const
+{
+ return isHTMLUListElement(*node) || isHTMLOListElement(*node) || isHTMLDListElement(*node);
+}
+
+bool AXLayoutObject::isPresentationRole(AXObject* parent) const
+{
+ return parent->roleValue() == NoneRole || parent->roleValue() == PresentationalRole
+ || parent->hasInheritedPresentationRole();
+}
+
+bool AXLayoutObject::isPresentationRoleInTable(AXObject* parent) const
+{
+ Node* parentNode = parent->node();
+ if (!parentNode || !parentNode->isElementNode())
+ return false;
+ Node* curNode = node();
+ // AXTable determines the role as checking isTableXXX.
+ // If Table has explicit role including presentation, AXTable doesn't assign implicit Role
+ // to a whole Table. That's why we should check it based on node.
+ // Normal Table Tree is that
+ // cell(its role)-> tr(tr role)-> tfoot, tbody, thead(ignored role) -> table(table role).
+ // If table has presentation role, it will be like
+ // cell(group)-> tr(unknown) -> tfoot, tbody, thead(ignored) -> table(presentation).
+ if (isHTMLTableCellElement(curNode) && isHTMLTableRowElement(*parentNode))
+ return parent->hasInheritedPresentationRole();
+
+ if (isHTMLTableRowElement(curNode) && isHTMLTableSectionElement(*parentNode)) {
+ // Because TableSections have ignored role, presentation should be checked with its parent node
+ AXObject* tableObject = parent->parentObject();
+ Node* tableNode = tableObject->node();
+ return isHTMLTableElement(tableNode) && tableObject->hasInheritedPresentationRole();
+ }
return false;
}

Powered by Google App Engine
This is Rietveld 408576698