Bug 1343210 - Only move focus into identity popup when opened via keyboard. r=Gijs
MozReview-Commit-ID: FZG2DKSM5Fh
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6716,16 +6716,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,
+
get _isBroken() {
return this._state & Ci.nsIWebProgressListener.STATE_IS_BROKEN;
},
get _isSecure() {
// If a <browser> is included within a chrome document, then this._state
// will refer to the security state for the <browser> and not the top level
// document. In this case, don't upgrade the security state in the UI
@@ -7356,16 +7362,18 @@ 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;
// Remove the reload hint that we show after a user has cleared a permission.
this._permissionReloadHint.setAttribute("hidden", "true");
// Update the popup strings
@@ -7375,20 +7383,22 @@ var gIdentityHandler = {
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
@@ -42,16 +42,17 @@ support-files =
[browser_csp_block_all_mixedcontent.js]
tags = mcb
support-files =
file_csp_block_all_mixedcontent.html
file_csp_block_all_mixedcontent.js
[browser_identity_UI.js]
[browser_identityBlock_focus.js]
support-files = ../general/permissions.html
+[browser_identityPopup_focus.js]
[browser_insecureLoginForms.js]
support-files =
insecure_opener.html
!/toolkit/components/passwordmgr/test/browser/form_basic.html
!/toolkit/components/passwordmgr/test/browser/insecure_test.html
!/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html
[browser_mcb_redirect.js]
tags = mcb
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"));
+ });
+});
+