Bug 970005 - Infinite long loop in a11y:FocusManager::ProcessFocusEvent. r=tbsaunde, a=sledru
authorAlexander Surkov <surkov.alexander@gmail.com>
Mon, 10 Feb 2014 17:18:43 -0500
changeset 176284 708e30a08b94b68cdf37bfa255d714c05b9688df
parent 176283 16a356b130577b4cbb7996b1ca870d912a8a9dee
child 176285 88806ebdaacd6dcbf8a14c01a54eb19b8bb44182
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde, sledru
bugs970005
milestone28.0
Bug 970005 - Infinite long loop in a11y:FocusManager::ProcessFocusEvent. r=tbsaunde, a=sledru
accessible/src/base/FocusManager.cpp
accessible/tests/mochitest/events/test_aria_menu.html
--- a/accessible/src/base/FocusManager.cpp
+++ b/accessible/src/base/FocusManager.cpp
@@ -284,39 +284,45 @@ FocusManager::ProcessFocusEvent(AccEvent
       mActiveItem = activeItem;
       target = activeItem;
     }
   }
 
   // Fire menu start/end events for ARIA menus.
   if (target->IsARIARole(nsGkAtoms::menuitem)) {
     // The focus was moved into menu.
+    bool tryOwnsParent = true;
     Accessible* ARIAMenubar = nullptr;
     Accessible* child = target;
     Accessible* parent = child->Parent();
     while (parent) {
       nsRoleMapEntry* roleMap = parent->ARIARoleMap();
       if (roleMap) {
         if (roleMap->Is(nsGkAtoms::menubar)) {
           ARIAMenubar = parent;
           break;
         }
 
         // Go up in the parent chain of the menu hierarchy.
         if (roleMap->Is(nsGkAtoms::menuitem) || roleMap->Is(nsGkAtoms::menu)) {
           child = parent;
           parent = child->Parent();
+          tryOwnsParent = true;
           continue;
         }
       }
 
       // If no required context role then check aria-owns relation.
+      if (!tryOwnsParent)
+        break;
+
       RelatedAccIterator iter(child->Document(), child->GetContent(),
                               nsGkAtoms::aria_owns);
       parent = iter.Next();
+      tryOwnsParent = false;
     }
 
     if (ARIAMenubar != mActiveARIAMenubar) {
       // Leaving ARIA menu. Fire menu_end event on current menubar.
       if (mActiveARIAMenubar) {
         nsRefPtr<AccEvent> menuEndEvent =
           new AccEvent(nsIAccessibleEvent::EVENT_MENU_END, mActiveARIAMenubar,
                        aEvent->FromUserInput());
--- a/accessible/tests/mochitest/events/test_aria_menu.html
+++ b/accessible/tests/mochitest/events/test_aria_menu.html
@@ -165,16 +165,18 @@
       gQueue.push(new focusInsideMenu("menu-edit", "menubar"));
       gQueue.push(new blurMenu("menubar"));
 
       gQueue.push(new focusMenu("menubar3", "mb3-mi-outside"));
       gQueue.push(new showMenu("mb4-menu", document, kViaDisplayStyle));
       gQueue.push(new focusMenu("menubar4", "mb4-item1"));
       gQueue.push(new focusMenu("menubar5", "mb5-mi"));
 
+      gQueue.push(new synthFocus("mi6"));
+
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
 
@@ -205,16 +207,21 @@
      title="menustart/end events are missing when aria-owns makes a menu hierarchy">
     Bug 933322
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=934460"
      title="menustart/end events may be missed when top level menuitem is focused">
     Bug 934460
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=970005"
+     title="infinite long loop in a11y:FocusManager::ProcessFocusEvent">
+    Bug 970005
+  </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div id="menubar" role="menubar">
     <div id="menu-file" role="menuitem" tabindex="0">
@@ -260,12 +267,16 @@
       Item
       <div role="menu" style="display:none;">
         <div role="menuitem" tabindex="0">Item 1.1</div>
         <div role="menuitem" tabindex="0">Item 1.2</div>
       </div>
     </div>
   </div>
 
+  <!-- other aria-owns relations -->
+  <div id="mi6" tabindex="0" role="menuitem">aria-owned item</div>
+  <div aria-owns="mi6">Obla</div>
+
   <div id="eventdump"></div>
 
 </body>
 </html>