Bug 544146, when focusing at the caret position, if the caret is not set or at the root, don't look for a node to focus, r=smaug, a=dveditz
authorNeil Deakin <neil@mozilla.com>
Fri, 25 Jun 2010 15:35:01 -0400
changeset 34380 34c868ca9c889d75dd6a1642d651837c1c9d6886
parent 34379 a026be4d85e06f6ab4ae6969c518df841a798661
child 34381 8686a1a62d3ee3488ba99d5e865a28c9fc00f357
push id1429
push userneil@mozilla.com
push dateFri, 25 Jun 2010 19:36:00 +0000
reviewerssmaug, dveditz
bugs544146
milestone1.9.2.6pre
Bug 544146, when focusing at the caret position, if the caret is not set or at the root, don't look for a node to focus, r=smaug, a=dveditz
dom/base/nsFocusManager.cpp
dom/tests/mochitest/chrome/window_focus.xul
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -2139,17 +2139,17 @@ nsFocusManager::DetermineElementToMoveFo
   if (aType == MOVEFOCUS_LAST) {
     if (!aStartContent)
       startContent = rootContent;
     return GetNextTabbableContent(presShell, startContent,
                                   nsnull, startContent,
                                   PR_FALSE, 0, PR_FALSE, aNextContent);
   }
 
-  PRBool forward = (aType == MOVEFOCUS_FORWARD);
+  PRBool forward = (aType == MOVEFOCUS_FORWARD || aType == MOVEFOCUS_CARET);
   PRBool doNavigation = PR_TRUE;
   PRBool ignoreTabIndex = PR_FALSE;
   // when a popup is open, we want to ensure that tab navigation occurs only
   // within the most recently opened panel. If a popup is open, its frame will
   // be stored in popupFrame.
   nsIFrame* popupFrame = nsnull;
 
   PRInt32 tabIndex = forward ? 1 : 0;
@@ -2221,23 +2221,28 @@ nsFocusManager::DetermineElementToMoveFo
           // Don't start from the selection if the selection is in a
           // contentEditable region.
           nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
           if (htmlDoc &&
               htmlDoc->GetEditingState() == nsIHTMLDocument::eContentEditable)
             startContent = nsnull;
         }
 
-        if (startContent) {
-          if (aType == MOVEFOCUS_CARET) {
+        if (aType == MOVEFOCUS_CARET) {
+          // GetFocusInSelection finds a focusable link near the caret.
+          // If there is no start content though, don't do this to avoid
+          // focusing something unexpected.
+          if (startContent) {
             GetFocusInSelection(aWindow, startContent,
                                 endSelectionContent, aNextContent);
-            return NS_OK;
           }
-
+          return NS_OK;
+        }
+
+        if (startContent) {
           // when starting from a selection, we always want to find the next or
           // previous element in the document. So the tabindex on elements
           // should be ignored.
           ignoreTabIndex = PR_TRUE;
         }
       }
 
       if (!startContent) {
--- a/dom/tests/mochitest/chrome/window_focus.xul
+++ b/dom/tests/mochitest/chrome/window_focus.xul
@@ -908,31 +908,35 @@ function testMoveFocus()
 
   // MOVEFOCUS_CARET tests
   getById("t20").focus();
   gEvents = "";
 
   var selection = gChildWindow.getSelection();
   selection.removeAllRanges();
 
+  newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
+  is(newFocus, null, "move caret when at document root");
+  is(fm.focusedElement, null, "move caret when at document root");
+
   var node = getById("t16").firstChild;
   var range = gChildWindow.document.createRange();
   range.setStart(node, 3);
   range.setEnd(node, 3);
   selection.addRange(range);
 
   newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
   is(newFocus, null, "move caret to non-link return value");
   is(fm.focusedElement, null, "move caret to non-link");
 
-  var t25 = getById("t25")
+  var t25 = getById("t25");
   var node = t25.firstChild;
   range.setStart(node, 1);
   range.setEnd(node, 1);
-  var newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
+  newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
 
   is(newFocus, t25, "move caret to link return value");
   is(fm.focusedElement, t25, "move caret to link focusedElement");
 
   // enable caret browsing temporarily to test caret movement
   var prefs = Components.classes["@mozilla.org/preferences-service;1"].
                 getService(Components.interfaces.nsIPrefBranch);
   prefs.setBoolPref("accessibility.browsewithcaret", true);