Changeset 270333 in webkit


Ignore:
Timestamp:
Dec 1, 2020 4:55:04 PM (20 months ago)
Author:
Chris Fleizach
Message:

AX: VoiceOver does not announce the aria-checked state for ARIA treeitem
https://bugs.webkit.org/show_bug.cgi?id=218316
<rdar://problem/70787809>

Reviewed by Zalan Bujtas.

Source/WebCore:

Tree items need to be able to support their aria-checked status according to WAI-ARIA.
In addition, when the value changes they need to be able to post an appropriate notification.
While working on this, I realized that if an attribute changes, the notification is not fired until the next layout change
which is problematic. Those need to fire immediately.

Test: accessibility/mac/checked-status-tree-items.html

accessibility/ios-simulator/checked-status-tree-items.html

  • accessibility/AXObjectCache.cpp:

(WebCore::AXObjectCache::deferAttributeChangeIfNeeded):

  • accessibility/AccessibilityNodeObject.cpp:

(WebCore::AccessibilityNodeObject::isChecked const):

  • accessibility/AccessibilityObject.cpp:

(WebCore::AccessibilityObject::supportsCheckedState const):

  • accessibility/AccessibilityObject.h:
  • accessibility/AccessibilityObjectInterface.h:
  • accessibility/AccessibilityTreeItem.cpp:

(WebCore::AccessibilityTreeItem::supportsCheckedState const):

  • accessibility/AccessibilityTreeItem.h:
  • accessibility/ios/AXObjectCacheIOS.mm:

(WebCore::AXObjectCache::postPlatformNotification):

  • accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:

(-[WebAccessibilityObjectWrapper accessibilityTraits]):
(-[WebAccessibilityObjectWrapper accessibilityValue]):

  • accessibility/isolatedtree/AXIsolatedObject.cpp:

(WebCore::AXIsolatedObject::initializeAttributeData):

  • accessibility/isolatedtree/AXIsolatedObject.h:
  • accessibility/isolatedtree/AXIsolatedTree.h:
  • accessibility/mac/WebAccessibilityObjectWrapperMac.mm:

(AXAttributedStringAppendText):
(-[WebAccessibilityObjectWrapper ALLOW_DEPRECATED_IMPLEMENTATIONS_END]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):

LayoutTests:

  • accessibility/ios-simulator/checked-status-tree-items-expected.txt: Added.
  • accessibility/ios-simulator/checked-status-tree-items.html: Added.
  • accessibility/mac/checked-status-tree-items-expected.txt: Added.
  • accessibility/mac/checked-status-tree-items.html: Added.
Location:
trunk
Files:
4 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r270329 r270333  
     12020-12-01  Chris Fleizach  <cfleizach@apple.com>
     2
     3        AX: VoiceOver does not announce the  aria-checked state for ARIA treeitem
     4        https://bugs.webkit.org/show_bug.cgi?id=218316
     5        <rdar://problem/70787809>
     6
     7        Reviewed by Zalan Bujtas.
     8
     9        * accessibility/ios-simulator/checked-status-tree-items-expected.txt: Added.
     10        * accessibility/ios-simulator/checked-status-tree-items.html: Added.
     11        * accessibility/mac/checked-status-tree-items-expected.txt: Added.
     12        * accessibility/mac/checked-status-tree-items.html: Added.
     13
    1142020-12-01  Truitt Savell  <tsavell@apple.com>
    215
  • trunk/LayoutTests/accessibility/ios-simulator/toggle-button-expected.txt

    r267644 r270333  
    66
    77Button1 : AXLabel: Bold
    8 Button1 : AXValue:
     8Button1 : AXValue: 0
    99Button2 : AXLabel: Italic
    1010Button2 : AXValue: 1
  • trunk/Source/WebCore/ChangeLog

    r270331 r270333  
     12020-12-01  Chris Fleizach  <cfleizach@apple.com>
     2
     3        AX: VoiceOver does not announce the  aria-checked state for ARIA treeitem
     4        https://bugs.webkit.org/show_bug.cgi?id=218316
     5        <rdar://problem/70787809>
     6
     7        Reviewed by Zalan Bujtas.
     8
     9        Tree items need to be able to support their aria-checked status according to WAI-ARIA.
     10        In addition, when the value changes they need to be able to post an appropriate notification.
     11        While working on this, I realized that if an attribute changes, the notification is not fired until the next layout change
     12        which is problematic. Those need to fire immediately.
     13
     14        Test: accessibility/mac/checked-status-tree-items.html
     15              accessibility/ios-simulator/checked-status-tree-items.html
     16
     17        * accessibility/AXObjectCache.cpp:
     18        (WebCore::AXObjectCache::deferAttributeChangeIfNeeded):
     19        * accessibility/AccessibilityNodeObject.cpp:
     20        (WebCore::AccessibilityNodeObject::isChecked const):
     21        * accessibility/AccessibilityObject.cpp:
     22        (WebCore::AccessibilityObject::supportsCheckedState const):
     23        * accessibility/AccessibilityObject.h:
     24        * accessibility/AccessibilityObjectInterface.h:
     25        * accessibility/AccessibilityTreeItem.cpp:
     26        (WebCore::AccessibilityTreeItem::supportsCheckedState const):
     27        * accessibility/AccessibilityTreeItem.h:
     28        * accessibility/ios/AXObjectCacheIOS.mm:
     29        (WebCore::AXObjectCache::postPlatformNotification):
     30        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
     31        (-[WebAccessibilityObjectWrapper accessibilityTraits]):
     32        (-[WebAccessibilityObjectWrapper accessibilityValue]):
     33        * accessibility/isolatedtree/AXIsolatedObject.cpp:
     34        (WebCore::AXIsolatedObject::initializeAttributeData):
     35        * accessibility/isolatedtree/AXIsolatedObject.h:
     36        * accessibility/isolatedtree/AXIsolatedTree.h:
     37        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
     38        (AXAttributedStringAppendText):
     39        (-[WebAccessibilityObjectWrapper ALLOW_DEPRECATED_IMPLEMENTATIONS_END]):
     40        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
     41
    1422020-12-01  Andres Gonzalez  <andresg_22@apple.com>
    243
  • trunk/Source/WebCore/accessibility/AXObjectCache.cpp

    r270238 r270333  
    17001700void AXObjectCache::deferAttributeChangeIfNeeded(const QualifiedName& attrName, Element* element)
    17011701{
    1702     if (nodeAndRendererAreValid(element) && rendererNeedsDeferredUpdate(*element->renderer()))
     1702    if (nodeAndRendererAreValid(element) && rendererNeedsDeferredUpdate(*element->renderer())) {
    17031703        m_deferredAttributeChange.add(element, attrName);
     1704        if (!m_performCacheUpdateTimer.isActive())
     1705            m_performCacheUpdateTimer.startOneShot(0_s);
     1706    }
    17041707    else
    17051708        handleAttributeChange(attrName, element);
  • trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp

    r269848 r270333  
    692692    case AccessibilityRole::MenuItemRadio:
    693693    case AccessibilityRole::Switch:
     694    case AccessibilityRole::TreeItem:
    694695        validRole = true;
    695696        break;
  • trunk/Source/WebCore/accessibility/AccessibilityObject.cpp

    r270154 r270333  
    14881488
    14891489    return getAttribute(aria_readonlyAttr).string().convertToASCIILowercase();
     1490}
     1491
     1492bool AccessibilityObject::supportsCheckedState() const
     1493{
     1494    auto role = roleValue();
     1495    return isCheckboxOrRadio()
     1496    || role == AccessibilityRole::MenuItemCheckbox
     1497    || role == AccessibilityRole::MenuItemRadio
     1498    || role == AccessibilityRole::Switch
     1499    || isToggleButton();
    14901500}
    14911501
  • trunk/Source/WebCore/accessibility/AccessibilityObject.h

    r269923 r270333  
    276276    double estimatedLoadingProgress() const override { return 0; }
    277277    WEBCORE_EXPORT static bool isARIAControl(AccessibilityRole);
    278 
     278    bool supportsCheckedState() const override;
     279   
    279280    bool supportsARIAOwns() const override { return false; }
    280281    bool isActiveDescendantOfFocusedContainer() const override;
  • trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h

    r270041 r270333  
    958958    virtual FloatRect relativeFrame() const = 0;
    959959    virtual FloatRect convertFrameToSpace(const FloatRect&, AccessibilityConversionSpace) const = 0;
    960 
     960    virtual bool supportsCheckedState() const = 0;
     961   
    961962    // In a multi-select list, many items can be selected but only one is active at a time.
    962963    virtual bool isSelectedOptionActive() const = 0;
  • trunk/Source/WebCore/accessibility/AccessibilityTreeItem.cpp

    r223728 r270333  
    4949}
    5050
     51bool AccessibilityTreeItem::supportsCheckedState() const
     52{
     53    return hasAttribute(aria_checkedAttr);
     54}
     55
    5156AccessibilityRole AccessibilityTreeItem::determineAccessibilityRole()
    5257{
  • trunk/Source/WebCore/accessibility/AccessibilityTreeItem.h

    r208179 r270333  
    3939
    4040    bool shouldIgnoreAttributeRole() const override { return !m_isTreeItemValid; }
     41    bool supportsCheckedState() const override;
    4142
    4243private:
  • trunk/Source/WebCore/accessibility/ios/AXObjectCacheIOS.mm

    r266805 r270333  
    7676            [obj->wrapper() postInvalidStatusChangedNotification];
    7777            break;
     78        case AXCheckedStateChanged:
    7879        case AXValueChanged:
    7980            [obj->wrapper() postValueChangedNotification];
     81            notificationString = @"AXValueChanged";
    8082            break;
    8183        case AXExpandedChanged:
     
    8385            break;
    8486        case AXSelectedChildrenChanged:
    85         case AXCheckedStateChanged:
    8687        default:
    8788            break;
  • trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm

    r268610 r270333  
    852852        traits |= [self _axNotEnabledTrait];
    853853   
     854    // If the treeitem supports the checked state, then it should also be marked with toggle status.
     855    if (self.axBackingObject->supportsCheckedState())
     856        traits |= [self _axToggleTrait];
     857
    854858    if (m_accessibilityTraitsFromAncestor == ULLONG_MAX)
    855859        m_accessibilityTraitsFromAncestor = [self _accessibilityTraitsFromAncestors];
     
    14471451        return value;
    14481452   
    1449     AccessibilityRole role = self.axBackingObject->roleValue();
    1450     if (self.axBackingObject->isCheckboxOrRadio() || role == AccessibilityRole::MenuItemCheckbox || role == AccessibilityRole::MenuItemRadio || role == AccessibilityRole::Switch) {
     1453    if (self.axBackingObject->supportsCheckedState()) {
    14511454        switch (self.axBackingObject->checkboxOrRadioValue()) {
    14521455        case AccessibilityButtonState::Off:
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp

    r270331 r270333  
    230230    setObjectProperty(AXPropertyName::NextSibling, object.nextSibling());
    231231    setObjectProperty(AXPropertyName::PreviousSibling, object.previousSibling());
     232    setProperty(AXPropertyName::SupportsCheckedState, object.supportsCheckedState());
    232233
    233234    if (object.isTable()) {
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h

    r270331 r270333  
    353353    bool isIncrementor() const override { return boolAttributeValue(AXPropertyName::IsIncrementor); }
    354354    AccessibilityChildrenVector documentLinks() override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::DocumentLinks)); }
     355    bool supportsCheckedState() const override { return boolAttributeValue(AXPropertyName::SupportsCheckedState); }
    355356
    356357    String stringValue() const override { return stringAttributeValue(AXPropertyName::StringValue); }
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h

    r270238 r270333  
    281281    SupportsDropping,
    282282    SupportsARIAOwns,
     283    SupportsCheckedState,
    283284    SupportsCurrent,
    284285    SupportsDatetimeAttribute,
  • trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm

    r270281 r270333  
    11481148    // skip invisible text
    11491149    RenderObject* renderer = node->renderer();
    1150     if (!renderer)
     1150    if (!renderer || !text.length())
    11511151        return;
    11521152   
     
    17241724        [tempArray addObject:NSAccessibilityDisclosureLevelAttribute];
    17251725        [tempArray addObject:NSAccessibilityDisclosedRowsAttribute];
     1726        [tempArray removeObject:NSAccessibilityValueAttribute];
    17261727        outlineRowAttrs = [[NSArray alloc] initWithArray:tempArray];
    17271728        [tempArray release];
     
    17601761    } else if (backingObject->isTree())
    17611762        objectAttributes = outlineAttrs;
    1762     else if (backingObject->isTreeItem())
    1763         objectAttributes = outlineRowAttrs;
     1763    else if (backingObject->isTreeItem()) {
     1764        if (backingObject->supportsCheckedState())
     1765            objectAttributes = [outlineRowAttrs arrayByAddingObject:NSAccessibilityValueAttribute];
     1766        else
     1767            objectAttributes = outlineRowAttrs;
     1768    }
    17641769    else if (backingObject->isListBox())
    17651770        objectAttributes = listBoxAttrs;
     
    24732478            return @(backingObject->headingLevel());
    24742479
    2475         if (backingObject->isCheckboxOrRadio() || backingObject->isMenuItem() || backingObject->isSwitch() || backingObject->isToggleButton()) {
     2480        if (backingObject->supportsCheckedState()) {
    24762481            switch (backingObject->checkboxOrRadioValue()) {
    24772482            case AccessibilityButtonState::Off:
Note: See TracChangeset for help on using the changeset viewer.