Title: [294167] trunk/Source/WebCore
Revision
294167
Author
andresg...@apple.com
Date
2022-05-13 11:22:07 -0700 (Fri, 13 May 2022)

Log Message

Move handling of active descendant changed notifications out of AccessibilityRenderObject.
https://bugs.webkit.org/show_bug.cgi?id=240357
<rdar://problem/93196901>

Reviewed by Chris Fleizach.

No change in functionality.

AXObjectCache::handleActiveDescendantChanged now handles this
notifications as appropriate. This makes the code cleaner and more
straightforward. More importantly this change is necessary for the
refactoring of relationships implementation.

* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::handleActiveDescendantChanged):
(WebCore::AXObjectCache::handleAttributeChange):
* accessibility/AXObjectCache.h:
(WebCore::AXObjectCache::handleActiveDescendantChanged):
* accessibility/AccessibilityObject.h:
* accessibility/AccessibilityObjectInterface.h:
(WebCore::Accessibility::findRelatedObjectInAncestry):
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::activeDescendant const):
(WebCore::AccessibilityRenderObject::shouldNotifyActiveDescendant const): Deleted.
(WebCore::AccessibilityRenderObject::targetElementForActiveDescendant const): Deleted.
(WebCore::AccessibilityRenderObject::handleActiveDescendantChanged): Deleted.
* accessibility/AccessibilityRenderObject.h:
* accessibility/isolatedtree/AXIsolatedObject.cpp:
(WebCore::AXIsolatedObject::handleActiveDescendantChanged): Deleted.
* accessibility/isolatedtree/AXIsolatedObject.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (294166 => 294167)


--- trunk/Source/WebCore/ChangeLog	2022-05-13 18:06:14 UTC (rev 294166)
+++ trunk/Source/WebCore/ChangeLog	2022-05-13 18:22:07 UTC (rev 294167)
@@ -1,3 +1,36 @@
+2022-05-13  Andres Gonzalez  <andresg...@apple.com>
+
+        Move handling of active descendant changed notifications out of AccessibilityRenderObject.
+        https://bugs.webkit.org/show_bug.cgi?id=240357
+        <rdar://problem/93196901>
+
+        Reviewed by Chris Fleizach.
+
+        No change in functionality.
+
+        AXObjectCache::handleActiveDescendantChanged now handles this
+        notifications as appropriate. This makes the code cleaner and more
+        straightforward. More importantly this change is necessary for the
+        refactoring of relationships implementation.
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::handleActiveDescendantChanged):
+        (WebCore::AXObjectCache::handleAttributeChange):
+        * accessibility/AXObjectCache.h:
+        (WebCore::AXObjectCache::handleActiveDescendantChanged):
+        * accessibility/AccessibilityObject.h:
+        * accessibility/AccessibilityObjectInterface.h:
+        (WebCore::Accessibility::findRelatedObjectInAncestry):
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::activeDescendant const):
+        (WebCore::AccessibilityRenderObject::shouldNotifyActiveDescendant const): Deleted.
+        (WebCore::AccessibilityRenderObject::targetElementForActiveDescendant const): Deleted.
+        (WebCore::AccessibilityRenderObject::handleActiveDescendantChanged): Deleted.
+        * accessibility/AccessibilityRenderObject.h:
+        * accessibility/isolatedtree/AXIsolatedObject.cpp:
+        (WebCore::AXIsolatedObject::handleActiveDescendantChanged): Deleted.
+        * accessibility/isolatedtree/AXIsolatedObject.h:
+
 2022-05-13  Anjali Kumar  <anjalik...@apple.com>
 
         Web Inspector: [Meta] Implement Timelines Film Strip

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (294166 => 294167)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2022-05-13 18:06:14 UTC (rev 294166)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2022-05-13 18:22:07 UTC (rev 294167)
@@ -1800,10 +1800,33 @@
     }
 }
 
-void AXObjectCache::handleActiveDescendantChanged(Node* node)
+void AXObjectCache::handleActiveDescendantChanged(Element& element)
 {
-    if (AccessibilityObject* obj = getOrCreate(node))
-        obj->handleActiveDescendantChanged();
+    if (!document().frame()->selection().isFocusedAndActive() || document().focusedElement() != &element)
+        return;
+
+    auto* object = getOrCreate(&element);
+    if (!object)
+        return;
+
+    auto* activeDescendant = object->activeDescendant();
+    // We want to notify that the combo box has changed its active descendant,
+    // but we do not want to change the focus, because focus should remain with the combo box.
+    if (activeDescendant && (object->isComboBox() || object->shouldFocusActiveDescendant())) {
+        auto target = object;
+
+#if PLATFORM(COCOA)
+        // If the combobox's activeDescendant is inside a descendant owned or controlled by the combobox, that descendant should be the target of the notification and not the combobox itself.
+        if (object->isComboBox()) {
+            if (auto* ownedObject = Accessibility::findRelatedObjectInAncestry(*object, aria_ownsAttr, *activeDescendant))
+                target = ownedObject;
+            else if (auto* controlledObject = Accessibility::findRelatedObjectInAncestry(*object, aria_controlsAttr, *activeDescendant))
+                target = controlledObject;
+        }
+#endif
+
+        postNotification(target, &document(), AXActiveDescendantChanged);
+    }
 }
 
 void AXObjectCache::handleRoleChange(AccessibilityObject* axObject)
@@ -1878,7 +1901,7 @@
         return;
 
     if (attrName == aria_activedescendantAttr)
-        handleActiveDescendantChanged(element);
+        handleActiveDescendantChanged(*element);
     else if (attrName == aria_busyAttr)
         postNotification(element, AXObjectCache::AXElementBusyChanged);
     else if (attrName == aria_valuenowAttr || attrName == aria_valuetextAttr)

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (294166 => 294167)


--- trunk/Source/WebCore/accessibility/AXObjectCache.h	2022-05-13 18:06:14 UTC (rev 294166)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h	2022-05-13 18:22:07 UTC (rev 294167)
@@ -468,7 +468,9 @@
     void selectedStateChanged(Node*);
     // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
     void textChanged(Node*);
-    void handleActiveDescendantChanged(Node*);
+
+    void handleActiveDescendantChanged(Element&);
+
     void handleAriaExpandedChange(Node*);
     void handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
     void handleMenuListValueChanged(Element&);
@@ -599,7 +601,7 @@
 inline void AXObjectCache::performCacheUpdateTimerFired() { }
 inline void AXObjectCache::frameLoadingEventNotification(Frame*, AXLoadingEvent) { }
 inline void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject*, AXLoadingEvent) { }
-inline void AXObjectCache::handleActiveDescendantChanged(Node*) { }
+inline void AXObjectCache::handleActiveDescendantChanged(Element&) { }
 inline void AXObjectCache::handleAriaExpandedChange(Node*) { }
 inline void AXObjectCache::handleModalChange(Element&) { }
 inline void AXObjectCache::deferModalChange(Element*) { }

Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (294166 => 294167)


--- trunk/Source/WebCore/accessibility/AccessibilityObject.h	2022-05-13 18:06:14 UTC (rev 294166)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h	2022-05-13 18:22:07 UTC (rev 294167)
@@ -536,7 +536,6 @@
     void tabChildren(AccessibilityChildrenVector&) override { }
     bool shouldFocusActiveDescendant() const override { return false; }
     AccessibilityObject* activeDescendant() const override { return nullptr; }
-    void handleActiveDescendantChanged() override { }
     AccessibilityObject* firstAnonymousBlockChild() const override;
 
     WEBCORE_EXPORT static AccessibilityRole ariaRoleToWebCoreRole(const String&);
@@ -786,6 +785,8 @@
     String documentEncoding() const override;
     AccessibilityChildrenVector documentLinks() override { return AccessibilityChildrenVector(); }
 
+    AccessibilityChildrenVector ariaElementsFromAttribute(const QualifiedName&) const;
+    AccessibilityChildrenVector ariaElementsReferencedByAttribute(const QualifiedName&) const;
 protected:
     AccessibilityObject() = default;
 
@@ -812,8 +813,6 @@
 
     static bool isARIAInput(AccessibilityRole);
 
-    AccessibilityChildrenVector ariaElementsFromAttribute(const QualifiedName&) const;
-    AccessibilityChildrenVector ariaElementsReferencedByAttribute(const QualifiedName&) const;
     virtual bool exposesTitleUIElement() const { return true; }
     FloatRect unobscuredContentRect() const override;
     AccessibilityObject* radioGroupAncestor() const;

Modified: trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h (294166 => 294167)


--- trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h	2022-05-13 18:06:14 UTC (rev 294166)
+++ trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h	2022-05-13 18:22:07 UTC (rev 294167)
@@ -1266,7 +1266,6 @@
     virtual void tabChildren(AccessibilityChildrenVector&) = 0;
     virtual bool shouldFocusActiveDescendant() const = 0;
     virtual AXCoreObject* activeDescendant() const = 0;
-    virtual void handleActiveDescendantChanged() = 0;
     bool isDescendantOfObject(const AXCoreObject*) const;
     bool isAncestorOfObject(const AXCoreObject*) const;
     virtual AXCoreObject* firstAnonymousBlockChild() const = 0;
@@ -1617,6 +1616,20 @@
     return nullptr;
 }
 
+template<typename T>
+T* findRelatedObjectInAncestry(const T& object, const QualifiedName& relationAttribute, const T& descendant)
+{
+    auto relatedObjects = object.ariaElementsFromAttribute(relationAttribute);
+    for (const auto& object : relatedObjects) {
+        auto* ancestor = findAncestor(descendant, false, [&object] (const auto& ancestor) {
+            return object.get() == &ancestor;
+        });
+        if (ancestor)
+            return ancestor;
+    }
+    return nullptr;
+}
+
 void findMatchingObjects(AccessibilitySearchCriteria const&, AXCoreObject::AccessibilityChildrenVector&);
 
 template<typename T, typename F>

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (294166 => 294167)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2022-05-13 18:06:14 UTC (rev 294166)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2022-05-13 18:22:07 UTC (rev 294167)
@@ -2650,16 +2650,6 @@
     return result;
 }
 
-bool AccessibilityRenderObject::shouldNotifyActiveDescendant() const
-{
-    // We want to notify that the combo box has changed its active descendant,
-    // but we do not want to change the focus, because focus should remain with the combo box.
-    if (isComboBox())
-        return true;
-    
-    return shouldFocusActiveDescendant();
-}
-
 bool AccessibilityRenderObject::shouldFocusActiveDescendant() const
 {
     switch (ariaRoleAttribute()) {
@@ -2691,67 +2681,13 @@
 
 AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
 {
-    if (!m_renderer)
-        return nullptr;
-    
-    const AtomString& activeDescendantAttrStr = getAttribute(aria_activedescendantAttr);
-    if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
-        return nullptr;
-    Element* element = this->element();
-    if (!element)
-        return nullptr;
-    
-    Element* target = element->treeScope().getElementById(activeDescendantAttrStr);
-    if (!target)
-        return nullptr;
-    
-    if (AXObjectCache* cache = axObjectCache()) {
-        AccessibilityObject* obj = cache->getOrCreate(target);
-        if (obj && obj->isAccessibilityRenderObject())
-            // an activedescendant is only useful if it has a renderer, because that's what's needed to post the notification
-            return obj;
-    }
-    
+    auto activeDescendants = ariaElementsFromAttribute(aria_activedescendantAttr);
+    ASSERT(activeDescendants.size() <= 1);
+    if (!activeDescendants.isEmpty())
+        return downcast<AccessibilityObject>(activeDescendants[0].get());
     return nullptr;
 }
 
-RenderObject* AccessibilityRenderObject::targetElementForActiveDescendant(const QualifiedName& attributeName, AccessibilityObject* activeDescendant) const
-{
-    auto objects = ariaElementsFromAttribute(attributeName);
-    for (const auto& object : objects) {
-        if (activeDescendant->isDescendantOfObject(object.get()))
-            return object->renderer();
-    }
-
-    return nullptr;
-}
-
-void AccessibilityRenderObject::handleActiveDescendantChanged()
-{
-    Element* element = downcast<Element>(renderer()->node());
-    if (!element)
-        return;
-    if (!renderer()->frame().selection().isFocusedAndActive() || renderer()->document().focusedElement() != element)
-        return;
-
-    auto* activeDescendant = this->activeDescendant();
-    if (activeDescendant && shouldNotifyActiveDescendant()) {
-        auto* targetRenderer = renderer();
-        
-#if PLATFORM(COCOA)
-        // If the combobox's activeDescendant is inside another object, the target element should be that parent.
-        if (isComboBox()) {
-            if (auto* ariaOwner = targetElementForActiveDescendant(aria_ownsAttr, activeDescendant))
-                targetRenderer = ariaOwner;
-            else if (auto* ariaController = targetElementForActiveDescendant(aria_controlsAttr, activeDescendant))
-                targetRenderer = ariaController;
-        }
-#endif
-    
-        renderer()->document().axObjectCache()->postNotification(targetRenderer, AXObjectCache::AXActiveDescendantChanged);
-    }
-}
-
 bool AccessibilityRenderObject::renderObjectIsObservable(RenderObject& renderer) const
 {
     // AX clients will listen for AXValueChange on a text control.

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h (294166 => 294167)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h	2022-05-13 18:06:14 UTC (rev 294166)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h	2022-05-13 18:22:07 UTC (rev 294167)
@@ -151,9 +151,7 @@
     void visibleChildren(AccessibilityChildrenVector&) override;
     void tabChildren(AccessibilityChildrenVector&) override;
     bool shouldFocusActiveDescendant() const override;
-    bool shouldNotifyActiveDescendant() const;
     AccessibilityObject* activeDescendant() const override;
-    void handleActiveDescendantChanged() override;
 
     VisiblePositionRange visiblePositionRange() const override;
     VisiblePositionRange visiblePositionRangeForLine(unsigned) const override;
@@ -282,7 +280,6 @@
     String applePayButtonDescription() const;
 #endif
 
-    RenderObject* targetElementForActiveDescendant(const QualifiedName&, AccessibilityObject*) const;
     bool canHavePlainText() const;
     // Special handling of click point for links.
     IntPoint linkClickPoint();

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp (294166 => 294167)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2022-05-13 18:06:14 UTC (rev 294166)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2022-05-13 18:22:07 UTC (rev 294167)
@@ -2183,11 +2183,6 @@
     return nullptr;
 }
 
-void AXIsolatedObject::handleActiveDescendantChanged()
-{
-    ASSERT_NOT_REACHED();
-}
-
 OptionSet<AXAncestorFlag> AXIsolatedObject::ancestorFlags() const
 {
     auto value = m_propertyMap.get(AXPropertyName::AncestorFlags);

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h (294166 => 294167)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2022-05-13 18:06:14 UTC (rev 294166)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2022-05-13 18:22:07 UTC (rev 294167)
@@ -612,7 +612,6 @@
     void detachFromParent() override;
     bool shouldFocusActiveDescendant() const override;
     AXCoreObject* activeDescendant() const override;
-    void handleActiveDescendantChanged() override;
 
     OptionSet<AXAncestorFlag> ancestorFlags() const;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to