Bug 546068 - Position is not being updated when atk_text_set_caret_offset is used, r=marcoz, enndeakin
authorAlexander Surkov <surkov.alexander@gmail.com>
Sun, 16 Oct 2011 12:38:19 +0900
changeset 78824 0a6b707742dd2437daaaee5137501d28ff9884c6
parent 78823 6ef8c395b2df1f584c9fe77c26a2856118c6d5fc
child 78825 cf5da681d57738a59d19ca9d864fd6e36144dda1
push id21337
push usereakhgari@mozilla.com
push dateSun, 16 Oct 2011 17:28:58 +0000
treeherdermozilla-central@cf5da681d577 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarcoz, enndeakin
bugs546068
milestone10.0a1
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 546068 - Position is not being updated when atk_text_set_caret_offset is used, r=marcoz, enndeakin
accessible/src/base/nsCaretAccessible.cpp
accessible/src/html/nsHyperTextAccessible.cpp
accessible/tests/mochitest/test_text_caret.html
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -221,16 +221,20 @@ nsCaretAccessible::NotifySelectionChange
 
     bool isNormalSelection =
       (type == nsISelectionController::SELECTION_NORMAL);
 
     bool isIgnored = !document || !document->IsContentLoaded();
     printf("\nSelection changed, selection type: %s, notification %s\n",
            (isNormalSelection ? "normal" : "spellcheck"),
            (isIgnored ? "ignored" : "pending"));
+  } else {
+    bool isIgnored = !document || !document->IsContentLoaded();
+    printf("\nSelection changed, selection type: unknown, notification %s\n",
+               (isIgnored ? "ignored" : "pending"));
   }
 #endif
 
   // Don't fire events until document is loaded.
   if (document && document->IsContentLoaded()) {
     // The caret accessible has the same lifetime as the root accessible, and
     // this outlives all its descendant document accessibles, so that we are
     // guaranteed that the notification is processed before the caret accessible
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -41,16 +41,17 @@
 
 #include "States.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsTextAttrs.h"
 
 #include "nsIClipboard.h"
 #include "nsContentCID.h"
+#include "nsFocusManager.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMNSRange.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIEditingSession.h"
 #include "nsIEditor.h"
 #include "nsIFrame.h"
@@ -1590,21 +1591,30 @@ nsHyperTextAccessible::SetSelectionRange
   domSel->GetRangeCount(&numRanges);
 
   for (PRInt32 count = 0; count < numRanges - 1; count ++) {
     nsCOMPtr<nsIDOMRange> range;
     domSel->GetRangeAt(1, getter_AddRefs(range));
     domSel->RemoveRange(range);
   }
 
-  // XXX I'm not sure this can do synchronous scrolling. If the last param is
-  // set to true, this calling might flush the pending reflow. See bug 418470.
-  return frameSelection->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL,
-                                                 nsISelectionController::SELECTION_FOCUS_REGION,
-                                                 0);
+  // Now that selection is done, move the focus to the selection.
+  nsFocusManager* DOMFocusManager = nsFocusManager::GetFocusManager();
+  if (DOMFocusManager) {
+    nsCOMPtr<nsIPresShell> shell = GetPresShell();
+    NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
+    nsCOMPtr<nsIDocument> doc = shell->GetDocument();
+    NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
+    nsCOMPtr<nsPIDOMWindow> window = doc->GetWindow();
+    nsCOMPtr<nsIDOMElement> result;
+    DOMFocusManager->MoveFocus(window, nsnull, nsIFocusManager::MOVEFOCUS_CARET,
+                               nsIFocusManager::FLAG_BYMOVEFOCUS, getter_AddRefs(result));
+  }
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHyperTextAccessible::SetCaretOffset(PRInt32 aCaretOffset)
 {
   return SetSelectionRange(aCaretOffset, aCaretOffset);
 }
 
--- a/accessible/tests/mochitest/test_text_caret.html
+++ b/accessible/tests/mochitest/test_text_caret.html
@@ -29,69 +29,95 @@
            aOffset,
            "Wrong caret offset for " + prettyName(aEvent.target));
       }
     }
 
     /**
      * Invokers.
      */
-    function setCaretOffsetInvoker(aID, aOffset)
+    function setCaretOffsetInvoker(aID, aOffset, aFocusableContainerID)
     {
       this.target = getAccessible(aID, [nsIAccessibleText]);
+      this.focus = aFocusableContainerID ?
+        getAccessible(aFocusableContainerID) : this.target;
 
       this.invoke = function setCaretOffsetInvoker_invoke()
       {
         this.target.caretOffset = aOffset;
       }
 
       this.getID = function setCaretOffsetInvoker_getID()
       {
-        return "nsIAccessibleText::caretOffset test";
+        return "Set caretOffset on " + prettyName(aID) + " at " + aOffset;
       }
 
       this.eventSeq = [
-        new invokerChecker(EVENT_FOCUS, this.target),
-        new caretMovedChecker(this.target, aOffset)
+        new caretMovedChecker(this.target, aOffset),
+        new asyncInvokerChecker(EVENT_FOCUS, this.focus)
       ];
     }
 
     /**
+     * Turn on/off the caret browsing mode.
+     */
+    function turnCaretBrowsing(aIsOn)
+    {
+      var prefs = Components.classes["@mozilla.org/preferences-service;1"].
+        getService(Components.interfaces.nsIPrefBranch);
+      prefs.setBoolPref("accessibility.browsewithcaret", aIsOn);
+    }
+
+    /**
      * Do tests.
      */
     var gQueue = null;
 
-    // gA11yEventDumpID = "eventdump"; // debug stuff
+    //gA11yEventDumpID = "eventdump"; // debug stuff
+    //gA11yEventDumpToConsole = true;
 
     function doTests()
     {
+      turnCaretBrowsing(true);
+
       // test caret move events and caret offsets
       gQueue = new eventQueue();
 
       gQueue.push(new setCaretOffsetInvoker("textbox", 1));
       gQueue.push(new setCaretOffsetInvoker("link", 1));
+      gQueue.push(new setCaretOffsetInvoker("heading", 1, document));
+      gQueue.onFinish = function()
+      {
+        turnCaretBrowsing(false);
+      }
 
       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=524115"
      title="HyperText accessible should get focus when the caret is positioned inside of it, text is changed or copied into clipboard by ATs">
     Mozilla Bug 524115
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=546068"
+     title="Position is not being updated when atk_text_set_caret_offset is used">
+    Mozilla Bug 546068
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <input id="textbox" value="hello"/>
   <a id="link" href="about:">about mozilla</a>
+  <h5 id="heading">heading</h5>
 
   <div id="eventdump"></div>
 </body>
 </html>