Bug 1336352 - Don't autofocus buttons when about:certerror is embedded in an iframe. r=nhnt11, a=jcristau
authorPanos Astithas <past@mozilla.com>
Wed, 08 Feb 2017 16:43:39 +0200
changeset 376239 9e1cfea4cefbceaa9bfddebfecd25ddca520aaa2
parent 376238 7597080fcccbebbd7d1e01e8353bec0893723fc1
child 376240 77c5dd7e1f3a53ee46741522650871b5da6f602e
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnhnt11, jcristau
bugs1336352
milestone53.0a2
Bug 1336352 - Don't autofocus buttons when about:certerror is embedded in an iframe. r=nhnt11, a=jcristau MozReview-Commit-ID: BT8oCmX9stf
browser/base/content/aboutNetError.xhtml
browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js
browser/base/content/test/general/browser_aboutCertError.js
browser/base/content/test/general/browser_aboutNetError.js
--- a/browser/base/content/aboutNetError.xhtml
+++ b/browser/base/content/aboutNetError.xhtml
@@ -100,16 +100,17 @@
       function showPrefChangeContainer() {
         const panel = document.getElementById("prefChangeContainer");
         panel.style.display = "block";
         document.getElementById("netErrorButtonContainer").style.display = "none";
         document.getElementById("prefResetButton").addEventListener("click", function resetPreferences(e) {
           const event = new CustomEvent("AboutNetErrorResetPreferences", {bubbles:true});
           document.dispatchEvent(event);
         });
+        addAutofocus("prefResetButton", "beforeend");
       }
 
       function setupAdvancedButton(allowOverride) {
         // Get the hostname and add it to the panel
         var panelId = gIsCertError ? "badCertAdvancedPanel" : "weakCryptoAdvancedPanel";
         var panel = document.getElementById(panelId);
         for (var span of panel.querySelectorAll("span.hostname")) {
           span.textContent = document.location.hostname;
@@ -206,16 +207,17 @@
         if (showCaptivePortalUI) {
           initPageCaptivePortal();
           return;
         }
         if (gIsCertError) {
           initPageCertError();
           return;
         }
+        addAutofocus("errorTryAgain");
 
         document.body.className = "neterror";
 
         var ld = document.getElementById("errorLongDesc");
         if (ld) {
           ld.innerHTML = errDesc.innerHTML;
         }
 
@@ -332,16 +334,17 @@
         document.title = document.getElementById("captivePortalPageTitle").textContent;
 
         document.getElementById("openPortalLoginPageButton")
                 .addEventListener("click", () => {
           let event = new CustomEvent("AboutNetErrorOpenCaptivePortal", {bubbles:true});
           document.dispatchEvent(event);
         });
 
+        addAutofocus("openPortalLoginPageButton");
         setupAdvancedButton(true);
 
         addDomainErrorLinks();
 
         // When the portal is freed, an event is generated by the frame script
         // that we can pick up and attempt to reload the original page.
         window.addEventListener("AboutNetErrorCaptivePortalFreed", () => {
           document.location.reload();
@@ -350,16 +353,17 @@
 
       function initPageCertError() {
         document.body.className = "certerror";
         document.title = document.getElementById("certErrorPageTitle").textContent;
         for (let host of document.querySelectorAll(".hostname")) {
           host.textContent = document.location.hostname;
         }
 
+        addAutofocus("returnButton");
         setupAdvancedButton(true);
 
         document.getElementById("learnMoreContainer").style.display = "block";
 
         let checkbox = document.getElementById("automaticallyReportInFuture");
         checkbox.addEventListener("change", function({target: {checked}}) {
           document.dispatchEvent(new CustomEvent("AboutNetErrorSetAutomatic", {
             detail: checked,
@@ -379,16 +383,32 @@
         }, true, true);
 
         let event = new CustomEvent("AboutNetErrorLoad", {bubbles:true});
         document.getElementById("advancedButton").dispatchEvent(event);
 
         addDomainErrorLinks();
       }
 
+      /* Only do autofocus if we're the toplevel frame; otherwise we
+         don't want to call attention to ourselves!  The key part is
+         that autofocus happens on insertion into the tree, so we
+         can remove the button, add @autofocus, and reinsert the
+         button.
+      */
+      function addAutofocus(buttonId, position = "afterbegin") {
+        if (window.top == window) {
+            var button = document.getElementById(buttonId);
+            var parent = button.parentNode;
+            button.remove();
+            button.setAttribute("autofocus", "true");
+            parent.insertAdjacentElement(position, button);
+        }
+      }
+
       /* Try to preserve the links contained in the error description, like
          the error code.
 
          Also, in the case of SSL error pages about domain mismatch, see if
          we can hyperlink the user to the correct site.  We don't want
          to do this generically since it allows MitM attacks to redirect
          users to a site under attacker control, but in certain cases
          it is safe (and helpful!) to do so.  Bug 402210
@@ -613,42 +633,27 @@
         </div>
 
         <div id="prefChangeContainer" class="button-container">
           <p>&prefReset.longDesc;</p>
           <button id="prefResetButton" class="primary" autocomplete="off">&prefReset.label;</button>
         </div>
 
         <div id="certErrorAndCaptivePortalButtonContainer" class="button-container">
-          <button id="returnButton" class="primary" autocomplete="off" autofocus="true">&returnToPreviousPage.label;</button>
-          <button id="openPortalLoginPageButton" class="primary" autocomplete="off" autofocus="true">&openPortalLoginPage.label;</button>
+          <button id="returnButton" class="primary" autocomplete="off">&returnToPreviousPage.label;</button>
+          <button id="openPortalLoginPageButton" class="primary" autocomplete="off">&openPortalLoginPage.label;</button>
           <div class="button-spacer"></div>
-          <button id="advancedButton" autocomplete="off" autofocus="true">&advanced.label;</button>
+          <button id="advancedButton" autocomplete="off">&advanced.label;</button>
         </div>
       </div>
 
       <div id="netErrorButtonContainer" class="button-container">
         <button id="errorTryAgain" class="primary" autocomplete="off" onclick="retryThis(this);">&retry.label;</button>
       </div>
 
-      <script>
-        // Only do autofocus if we're the toplevel frame; otherwise we
-        // don't want to call attention to ourselves!  The key part is
-        // that autofocus happens on insertion into the tree, so we
-        // can remove the button, add @autofocus, and reinsert the
-        // button.
-        if (window.top == window) {
-            var button = document.getElementById("errorTryAgain");
-            var parent = button.parentNode;
-            button.remove();
-            button.setAttribute("autofocus", "true");
-            parent.appendChild(button);
-        }
-      </script>
-
       <!-- UI for option to report certificate errors to Mozilla. Removed on
            init for other error types .-->
       <div id="certificateErrorReporting">
         <p class="toggle-container-with-text">
           <input type="checkbox" id="automaticallyReportInFuture" />
           <label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic2;</label>
         </p>
       </div>
--- a/browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js
+++ b/browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js
@@ -41,17 +41,19 @@ add_task(function* checkCaptivePortalCer
   let portalTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, CANONICAL_URL);
 
   yield ContentTask.spawn(browser, null, () => {
     let doc = content.document;
     ok(doc.body.classList.contains("captiveportal"),
        "Captive portal error page UI is visible.");
 
     info("Clicking the Open Login Page button.");
-    doc.getElementById("openPortalLoginPageButton").click();
+    let loginButton = doc.getElementById("openPortalLoginPageButton");
+    is(loginButton.getAttribute("autofocus"), "true", "openPortalLoginPageButton has autofocus");
+    loginButton.click();
   });
 
   let portalTab = yield portalTabPromise;
   is(gBrowser.selectedTab, portalTab, "Login page should be open in a new foreground tab.");
 
   // Make sure clicking the "Open Login Page" button again focuses the existing portal tab.
   yield BrowserTestUtils.switchTab(gBrowser, errorTab);
   // Passing an empty function to BrowserTestUtils.switchTab lets us wait for an arbitrary
--- a/browser/base/content/test/general/browser_aboutCertError.js
+++ b/browser/base/content/test/general/browser_aboutCertError.js
@@ -34,16 +34,17 @@ add_task(function* checkReturnToAboutHom
   let {entries} = JSON.parse(ss.getTabState(tab));
   is(entries.length, 1, "there is one shistory entry");
 
   info("Clicking the go back button on about:certerror");
   let pageshowPromise = promiseWaitForEvent(browser, "pageshow");
   yield ContentTask.spawn(browser, null, function* () {
     let doc = content.document;
     let returnButton = doc.getElementById("returnButton");
+    is(returnButton.getAttribute("autofocus"), "true", "returnButton has autofocus");
     returnButton.click();
   });
   yield pageshowPromise;
 
   is(browser.webNavigation.canGoBack, true, "webNavigation.canGoBack");
   is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
   is(gBrowser.currentURI.spec, "about:home", "Went back");
 
--- a/browser/base/content/test/general/browser_aboutNetError.js
+++ b/browser/base/content/test/general/browser_aboutNetError.js
@@ -26,16 +26,19 @@ add_task(function* checkReturnToPrevious
 
   Assert.ok(content.document.getElementById("prefResetButton").getBoundingClientRect().left >= 0,
     "Should have a visible button");
 
   Assert.ok(content.document.documentURI.startsWith("about:neterror"), "Should be showing error page");
 
   let pageshowPromise = promiseWaitForEvent(browser, "pageshow");
   yield ContentTask.spawn(browser, null, function* () {
-    content.document.getElementById("prefResetButton").click();
+    let doc = content.document;
+    let prefResetButton = doc.getElementById("prefResetButton");
+    Assert.equal(prefResetButton.getAttribute("autofocus"), "true", "prefResetButton has autofocus");
+    prefResetButton.click();
   });
   yield pageshowPromise;
 
   Assert.equal(content.document.documentURI, LOW_TLS_VERSION, "Should not be showing page");
 
   yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });