Changeset 210265 in webkit


Ignore:
Timestamp:
Jan 3, 2017 7:07:03 PM (7 years ago)
Author:
n_wang@apple.com
Message:

AX: Focus should jump into modal dialogs when one appears
https://bugs.webkit.org/show_bug.cgi?id=166670

Reviewed by Chris Fleizach.

Source/WebCore:

Added a timer to let focus jump into a modal dialog if the web
author didn't handle the focus movement.

Test: accessibility/mac/aria-modal-auto-focus.html

  • accessibility/AXObjectCache.cpp:

(WebCore::AXObjectCache::AXObjectCache):
(WebCore::AXObjectCache::~AXObjectCache):
(WebCore::firstFocusableChild):
(WebCore::AXObjectCache::focusAriaModalNode):
(WebCore::AXObjectCache::focusAriaModalNodeTimerFired):
(WebCore::AXObjectCache::handleAriaModalChange):

  • accessibility/AXObjectCache.h:

(WebCore::AXObjectCache::focusAriaModalNode):

LayoutTests:

  • accessibility/mac/aria-modal-auto-focus-expected.txt: Added.
  • accessibility/mac/aria-modal-auto-focus.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r210261 r210265  
     12017-01-03  Nan Wang  <n_wang@apple.com>
     2
     3        AX: Focus should jump into modal dialogs when one appears
     4        https://bugs.webkit.org/show_bug.cgi?id=166670
     5
     6        Reviewed by Chris Fleizach.
     7
     8        * accessibility/mac/aria-modal-auto-focus-expected.txt: Added.
     9        * accessibility/mac/aria-modal-auto-focus.html: Added.
     10
    1112017-01-03  Brian Burg  <bburg@apple.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r210258 r210265  
     12017-01-03  Nan Wang  <n_wang@apple.com>
     2
     3        AX: Focus should jump into modal dialogs when one appears
     4        https://bugs.webkit.org/show_bug.cgi?id=166670
     5
     6        Reviewed by Chris Fleizach.
     7
     8        Added a timer to let focus jump into a modal dialog if the web
     9        author didn't handle the focus movement.
     10
     11        Test: accessibility/mac/aria-modal-auto-focus.html
     12
     13        * accessibility/AXObjectCache.cpp:
     14        (WebCore::AXObjectCache::AXObjectCache):
     15        (WebCore::AXObjectCache::~AXObjectCache):
     16        (WebCore::firstFocusableChild):
     17        (WebCore::AXObjectCache::focusAriaModalNode):
     18        (WebCore::AXObjectCache::focusAriaModalNodeTimerFired):
     19        (WebCore::AXObjectCache::handleAriaModalChange):
     20        * accessibility/AXObjectCache.h:
     21        (WebCore::AXObjectCache::focusAriaModalNode):
     22
    1232017-01-03  Andy Estes  <aestes@apple.com>
    224
  • trunk/Source/WebCore/accessibility/AXObjectCache.cpp

    r209926 r210265  
    113113static double AccessibilityPasswordValueChangeNotificationInterval = 0.025;
    114114static double AccessibilityLiveRegionChangedNotificationInterval = 0.020;
     115static double AccessibilityFocusAriaModalNodeNotificationInterval = 0.050;
    115116
    116117AccessibilityObjectInclusion AXComputedObjectAttributeCache::getIgnored(AXID id) const
     
    188189    , m_passwordNotificationPostTimer(*this, &AXObjectCache::passwordNotificationPostTimerFired)
    189190    , m_liveRegionChangedPostTimer(*this, &AXObjectCache::liveRegionChangedNotificationPostTimerFired)
     191    , m_focusAriaModalNodeTimer(*this, &AXObjectCache::focusAriaModalNodeTimerFired)
    190192    , m_currentAriaModalNode(nullptr)
    191193{
     
    197199    m_notificationPostTimer.stop();
    198200    m_liveRegionChangedPostTimer.stop();
     201    m_focusAriaModalNodeTimer.stop();
    199202
    200203    for (const auto& object : m_objects.values()) {
     
    13511354}
    13521355
     1356static AccessibilityObject* firstFocusableChild(AccessibilityObject* obj)
     1357{
     1358    if (!obj)
     1359        return nullptr;
     1360   
     1361    for (auto* child = obj->firstChild(); child; child = child->nextSibling()) {
     1362        if (child->canSetFocusAttribute())
     1363            return child;
     1364        if (AccessibilityObject* focusable = firstFocusableChild(child))
     1365            return focusable;
     1366    }
     1367    return nullptr;
     1368}
     1369
     1370void AXObjectCache::focusAriaModalNode()
     1371{
     1372    if (m_focusAriaModalNodeTimer.isActive())
     1373        m_focusAriaModalNodeTimer.stop();
     1374   
     1375    m_focusAriaModalNodeTimer.startOneShot(AccessibilityFocusAriaModalNodeNotificationInterval);
     1376}
     1377
     1378void AXObjectCache::focusAriaModalNodeTimerFired()
     1379{
     1380    if (!m_currentAriaModalNode)
     1381        return;
     1382   
     1383    // Don't set focus if we are already focusing onto some element within
     1384    // the dialog.
     1385    if (m_currentAriaModalNode->contains(document().focusedElement()))
     1386        return;
     1387   
     1388    if (AccessibilityObject* currentAriaModalNodeObject = getOrCreate(m_currentAriaModalNode)) {
     1389        if (AccessibilityObject* focusable = firstFocusableChild(currentAriaModalNodeObject))
     1390            focusable->setFocused(true);
     1391    }
     1392}
     1393
    13531394void AXObjectCache::handleScrollbarUpdate(ScrollView* view)
    13541395{
     
    14401481        updateCurrentAriaModalNode();
    14411482    }
     1483    if (m_currentAriaModalNode)
     1484        focusAriaModalNode();
     1485   
    14421486    startCachingComputedObjectAttributesUntilTreeMutates();
    14431487}
  • trunk/Source/WebCore/accessibility/AXObjectCache.h

    r209926 r210265  
    303303    void postTextStateChangeNotification(const Position&, const AXTextStateChangeIntent&, const VisibleSelection&);
    304304    void postLiveRegionChangeNotification(AccessibilityObject*);
     305    void focusAriaModalNode();
    305306
    306307    enum AXLoadingEvent {
     
    383384
    384385    void liveRegionChangedNotificationPostTimerFired();
     386   
     387    void focusAriaModalNodeTimerFired();
    385388
    386389    void postTextStateChangeNotification(AccessibilityObject*, const AXTextStateChangeIntent&, const VisibleSelection&);
     
    420423    ListHashSet<RefPtr<AccessibilityObject>> m_liveRegionObjectsSet;
    421424   
     425    Timer m_focusAriaModalNodeTimer;
    422426    Node* m_currentAriaModalNode;
    423427    ListHashSet<Node*> m_ariaModalNodesSet;
     
    496500inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { }
    497501inline void AXObjectCache::postLiveRegionChangeNotification(AccessibilityObject*) { }
     502inline void AXObjectCache::focusAriaModalNode() { }
    498503inline RefPtr<Range> AXObjectCache::rangeForNodeContents(Node*) { return nullptr; }
    499504inline void AXObjectCache::remove(AXID) { }
Note: See TracChangeset for help on using the changeset viewer.