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;