Changeset 227144 in webkit


Ignore:
Timestamp:
Jan 18, 2018 9:26:23 AM (6 years ago)
Author:
Chris Fleizach
Message:

AX: Aria-activedescendant not supported
https://bugs.webkit.org/show_bug.cgi?id=161734
<rdar://problem/28202679>

Reviewed by Joanmarie Diggs.

Source/WebCore:

When a combo-box owns/controls a list/listbox/grid/tree, the owned element needs to check the active-descendant of the combobox when
checking if it has selected children.
The target of the selection change notification should also be the owned element in these cases.

Test: accessibility/aria-combobox-controlling-list.html

  • accessibility/AccessibilityObject.cpp:

(WebCore::AccessibilityObject::selectedListItem):

  • accessibility/AccessibilityObject.h:
  • accessibility/AccessibilityRenderObject.cpp:

(WebCore::AccessibilityRenderObject::targetElementForActiveDescendant const):
(WebCore::AccessibilityRenderObject::handleActiveDescendantChanged):
(WebCore::AccessibilityRenderObject::canHaveSelectedChildren const):
(WebCore::AccessibilityRenderObject::selectedChildren):

  • accessibility/AccessibilityRenderObject.h:
  • accessibility/mac/AXObjectCacheMac.mm:

(WebCore::AXObjectCache::postPlatformNotification):

LayoutTests:

  • accessibility/aria-combobox-control-owns-elements-expected.txt: Added.
  • accessibility/aria-combobox-control-owns-elements.html: Added.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r227143 r227144  
     12018-01-18  Chris Fleizach  <cfleizach@apple.com>
     2
     3        AX: Aria-activedescendant not supported
     4        https://bugs.webkit.org/show_bug.cgi?id=161734
     5        <rdar://problem/28202679>
     6
     7        Reviewed by Joanmarie Diggs.
     8
     9        * accessibility/aria-combobox-control-owns-elements-expected.txt: Added.
     10        * accessibility/aria-combobox-control-owns-elements.html: Added.
     11
    1122018-01-18  Per Arne Vollan  <pvollan@apple.com>
    213
  • trunk/LayoutTests/accessibility/lists-expected.txt

    r198356 r227144  
    3939AXEditableAncestor: (null)
    4040AXHighestEditableAncestor: (null)
    41 AXSelectedChildren: (null)
     41AXSelectedChildren: <array of size 0>
    4242AXVisibleChildren: <array of size 2>
    4343AXOrientation: AXVerticalOrientation
     
    7373AXEditableAncestor: (null)
    7474AXHighestEditableAncestor: (null)
    75 AXSelectedChildren: (null)
     75AXSelectedChildren: <array of size 0>
    7676AXVisibleChildren: <array of size 2>
    7777AXOrientation: AXVerticalOrientation
  • trunk/Source/WebCore/ChangeLog

    r227141 r227144  
     12018-01-18  Chris Fleizach  <cfleizach@apple.com>
     2
     3        AX: Aria-activedescendant not supported
     4        https://bugs.webkit.org/show_bug.cgi?id=161734
     5        <rdar://problem/28202679>
     6
     7        Reviewed by Joanmarie Diggs.
     8
     9        When a combo-box owns/controls a list/listbox/grid/tree, the owned element needs to check the active-descendant of the combobox when
     10        checking if it has selected children.
     11        The target of the selection change notification should also be the owned element in these cases.
     12
     13        Test: accessibility/aria-combobox-controlling-list.html
     14
     15        * accessibility/AccessibilityObject.cpp:
     16        (WebCore::AccessibilityObject::selectedListItem):
     17        * accessibility/AccessibilityObject.h:
     18        * accessibility/AccessibilityRenderObject.cpp:
     19        (WebCore::AccessibilityRenderObject::targetElementForActiveDescendant const):
     20        (WebCore::AccessibilityRenderObject::handleActiveDescendantChanged):
     21        (WebCore::AccessibilityRenderObject::canHaveSelectedChildren const):
     22        (WebCore::AccessibilityRenderObject::selectedChildren):
     23        * accessibility/AccessibilityRenderObject.h:
     24        * accessibility/mac/AXObjectCacheMac.mm:
     25        (WebCore::AXObjectCache::postPlatformNotification):
     26
    1272018-01-17  Per Arne Vollan  <pvollan@apple.com>
    228
  • trunk/Source/WebCore/accessibility/AccessibilityObject.cpp

    r227006 r227144  
    34113411    return is<HTMLInputElement>(element) && downcast<HTMLInputElement>(*element).isPasswordField();
    34123412}
     3413   
     3414AccessibilityObject* AccessibilityObject::selectedListItem()
     3415{
     3416    for (const auto& child : children()) {
     3417        if (child->isListItem() && (child->isSelected() || child->isActiveDescendantOfFocusedContainer()))
     3418            return child.get();
     3419    }
     3420   
     3421    return nullptr;
     3422}
    34133423
    34143424void AccessibilityObject::ariaElementsFromAttribute(AccessibilityChildrenVector& children, const QualifiedName& attributeName) const
  • trunk/Source/WebCore/accessibility/AccessibilityObject.h

    r226432 r227144  
    661661    virtual AccessibilityObject* selectedRadioButton() { return nullptr; }
    662662    virtual AccessibilityObject* selectedTabItem() { return nullptr; }
     663    AccessibilityObject* selectedListItem();
    663664    virtual int layoutCount() const { return 0; }
    664665    virtual double estimatedLoadingProgress() const { return 0; }
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp

    r226432 r227144  
    24962496        cache->postNotification(this, document(), AXObjectCache::AXExpandedChanged);
    24972497}
     2498   
     2499RenderObject* AccessibilityRenderObject::targetElementForActiveDescendant(const QualifiedName& attributeName, AccessibilityObject* activeDescendant) const
     2500{
     2501    AccessibilityObject::AccessibilityChildrenVector elements;
     2502    ariaElementsFromAttribute(elements, attributeName);
     2503    for (auto element : elements) {
     2504        if (activeDescendant->isDescendantOfObject(element.get()))
     2505            return element->renderer();
     2506    }
     2507
     2508    return nullptr;
     2509}
    24982510
    24992511void AccessibilityRenderObject::handleActiveDescendantChanged()
     
    25052517        return;
    25062518
    2507     if (activeDescendant() && shouldNotifyActiveDescendant())
    2508         renderer()->document().axObjectCache()->postNotification(renderer(), AXObjectCache::AXActiveDescendantChanged);
     2519    auto* activeDescendant = this->activeDescendant();
     2520    if (activeDescendant && shouldNotifyActiveDescendant()) {
     2521        auto* targetRenderer = renderer();
     2522       
     2523#if PLATFORM(COCOA)
     2524        // If the combobox's activeDescendant is inside another object, the target element should be that parent.
     2525        if (isComboBox()) {
     2526            if (auto* ariaOwner = targetElementForActiveDescendant(aria_ownsAttr, activeDescendant))
     2527                targetRenderer = ariaOwner;
     2528            else if (auto* ariaController = targetElementForActiveDescendant(aria_controlsAttr, activeDescendant))
     2529                targetRenderer = ariaController;
     2530        }
     2531#endif
     2532   
     2533        renderer()->document().axObjectCache()->postNotification(targetRenderer, AXObjectCache::AXActiveDescendantChanged);
     2534    }
    25092535}
    25102536
     
    33003326    case AccessibilityRole::Tree:
    33013327    case AccessibilityRole::TreeGrid:
     3328    case AccessibilityRole::List:
    33023329    // These roles are containers whose children are treated as selected by assistive
    33033330    // technologies. We can get the "selected" item via aria-activedescendant or the
     
    33273354    auto rowsIteration = [&](auto& rows) {
    33283355        for (auto& row : rows) {
    3329             if (row->isSelected()) {
     3356            if (row->isSelected() || row->isActiveDescendantOfFocusedContainer()) {
    33303357                result.append(row);
    33313358                if (!isMulti)
     
    33513378    for (const auto& child : children()) {
    33523379        // Every child should have aria-role option, and if so, check for selected attribute/state.
    3353         if (child->isSelected() && child->ariaRoleAttribute() == AccessibilityRole::ListBoxOption) {
     3380        if (child->ariaRoleAttribute() == AccessibilityRole::ListBoxOption && (child->isSelected() || child->isActiveDescendantOfFocusedContainer())) {
    33543381            result.append(child);
    33553382            if (!isMulti)
     
    33793406        if (AccessibilityObject* selectedTab = selectedTabItem())
    33803407            result.append(selectedTab);
     3408        return;
     3409    case AccessibilityRole::List:
     3410        if (auto* selectedListItemChild = selectedListItem())
     3411            result.append(selectedListItemChild);
    33813412        return;
    33823413    case AccessibilityRole::Menu:
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h

    r226432 r227144  
    286286    bool shouldGetTextFromNode(AccessibilityTextUnderElementMode) const;
    287287
     288    RenderObject* targetElementForActiveDescendant(const QualifiedName&, AccessibilityObject*) const;
    288289    bool canHavePlainText() const;
    289290};
  • trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm

    r222898 r227144  
    272272        case AXActiveDescendantChanged:
    273273            // An active descendant change for trees means a selected rows change.
    274             if (obj->isTree())
     274            if (obj->isTree() || obj->isTable())
    275275                macNotification = NSAccessibilitySelectedRowsChangedNotification;
    276276           
     
    278278            // list has changed. In these cases we should use selected children changed, because
    279279            // we don't want the focus to change away from the combobox where the user is typing.
    280             else if (obj->isComboBox())
     280            else if (obj->isComboBox() || obj->isList() || obj->isListBox())
    281281                macNotification = NSAccessibilitySelectedChildrenChangedNotification;
    282282            else
Note: See TracChangeset for help on using the changeset viewer.