Bug 1502950 - Fix error pages in custom tabs. r=snorp
authorDylan Roeh <droeh@mozilla.com>
Mon, 05 Nov 2018 12:31:10 -0600
changeset 444423 be98a5ed931b69db01361ca6b7dca785bcfbc503
parent 444422 4cc1239a7be40e828639a66bfdbdc5c4fdf1d894
child 444424 56bb430315885b97469a28aef13c2f48bc6fc276
push id109587
push userdroeh@mozilla.com
push dateMon, 05 Nov 2018 18:34:08 +0000
treeherdermozilla-inbound@be98a5ed931b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1502950
milestone65.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 1502950 - Fix error pages in custom tabs. r=snorp
mobile/android/chrome/geckoview/GeckoViewNavigationChild.js
mobile/android/modules/geckoview/LoadURIDelegate.jsm
--- a/mobile/android/chrome/geckoview/GeckoViewNavigationChild.js
+++ b/mobile/android/chrome/geckoview/GeckoViewNavigationChild.js
@@ -1,28 +1,33 @@
 /* -*- 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/. */
 
 ChromeUtils.import("resource://gre/modules/GeckoViewChildModule.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
   E10SUtils: "resource://gre/modules/E10SUtils.jsm",
   ErrorPageEventHandler: "chrome://geckoview/content/ErrorPageEventHandler.js",
   LoadURIDelegate: "resource://gre/modules/LoadURIDelegate.jsm",
 });
 
 // Implements nsILoadURIDelegate.
 class GeckoViewNavigationChild extends GeckoViewChildModule {
   onInit() {
     docShell.loadURIDelegate = this;
 
+    if (Services.androidBridge.isFennec) {
+      addEventListener("DOMContentLoaded", this);
+    }
+
     if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) {
       let tabchild = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsITabChild);
       tabchild.webBrowserChrome = this;
     }
   }
 
   // nsILoadURIDelegate.
@@ -31,21 +36,16 @@ class GeckoViewNavigationChild extends G
                     where=${aWhere} flags=${aFlags}
                     tp=${aTriggeringPrincipal && aTriggeringPrincipal.URI &&
                          aTriggeringPrincipal.URI.spec}`;
 
     if (!this.enabled) {
       return false;
     }
 
-    // TODO: Remove this when we have a sensible error API.
-    if (aUri && aUri.displaySpec.startsWith("about:certerror")) {
-      addEventListener("click", ErrorPageEventHandler, true);
-    }
-
     return LoadURIDelegate.load(content, this.eventDispatcher,
                                 aUri, aWhere, aFlags, aTriggeringPrincipal);
   }
 
   // nsILoadURIDelegate.
   handleLoadError(aUri, aError, aErrorModule) {
     debug `handleLoadError: uri=${aUri && aUri.spec}
                              uri2=${aUri && aUri.displaySpec}
@@ -93,12 +93,39 @@ class GeckoViewNavigationChild extends G
   }
 
   // nsIWebBrowserChrome
   reloadInFreshProcess(aDocShell, aURI, aReferrer, aTriggeringPrincipal, aLoadFlags) {
     debug `reloadInFreshProcess ${aURI.displaySpec}`;
     E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, true, aLoadFlags);
     return true;
   }
+
+  handleEvent(aEvent) {
+    switch (aEvent.type) {
+      case "DOMContentLoaded": {
+        // TODO: Remove this when we have a better story re: interactive error pages.
+        let target = aEvent.originalTarget;
+
+        // ignore on frames and other documents
+        if (target != content.document)
+          return;
+
+        let docURI = target.documentURI;
+
+        if (docURI.startsWith("about:certerror") || docURI.startsWith("about:blocked")) {
+          addEventListener("click", ErrorPageEventHandler, true);
+          let listener = () => {
+            removeEventListener("click", ErrorPageEventHandler, true);
+            removeEventListener("pagehide", listener, true);
+          };
+
+          addEventListener("pagehide", listener, true);
+        }
+
+        break;
+      }
+    }
+  }
 }
 
 let {debug, warn} = GeckoViewNavigationChild.initLogging("GeckoViewNavigation");
 let module = GeckoViewNavigationChild.create(this);
--- a/mobile/android/modules/geckoview/LoadURIDelegate.jsm
+++ b/mobile/android/modules/geckoview/LoadURIDelegate.jsm
@@ -66,17 +66,17 @@ const LoadURIDelegate = {
       error: aError,
       errorModule: aErrorModule,
       errorClass,
     };
 
     let errorPageURI = undefined;
     aEventDispatcher.sendRequestForResult(msg).then(response => {
       try {
-        errorPageURI = Services.io.newURI(response);
+        errorPageURI = response ? Services.io.newURI(response) : null;
       } catch (e) {
         warn `Failed to parse URI '${response}`;
         errorPageURI = null;
         Components.returnCode = Cr.NS_ERROR_ABORT;
       }
     }, e => {
       errorPageURI = null;
       Components.returnCode = Cr.NS_ERROR_ABORT;