Bug 614829 - menupopup end event isn't fired for ARIA menus, r=fer, marcoz, a=blocking2.0final+
authorAlexander Surkov <surkov.alexander@gmail.com>
Tue, 30 Nov 2010 23:43:17 +0800
changeset 58370 71705aa67f3eeffedc91e0852f0c6e77f09fa59a
parent 58369 02a136225ccb56f024763c284d27a59e5f1a7dbc
child 58371 3e3726fc8083971b223952a29cf2289ed0915867
push id17270
push usersurkov.alexander@gmail.com
push dateTue, 30 Nov 2010 15:43:51 +0000
treeherdermozilla-central@71705aa67f3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfer, marcoz, blocking2.0final
bugs614829
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 614829 - menupopup end event isn't fired for ARIA menus, r=fer, marcoz, a=blocking2.0final+
accessible/src/base/nsDocAccessible.cpp
accessible/tests/mochitest/events/test_aria_menu.html
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1918,16 +1918,36 @@ nsDocAccessible::UpdateTreeInternal(nsAc
       updateFlags |= UpdateTreeInternal(aContainer, node->GetFirstChild(),
                                         nsnull, aIsInsert, aFireAllEvents,
                                         aFromUserInput);
       continue;
     }
 
     updateFlags |= eAccessible;
 
+    if (!aIsInsert) {
+      // Fire menupopup end event before hide event if a menu goes away.
+
+      // XXX: We don't look into children of hidden subtree to find hiding
+      // menupopup (as we did prior bug 570275) because we don't do that when
+      // menu is showing (and that's impossible until bug 606924 is fixed).
+      // Nevertheless we should do this at least because layout coalesces
+      // the changes before our processing and we may miss some menupopup
+      // events. Now we just want to be consistent in content insertion/removal
+      // handling.
+      const nsRoleMapEntry* roleMapEntry = accessible->GetRoleMapEntry();
+      if (roleMapEntry && roleMapEntry->role == nsIAccessibleRole::ROLE_MENUPOPUP) {
+        nsRefPtr<AccEvent> event =
+          new AccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, accessible);
+
+        if (event)
+          FireDelayedAccessibleEvent(event);
+      }
+    }
+
     // Fire show/hide event.
     if (aFireAllEvents) {
       nsRefPtr<AccEvent> event;
       if (aIsInsert)
         event = new AccShowEvent(accessible, node, aFromUserInput);
       else
         event = new AccHideEvent(accessible, node, aFromUserInput);
 
--- a/accessible/tests/mochitest/events/test_aria_menu.html
+++ b/accessible/tests/mochitest/events/test_aria_menu.html
@@ -14,64 +14,117 @@
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../states.js"></script>
   <script type="application/javascript"
           src="../events.js"></script>
 
   <script type="application/javascript">
-    function showMenu(aID, aViaDisplayStyle)
+    const kViaDisplayStyle = 0;
+    const kViaVisibilityStyle = 1;
+
+    function showMenu(aMenuID, aHow)
     {
-      this.DOMNode = getNode(aID);
+      this.menuNode = getNode(aMenuID);
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_SHOW, this.menuNode),
+        new invokerChecker(EVENT_MENUPOPUP_START, this.menuNode),
+        new invokerChecker(EVENT_REORDER, document)
+      ];
 
       this.invoke = function showMenu_invoke()
       {
-        if (aViaDisplayStyle)
-          this.DOMNode.style.display = "block";
+        if (aHow == kViaDisplayStyle)
+          this.menuNode.style.display = "block";
         else
-          this.DOMNode.style.visibility = "visible";
+          this.menuNode.style.visibility = "visible";
       };
 
       this.getID = function showMenu_getID()
       {
-        return "Show ARIA menu " + aID + " by " +
-          (aViaDisplayStyle ? "display" : "visibility") + " style tricks";
+        return "Show ARIA menu " + aMenuID + " by " +
+          (aHow == kViaDisplayStyle ? "display" : "visibility") +
+          " style tricks";
       };
     }
 
+    function closeMenu(aMenuID, aHow)
+    {
+      this.menuNode = getNode(aMenuID);
+      this.menu = null;
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_MENUPOPUP_END, getMenu, this),
+        new invokerChecker(EVENT_HIDE, getMenu, this),
+        new invokerChecker(EVENT_REORDER, document),
+      ];
+
+      this.invoke = function closeMenu_invoke()
+      {
+        // Store menu accessible reference while menu is still open.
+        this.menu = getAccessible(this.menuNode);
+
+        // Hide menu.
+        if (aHow == kViaDisplayStyle)
+          this.menuNode.style.display = "none";
+        else
+          this.menuNode.style.visibility = "hidden";
+      }
+
+      this.getID = function closeMenu_getID()
+      {
+        return "Close ARIA menu " + aMenuID + " by " +
+          (aHow == kViaDisplayStyle ? "display" : "visibility") +
+          " style tricks";
+      }
+
+      function getMenu(aThisObj)
+      {
+        return aThisObj.menu;
+      }
+    }
+
     ////////////////////////////////////////////////////////////////////////////
     // Do tests
 
     var gQueue = null;
 
     //gA11yEventDumpID = "eventdump";
 
     function doTests()
     {
-      gQueue = new eventQueue(EVENT_MENUPOPUP_START);
+      gQueue = new eventQueue();
 
-      gQueue.push(new showMenu("menu1", true));
-      gQueue.push(new showMenu("menu2", false));
+      gQueue.push(new showMenu("menu1", kViaDisplayStyle));
+      gQueue.push(new closeMenu("menu1", kViaDisplayStyle));
+      gQueue.push(new showMenu("menu2", kViaVisibilityStyle));
+      gQueue.push(new closeMenu("menu2", kViaVisibilityStyle));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
 
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=606207"
      title="Dojo dropdown buttons are broken">
     Mozilla Bug 606207
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=614829"
+     title="Menupopup end event isn't fired for ARIA menus">
+    Mozilla Bug 614829
+  </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div id="menu1" role="menu" style="display: none;">
     <div role="menuitem">menuitem1.1</div>