Bug 1539984 - pass along whether a focus change was tripped by a keypress to ensure :-moz-focusring works as designed, r=Jamie
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Tue, 23 Apr 2019 11:12:02 +0000
changeset 470468 4ffdb79d807550910a3d501ad730834f5bdf0ca1
parent 470467 2b287d167a3ec1c72f953187b2ed74bce9ec90fe
child 470469 3b274cabedb6120549dd2afefbcaa4833ccb1311
push id35906
push useraciure@mozilla.com
push dateTue, 23 Apr 2019 22:14:56 +0000
treeherdermozilla-central@0ce3633f8b80 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJamie
bugs1539984
milestone68.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 1539984 - pass along whether a focus change was tripped by a keypress to ensure :-moz-focusring works as designed, r=Jamie Differential Revision: https://phabricator.services.mozilla.com/D27874
browser/components/customizableui/PanelMultiView.jsm
browser/components/customizableui/test/browser_PanelMultiView_keyboard.js
browser/themes/shared/controlcenter/panel.inc.css
--- a/browser/components/customizableui/PanelMultiView.jsm
+++ b/browser/components/customizableui/PanelMultiView.jsm
@@ -1494,32 +1494,32 @@ var PanelView = class extends Associated
       this._arrowNavigableWalker : this._tabNavigableWalker;
     walker.currentNode = walker.root;
     this.selectedElement = walker.firstChild();
     if (skipBack && walker.currentNode
         && walker.currentNode.classList.contains("subviewbutton-back")
         && walker.nextNode()) {
       this.selectedElement = walker.currentNode;
     }
-    this.focusSelectedElement();
+    this.focusSelectedElement(/* byKey */ true);
   }
 
   /**
    * Focuses and moves keyboard selection to the last navigable element.
    * This is a no-op if there are no navigable elements.
    *
    * @param {Boolean} endKey   `true` if this is for the end key.
    */
   focusLastNavigableElement(endKey = false) {
     // The end key is conceptually similar to the up/down arrow keys.
     let walker = endKey ?
       this._arrowNavigableWalker : this._tabNavigableWalker;
     walker.currentNode = walker.root;
     this.selectedElement = walker.lastChild();
-    this.focusSelectedElement();
+    this.focusSelectedElement(/* byKey */ true);
   }
 
   /**
    * Based on going up or down, select the previous or next focusable element.
    *
    * @param {Boolean} isDown   whether we're going down (true) or up (false).
    * @param {Boolean} arrowKey   `true` if this is for the up/down arrow keys.
    *
@@ -1602,17 +1602,17 @@ var PanelView = class extends Associated
           break;
         }
         // Fall-through...
       case "Tab": {
         stop();
         let isDown = (keyCode == "ArrowDown") ||
                      (keyCode == "Tab" && !event.shiftKey);
         let button = this.moveSelection(isDown, keyCode != "Tab");
-        button.focus();
+        Services.focus.setFocus(button, Services.focus.FLAG_BYKEY);
         break;
       }
       case "Home":
         if (tabOnly()) {
           break;
         }
         stop();
         this.focusFirstNavigableElement(true);
@@ -1665,21 +1665,25 @@ var PanelView = class extends Associated
         this._doingKeyboardActivation = false;
         break;
       }
     }
   }
 
   /**
    * Focus the last selected element in the view, if any.
+   *
+   * @param byKey {Boolean} whether focus was moved by the user pressing a key.
+   *                        Needed to ensure we show focus styles in the right cases.
    */
-  focusSelectedElement() {
+  focusSelectedElement(byKey = false) {
     let selected = this.selectedElement;
     if (selected) {
-      selected.focus();
+      let flag = byKey ? "FLAG_BYKEY" : "FLAG_BYELEMENTFOCUS";
+      Services.focus.setFocus(selected, Services.focus[flag]);
     }
   }
 
   /**
    * Clear all traces of keyboard navigation happening right now.
    */
   clearNavigation() {
     let selected = this.selectedElement;
--- a/browser/components/customizableui/test/browser_PanelMultiView_keyboard.js
+++ b/browser/components/customizableui/test/browser_PanelMultiView_keyboard.js
@@ -206,17 +206,17 @@ add_task(async function testArrowsMenuli
   await hidePopup();
 });
 
 // Test that pressing space in a textbox inserts a space (instead of trying to
 // activate the control).
 add_task(async function testSpaceTextbox() {
   await openPopup();
   gMainTextbox.focus();
-  EventUtils.synthesizeKey("KEY_Home");
+  gMainTextbox.selectionStart = gMainTextbox.selectionEnd = 0;
   EventUtils.synthesizeKey(" ");
   is(gMainTextbox.value, " value", "Space typed into textbox");
   gMainTextbox.value = "value";
   await hidePopup();
 });
 
 // Tests that the left arrow key normally moves back to the previous view.
 add_task(async function testLeftArrow() {
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -365,16 +365,17 @@ description#identity-popup-content-verif
   margin: 0;
   padding-inline-start: 0;
 }
 
 .identity-popup-content-blocking-category:-moz-focusring,
 .identity-popup-content-blocking-category:hover {
   border-radius: 2px;
   background-color: var(--arrowpanel-dimmed);
+  outline: none;
 }
 
 .identity-popup-content-blocking-category:hover:active {
   background-color: var(--arrowpanel-dimmed-further);
 }
 
 .identity-popup-content-blocking-category::after {
   content: url(chrome://browser/skin/back-12.svg);