Bug 1343210 - Only move focus into identity popup when opened via keyboard. r=Gijs, a=lizzard
authorJohann Hofmann <jhofmann@mozilla.com>
Tue, 28 Feb 2017 14:29:03 +0100
changeset 355439 ed9521749d6f9f5945fac2383292c453e30f7285
parent 355438 420396d5e26de377c222ce81c7b0b152335ba8fa
child 355440 775b6f85ef818dd37756ad64e458fd53964557a8
push id6975
push userryanvm@gmail.com
push dateFri, 24 Mar 2017 21:24:58 +0000
treeherdermozilla-esr52@62df7046e959 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs, lizzard
bugs1343210
milestone52.0.2
Bug 1343210 - Only move focus into identity popup when opened via keyboard. r=Gijs, a=lizzard MozReview-Commit-ID: FZG2DKSM5Fh
browser/base/content/browser.js
browser/base/content/test/siteIdentity/browser.ini
browser/base/content/test/siteIdentity/browser_identityPopup_focus.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6627,16 +6627,22 @@ var gIdentityHandler = {
   _sslStatus: null,
 
   /**
    * Bitmask provided by nsIWebProgressListener.onSecurityChange.
    */
   _state: 0,
 
   /**
+   * This flag gets set if the identity popup was opened by a keypress,
+   * to be able to focus it on the popupshown event.
+   */
+  _popupTriggeredByKeyboard: false,
+
+  /**
    * Whether a permission is just removed from permission list.
    */
   _permissionJustRemoved: false,
 
   get _isBroken() {
     return this._state & Ci.nsIWebProgressListener.STATE_IS_BROKEN;
   },
 
@@ -7321,36 +7327,40 @@ var gIdentityHandler = {
       return; // Left click, space or enter only
     }
 
     // Don't allow left click, space or enter if the location has been modified.
     if (gURLBar.getAttribute("pageproxystate") != "valid") {
       return;
     }
 
+    this._popupTriggeredByKeyboard = event.type == "keypress";
+
     // Make sure that the display:none style we set in xul is removed now that
     // the popup is actually needed
     this._identityPopup.hidden = false;
 
     // Update the popup strings
     this.refreshIdentityPopup();
 
     // Add the "open" attribute to the identity box for styling
     this._identityBox.setAttribute("open", "true");
 
     // Now open the popup, anchored off the primary chrome element
     this._identityPopup.openPopup(this._identityIcon, "bottomcenter topleft");
   },
 
   onPopupShown(event) {
     if (event.target == this._identityPopup) {
-      // Move focus to the next available element in the identity popup.
-      // This is required by role=alertdialog and fixes an issue where
-      // an already open panel would steal focus from the identity popup.
-      document.commandDispatcher.advanceFocusIntoSubtree(this._identityPopup);
+      if (this._popupTriggeredByKeyboard) {
+        // Move focus to the next available element in the identity popup.
+        // This is required by role=alertdialog and fixes an issue where
+        // an already open panel would steal focus from the identity popup.
+        document.commandDispatcher.advanceFocusIntoSubtree(this._identityPopup);
+      }
 
       window.addEventListener("focus", this, true);
     }
   },
 
   onPopupHidden(event) {
     if (event.target == this._identityPopup) {
       window.removeEventListener("focus", this, true);
--- a/browser/base/content/test/siteIdentity/browser.ini
+++ b/browser/base/content/test/siteIdentity/browser.ini
@@ -1,7 +1,8 @@
 [DEFAULT]
 support-files =
   head.js
 
 [browser_identityBlock_focus.js]
 skip-if = os == 'mac' # Bug 1334418 (try only)
 support-files = ../general/permissions.html
+[browser_identityPopup_focus.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/siteIdentity/browser_identityPopup_focus.js
@@ -0,0 +1,27 @@
+/* Tests the focus behavior of the identity popup. */
+
+// Access the identity popup via mouseclick. Focus should not be moved inside.
+add_task(function* testIdentityPopupFocusClick() {
+  yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
+  yield BrowserTestUtils.withNewTab("https://example.com", function*() {
+    let shown = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
+    EventUtils.synthesizeMouseAtCenter(gIdentityHandler._identityBox, {});
+    yield shown;
+    isnot(Services.focus.focusedElement, document.getElementById("identity-popup-security-expander"));
+  });
+});
+
+// Access the identity popup via keyboard. Focus should be moved inside.
+add_task(function* testIdentityPopupFocusKeyboard() {
+  yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
+  yield BrowserTestUtils.withNewTab("https://example.com", function*() {
+    let focused = BrowserTestUtils.waitForEvent(gIdentityHandler._identityBox, "focus");
+    gIdentityHandler._identityBox.focus();
+    yield focused;
+    let shown = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
+    EventUtils.synthesizeKey(" ", {});
+    yield shown;
+    is(Services.focus.focusedElement, document.getElementById("identity-popup-security-expander"));
+  });
+});
+