Title: [259633] trunk/Source/WebCore
Revision
259633
Author
[email protected]
Date
2020-04-07 04:52:25 -0700 (Tue, 07 Apr 2020)

Log Message

Initialization of modal nodes should happen lazily, not in the AXObjectCache constructor.
https://bugs.webkit.org/show_bug.cgi?id=210090

Reviewed by Chris Fleizach.

- The initialization of modal nodes was performed in the AXObjectCache
constructor, which is not necessary. Instead, this change performs the
initialization of the modal nodes before they are needed.
- updateCurrentModalNode was replaced with currentModalNode, and its
implementation cleaned up.
- Now the initialization and update of AXObjectCached::m_modalNodesSet
and m_currentMOdalNode is clearer.

* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::AXObjectCache):
(WebCore::AXObjectCache::findModalNodes):
(WebCore::AXObjectCache::currentModalNode const):
(WebCore::AXObjectCache::modalNode):
(WebCore::AXObjectCache::handleModalChange):
(WebCore::AXObjectCache::updateCurrentModalNode): Renamed currentModalNode.
* accessibility/AXObjectCache.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (259632 => 259633)


--- trunk/Source/WebCore/ChangeLog	2020-04-07 11:14:01 UTC (rev 259632)
+++ trunk/Source/WebCore/ChangeLog	2020-04-07 11:52:25 UTC (rev 259633)
@@ -1,3 +1,27 @@
+2020-04-07  Andres Gonzalez  <[email protected]>
+
+        Initialization of modal nodes should happen lazily, not in the AXObjectCache constructor.
+        https://bugs.webkit.org/show_bug.cgi?id=210090
+
+        Reviewed by Chris Fleizach.
+
+        - The initialization of modal nodes was performed in the AXObjectCache
+        constructor, which is not necessary. Instead, this change performs the
+        initialization of the modal nodes before they are needed.
+        - updateCurrentModalNode was replaced with currentModalNode, and its
+        implementation cleaned up.
+        - Now the initialization and update of AXObjectCached::m_modalNodesSet
+        and m_currentMOdalNode is clearer.
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::AXObjectCache):
+        (WebCore::AXObjectCache::findModalNodes):
+        (WebCore::AXObjectCache::currentModalNode const):
+        (WebCore::AXObjectCache::modalNode):
+        (WebCore::AXObjectCache::handleModalChange):
+        (WebCore::AXObjectCache::updateCurrentModalNode): Renamed currentModalNode.
+        * accessibility/AXObjectCache.h:
+
 2020-04-07  Youenn Fablet  <[email protected]>
 
         Remove unnecessary memory allocation from RealtimeIncomingAudioSourceCocoa::OnData

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (259632 => 259633)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2020-04-07 11:14:01 UTC (rev 259632)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2020-04-07 11:52:25 UTC (rev 259633)
@@ -221,7 +221,6 @@
     , m_currentModalNode(nullptr)
     , m_performCacheUpdateTimer(*this, &AXObjectCache::performCacheUpdateTimerFired)
 {
-    findModalNodes();
 }
 
 AXObjectCache::~AXObjectCache()
@@ -244,50 +243,45 @@
 {
     // Traverse the DOM tree to look for the aria-modal=true nodes.
     for (Element* element = ElementTraversal::firstWithin(document().rootNode()); element; element = ElementTraversal::nextIncludingPseudo(*element)) {
-        
         // Must have dialog or alertdialog role
         if (!nodeHasRole(element, "dialog") && !nodeHasRole(element, "alertdialog"))
             continue;
         if (!equalLettersIgnoringASCIICase(element->attributeWithoutSynchronization(aria_modalAttr), "true"))
             continue;
-        
+
         m_modalNodesSet.add(element);
     }
-    
-    // Set the current valid aria-modal node if possible.
-    updateCurrentModalNode();
+
+    m_modalNodesInitialized = true;
 }
 
-void AXObjectCache::updateCurrentModalNode()
+Node* AXObjectCache::currentModalNode()
 {
     // There might be multiple nodes with aria-modal=true set.
     // We use this function to pick the one we want.
     m_currentModalNode = nullptr;
     if (m_modalNodesSet.isEmpty())
-        return;
-    
-    // We only care about the nodes which are visible.
-    ListHashSet<RefPtr<Node>> visibleNodes;
-    for (auto& object : m_modalNodesSet) {
-        if (isNodeVisible(object))
-            visibleNodes.add(object);
-    }
-    
-    if (visibleNodes.isEmpty())
-        return;
-    
-    // If any of the node are keyboard focused, we want to pick that.
-    Node* focusedNode = document().focusedElement();
-    for (auto& object : visibleNodes) {
-        if (focusedNode != nullptr && focusedNode->isDescendantOf(object.get())) {
-            m_currentModalNode = object.get();
-            break;
+        return nullptr;
+
+    // If any of the modal nodes contains the keyboard focus, we want to pick that one.
+    // If not, we want to pick the last visible dialog in the DOM.
+    RefPtr<Element> focusedElement = document().focusedElement();
+    RefPtr<Node> lastVisible;
+    for (auto& node : m_modalNodesSet) {
+        if (isNodeVisible(node)) {
+            if (focusedElement && focusedElement->isDescendantOf(node)) {
+                m_currentModalNode = node;
+                break;
+            }
+
+            lastVisible = node;
         }
     }
-    
-    // If none of the nodes are focused, we want to pick the last dialog in the DOM.
+
     if (!m_currentModalNode)
-        m_currentModalNode = visibleNodes.last().get();
+        m_currentModalNode = lastVisible.get();
+
+    return m_currentModalNode;
 }
 
 bool AXObjectCache::isNodeVisible(Node* node) const
@@ -312,17 +306,21 @@
 Node* AXObjectCache::modalNode()
 {
     // This function returns the valid aria modal node.
+    if (!m_modalNodesInitialized) {
+        findModalNodes();
+        return currentModalNode();
+    }
+
     if (m_modalNodesSet.isEmpty())
         return nullptr;
-    
-    // Check the current valid aria modal node first.
+
+    // Check the cached current valid aria modal node first.
     // Usually when one dialog sets aria-modal=true, that dialog is the one we want.
     if (isNodeVisible(m_currentModalNode))
         return m_currentModalNode;
-    
+
     // Recompute the valid aria modal node when m_currentModalNode is null or hidden.
-    updateCurrentModalNode();
-    return isNodeVisible(m_currentModalNode) ? m_currentModalNode : nullptr;
+    return currentModalNode();
 }
 
 AccessibilityObject* AXObjectCache::focusedImageMapUIElement(HTMLAreaElement* areaElement)
@@ -1679,11 +1677,15 @@
 {
     if (!is<Element>(node))
         return;
-    
+
     if (!nodeHasRole(node, "dialog") && !nodeHasRole(node, "alertdialog"))
         return;
-    
+
     stopCachingComputedObjectAttributes();
+
+    if (!m_modalNodesInitialized)
+        findModalNodes();
+
     if (equalLettersIgnoringASCIICase(downcast<Element>(*node).attributeWithoutSynchronization(aria_modalAttr), "true")) {
         // Add the newly modified node to the modal nodes set, and set it to be the current valid aria modal node.
         // We will recompute the current valid aria modal node in modalNode() when this node is not visible.
@@ -1692,11 +1694,12 @@
     } else {
         // Remove the node from the modal nodes set. There might be other visible modal nodes, so we recompute here.
         m_modalNodesSet.remove(node);
-        updateCurrentModalNode();
+        currentModalNode();
     }
+
     if (m_currentModalNode)
         focusModalNode();
-    
+
     startCachingComputedObjectAttributesUntilTreeMutates();
 }
 

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (259632 => 259633)


--- trunk/Source/WebCore/accessibility/AXObjectCache.h	2020-04-07 11:14:01 UTC (rev 259632)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h	2020-04-07 11:52:25 UTC (rev 259633)
@@ -452,7 +452,7 @@
 
     // aria-modal related
     void findModalNodes();
-    void updateCurrentModalNode();
+    Node* currentModalNode();
     bool isNodeVisible(Node*) const;
     void handleModalChange(Node*);
 
@@ -478,11 +478,12 @@
     
     Timer m_liveRegionChangedPostTimer;
     ListHashSet<RefPtr<AccessibilityObject>> m_liveRegionObjectsSet;
-    
+
     Timer m_focusModalNodeTimer;
     Node* m_currentModalNode;
     ListHashSet<Node*> m_modalNodesSet;
-    
+    bool m_modalNodesInitialized { false };
+
     Timer m_performCacheUpdateTimer;
 
     AXTextStateChangeIntent m_textSelectionIntent;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to