Bug 1472491: Part 5k - Add NetErrorChild actor. r=johannh f=felipe
authorKris Maglione <maglione.k@gmail.com>
Sun, 29 Jul 2018 21:00:29 -0700
changeset 486563 0196bac4114b13c869f57cad22d922920a5b8180
parent 486562 17440776f078aa0219f72e97ce88f0b7a1217b30
child 486564 58587e163a5912cf56164a3f4af43a8d114913be
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh
bugs1472491
milestone63.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 1472491: Part 5k - Add NetErrorChild actor. r=johannh f=felipe MozReview-Commit-ID: EclR3sogB4i
browser/actors/ClickHandlerChild.jsm
browser/actors/NetErrorChild.jsm
browser/actors/moz.build
browser/base/content/content.js
browser/components/extensions/test/browser/browser_ext_menus_events.js
browser/components/nsBrowserGlue.js
browser/modules/NetErrorContent.jsm
browser/modules/moz.build
--- a/browser/actors/ClickHandlerChild.jsm
+++ b/browser/actors/ClickHandlerChild.jsm
@@ -5,18 +5,16 @@
 
 var EXPORTED_SYMBOLS = ["ClickHandlerChild"];
 
 ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 ChromeUtils.defineModuleGetter(this, "BrowserUtils",
                                "resource://gre/modules/BrowserUtils.jsm");
-ChromeUtils.defineModuleGetter(this, "NetErrorContent",
-                               "resource:///modules/NetErrorContent.jsm");
 ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
                                "resource://gre/modules/PrivateBrowsingUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "WebNavigationFrames",
                                "resource://gre/modules/WebNavigationFrames.jsm");
 
 class ClickHandlerChild extends ActorChild {
   handleEvent(event) {
     if (!event.isTrusted || event.defaultPrevented || event.button == 2) {
@@ -26,23 +24,17 @@ class ClickHandlerChild extends ActorChi
     let originalTarget = event.originalTarget;
     let ownerDoc = originalTarget.ownerDocument;
     if (!ownerDoc) {
       return;
     }
 
     // Handle click events from about pages
     if (event.button == 0) {
-      if (this.mm.AboutNetAndCertErrorListener.isAboutCertError(ownerDoc)) {
-        NetErrorContent.onCertError(this.mm, originalTarget, ownerDoc.defaultView);
-        return;
-      } else if (ownerDoc.documentURI.startsWith("about:blocked")) {
-        return;
-      } else if (this.mm.AboutNetAndCertErrorListener.isAboutNetError(ownerDoc)) {
-        NetErrorContent.onAboutNetError(this.mm, event, ownerDoc.documentURI);
+      if (ownerDoc.documentURI.startsWith("about:blocked")) {
         return;
       }
     }
 
     let [href, node, principal] = this._hrefAndLinkNodeForClickEvent(event);
 
     // get referrer attribute from clicked link and parse it
     // if per element referrer is enabled, the element referrer overrules
rename from browser/modules/NetErrorContent.jsm
rename to browser/actors/NetErrorChild.jsm
--- a/browser/modules/NetErrorContent.jsm
+++ b/browser/actors/NetErrorChild.jsm
@@ -1,17 +1,18 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-var EXPORTED_SYMBOLS = ["NetErrorContent"];
+var EXPORTED_SYMBOLS = ["NetErrorChild"];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
 
 ChromeUtils.defineModuleGetter(this, "BrowserUtils",
                                "resource://gre/modules/BrowserUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "WebNavigationFrames",
                                "resource://gre/modules/WebNavigationFrames.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "gPipNSSBundle", function() {
   return Services.strings.createBundle("chrome://pipnss/locale/pipnss.properties");
@@ -65,24 +66,24 @@ function getSerializedSecurityInfo(docSh
     return "";
   }
   securityInfo.QueryInterface(Ci.nsITransportSecurityInfo)
               .QueryInterface(Ci.nsISerializable);
 
   return serhelper.serializeToString(securityInfo);
 }
 
-var NetErrorContent = {
+class NetErrorChild extends ActorChild {
   isAboutNetError(doc) {
     return doc.documentURI.startsWith("about:neterror");
-  },
+  }
 
   isAboutCertError(doc) {
     return doc.documentURI.startsWith("about:certerror");
-  },
+  }
 
   _getCertValidityRange(docShell) {
     let {securityInfo} = docShell.failedChannel;
     securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
     let certs = securityInfo.failedCertChain.getEnumerator();
     let notBefore = 0;
     let notAfter = Number.MAX_SAFE_INTEGER;
     while (certs.hasMoreElements()) {
@@ -90,17 +91,17 @@ var NetErrorContent = {
       cert.QueryInterface(Ci.nsIX509Cert);
       notBefore = Math.max(notBefore, cert.validity.notBefore);
       notAfter = Math.min(notAfter, cert.validity.notAfter);
     }
     // nsIX509Cert reports in PR_Date terms, which uses microseconds. Convert:
     notBefore /= 1000;
     notAfter /= 1000;
     return {notBefore, notAfter};
-  },
+  }
 
   _setTechDetails(input, doc) {
     // CSS class and error code are set from nsDocShell.
     let searchParams = new URLSearchParams(doc.documentURI.split("?")[1]);
     let cssClass = searchParams.get("s");
     let error = searchParams.get("e");
     let technicalInfo = doc.getElementById("badCertTechnicalInfo");
     technicalInfo.textContent = "";
@@ -324,25 +325,25 @@ var NetErrorContent = {
     if (errorCode) {
       errorCode.href = "javascript:void(0)";
       errorCode.addEventListener("click", () => {
         let debugInfo = doc.getElementById("certificateErrorDebugInformation");
         debugInfo.style.display = "block";
         debugInfo.scrollIntoView({block: "start", behavior: "smooth"});
       });
     }
-  },
+  }
 
-  onCertErrorDetails(global, msg, docShell) {
+  onCertErrorDetails(msg, docShell) {
     let doc = docShell.document;
 
-  function updateContainerPosition() {
-    let textContainer = doc.getElementById("text-container");
-    textContainer.style.marginTop = `calc(50vh - ${textContainer.clientHeight / 2}px)`;
-  }
+    function updateContainerPosition() {
+      let textContainer = doc.getElementById("text-container");
+      textContainer.style.marginTop = `calc(50vh - ${textContainer.clientHeight / 2}px)`;
+    }
 
     let div = doc.getElementById("certificateErrorText");
     div.textContent = msg.data.info;
     this._setTechDetails(msg, doc);
     let learnMoreLink = doc.getElementById("learnMoreLink");
     let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
     let errWhatToDo = doc.getElementById("es_nssBadCert_" + msg.data.codeString);
     let es = doc.getElementById("errorWhatToDoText");
@@ -479,101 +480,133 @@ var NetErrorContent = {
               // eslint-disable-next-line no-unsanitized/property
               est.textContent = errWhatToDoTitle.textContent;
               est.style.fontWeight = "bold";
             }
             updateContainerPosition();
         }
         break;
     }
-  },
+  }
 
-  handleEvent(aGlobal, aEvent) {
+  handleEvent(aEvent) {
     // Documents have a null ownerDocument.
     let doc = aEvent.originalTarget.ownerDocument || aEvent.originalTarget;
 
     switch (aEvent.type) {
     case "AboutNetErrorLoad":
-      this.onPageLoad(aGlobal, aEvent.originalTarget, doc.defaultView);
+      this.onPageLoad(aEvent.originalTarget, doc.defaultView);
       break;
     case "AboutNetErrorOpenCaptivePortal":
-      this.openCaptivePortalPage(aGlobal, aEvent);
+      this.openCaptivePortalPage(aEvent);
       break;
     case "AboutNetErrorSetAutomatic":
-      this.onSetAutomatic(aGlobal, aEvent);
+      this.onSetAutomatic(aEvent);
       break;
     case "AboutNetErrorResetPreferences":
-      this.onResetPreferences(aGlobal, aEvent);
+      this.onResetPreferences(aEvent);
       break;
+    case "click":
+      if (aEvent.button == 0) {
+        if (this.isAboutCertError(doc)) {
+          this.onCertError(aEvent.originalTarget, doc.defaultView);
+        } else {
+          this.onClick(aEvent);
+        }
+      }
     }
-  },
+  }
+
+  receiveMessage(msg) {
+    if (msg.name == "CertErrorDetails") {
+      let frameDocShell = WebNavigationFrames.findDocShell(msg.data.frameId, this.docShell);
+      // We need nsIWebNavigation to access docShell.document.
+      frameDocShell && frameDocShell.QueryInterface(Ci.nsIWebNavigation);
+      if (!frameDocShell || !this.isAboutCertError(frameDocShell.document)) {
+        return;
+      }
+
+      this.onCertErrorDetails(msg, frameDocShell);
+    } else if (msg.name == "Browser:CaptivePortalFreed") {
+      // TODO: This check is not correct for frames.
+      if (!this.isAboutCertError(this.content.document)) {
+        return;
+      }
+
+      this.onCaptivePortalFreed(msg);
+    }
+  }
+
+  onCaptivePortalFreed(msg) {
+    this.content.dispatchEvent(new this.content.CustomEvent("AboutNetErrorCaptivePortalFreed"));
+  }
 
   changedCertPrefs() {
     let prefSSLImpact = PREF_SSL_IMPACT_ROOTS.reduce((prefs, root) => {
        return prefs.concat(Services.prefs.getChildList(root));
     }, []);
     for (let prefName of prefSSLImpact) {
       if (Services.prefs.prefHasUserValue(prefName)) {
         return true;
       }
     }
 
     return false;
-  },
+  }
 
-   _getErrorMessageFromCode(securityInfo, doc) {
-     let uri = Services.io.newURI(doc.location);
-     let hostString = uri.host;
-     if (uri.port != 443 && uri.port != -1) {
-       hostString = uri.hostPort;
-     }
+  _getErrorMessageFromCode(securityInfo, doc) {
+    let uri = Services.io.newURI(doc.location);
+    let hostString = uri.host;
+    if (uri.port != 443 && uri.port != -1) {
+      hostString = uri.hostPort;
+    }
 
-     let id_str = "";
-     switch (securityInfo.errorCode) {
-       case SSL_ERROR_SSL_DISABLED:
-         id_str = "PSMERR_SSL_Disabled";
-         break;
-       case SSL_ERROR_SSL2_DISABLED:
-         id_str = "PSMERR_SSL2_Disabled";
-         break;
-       case SEC_ERROR_REUSED_ISSUER_AND_SERIAL:
-         id_str = "PSMERR_HostReusedIssuerSerial";
-         break;
-     }
-     let nss_error_id_str = securityInfo.errorCodeString;
-     let msg2 = "";
-     if (id_str) {
-       msg2 = gPipNSSBundle.GetStringFromName(id_str) + "\n";
-     } else if (nss_error_id_str) {
-       msg2 = gNSSErrorsBundle.GetStringFromName(nss_error_id_str) + "\n";
-     }
+    let id_str = "";
+    switch (securityInfo.errorCode) {
+      case SSL_ERROR_SSL_DISABLED:
+        id_str = "PSMERR_SSL_Disabled";
+        break;
+      case SSL_ERROR_SSL2_DISABLED:
+        id_str = "PSMERR_SSL2_Disabled";
+        break;
+      case SEC_ERROR_REUSED_ISSUER_AND_SERIAL:
+        id_str = "PSMERR_HostReusedIssuerSerial";
+        break;
+    }
+    let nss_error_id_str = securityInfo.errorCodeString;
+    let msg2 = "";
+    if (id_str) {
+      msg2 = gPipNSSBundle.GetStringFromName(id_str) + "\n";
+    } else if (nss_error_id_str) {
+      msg2 = gNSSErrorsBundle.GetStringFromName(nss_error_id_str) + "\n";
+    }
 
-     if (!msg2) {
-       // We couldn't get an error message. Use the error string.
-       // Note that this is different from before where we used PR_ErrorToString.
-       msg2 = nss_error_id_str;
-     }
-     let msg = gPipNSSBundle.formatStringFromName("SSLConnectionErrorPrefix2",
-                                                  [hostString, msg2], 2);
+    if (!msg2) {
+      // We couldn't get an error message. Use the error string.
+      // Note that this is different from before where we used PR_ErrorToString.
+      msg2 = nss_error_id_str;
+    }
+    let msg = gPipNSSBundle.formatStringFromName("SSLConnectionErrorPrefix2",
+                                                 [hostString, msg2], 2);
 
-     if (nss_error_id_str) {
-       msg += gPipNSSBundle.formatStringFromName("certErrorCodePrefix3",
-                                                 [nss_error_id_str], 1) + "\n";
-     }
-     return msg;
-   },
+    if (nss_error_id_str) {
+      msg += gPipNSSBundle.formatStringFromName("certErrorCodePrefix3",
+                                                [nss_error_id_str], 1) + "\n";
+    }
+    return msg;
+  }
 
-  onPageLoad(global, originalTarget, win) {
+  onPageLoad(originalTarget, win) {
     // Values for telemtery bins: see TLS_ERROR_REPORT_UI in Histograms.json
     const TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN = 0;
 
     let hideAddExceptionButton = false;
 
     if (this.isAboutCertError(win.document)) {
-      this.onCertError(global, originalTarget, win);
+      this.onCertError(originalTarget, win);
       hideAddExceptionButton =
         Services.prefs.getBoolPref("security.certerror.hideAddException", false);
     }
     if (this.isAboutNetError(win.document)) {
       let docShell = win.docShell;
       if (docShell) {
         let {securityInfo} = docShell.failedChannel;
         // We don't have a securityInfo when this is for example a DNS error.
@@ -592,70 +625,71 @@ var NetErrorContent = {
       detail: JSON.stringify({
         enabled: Services.prefs.getBoolPref("security.ssl.errorReporting.enabled"),
         changedCertPrefs: this.changedCertPrefs(),
         automatic,
         hideAddExceptionButton,
       })
     }));
 
-    global.sendAsyncMessage("Browser:SSLErrorReportTelemetry",
+    this.mm.sendAsyncMessage("Browser:SSLErrorReportTelemetry",
                             {reportStatus: TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN});
-  },
+  }
 
-  openCaptivePortalPage(global, evt) {
-    global.sendAsyncMessage("Browser:OpenCaptivePortalPage");
-  },
+  openCaptivePortalPage(evt) {
+    this.mm.sendAsyncMessage("Browser:OpenCaptivePortalPage");
+  }
 
 
-  onResetPreferences(global, evt) {
-    global.sendAsyncMessage("Browser:ResetSSLPreferences");
-  },
+  onResetPreferences(evt) {
+    this.mm.sendAsyncMessage("Browser:ResetSSLPreferences");
+  }
 
-  onSetAutomatic(global, evt) {
-    global.sendAsyncMessage("Browser:SetSSLErrorReportAuto", {
+  onSetAutomatic(evt) {
+    this.mm.sendAsyncMessage("Browser:SetSSLErrorReportAuto", {
       automatic: evt.detail
     });
 
     // If we're enabling reports, send a report for this failure.
     if (evt.detail) {
       let win = evt.originalTarget.ownerGlobal;
       let docShell = win.docShell;
 
       let {securityInfo} = docShell.failedChannel;
       securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
       let {host, port} = win.document.mozDocumentURIIfNotForErrorPages;
 
       let errorReporter = Cc["@mozilla.org/securityreporter;1"]
                             .getService(Ci.nsISecurityReporter);
       errorReporter.reportTLSError(securityInfo, host, port);
     }
-  },
+  }
 
-  onCertError(global, targetElement, win) {
-    let docShell = win.docShell;
-    global.sendAsyncMessage("Browser:CertExceptionError", {
+  onCertError(target, win) {
+    this.mm.sendAsyncMessage("Browser:CertExceptionError", {
       frameId: WebNavigationFrames.getFrameId(win),
       location: win.document.location.href,
-      elementId: targetElement.getAttribute("id"),
+      elementId: target.getAttribute("id"),
       isTopFrame: (win.parent === win),
-      securityInfoAsString: getSerializedSecurityInfo(docShell),
+      securityInfoAsString: getSerializedSecurityInfo(win.docShell),
     });
-  },
+  }
 
-  onAboutNetError(global, event, documentURI) {
+  onClick(event) {
+    let {documentURI} = event.target.ownerDocument;
+
     let elmId = event.originalTarget.getAttribute("id");
     if (elmId == "returnButton") {
-      global.sendAsyncMessage("Browser:SSLErrorGoBack", {});
+      this.mm.sendAsyncMessage("Browser:SSLErrorGoBack", {});
       return;
     }
     if (elmId != "errorTryAgain" || !/e=netOffline/.test(documentURI)) {
       return;
     }
     // browser front end will handle clearing offline mode and refreshing
     // the page *if* we're in offline mode now. Otherwise let the error page
     // handle the click.
     if (Services.io.offline) {
       event.preventDefault();
-      global.sendAsyncMessage("Browser:EnableOnlineMode", {});
+      this.mm.sendAsyncMessage("Browser:EnableOnlineMode", {});
     }
-  },
-};
+  }
+}
--- a/browser/actors/moz.build
+++ b/browser/actors/moz.build
@@ -19,12 +19,13 @@ with Files("PluginChild.jsm"):
 FINAL_TARGET_FILES.actors += [
     'AboutReaderChild.jsm',
     'BlockedSiteChild.jsm',
     'BrowserTabChild.jsm',
     'ClickHandlerChild.jsm',
     'ContentSearchChild.jsm',
     'ContextMenuChild.jsm',
     'LightWeightThemeInstallChild.jsm',
+    'NetErrorChild.jsm',
     'PageInfoChild.jsm',
     'PageStyleChild.jsm',
     'PluginChild.jsm',
 ]
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -17,19 +17,17 @@ var global = this;
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   ContentLinkHandler: "resource:///modules/ContentLinkHandler.jsm",
   ContentMetaHandler: "resource:///modules/ContentMetaHandler.jsm",
   ContentWebRTC: "resource:///modules/ContentWebRTC.jsm",
   LoginFormFactory: "resource://gre/modules/LoginManagerContent.jsm",
   InsecurePasswordUtils: "resource://gre/modules/InsecurePasswordUtils.jsm",
   FormSubmitObserver: "resource:///modules/FormSubmitObserver.jsm",
-  NetErrorContent: "resource:///modules/NetErrorContent.jsm",
   PageMetadata: "resource://gre/modules/PageMetadata.jsm",
-  WebNavigationFrames: "resource://gre/modules/WebNavigationFrames.jsm",
   ContextMenuChild: "resource:///actors/ContextMenuChild.jsm",
 });
 
 XPCOMUtils.defineLazyGetter(this, "LoginManagerContent", () => {
   let tmp = {};
   ChromeUtils.import("resource://gre/modules/LoginManagerContent.jsm", tmp);
   tmp.LoginManagerContent.setupEventListeners(global);
   return tmp.LoginManagerContent;
@@ -59,72 +57,16 @@ addEventListener("DOMInputPasswordAdded"
   LoginManagerContent.onDOMInputPasswordAdded(event, content);
   let formLike = LoginFormFactory.createFromField(event.originalTarget);
   InsecurePasswordUtils.reportInsecurePasswords(formLike);
 });
 addEventListener("DOMAutoComplete", function(event) {
   LoginManagerContent.onUsernameInput(event);
 });
 
-this.AboutNetAndCertErrorListener = {
-  init(chromeGlobal) {
-    addMessageListener("CertErrorDetails", this);
-    addMessageListener("Browser:CaptivePortalFreed", this);
-    chromeGlobal.addEventListener("AboutNetErrorLoad", this, false, true);
-    chromeGlobal.addEventListener("AboutNetErrorOpenCaptivePortal", this, false, true);
-    chromeGlobal.addEventListener("AboutNetErrorSetAutomatic", this, false, true);
-    chromeGlobal.addEventListener("AboutNetErrorResetPreferences", this, false, true);
-    this.init = null;
-  },
-
-  isAboutNetError(doc) {
-    return doc.documentURI.startsWith("about:neterror");
-  },
-
-  isAboutCertError(doc) {
-    return doc.documentURI.startsWith("about:certerror");
-  },
-
-  receiveMessage(msg) {
-    if (msg.name == "CertErrorDetails") {
-      let frameDocShell = WebNavigationFrames.findDocShell(msg.data.frameId, docShell);
-      // We need nsIWebNavigation to access docShell.document.
-      frameDocShell && frameDocShell.QueryInterface(Ci.nsIWebNavigation);
-      if (!frameDocShell || !this.isAboutCertError(frameDocShell.document)) {
-        return;
-      }
-
-      NetErrorContent.onCertErrorDetails(global, msg, frameDocShell);
-    } else if (msg.name == "Browser:CaptivePortalFreed") {
-      // TODO: This check is not correct for frames.
-      if (!this.isAboutCertError(content.document)) {
-        return;
-      }
-
-      this.onCaptivePortalFreed(msg);
-    }
-  },
-
-  onCaptivePortalFreed(msg) {
-    content.dispatchEvent(new content.CustomEvent("AboutNetErrorCaptivePortalFreed"));
-  },
-
-  handleEvent(aEvent) {
-    // Documents have a null ownerDocument.
-    let doc = aEvent.originalTarget.ownerDocument || aEvent.originalTarget;
-
-    if (!this.isAboutNetError(doc) && !this.isAboutCertError(doc)) {
-      return;
-    }
-
-    NetErrorContent.handleEvent(global, aEvent);
-  },
-};
-AboutNetAndCertErrorListener.init(this);
-
 new ContentLinkHandler(this);
 ContentMetaHandler.init(this);
 
 // This is a temporary hack to prevent regressions (bug 1471327).
 void content;
 
 addEventListener("DOMWindowFocus", function(event) {
   sendAsyncMessage("DOMWindowFocus", {});
--- a/browser/components/extensions/test/browser/browser_ext_menus_events.js
+++ b/browser/components/extensions/test/browser/browser_ext_menus_events.js
@@ -402,16 +402,18 @@ add_task(async function test_show_hide_f
       editable: false,
       get frameId() { return frameId; },
       pageUrl: PAGE,
       frameUrl: PAGE_BASE + "context_frame.html",
       targetElementId: EXPECT_TARGET_ELEMENT,
     },
     async doOpenMenu() {
       frameId = await ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
+        ChromeUtils.import("resource://gre/modules/WebNavigationFrames.jsm");
+
         let {contentWindow} = content.document.getElementById("frame");
         return WebNavigationFrames.getFrameId(contentWindow);
       });
       await openContextMenuInFrame("#frame");
     },
     async doCloseMenu() {
       await closeExtensionContextMenu();
     },
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -108,16 +108,35 @@ let ACTORS = {
       events: {
         "InstallBrowserTheme": {wantUntrusted: true},
         "PreviewBrowserTheme": {wantUntrusted: true},
         "ResetBrowserThemePreview": {wantUntrusted: true},
       },
     },
   },
 
+  NetError: {
+    child: {
+      module: "resource:///actors/NetErrorChild.jsm",
+      events: {
+        "AboutNetErrorLoad": {wantUntrusted: true},
+        "AboutNetErrorOpenCaptivePortal": {wantUntrusted: true},
+        "AboutNetErrorSetAutomatic": {wantUntrusted: true},
+        "AboutNetErrorResetPreferences": {wantUntrusted: true},
+        "click": {},
+      },
+      matches: ["about:certerror?*", "about:neterror?*"],
+      allFrames: true,
+      messages: [
+        "Browser:CaptivePortalFreed",
+        "CertErrorDetails",
+      ],
+    },
+  },
+
   PageInfo: {
     child: {
       module: "resource:///actors/PageInfoChild.jsm",
       messages: ["PageInfo:getData"],
     },
   },
 
   PageStyle: {
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -134,17 +134,16 @@ EXTRA_JS_MODULES += [
     'ContentWebRTC.jsm',
     'ExtensionsUI.jsm',
     'Feeds.jsm',
     'FormSubmitObserver.jsm',
     'FormValidationHandler.jsm',
     'HomePage.jsm',
     'LaterRun.jsm',
     'LightweightThemeChildHelper.jsm',
-    'NetErrorContent.jsm',
     'OpenInTabsUtils.jsm',
     'PageActions.jsm',
     'PermissionUI.jsm',
     'PingCentre.jsm',
     'ProcessHangMonitor.jsm',
     'ReaderParent.jsm',
     'RemotePrompt.jsm',
     'Sanitizer.jsm',