Changeset 259633 in webkit


Ignore:
Timestamp:
Apr 7, 2020 4:52:25 AM (4 years ago)
Author:
Andres Gonzalez
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:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r259632 r259633  
     12020-04-07  Andres Gonzalez  <andresg_22@apple.com>
     2
     3        Initialization of modal nodes should happen lazily, not in the AXObjectCache constructor.
     4        https://bugs.webkit.org/show_bug.cgi?id=210090
     5
     6        Reviewed by Chris Fleizach.
     7
     8        - The initialization of modal nodes was performed in the AXObjectCache
     9        constructor, which is not necessary. Instead, this change performs the
     10        initialization of the modal nodes before they are needed.
     11        - updateCurrentModalNode was replaced with currentModalNode, and its
     12        implementation cleaned up.
     13        - Now the initialization and update of AXObjectCached::m_modalNodesSet
     14        and m_currentMOdalNode is clearer.
     15
     16        * accessibility/AXObjectCache.cpp:
     17        (WebCore::AXObjectCache::AXObjectCache):
     18        (WebCore::AXObjectCache::findModalNodes):
     19        (WebCore::AXObjectCache::currentModalNode const):
     20        (WebCore::AXObjectCache::modalNode):
     21        (WebCore::AXObjectCache::handleModalChange):
     22        (WebCore::AXObjectCache::updateCurrentModalNode): Renamed currentModalNode.
     23        * accessibility/AXObjectCache.h:
     24
    1252020-04-07  Youenn Fablet  <youenn@apple.com>
    226
  • trunk/Source/WebCore/accessibility/AXObjectCache.cpp

    r259435 r259633  
    222222    , m_performCacheUpdateTimer(*this, &AXObjectCache::performCacheUpdateTimerFired)
    223223{
    224     findModalNodes();
    225224}
    226225
     
    245244    // Traverse the DOM tree to look for the aria-modal=true nodes.
    246245    for (Element* element = ElementTraversal::firstWithin(document().rootNode()); element; element = ElementTraversal::nextIncludingPseudo(*element)) {
    247        
    248246        // Must have dialog or alertdialog role
    249247        if (!nodeHasRole(element, "dialog") && !nodeHasRole(element, "alertdialog"))
     
    251249        if (!equalLettersIgnoringASCIICase(element->attributeWithoutSynchronization(aria_modalAttr), "true"))
    252250            continue;
    253        
     251
    254252        m_modalNodesSet.add(element);
    255253    }
    256    
    257     // Set the current valid aria-modal node if possible.
    258     updateCurrentModalNode();
    259 }
    260 
    261 void AXObjectCache::updateCurrentModalNode()
     254
     255    m_modalNodesInitialized = true;
     256}
     257
     258Node* AXObjectCache::currentModalNode()
    262259{
    263260    // There might be multiple nodes with aria-modal=true set.
     
    265262    m_currentModalNode = nullptr;
    266263    if (m_modalNodesSet.isEmpty())
    267         return;
    268    
    269     // We only care about the nodes which are visible.
    270     ListHashSet<RefPtr<Node>> visibleNodes;
    271     for (auto& object : m_modalNodesSet) {
    272         if (isNodeVisible(object))
    273             visibleNodes.add(object);
    274     }
    275    
    276     if (visibleNodes.isEmpty())
    277         return;
    278    
    279     // If any of the node are keyboard focused, we want to pick that.
    280     Node* focusedNode = document().focusedElement();
    281     for (auto& object : visibleNodes) {
    282         if (focusedNode != nullptr && focusedNode->isDescendantOf(object.get())) {
    283             m_currentModalNode = object.get();
    284             break;
     264        return nullptr;
     265
     266    // If any of the modal nodes contains the keyboard focus, we want to pick that one.
     267    // If not, we want to pick the last visible dialog in the DOM.
     268    RefPtr<Element> focusedElement = document().focusedElement();
     269    RefPtr<Node> lastVisible;
     270    for (auto& node : m_modalNodesSet) {
     271        if (isNodeVisible(node)) {
     272            if (focusedElement && focusedElement->isDescendantOf(node)) {
     273                m_currentModalNode = node;
     274                break;
     275            }
     276
     277            lastVisible = node;
    285278        }
    286279    }
    287    
    288     // If none of the nodes are focused, we want to pick the last dialog in the DOM.
     280
    289281    if (!m_currentModalNode)
    290         m_currentModalNode = visibleNodes.last().get();
     282        m_currentModalNode = lastVisible.get();
     283
     284    return m_currentModalNode;
    291285}
    292286
     
    313307{
    314308    // This function returns the valid aria modal node.
     309    if (!m_modalNodesInitialized) {
     310        findModalNodes();
     311        return currentModalNode();
     312    }
     313
    315314    if (m_modalNodesSet.isEmpty())
    316315        return nullptr;
    317    
    318     // Check the current valid aria modal node first.
     316
     317    // Check the cached current valid aria modal node first.
    319318    // Usually when one dialog sets aria-modal=true, that dialog is the one we want.
    320319    if (isNodeVisible(m_currentModalNode))
    321320        return m_currentModalNode;
    322    
     321
    323322    // Recompute the valid aria modal node when m_currentModalNode is null or hidden.
    324     updateCurrentModalNode();
    325     return isNodeVisible(m_currentModalNode) ? m_currentModalNode : nullptr;
     323    return currentModalNode();
    326324}
    327325
     
    16801678    if (!is<Element>(node))
    16811679        return;
    1682    
     1680
    16831681    if (!nodeHasRole(node, "dialog") && !nodeHasRole(node, "alertdialog"))
    16841682        return;
    1685    
     1683
    16861684    stopCachingComputedObjectAttributes();
     1685
     1686    if (!m_modalNodesInitialized)
     1687        findModalNodes();
     1688
    16871689    if (equalLettersIgnoringASCIICase(downcast<Element>(*node).attributeWithoutSynchronization(aria_modalAttr), "true")) {
    16881690        // Add the newly modified node to the modal nodes set, and set it to be the current valid aria modal node.
     
    16931695        // Remove the node from the modal nodes set. There might be other visible modal nodes, so we recompute here.
    16941696        m_modalNodesSet.remove(node);
    1695         updateCurrentModalNode();
    1696     }
     1697        currentModalNode();
     1698    }
     1699
    16971700    if (m_currentModalNode)
    16981701        focusModalNode();
    1699    
     1702
    17001703    startCachingComputedObjectAttributesUntilTreeMutates();
    17011704}
  • trunk/Source/WebCore/accessibility/AXObjectCache.h

    r259288 r259633  
    453453    // aria-modal related
    454454    void findModalNodes();
    455     void updateCurrentModalNode();
     455    Node* currentModalNode();
    456456    bool isNodeVisible(Node*) const;
    457457    void handleModalChange(Node*);
     
    479479    Timer m_liveRegionChangedPostTimer;
    480480    ListHashSet<RefPtr<AccessibilityObject>> m_liveRegionObjectsSet;
    481    
     481
    482482    Timer m_focusModalNodeTimer;
    483483    Node* m_currentModalNode;
    484484    ListHashSet<Node*> m_modalNodesSet;
    485    
     485    bool m_modalNodesInitialized { false };
     486
    486487    Timer m_performCacheUpdateTimer;
    487488
Note: See TracChangeset for help on using the changeset viewer.