Modified: trunk/Source/WebCore/ChangeLog (287810 => 287811)
--- trunk/Source/WebCore/ChangeLog 2022-01-08 16:40:34 UTC (rev 287810)
+++ trunk/Source/WebCore/ChangeLog 2022-01-08 16:46:39 UTC (rev 287811)
@@ -1,5 +1,33 @@
2022-01-08 Tyler Wilcock <[email protected]>
+ AX: Improve WeakHashSet hygienics in AXObjectCache
+ https://bugs.webkit.org/show_bug.cgi?id=234961
+
+ Reviewed by Andres Gonzalez.
+
+ AXObjectCache owns four WeakHashSets. WeakHashSets are not notified
+ when the objects they hold are deleted[1], so we should be cleaning
+ them up in AXObjectCache::remove(Node&).
+
+ This patch also replaces range-based for loop iteration over these
+ WeakHashSets with WeakHashSet::forEach, which inherently checks that
+ each item is valid (non-null and contained in the hashset) before
+ using the item.
+
+ [1]: https://github.com/WebKit/WebKit/blob/main/Introduction.md#weakhashset
+
+ * accessibility/AXObjectCache.cpp:
+ (WebCore::AXObjectCache::remove):
+ Delete the removed node from AXObjectCache's owned WeakHashSets.
+ (WebCore::filterWeakHashSetForRemoval): Added.
+ (WebCore::AXObjectCache::prepareForDocumentDestruction):
+ Use filterWeakHashSetForRemoval to remove soon-to-be-deleted nodes
+ from AXObjectCache's owned WeakHashSets.
+ (WebCore::AXObjectCache::performDeferredCacheUpdate):
+ Use WeakHashSet::forEach instead of range-based for loops.
+
+2022-01-08 Tyler Wilcock <[email protected]>
+
AX: AccessibilityObject::setFocused(true) should make the webpage focused, and make web content the first responder
https://bugs.webkit.org/show_bug.cgi?id=234885
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (287810 => 287811)
--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2022-01-08 16:40:34 UTC (rev 287810)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2022-01-08 16:46:39 UTC (rev 287811)
@@ -863,6 +863,10 @@
m_deferredTextFormControlValue.remove(downcast<Element>(&node));
m_deferredAttributeChange.remove(downcast<Element>(&node));
m_modalElementsSet.remove(downcast<Element>(&node));
+ m_deferredRecomputeIsIgnoredList.remove(downcast<Element>(node));
+ m_deferredSelectedChildredChangedList.remove(downcast<Element>(node));
+ m_deferredModalChangedList.remove(downcast<Element>(node));
+ m_deferredMenuListChange.remove(downcast<Element>(node));
}
m_deferredChildrenChangedNodeList.remove(&node);
m_deferredTextChangedList.remove(&node);
@@ -3161,6 +3165,13 @@
conditionallyAddNodeToFilterList(node, document, nodesToRemove);
}
+static void filterWeakHashSetForRemoval(WeakHashSet<Element>& weakHashSet, const Document& document, HashSet<Ref<Node>>& nodesToRemove)
+{
+ weakHashSet.forEach([&] (auto& element) {
+ conditionallyAddNodeToFilterList(&element, document, nodesToRemove);
+ });
+}
+
void AXObjectCache::prepareForDocumentDestruction(const Document& document)
{
HashSet<Ref<Node>> nodesToRemove;
@@ -3168,6 +3179,10 @@
filterListForRemoval(m_modalElementsSet, document, nodesToRemove);
filterListForRemoval(m_deferredTextChangedList, document, nodesToRemove);
filterListForRemoval(m_deferredChildrenChangedNodeList, document, nodesToRemove);
+ filterWeakHashSetForRemoval(m_deferredRecomputeIsIgnoredList, document, nodesToRemove);
+ filterWeakHashSetForRemoval(m_deferredSelectedChildredChangedList, document, nodesToRemove);
+ filterWeakHashSetForRemoval(m_deferredModalChangedList, document, nodesToRemove);
+ filterWeakHashSetForRemoval(m_deferredMenuListChange, document, nodesToRemove);
filterMapForRemoval(m_deferredTextFormControlValue, document, nodesToRemove);
filterMapForRemoval(m_deferredAttributeChange, document, nodesToRemove);
filterVectorPairForRemoval(m_deferredFocusedNodeChange, document, nodesToRemove);
@@ -3218,14 +3233,15 @@
textChanged(node);
m_deferredTextChangedList.clear();
- for (auto& element : m_deferredRecomputeIsIgnoredList) {
+ m_deferredRecomputeIsIgnoredList.forEach([this] (auto& element) {
if (auto* renderer = element.renderer())
recomputeIsIgnored(renderer);
- }
+ });
m_deferredRecomputeIsIgnoredList.clear();
-
- for (auto& selectElement : m_deferredSelectedChildredChangedList)
+
+ m_deferredSelectedChildredChangedList.forEach([this] (auto& selectElement) {
selectedChildrenChanged(&selectElement);
+ });
m_deferredSelectedChildredChangedList.clear();
for (auto& deferredFormControlContext : m_deferredTextFormControlValue) {
@@ -3246,12 +3262,14 @@
}
m_deferredFocusedNodeChange.clear();
- for (auto& deferredModalChangedElement : m_deferredModalChangedList)
+ m_deferredModalChangedList.forEach([this] (auto& deferredModalChangedElement) {
handleModalChange(deferredModalChangedElement);
+ });
m_deferredModalChangedList.clear();
- for (auto& deferredMenuListChangeElement : m_deferredMenuListChange)
+ m_deferredMenuListChange.forEach([this] (auto& deferredMenuListChangeElement) {
postNotification(&deferredMenuListChangeElement, AXObjectCache::AXMenuListValueChanged);
+ });
m_deferredMenuListChange.clear();
platformPerformDeferredCacheUpdate();