Bug 760972 - Remove focus-follows-cursor behavior and add cursor-follows-focus. r=davidb
authorEitan Isaacson <eitan@monotonous.org>
Wed, 06 Jun 2012 13:02:24 -0400
changeset 98711 3f4e6f14fd28cae1818d6c388bfb0c158cf568c7
parent 98710 484f9e22295db88a5636e1df4457a7b529810882
child 98712 cd8e40687a8d98f50cebb1d7e75815ef0ad4ffd7
push id1729
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 20:02:43 +0000
treeherdermozilla-aurora@f4e75e148951 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdavidb
bugs760972
milestone16.0a1
Bug 760972 - Remove focus-follows-cursor behavior and add cursor-follows-focus. r=davidb
accessible/src/jsat/AccessFu.jsm
accessible/src/jsat/VirtualCursorController.jsm
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -217,29 +217,16 @@ var AccessFu = {
           let position = pivot.position;
           let doc = aEvent.DOMNode;
 
           let presenterContext =
             new PresenterContext(position, event.oldAccessible);
           this.presenters.forEach(
             function(p) { p.pivotChanged(presenterContext); });
 
-          if (position && position.DOMNode &&
-              doc instanceof Ci.nsIDOMDocument) {
-            // Set the caret to the start of the pivot position, and move
-            // the focus in the same manner as browse with caret mode.
-            // This blurs the focus on the previous pivot position (if it
-            // was activated), and keeps us in a predictable spot for tab
-            // focus.
-            let sel = doc.getSelection();
-            sel.collapse(position.DOMNode, 0);
-            Cc["@mozilla.org/focus-manager;1"]
-              .getService(Ci.nsIFocusManager).moveFocus(
-                doc.defaultView, null, Ci.nsIFocusManager.MOVEFOCUS_CARET, 0);
-          }
           break;
         }
       case Ci.nsIAccessibleEvent.EVENT_STATE_CHANGE:
         {
           let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
           if (event.state == Ci.nsIAccessibleStates.STATE_CHECKED &&
               !(event.isExtraState())) {
             this.presenters.forEach(
@@ -351,16 +338,25 @@ var AccessFu = {
         }
         break;
       }
       case Ci.nsIAccessibleEvent.EVENT_SCROLLING_START:
       {
         VirtualCursorController.moveCursorToObject(aEvent.accessible);
         break;
       }
+      case Ci.nsIAccessibleEvent.EVENT_FOCUS:
+      {
+        let acc = aEvent.accessible;
+        let doc = aEvent.accessibleDocument;
+        if (acc.role != Ci.nsIAccessibleRole.ROLE_DOCUMENT &&
+            doc.role != Ci.nsIAccessibleRole.ROLE_CHROME_WINDOW)
+          VirtualCursorController.moveCursorToObject(acc);
+        break;
+      }
       default:
         break;
     }
   },
 
   /**
    * Check if accessible is a top-level content document (i.e. a child of a XUL
    * browser node).
--- a/accessible/src/jsat/VirtualCursorController.jsm
+++ b/accessible/src/jsat/VirtualCursorController.jsm
@@ -47,36 +47,46 @@ var VirtualCursorController = {
     switch (aEvent.keyCode) {
       case aEvent.DOM_VK_END:
         this.moveForward(document, true);
         break;
       case aEvent.DOM_VK_HOME:
         this.moveBackward(document, true);
         break;
       case aEvent.DOM_VK_RIGHT:
-        if (this._isEditableText(target) &&
-            target.selectionEnd != target.textLength)
-          // Don't move forward if caret is not at end of entry.
-          // XXX: Fix for rtl
-          return;
+        if (this._isEditableText(target)) {
+          if (target.selectionEnd != target.textLength)
+            // Don't move forward if caret is not at end of entry.
+            // XXX: Fix for rtl
+            return;
+          else
+            target.blur();
+        }
         this.moveForward(document, aEvent.shiftKey);
         break;
       case aEvent.DOM_VK_LEFT:
-        if (this._isEditableText(target) &&
-            target.selectionEnd != 0)
-          // Don't move backward if caret is not at start of entry.
-          // XXX: Fix for rtl
-          return;
+        if (this._isEditableText(target)) {
+          if (target.selectionEnd != 0)
+            // Don't move backward if caret is not at start of entry.
+            // XXX: Fix for rtl
+            return;
+          else
+            target.blur();
+        }
         this.moveBackward(document, aEvent.shiftKey);
         break;
       case aEvent.DOM_VK_UP:
-        if (this._isEditableText(target) == this.MULTI_LINE_EDITABLE &&
-            target.selectionEnd != 0)
-          // Don't blur content if caret is not at start of text area.
-          return;
+        if (this._isEditableText(target) == this.MULTI_LINE_EDITABLE) {
+          if (target.selectionEnd != 0)
+            // Don't blur content if caret is not at start of text area.
+            return;
+          else
+            target.blur();
+        }
+
         if (Services.appinfo.OS == 'Android')
           // Return focus to native Android browser chrome.
           Cc['@mozilla.org/android/bridge;1'].
             getService(Ci.nsIAndroidBridge).handleGeckoMessage(
               JSON.stringify({ gecko: { type: 'ToggleChrome:Focus' } }));
         break;
       case aEvent.DOM_VK_RETURN:
       case aEvent.DOM_VK_ENTER:
@@ -107,32 +117,32 @@ var VirtualCursorController = {
   moveForward: function moveForward(document, last) {
     let virtualCursor = this.getVirtualCursor(document);
     if (last) {
       virtualCursor.moveLast(this.SimpleTraversalRule);
     } else {
       try {
         virtualCursor.moveNext(this.SimpleTraversalRule);
       } catch (x) {
-        virtualCursor.position =
-          gAccRetrieval.getAccessibleFor(document.activeElement);
+        this.moveCursorToObject(
+          gAccRetrieval.getAccessibleFor(document.activeElement));
       }
     }
   },
 
   moveBackward: function moveBackward(document, first) {
     let virtualCursor = this.getVirtualCursor(document);
     if (first) {
       virtualCursor.moveFirst(this.SimpleTraversalRule);
     } else {
       try {
         virtualCursor.movePrevious(this.SimpleTraversalRule);
       } catch (x) {
-        virtualCursor.position =
-          gAccRetrieval.getAccessibleFor(document.activeElement);
+        this.moveCursorToObject(
+          gAccRetrieval.getAccessibleFor(document.activeElement));
       }
     }
   },
 
   activateCurrent: function activateCurrent(document) {
     let virtualCursor = this.getVirtualCursor(document);
     let acc = virtualCursor.position;