Bug 913243 - Load ErrorPage.js only when error occurs. r=fabrice
authorPatrick Wang (Chih-Kai Wang) <kk1fff@patrickz.net>
Tue, 07 Jan 2014 14:39:32 +0800
changeset 162251 8be08de08cc46637d2fe9571912f7e62a26937fa
parent 162250 c50558a3a6160ea8fcda1d0cb849b7153d682bf6
child 162270 c9b60fc06e4cee659bc281f913e16368c851beb7
child 162394 b80d9fe2c98cd104cd743ca2197dbf6b7c9e0d33
push idunknown
push userunknown
push dateunknown
reviewersfabrice
bugs913243
milestone29.0a1
Bug 913243 - Load ErrorPage.js only when error occurs. r=fabrice
b2g/chrome/content/ErrorPage.js
b2g/components/ErrorPage.jsm
dom/browser-element/BrowserElementChild.js
dom/ipc/preload.js
--- a/b2g/chrome/content/ErrorPage.js
+++ b/b2g/chrome/content/ErrorPage.js
@@ -3,16 +3,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 'use strict';
 
 let Cu = Components.utils;
 let Cc = Components.classes;
 let Ci = Components.interfaces;
 
+dump("############ ErrorPage.js\n");
+
 let ErrorPageHandler = {
   _reload: function() {
     docShell.QueryInterface(Ci.nsIWebNavigation).reload(Ci.nsIWebNavigation.LOAD_FLAGS_NONE);
   },
 
   _certErrorPageEventHandler: function(e) {
     let target = e.originalTarget;
     let errorDoc = target.ownerDocument;
@@ -26,38 +28,46 @@ let ErrorPageHandler = {
         sendAsyncMessage("ErrorPage:AddCertException", {
           url: errorDoc.location.href,
           isPermanent: target == permanent
         });
       }
     }
   },
 
-  domContentLoadedHandler: function(e) {
-    let target = e.originalTarget;
-    let targetDocShell = target.defaultView
-                               .QueryInterface(Ci.nsIInterfaceRequestor)
-                               .getInterface(Ci.nsIWebNavigation);
-    if (targetDocShell != docShell) {
+  _bindPageEvent: function(target) {
+    if (!target) {
       return;
     }
 
     if (/^about:certerror/.test(target.documentURI)) {
       let errorPageEventHandler = this._certErrorPageEventHandler.bind(this);
       addEventListener("click", errorPageEventHandler, true, false);
       let listener = function() {
         removeEventListener("click", errorPageEventHandler, true);
         removeEventListener("pagehide", listener, true);
       }.bind(this);
 
       addEventListener("pagehide", listener, true);
     }
   },
 
+  domContentLoadedHandler: function(e) {
+    let target = e.originalTarget;
+    let targetDocShell = target.defaultView
+                               .QueryInterface(Ci.nsIInterfaceRequestor)
+                               .getInterface(Ci.nsIWebNavigation);
+    if (targetDocShell != docShell) {
+      return;
+    }
+    this._bindPageEvent(target);
+  },
+
   init: function() {
     addMessageListener("ErrorPage:ReloadPage", this._reload.bind(this));
     addEventListener('DOMContentLoaded',
                      this.domContentLoadedHandler.bind(this),
                      true);
+    this._bindPageEvent(content.document);
   }
 };
 
 ErrorPageHandler.init();
--- a/b2g/components/ErrorPage.jsm
+++ b/b2g/components/ErrorPage.jsm
@@ -144,30 +144,40 @@ let ErrorPage = {
     }).bind(this), uri, win);
     try {
       sslExceptions.addException(!aMessage.data.isPermanent);
     } catch (e) {
       dump("Failed to set cert exception: " + e + "\n");
     }
   },
 
+  _listenError: function(frameLoader) {
+    let self = this;
+    let frameElement = frameLoader.ownerElement;
+    let injectErrorPageScript = function() {
+      let mm = frameLoader.messageManager;
+      try {
+        mm.loadFrameScript(kErrorPageFrameScript, true, true);
+      } catch (e) {
+        dump('Error loading ' + kErrorPageFrameScript + ' as frame script: ' + e + '\n');
+      }
+      mm.addMessageListener('ErrorPage:AddCertException', self._addCertException.bind(self));
+      frameElement.removeEventListener('mozbrowsererror', injectErrorPageScript, true);
+    };
+
+    frameElement.addEventListener('mozbrowsererror',
+                                  injectErrorPageScript,
+                                  true // use capture
+                                 );
+  },
+
   init: function errorPageInit() {
     Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', false);
     Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
   },
 
   observe: function errorPageObserve(aSubject, aTopic, aData) {
     let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
-    let mm = frameLoader.messageManager;
-
-    // This won't happen from dom/ipc/preload.js in non-OOP builds.
-    try {
-      if (Services.prefs.getBoolPref("dom.ipc.tabs.disabled") === true) {
-        mm.loadFrameScript(kErrorPageFrameScript, true, true);
-      }
-    } catch (e) {
-      dump('Error loading ' + kErrorPageFrameScript + ' as frame script: ' + e + '\n');
-    }
-    mm.addMessageListener('ErrorPage:AddCertException', this._addCertException.bind(this));
+    this._listenError(frameLoader);
   }
 };
 
 ErrorPage.init();
--- a/dom/browser-element/BrowserElementChild.js
+++ b/dom/browser-element/BrowserElementChild.js
@@ -44,21 +44,16 @@ function isTopBrowserElement(docShell) {
 if (!('BrowserElementIsPreloaded' in this)) {
   if (isTopBrowserElement(docShell) &&
       Services.prefs.getBoolPref("dom.mozInputMethod.enabled")) {
     try {
       Services.scriptloader.loadSubScript("chrome://global/content/forms.js");
     } catch (e) {
     }
   }
-  // Those are produc-specific files that's sometimes unavailable.
-  try {
-    Services.scriptloader.loadSubScript("chrome://browser/content/ErrorPage.js");
-  } catch (e) {
-  }
 
   Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementPanning.js");
   ContentPanning.init();
 
   Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js");
 } else {
   ContentPanning.init();
 }
--- a/dom/ipc/preload.js
+++ b/dom/ipc/preload.js
@@ -89,21 +89,16 @@ const BrowserElementIsPreloaded = true;
 
   try {
     if (Services.prefs.getBoolPref("dom.mozInputMethod.enabled")) {
       Services.scriptloader.loadSubScript("chrome://global/content/forms.js", global);
     }
   } catch (e) {
   }
 
-  // Those are produc-specific files that's sometimes unavailable.
-  try {
-    Services.scriptloader.loadSubScript("chrome://browser/content/ErrorPage.js", global);
-  } catch (e) {
-  }
   Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementPanning.js", global);
   Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js", global);
 
   Services.io.getProtocolHandler("app");
   Services.io.getProtocolHandler("default");
 
   docShell.isActive = false;
   docShell.createAboutBlankContentViewer(null);