Changeset 91132 in webkit


Ignore:
Timestamp:
Jul 15, 2011 4:55:31 PM (13 years ago)
Author:
jhoneycutt@apple.com
Message:

Focus and selection events are not fired when a <select>'s selection
changes
https://bugs.webkit.org/show_bug.cgi?id=64504
<rdar://problem/9319881>

Reviewed by Alice Liu.

Source/WebCore:

Test: platform/win/accessibility/option-element-selection-and-focus-events.html

  • accessibility/chromium/AXObjectCacheChromium.cpp:

(WebCore::AXObjectCache::postPlatformNotification):
Add new notification type to the section of unhandled notifications.

  • accessibility/AXObjectCache.h:

Declare a new notification, AXMenuListItemSelected.

  • accessibility/AccessibilityMenuList.cpp:

(WebCore::AccessibilityMenuList::didUpdateActiveOption):
Tell our child popup that the active option changed, and post a
notification that our value changed.

  • accessibility/AccessibilityMenuList.h:

Declare didUpdateActiveOption().

  • accessibility/AccessibilityMenuListPopup.cpp:

(WebCore::AccessibilityMenuListPopup::didUpdateActiveOption):
Get the child <option> element that is selected, and fire focus and
selection events for it.

  • accessibility/AccessibilityMenuListPopup.h:

Declare didUpdateActiveOption().

  • accessibility/win/AXObjectCacheWin.cpp:

(WebCore::AXObjectCache::postPlatformNotification):
Map AXMenuListItemSelected -> EVENT_OBJECT_SELECTION.

  • dom/SelectElement.cpp:

(WebCore::SelectElement::setSelectedIndex):
Pass the newly-selected index.

  • rendering/RenderMenuList.cpp:

(WebCore::RenderMenuList::RenderMenuList):
Update the initialization list for the renamed m_lastActiveIndex.
(WebCore::RenderMenuList::setTextFromOption):
A new selection has been made in the popup; call
didUpdateActiveOption().
(WebCore::RenderMenuList::didSetSelectedIndex):
Call didUpdateActiveOption(), passing the index of the newly-selected
<option>.
(WebCore::RenderMenuList::didUpdateActiveOption):
If accessibility is disabled, or if the active option has not changed,
return early. Check whether the option index is in the range of list
items, and assert that the item at that index is an <option> element.
Tell the AccessibilityMenuList for this element that we updated the
active option.

  • rendering/RenderMenuList.h:

Updated the declaration of didSetSelectedIndex() to take the selected
index. Declared didUpdateActiveOption(). Renamed m_lastSelectedIndex to
m_lastActiveIndex.

Tools:

  • DumpRenderTree/AccessibilityController.h:

Added m_notificationsEventHook for addNotificationListener().
m_allEventsHook will now be used for setLogAccessibilityEvents().

  • DumpRenderTree/win/AccessibilityControllerWin.cpp:

(AccessibilityController::AccessibilityController):
Initialize m_notificationsEventHook.
(AccessibilityController::~AccessibilityController):
Turn off logging of all accessibility events. If
m_notificationsEventHook is non-null, unhook it.
(logEventProc):
Add handling of EVENT_OBJECT_SELECTION.
(AccessibilityController::setLogAccessibilityEvents):
If the state of logging is not changing, return early. If we're turning
off logging, unhook m_allEventsHook, and zero it out. Otherwise, add a
hook for all events.
(AccessibilityController::addNotificationListener):
Use m_notificationsEventHook rather than m_allEventsHook.

LayoutTests:

  • platform/win/accessibility/option-element-selection-and-focus-events-expected.txt: Added.
  • platform/win/accessibility/option-element-selection-and-focus-events.html: Added.
Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r91128 r91132  
     12011-07-13  Jon Honeycutt  <jhoneycutt@apple.com>
     2
     3        Focus and selection events are not fired when a <select>'s selection
     4        changes
     5        https://bugs.webkit.org/show_bug.cgi?id=64504
     6        <rdar://problem/9319881>
     7
     8        Reviewed by Alice Liu.
     9
     10        * platform/win/accessibility/option-element-selection-and-focus-events-expected.txt: Added.
     11        * platform/win/accessibility/option-element-selection-and-focus-events.html: Added.
     12
    1132011-07-12  Jon Honeycutt  <jhoneycutt@apple.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r91129 r91132  
     12011-07-13  Jon Honeycutt  <jhoneycutt@apple.com>
     2
     3        Focus and selection events are not fired when a <select>'s selection
     4        changes
     5        https://bugs.webkit.org/show_bug.cgi?id=64504
     6        <rdar://problem/9319881>
     7
     8        Reviewed by Alice Liu.
     9
     10        Test: platform/win/accessibility/option-element-selection-and-focus-events.html
     11
     12        * accessibility/chromium/AXObjectCacheChromium.cpp:
     13        (WebCore::AXObjectCache::postPlatformNotification):
     14        Add new notification type to the section of unhandled notifications.
     15
     16        * accessibility/AXObjectCache.h:
     17        Declare a new notification, AXMenuListItemSelected.
     18
     19        * accessibility/AccessibilityMenuList.cpp:
     20        (WebCore::AccessibilityMenuList::didUpdateActiveOption):
     21        Tell our child popup that the active option changed, and post a
     22        notification that our value changed.
     23
     24        * accessibility/AccessibilityMenuList.h:
     25        Declare didUpdateActiveOption().
     26
     27        * accessibility/AccessibilityMenuListPopup.cpp:
     28        (WebCore::AccessibilityMenuListPopup::didUpdateActiveOption):
     29        Get the child <option> element that is selected, and fire focus and
     30        selection events for it.
     31
     32        * accessibility/AccessibilityMenuListPopup.h:
     33        Declare didUpdateActiveOption().
     34
     35        * accessibility/win/AXObjectCacheWin.cpp:
     36        (WebCore::AXObjectCache::postPlatformNotification):
     37        Map AXMenuListItemSelected -> EVENT_OBJECT_SELECTION.
     38
     39        * dom/SelectElement.cpp:
     40        (WebCore::SelectElement::setSelectedIndex):
     41        Pass the newly-selected index.
     42
     43        * rendering/RenderMenuList.cpp:
     44        (WebCore::RenderMenuList::RenderMenuList):
     45        Update the initialization list for the renamed m_lastActiveIndex.
     46        (WebCore::RenderMenuList::setTextFromOption):
     47        A new selection has been made in the popup; call
     48        didUpdateActiveOption().
     49        (WebCore::RenderMenuList::didSetSelectedIndex):
     50        Call didUpdateActiveOption(), passing the index of the newly-selected
     51        <option>.
     52        (WebCore::RenderMenuList::didUpdateActiveOption):
     53        If accessibility is disabled, or if the active option has not changed,
     54        return early. Check whether the option index is in the range of list
     55        items, and assert that the item at that index is an <option> element.
     56        Tell the AccessibilityMenuList for this element that we updated the
     57        active option.
     58
     59        * rendering/RenderMenuList.h:
     60        Updated the declaration of didSetSelectedIndex() to take the selected
     61        index. Declared didUpdateActiveOption(). Renamed m_lastSelectedIndex to
     62        m_lastActiveIndex.
     63
    1642011-07-13  Jon Honeycutt  <jhoneycutt@apple.com>
    265
  • trunk/Source/WebCore/accessibility/AXObjectCache.h

    r89609 r91132  
    130130        AXScrolledToAnchor,
    131131        AXLiveRegionChanged,
     132        AXMenuListItemSelected,
    132133        AXMenuListValueChanged,
    133134        AXRowCountChanged,
  • trunk/Source/WebCore/accessibility/AccessibilityMenuList.cpp

    r89609 r91132  
    8383}
    8484
     85void AccessibilityMenuList::didUpdateActiveOption(int optionIndex)
     86{
     87    const AccessibilityChildrenVector& childObjects = children();
     88    if (childObjects.isEmpty())
     89        return;
     90
     91    ASSERT(childObjects.size() == 1);
     92    ASSERT(childObjects[0]->isMenuListPopup());
     93
     94    RefPtr<Document> document = m_renderer->document();
     95    AXObjectCache* cache = document->axObjectCache();
     96
     97    if (AccessibilityMenuListPopup* popup = static_cast<AccessibilityMenuListPopup*>(childObjects[0].get()))
     98        popup->didUpdateActiveOption(optionIndex);
     99
     100    cache->postNotification(this, document.get(), AXObjectCache::AXMenuListValueChanged, true, PostSynchronously);
     101}
     102
    85103} // namespace WebCore
  • trunk/Source/WebCore/accessibility/AccessibilityMenuList.h

    r89609 r91132  
    4343    virtual bool press() const;
    4444
     45    void didUpdateActiveOption(int optionIndex);
     46
    4547private:
    4648    AccessibilityMenuList(RenderMenuList*);
  • trunk/Source/WebCore/accessibility/AccessibilityMenuListPopup.cpp

    r91128 r91132  
    124124}
    125125
     126void AccessibilityMenuListPopup::didUpdateActiveOption(int optionIndex)
     127{
     128    ASSERT_ARG(optionIndex, optionIndex >= 0);
     129    ASSERT_ARG(optionIndex, optionIndex < m_children.size());
     130
     131    RefPtr<Document> document = m_menuList->renderer()->document();
     132    AXObjectCache* cache = document->axObjectCache();
     133    RefPtr<AccessibilityObject> child = m_children[optionIndex].get();
     134
     135    cache->postNotification(child.get(), document.get(), AXObjectCache::AXFocusedUIElementChanged, true, PostSynchronously);
     136    cache->postNotification(child.get(), document.get(), AXObjectCache::AXMenuListItemSelected, true, PostSynchronously);
     137}
     138
    126139} // namespace WebCore
  • trunk/Source/WebCore/accessibility/AccessibilityMenuListPopup.h

    r89609 r91132  
    3434class AccessibilityMenuListOption;
    3535class HTMLElement;
     36class HTMLSelectElement;
    3637
    3738class AccessibilityMenuListPopup : public AccessibilityObject {
     
    4344    virtual bool isEnabled() const;
    4445    virtual bool isOffScreen() const;
     46
     47    void didUpdateActiveOption(int optionIndex);
    4548
    4649private:
  • trunk/Source/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp

    r86451 r91132  
    8888    case AXLiveRegionChanged:
    8989    case AXLoadComplete:
     90    case AXMenuListItemSelected:
    9091    case AXMenuListValueChanged:
    9192    case AXRowCollapsed:
  • trunk/Source/WebCore/accessibility/win/AXObjectCacheWin.cpp

    r68078 r91132  
    8989            break;
    9090
     91        case AXMenuListItemSelected:
     92            msaaEvent = EVENT_OBJECT_SELECTION;
     93            break;
     94
    9195        default:
    9296            return;
  • trunk/Source/WebCore/dom/SelectElement.cpp

    r91129 r91132  
    391391        if (renderer) {
    392392            if (data.usesMenuList())
    393                 toRenderMenuList(renderer)->didSetSelectedIndex();
     393                toRenderMenuList(renderer)->didSetSelectedIndex(listIndex);
    394394            else if (renderer->isListBox())
    395395                toRenderListBox(renderer)->selectionChanged();
  • trunk/Source/WebCore/rendering/RenderMenuList.cpp

    r90069 r91132  
    2727
    2828#include "AXObjectCache.h"
     29#include "AccessibilityMenuList.h"
    2930#include "CSSFontSelector.h"
    3031#include "CSSStyleSelector.h"
     
    5859    , m_optionsChanged(true)
    5960    , m_optionsWidth(0)
    60     , m_lastSelectedIndex(-1)
     61    , m_lastActiveIndex(-1)
    6162    , m_popupIsVisible(false)
    6263{
     
    205206
    206207    setText(text.stripWhiteSpace());
     208    didUpdateActiveOption(optionIndex);
    207209}
    208210
     
    339341#endif
    340342
    341 void RenderMenuList::didSetSelectedIndex()
    342 {
    343     int index = selectedIndex();
    344     if (m_lastSelectedIndex == index)
    345         return;
    346 
    347     m_lastSelectedIndex = index;
    348 
    349     if (AXObjectCache::accessibilityEnabled())
    350         document()->axObjectCache()->postNotification(this, AXObjectCache::AXMenuListValueChanged, true, PostSynchronously);
     343void RenderMenuList::didSetSelectedIndex(int listIndex)
     344{
     345    SelectElement* select = toSelectElement(static_cast<Element*>(node()));
     346    didUpdateActiveOption(select->listToOptionIndex(listIndex));
     347}
     348
     349void RenderMenuList::didUpdateActiveOption(int optionIndex)
     350{
     351    if (!AXObjectCache::accessibilityEnabled())
     352        return;
     353
     354    if (m_lastActiveIndex == optionIndex)
     355        return;
     356    m_lastActiveIndex = optionIndex;
     357
     358    SelectElement* select = toSelectElement(static_cast<Element*>(node()));
     359    if (optionIndex < 0 || optionIndex > static_cast<int>(select->listItems().size()))
     360        return;
     361
     362    ASSERT(toOptionElement(select->listItems()[optionIndex]));
     363
     364    if (AccessibilityMenuList* menuList = static_cast<AccessibilityMenuList*>(document()->axObjectCache()->get(this)))
     365        menuList->didUpdateActiveOption(optionIndex);
    351366}
    352367
  • trunk/Source/WebCore/rendering/RenderMenuList.h

    r88952 r91132  
    5656    void setOptionsChanged(bool changed) { m_optionsChanged = changed; }
    5757
    58     void didSetSelectedIndex();
     58    void didSetSelectedIndex(int listIndex);
    5959
    6060    String text() const;
     
    125125    void updateOptionsWidth();
    126126
     127    void didUpdateActiveOption(int optionIndex);
     128
    127129    RenderText* m_buttonText;
    128130    RenderBlock* m_innerBlock;
     
    131133    int m_optionsWidth;
    132134
    133     int m_lastSelectedIndex;
     135    int m_lastActiveIndex;
    134136
    135137    RefPtr<RenderStyle> m_optionStyle;
  • trunk/Tools/ChangeLog

    r91124 r91132  
     12011-07-13  Jon Honeycutt  <jhoneycutt@apple.com>
     2
     3        Focus and selection events are not fired when a <select>'s selection
     4        changes
     5        https://bugs.webkit.org/show_bug.cgi?id=64504
     6        <rdar://problem/9319881>
     7
     8        Reviewed by Alice Liu.
     9
     10        * DumpRenderTree/AccessibilityController.h:
     11        Added m_notificationsEventHook for addNotificationListener().
     12        m_allEventsHook will now be used for setLogAccessibilityEvents().
     13
     14        * DumpRenderTree/win/AccessibilityControllerWin.cpp:
     15        (AccessibilityController::AccessibilityController):
     16        Initialize m_notificationsEventHook.
     17        (AccessibilityController::~AccessibilityController):
     18        Turn off logging of all accessibility events. If
     19        m_notificationsEventHook is non-null, unhook it.
     20        (logEventProc):
     21        Add handling of EVENT_OBJECT_SELECTION.
     22        (AccessibilityController::setLogAccessibilityEvents):
     23        If the state of logging is not changing, return early. If we're turning
     24        off logging, unhook m_allEventsHook, and zero it out. Otherwise, add a
     25        hook for all events.
     26        (AccessibilityController::addNotificationListener):
     27        Use m_notificationsEventHook rather than m_allEventsHook.
     28
    1292011-07-15  Dimitri Glazkov  <dglazkov@chromium.org>
    230
  • trunk/Tools/DumpRenderTree/AccessibilityController.h

    r78179 r91132  
    6767
    6868    HWINEVENTHOOK m_allEventsHook;
     69    HWINEVENTHOOK m_notificationsEventHook;
    6970    HashMap<PlatformUIElement, JSObjectRef> m_notificationListeners;
    7071#endif
  • trunk/Tools/DumpRenderTree/win/AccessibilityControllerWin.cpp

    r78179 r91132  
    4545    , m_valueChangeEventHook(0)
    4646    , m_allEventsHook(0)
     47    , m_notificationsEventHook(0)
    4748{
    4849}
     
    5152{
    5253    setLogFocusEvents(false);
     54    setLogAccessibilityEvents(false);
    5355    setLogValueChangeEvents(false);
    5456
    55     if (m_allEventsHook)
    56         UnhookWinEvent(m_allEventsHook);
     57    if (m_notificationsEventHook)
     58        UnhookWinEvent(m_notificationsEventHook);
    5759
    5860    for (HashMap<PlatformUIElement, JSObjectRef>::iterator it = m_notificationListeners.begin(); it != m_notificationListeners.end(); ++it)
     
    131133            break;
    132134
     135        case EVENT_OBJECT_SELECTION:
     136            printf("Received selection event for object '%S'.\n", name.c_str());
     137            break;
     138
    133139        case EVENT_OBJECT_VALUECHANGE: {
    134140            BSTR valueBSTR;
     
    214220}
    215221
    216 void AccessibilityController::setLogAccessibilityEvents(bool)
    217 {
     222void AccessibilityController::setLogAccessibilityEvents(bool logAccessibilityEvents)
     223{
     224    if (!!m_allEventsHook == logAccessibilityEvents)
     225        return;
     226
     227    if (!logAccessibilityEvents) {
     228        UnhookWinEvent(m_allEventsHook);
     229        m_allEventsHook = 0;
     230        return;
     231    }
     232
     233    // Ensure that accessibility is initialized for the WebView by querying for
     234    // the root accessible object.
     235    rootElement();
     236
     237    m_allEventsHook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandle(0), logEventProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
     238
     239    ASSERT(m_allEventsHook);
    218240}
    219241
     
    292314void AccessibilityController::addNotificationListener(PlatformUIElement element, JSObjectRef functionCallback)
    293315{
    294     if (!m_allEventsHook)
    295         m_allEventsHook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandle(0), notificationListenerProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
     316    if (!m_notificationsEventHook)
     317        m_notificationsEventHook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandle(0), notificationListenerProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
    296318
    297319    JSValueProtect(frame->globalContext(), functionCallback);
Note: See TracChangeset for help on using the changeset viewer.