Chromium Code Reviews| Index: third_party/WebKit/Source/modules/accessibility/AXObject.cpp |
| diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp |
| index fee64c6d8d0827216bf91915953c1d68b30addb7..f219ccaa2831c03906f7656fc988688823078546 100644 |
| --- a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp |
| +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp |
| @@ -330,7 +330,8 @@ const char* ariaWidgets[] = { |
| "timer", |
| "tooltip", |
| "treeitem", |
| - // Composite user interface widgets. This list is also from w3.org site refrerenced above. |
| + // Composite user interface widgets. |
| + // This list is also from the w3.org site referenced above. |
| "combobox", |
| "grid", |
| "listbox", |
| @@ -388,6 +389,7 @@ AXObject::AXObject(AXObjectCacheImpl& axObjectCache) |
| , m_cachedIsDescendantOfDisabledNode(false) |
| , m_cachedHasInheritedPresentationalRole(false) |
| , m_cachedIsPresentationalChild(false) |
| + , m_cachedAncestorExposesActiveDescendant(false) |
| , m_cachedLiveRegionRoot(nullptr) |
| , m_axObjectCache(&axObjectCache) |
| { |
| @@ -521,6 +523,7 @@ void AXObject::updateCachedAttributeValuesIfNeeded() const |
| m_cachedLiveRegionRoot = isLiveRegion() ? |
| this : |
| (parentObjectIfExists() ? parentObjectIfExists()->liveRegionRoot() : 0); |
| + m_cachedAncestorExposesActiveDescendant = computeAncestorExposesActiveDescendant(); |
| } |
| bool AXObject::accessibilityIsIgnoredByDefault(IgnoredReasons* ignoredReasons) const |
| @@ -676,6 +679,24 @@ bool AXObject::isPresentationalChild() const |
| return m_cachedIsPresentationalChild; |
| } |
| +bool AXObject::ancestorExposesActiveDescendant() const |
| +{ |
| + updateCachedAttributeValuesIfNeeded(); |
| + return m_cachedAncestorExposesActiveDescendant; |
| +} |
| + |
| +bool AXObject::computeAncestorExposesActiveDescendant() const |
| +{ |
| + for (const AXObject* object = this; object; object = object->parentObjectUnignored()) { |
|
dmazzoni
2016/04/06 15:51:12
Should this return true for itself or only for an
|
| + if (object->supportsActiveDescendant() |
| + && !object->getAttribute(aria_activedescendantAttr).isEmpty()) { |
| + return true; |
| + } |
| + } |
| + |
| + return false; |
| +} |
| + |
| // Simplify whitespace, but preserve a single leading and trailing whitespace character if it's present. |
| // static |
| String AXObject::collapseWhitespace(const String& str) |
| @@ -979,6 +1000,32 @@ bool AXObject::ariaPressedIsPresent() const |
| return !getAttribute(aria_pressedAttr).isEmpty(); |
| } |
| +bool AXObject::supportsActiveDescendant() const |
| +{ |
| + // According to the ARIA Spec, all ARIA composite widgets, ARIA text boxes |
| + // and ARIA groups should be able to expose an active descendant. |
| + // Implicitly, <input> and <textarea> elements should also have this ability. |
| + switch (ariaRoleAttribute()) { |
| + case ComboBoxRole: |
| + case GridRole: |
| + case GroupRole: |
| + case ListBoxRole: |
| + case MenuRole: |
| + case MenuBarRole: |
| + case RadioGroupRole: |
| + case RowRole: |
| + case SearchBoxRole: |
| + case TabListRole: |
| + case TextFieldRole: |
| + case ToolbarRole: |
| + case TreeRole: |
| + case TreeGridRole: |
| + return true; |
| + default: |
| + return false; |
| + } |
| +} |
| + |
| bool AXObject::supportsARIAAttributes() const |
| { |
| return isLiveRegion() |