Chromium Code Reviews| Index: third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
| diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
| index 8713c736a3613bee0c0e32bfd6be86cc1dea3d69..8ed9e39f7a0a5a197fab42e6dbbea34758f5554d 100644 |
| --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
| +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
| @@ -143,6 +143,28 @@ void AXNodeObject::alterSliderValue(bool increase) |
| axObjectCache().postNotification(getNode(), AXObjectCacheImpl::AXValueChanged); |
| } |
| +AXObject* AXNodeObject::activeDescendant() const |
| +{ |
| + if (!getNode() || !getNode()->isElementNode()) |
| + return nullptr; |
| + |
| + const AtomicString& activeDescendantAttr = getAttribute(aria_activedescendantAttr); |
| + if (activeDescendantAttr.isNull() || activeDescendantAttr.isEmpty()) |
| + return nullptr; |
| + |
| + Element* element = toElement(getNode()); |
| + Element* descendant = element->treeScope().getElementById(activeDescendantAttr); |
| + if (!descendant) |
| + return nullptr; |
| + |
| + AXObject* axDescendant = axObjectCache().getOrCreate(descendant); |
| + // An active descendant is only useful if it has a layoutObject, because that's what's needed to post the notification. |
|
dmazzoni
2016/04/05 05:37:22
You can post a notification on any AXObject, so th
|
| + if (axDescendant && axDescendant->isAXLayoutObject()) |
| + return axDescendant; |
| + |
| + return nullptr; |
| +} |
| + |
| String AXNodeObject::ariaAccessibilityDescription() const |
| { |
| String ariaLabelledby = ariaLabelledbyAttribute(); |
| @@ -1065,19 +1087,21 @@ bool AXNodeObject::isRequired() const |
| bool AXNodeObject::canSetFocusAttribute() const |
| { |
| - Node* node = this->getNode(); |
| + Node* node = getNode(); |
| if (!node) |
| return false; |
| if (isWebArea()) |
| return true; |
| + // Children of elements with an aria-activedescendant attribute should be |
| + // focusable if they have an ARIA role. |
| + if (ariaRoleAttribute() != UnknownRole && ancestorExposesActiveDescendant()) |
| + return true; |
| + |
| // NOTE: It would be more accurate to ask the document whether setFocusedNode() would |
| // do anything. For example, setFocusedNode() will do nothing if the current focused |
| // node will not relinquish the focus. |
| - if (!node) |
| - return false; |
| - |
| if (isDisabledFormControl(node)) |
| return false; |
| @@ -1100,6 +1124,15 @@ bool AXNodeObject::canSetValueAttribute() const |
| return !isReadOnly(); |
| } |
| +bool AXNodeObject::canSetSelectedAttribute() const |
| +{ |
| + // ARIA list box options can be selected if they are children of an element |
| + // with an aria-activedescendant attribute. |
| + if (ariaRoleAttribute() == ListBoxOptionRole && ancestorExposesActiveDescendant()) |
| + return true; |
| + return AXObject::canSetSelectedAttribute(); |
| +} |
| + |
| bool AXNodeObject::canvasHasFallbackContent() const |
| { |
| Node* node = this->getNode(); |