Title: [91132] trunk
Revision
91132
Author
[email protected]
Date
2011-07-15 16:55:31 -0700 (Fri, 15 Jul 2011)

Log 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.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (91131 => 91132)


--- trunk/LayoutTests/ChangeLog	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/LayoutTests/ChangeLog	2011-07-15 23:55:31 UTC (rev 91132)
@@ -1,3 +1,15 @@
+2011-07-13  Jon Honeycutt  <[email protected]>
+
+        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.
+
+        * platform/win/accessibility/option-element-selection-and-focus-events-expected.txt: Added.
+        * platform/win/accessibility/option-element-selection-and-focus-events.html: Added.
+
 2011-07-12  Jon Honeycutt  <[email protected]>
 
         Ensure that a single select element's child option elements are

Modified: trunk/Source/WebCore/ChangeLog (91131 => 91132)


--- trunk/Source/WebCore/ChangeLog	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/ChangeLog	2011-07-15 23:55:31 UTC (rev 91132)
@@ -1,5 +1,68 @@
 2011-07-13  Jon Honeycutt  <[email protected]>
 
+        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.
+
+        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.
+
+2011-07-13  Jon Honeycutt  <[email protected]>
+
         ALT + DOWN arrow key does not open select
 
         https://bugs.webkit.org/show_bug.cgi?id=14407

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (91131 => 91132)


--- trunk/Source/WebCore/accessibility/AXObjectCache.h	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h	2011-07-15 23:55:31 UTC (rev 91132)
@@ -129,6 +129,7 @@
         AXValueChanged,
         AXScrolledToAnchor,
         AXLiveRegionChanged,
+        AXMenuListItemSelected,
         AXMenuListValueChanged,
         AXRowCountChanged,
         AXRowCollapsed,

Modified: trunk/Source/WebCore/accessibility/AccessibilityMenuList.cpp (91131 => 91132)


--- trunk/Source/WebCore/accessibility/AccessibilityMenuList.cpp	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/accessibility/AccessibilityMenuList.cpp	2011-07-15 23:55:31 UTC (rev 91132)
@@ -82,4 +82,22 @@
     return !static_cast<RenderMenuList*>(m_renderer)->popupIsVisible();
 }
 
+void AccessibilityMenuList::didUpdateActiveOption(int optionIndex)
+{
+    const AccessibilityChildrenVector& childObjects = children();
+    if (childObjects.isEmpty())
+        return;
+
+    ASSERT(childObjects.size() == 1);
+    ASSERT(childObjects[0]->isMenuListPopup());
+
+    RefPtr<Document> document = m_renderer->document();
+    AXObjectCache* cache = document->axObjectCache();
+
+    if (AccessibilityMenuListPopup* popup = static_cast<AccessibilityMenuListPopup*>(childObjects[0].get()))
+        popup->didUpdateActiveOption(optionIndex);
+
+    cache->postNotification(this, document.get(), AXObjectCache::AXMenuListValueChanged, true, PostSynchronously);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/accessibility/AccessibilityMenuList.h (91131 => 91132)


--- trunk/Source/WebCore/accessibility/AccessibilityMenuList.h	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/accessibility/AccessibilityMenuList.h	2011-07-15 23:55:31 UTC (rev 91132)
@@ -42,6 +42,8 @@
     virtual bool isCollapsed() const;
     virtual bool press() const;
 
+    void didUpdateActiveOption(int optionIndex);
+
 private:
     AccessibilityMenuList(RenderMenuList*);
 

Modified: trunk/Source/WebCore/accessibility/AccessibilityMenuListPopup.cpp (91131 => 91132)


--- trunk/Source/WebCore/accessibility/AccessibilityMenuListPopup.cpp	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/accessibility/AccessibilityMenuListPopup.cpp	2011-07-15 23:55:31 UTC (rev 91132)
@@ -123,4 +123,17 @@
     m_menuList = menuList;
 }
 
+void AccessibilityMenuListPopup::didUpdateActiveOption(int optionIndex)
+{
+    ASSERT_ARG(optionIndex, optionIndex >= 0);
+    ASSERT_ARG(optionIndex, optionIndex < m_children.size());
+
+    RefPtr<Document> document = m_menuList->renderer()->document();
+    AXObjectCache* cache = document->axObjectCache();
+    RefPtr<AccessibilityObject> child = m_children[optionIndex].get();
+
+    cache->postNotification(child.get(), document.get(), AXObjectCache::AXFocusedUIElementChanged, true, PostSynchronously);
+    cache->postNotification(child.get(), document.get(), AXObjectCache::AXMenuListItemSelected, true, PostSynchronously);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/accessibility/AccessibilityMenuListPopup.h (91131 => 91132)


--- trunk/Source/WebCore/accessibility/AccessibilityMenuListPopup.h	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/accessibility/AccessibilityMenuListPopup.h	2011-07-15 23:55:31 UTC (rev 91132)
@@ -33,6 +33,7 @@
 class AccessibilityMenuList;
 class AccessibilityMenuListOption;
 class HTMLElement;
+class HTMLSelectElement;
 
 class AccessibilityMenuListPopup : public AccessibilityObject {
 public:
@@ -43,6 +44,8 @@
     virtual bool isEnabled() const;
     virtual bool isOffScreen() const;
 
+    void didUpdateActiveOption(int optionIndex);
+
 private:
     AccessibilityMenuListPopup();
 

Modified: trunk/Source/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp (91131 => 91132)


--- trunk/Source/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp	2011-07-15 23:55:31 UTC (rev 91132)
@@ -87,6 +87,7 @@
     case AXLayoutComplete:
     case AXLiveRegionChanged:
     case AXLoadComplete:
+    case AXMenuListItemSelected:
     case AXMenuListValueChanged:
     case AXRowCollapsed:
     case AXRowCountChanged:

Modified: trunk/Source/WebCore/accessibility/win/AXObjectCacheWin.cpp (91131 => 91132)


--- trunk/Source/WebCore/accessibility/win/AXObjectCacheWin.cpp	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/accessibility/win/AXObjectCacheWin.cpp	2011-07-15 23:55:31 UTC (rev 91132)
@@ -88,6 +88,10 @@
             msaaEvent = EVENT_OBJECT_VALUECHANGE;
             break;
 
+        case AXMenuListItemSelected:
+            msaaEvent = EVENT_OBJECT_SELECTION;
+            break;
+
         default:
             return;
     }

Modified: trunk/Source/WebCore/dom/SelectElement.cpp (91131 => 91132)


--- trunk/Source/WebCore/dom/SelectElement.cpp	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/dom/SelectElement.cpp	2011-07-15 23:55:31 UTC (rev 91132)
@@ -390,7 +390,7 @@
         RenderObject* renderer = element->renderer();
         if (renderer) {
             if (data.usesMenuList())
-                toRenderMenuList(renderer)->didSetSelectedIndex();
+                toRenderMenuList(renderer)->didSetSelectedIndex(listIndex);
             else if (renderer->isListBox())
                 toRenderListBox(renderer)->selectionChanged();
         }

Modified: trunk/Source/WebCore/rendering/RenderMenuList.cpp (91131 => 91132)


--- trunk/Source/WebCore/rendering/RenderMenuList.cpp	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/rendering/RenderMenuList.cpp	2011-07-15 23:55:31 UTC (rev 91132)
@@ -26,6 +26,7 @@
 #include "RenderMenuList.h"
 
 #include "AXObjectCache.h"
+#include "AccessibilityMenuList.h"
 #include "CSSFontSelector.h"
 #include "CSSStyleSelector.h"
 #include "Chrome.h"
@@ -57,7 +58,7 @@
     , m_innerBlock(0)
     , m_optionsChanged(true)
     , m_optionsWidth(0)
-    , m_lastSelectedIndex(-1)
+    , m_lastActiveIndex(-1)
     , m_popupIsVisible(false)
 {
 }
@@ -204,6 +205,7 @@
     }
 
     setText(text.stripWhiteSpace());
+    didUpdateActiveOption(optionIndex);
 }
 
 void RenderMenuList::setText(const String& s)
@@ -338,16 +340,29 @@
 }
 #endif
 
-void RenderMenuList::didSetSelectedIndex()
+void RenderMenuList::didSetSelectedIndex(int listIndex)
 {
-    int index = selectedIndex();
-    if (m_lastSelectedIndex == index)
+    SelectElement* select = toSelectElement(static_cast<Element*>(node()));
+    didUpdateActiveOption(select->listToOptionIndex(listIndex));
+}
+
+void RenderMenuList::didUpdateActiveOption(int optionIndex)
+{
+    if (!AXObjectCache::accessibilityEnabled())
         return;
 
-    m_lastSelectedIndex = index;
+    if (m_lastActiveIndex == optionIndex)
+        return;
+    m_lastActiveIndex = optionIndex;
 
-    if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->postNotification(this, AXObjectCache::AXMenuListValueChanged, true, PostSynchronously);
+    SelectElement* select = toSelectElement(static_cast<Element*>(node()));
+    if (optionIndex < 0 || optionIndex > static_cast<int>(select->listItems().size()))
+        return;
+
+    ASSERT(toOptionElement(select->listItems()[optionIndex]));
+
+    if (AccessibilityMenuList* menuList = static_cast<AccessibilityMenuList*>(document()->axObjectCache()->get(this)))
+        menuList->didUpdateActiveOption(optionIndex);
 }
 
 String RenderMenuList::itemText(unsigned listIndex) const

Modified: trunk/Source/WebCore/rendering/RenderMenuList.h (91131 => 91132)


--- trunk/Source/WebCore/rendering/RenderMenuList.h	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Source/WebCore/rendering/RenderMenuList.h	2011-07-15 23:55:31 UTC (rev 91132)
@@ -55,7 +55,7 @@
 
     void setOptionsChanged(bool changed) { m_optionsChanged = changed; }
 
-    void didSetSelectedIndex();
+    void didSetSelectedIndex(int listIndex);
 
     String text() const;
 
@@ -124,13 +124,15 @@
     void setTextFromOption(int optionIndex);
     void updateOptionsWidth();
 
+    void didUpdateActiveOption(int optionIndex);
+
     RenderText* m_buttonText;
     RenderBlock* m_innerBlock;
 
     bool m_optionsChanged;
     int m_optionsWidth;
 
-    int m_lastSelectedIndex;
+    int m_lastActiveIndex;
 
     RefPtr<RenderStyle> m_optionStyle;
 

Modified: trunk/Tools/ChangeLog (91131 => 91132)


--- trunk/Tools/ChangeLog	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Tools/ChangeLog	2011-07-15 23:55:31 UTC (rev 91132)
@@ -1,3 +1,31 @@
+2011-07-13  Jon Honeycutt  <[email protected]>
+
+        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.
+
+        * 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.
+
 2011-07-15  Dimitri Glazkov  <[email protected]>
 
         Refactor TestExpectationModel to use TestExpectationLine as data item.

Modified: trunk/Tools/DumpRenderTree/AccessibilityController.h (91131 => 91132)


--- trunk/Tools/DumpRenderTree/AccessibilityController.h	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Tools/DumpRenderTree/AccessibilityController.h	2011-07-15 23:55:31 UTC (rev 91132)
@@ -66,6 +66,7 @@
     HWINEVENTHOOK m_scrollingStartEventHook;
 
     HWINEVENTHOOK m_allEventsHook;
+    HWINEVENTHOOK m_notificationsEventHook;
     HashMap<PlatformUIElement, JSObjectRef> m_notificationListeners;
 #endif
 };

Modified: trunk/Tools/DumpRenderTree/win/AccessibilityControllerWin.cpp (91131 => 91132)


--- trunk/Tools/DumpRenderTree/win/AccessibilityControllerWin.cpp	2011-07-15 23:52:21 UTC (rev 91131)
+++ trunk/Tools/DumpRenderTree/win/AccessibilityControllerWin.cpp	2011-07-15 23:55:31 UTC (rev 91132)
@@ -44,16 +44,18 @@
     , m_scrollingStartEventHook(0)
     , m_valueChangeEventHook(0)
     , m_allEventsHook(0)
+    , m_notificationsEventHook(0)
 {
 }
 
 AccessibilityController::~AccessibilityController()
 {
     setLogFocusEvents(false);
+    setLogAccessibilityEvents(false);
     setLogValueChangeEvents(false);
 
-    if (m_allEventsHook)
-        UnhookWinEvent(m_allEventsHook);
+    if (m_notificationsEventHook)
+        UnhookWinEvent(m_notificationsEventHook);
 
     for (HashMap<PlatformUIElement, JSObjectRef>::iterator it = m_notificationListeners.begin(); it != m_notificationListeners.end(); ++it)
         JSValueUnprotect(frame->globalContext(), it->second);
@@ -130,6 +132,10 @@
             printf("Received focus event for object '%S'.\n", name.c_str());
             break;
 
+        case EVENT_OBJECT_SELECTION:
+            printf("Received selection event for object '%S'.\n", name.c_str());
+            break;
+
         case EVENT_OBJECT_VALUECHANGE: {
             BSTR valueBSTR;
             hr = parentObject->get_accValue(vChild, &valueBSTR);
@@ -213,8 +219,24 @@
     ASSERT(m_scrollingStartEventHook);
 }
 
-void AccessibilityController::setLogAccessibilityEvents(bool)
+void AccessibilityController::setLogAccessibilityEvents(bool logAccessibilityEvents)
 {
+    if (!!m_allEventsHook == logAccessibilityEvents)
+        return;
+
+    if (!logAccessibilityEvents) {
+        UnhookWinEvent(m_allEventsHook);
+        m_allEventsHook = 0;
+        return;
+    }
+
+    // Ensure that accessibility is initialized for the WebView by querying for
+    // the root accessible object.
+    rootElement();
+
+    m_allEventsHook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandle(0), logEventProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
+
+    ASSERT(m_allEventsHook);
 }
 
 static string stringEvent(DWORD event)
@@ -291,8 +313,8 @@
 
 void AccessibilityController::addNotificationListener(PlatformUIElement element, JSObjectRef functionCallback)
 {
-    if (!m_allEventsHook)
-        m_allEventsHook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandle(0), notificationListenerProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
+    if (!m_notificationsEventHook)
+        m_notificationsEventHook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandle(0), notificationListenerProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
 
     JSValueProtect(frame->globalContext(), functionCallback);
     m_notificationListeners.add(element, functionCallback);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to