Bug 875496 - Simplify code that creates the newtab preload frame and remove unnecessary preload.xhtml; r=jaws
authorTim Taubert <ttaubert@mozilla.com>
Thu, 23 May 2013 23:52:06 +0200
changeset 132825 08ee9cb4412b77adb8fb940d01bfd4b60ba97bcc
parent 132743 22bb671d49822d7611fe6759f190a28918f25ed7
child 132826 e9f7fb8e234285a695d445d8d83a7a9c32973fc0
push id24716
push userttaubert@mozilla.com
push dateFri, 24 May 2013 08:05:45 +0000
treeherderautoland@fe53a0780c6f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs875496
milestone24.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 875496 - Simplify code that creates the newtab preload frame and remove unnecessary preload.xhtml; r=jaws
browser/base/content/newtab/preload.xhtml
browser/base/jar.mn
browser/modules/BrowserNewTabPreloader.jsm
deleted file mode 100644
--- a/browser/base/content/newtab/preload.xhtml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
-    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-
-<!-- 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/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title></title>
-  </head>
-  <body></body>
-</html>
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -58,17 +58,16 @@ browser.jar:
 *       content/browser/browser.css                   (content/browser.css)
 *       content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
 *       content/browser/browser-tabPreviews.xml       (content/browser-tabPreviews.xml)
         content/browser/content.js                    (content/content.js)
         content/browser/newtab/newTab.xul             (content/newtab/newTab.xul)
 *       content/browser/newtab/newTab.js              (content/newtab/newTab.js)
         content/browser/newtab/newTab.css             (content/newtab/newTab.css)
-        content/browser/newtab/preload.xhtml          (content/newtab/preload.xhtml)
 *       content/browser/pageinfo/pageInfo.xul         (content/pageinfo/pageInfo.xul)
         content/browser/pageinfo/pageInfo.js          (content/pageinfo/pageInfo.js)
         content/browser/pageinfo/pageInfo.css         (content/pageinfo/pageInfo.css)
         content/browser/pageinfo/pageInfo.xml         (content/pageinfo/pageInfo.xml)
         content/browser/pageinfo/feeds.js             (content/pageinfo/feeds.js)
         content/browser/pageinfo/feeds.xml            (content/pageinfo/feeds.xml)
         content/browser/pageinfo/permissions.js       (content/pageinfo/permissions.js)
         content/browser/pageinfo/security.js          (content/pageinfo/security.js)
--- a/browser/modules/BrowserNewTabPreloader.jsm
+++ b/browser/modules/BrowserNewTabPreloader.jsm
@@ -8,17 +8,19 @@ this.EXPORTED_SYMBOLS = ["BrowserNewTabP
 
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
+const HTML_NS = "http://www.w3.org/1999/xhtml";
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+const XUL_PAGE = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window id='win'/>";
 const PREF_BRANCH = "browser.newtab.";
 const TOPIC_DELAYED_STARTUP = "browser-delayed-startup-finished";
 const PRELOADER_INIT_DELAY_MS = 5000;
 
 this.BrowserNewTabPreloader = {
   init: function Preloader_init() {
     Initializer.start();
   },
@@ -144,127 +146,76 @@ let HiddenBrowser = {
       let tabbrowser = aTab.ownerDocument.defaultView.gBrowser;
       if (tabbrowser) {
         tabbrowser.swapNewTabWithBrowser(aTab, this._browser);
       }
     }
   },
 
   create: function HiddenBrowser_create() {
-    HostFrame.getFrame(function (aFrame) {
+    HostFrame.get(aFrame => {
       let doc = aFrame.document;
       this._browser = doc.createElementNS(XUL_NS, "browser");
       this._browser.setAttribute("type", "content");
       this._browser.setAttribute("src", Preferences.url);
-      doc.documentElement.appendChild(this._browser);
-    }.bind(this));
+      doc.getElementById("win").appendChild(this._browser);
+    });
   },
 
   update: function HiddenBrowser_update(aURL) {
     this._browser.setAttribute("src", aURL);
   },
 
   destroy: function HiddenBrowser_destroy() {
     if (this._browser) {
       this._browser.parentNode.removeChild(this._browser);
       this._browser = null;
     }
   }
 };
 
 let HostFrame = {
-  _listener: null,
-  _privilegedFrame: null,
+  _frame: null,
+  _loading: false,
 
-  _privilegedContentTypes: {
-    "application/vnd.mozilla.xul+xml": true,
-    "application/xhtml+xml": true
-  },
-
-  get _frame() {
-    delete this._frame;
-    return this._frame = Services.appShell.hiddenDOMWindow;
+  get hiddenDOMDocument() {
+    return Services.appShell.hiddenDOMWindow.document;
   },
 
-  get _isReady() {
-    let readyState = this._frame.document.readyState;
-    return (readyState == "complete" || readyState == "interactive");
-  },
-
-  get _isPrivileged() {
-    return (this._frame.location.protocol == "chrome:" &&
-            this._frame.document.contentType in this._privilegedContentTypes);
+  get isReady() {
+    return this.hiddenDOMDocument.readyState === "complete";
   },
 
-  getFrame: function HostFrame_getFrame(aCallback) {
-    if (this._isReady && !this._isPrivileged) {
-      this._createPrivilegedFrame();
-    }
-
-    if (this._isReady) {
-      aCallback(this._frame);
+  get: function (callback) {
+    if (this._frame) {
+      callback(this._frame);
+    } else if (this.isReady && !this._loading) {
+      this._create(callback);
+      this._loading = true;
     } else {
-      this._waitUntilLoaded(aCallback);
+      Services.tm.currentThread.dispatch(() => HostFrame.get(callback),
+                                         Ci.nsIThread.DISPATCH_NORMAL);
     }
   },
 
-  destroy: function HostFrame_destroy() {
-    delete this._frame;
-    this._listener = null;
+  destroy: function () {
+    this._frame = null;
   },
 
-  _createPrivilegedFrame: function HostFrame_createPrivilegedFrame() {
-    let doc = this._frame.document;
-    let iframe = doc.createElement("iframe");
-    iframe.setAttribute("src", "chrome://browser/content/newtab/preload.xhtml");
+  _create: function (callback) {
+    let doc = this.hiddenDOMDocument;
+    let iframe = doc.createElementNS(HTML_NS, "iframe");
     doc.documentElement.appendChild(iframe);
-    this._frame = iframe.contentWindow;
-  },
+
+    let frame = iframe.contentWindow;
+    let docShell = frame.QueryInterface(Ci.nsIInterfaceRequestor)
+                        .getInterface(Ci.nsIDocShell);
 
-  _waitUntilLoaded: function HostFrame_waitUntilLoaded(aCallback) {
-    this._listener = new HiddenWindowLoadListener(this._frame, function () {
-      HostFrame.getFrame(aCallback);
-    });
+    docShell.createAboutBlankContentViewer(null);
+    frame.location = XUL_PAGE;
+
+    let eventHandler = docShell.chromeEventHandler;
+    eventHandler.addEventListener("DOMContentLoaded", function onLoad() {
+      eventHandler.removeEventListener("DOMContentLoaded", onLoad, false);
+      callback(HostFrame._frame = frame);
+    }, false);
   }
 };
-
-
-function HiddenWindowLoadListener(aWindow, aCallback) {
-  this._window = aWindow;
-  this._callback = aCallback;
-
-  let docShell = Services.appShell.hiddenWindow.docShell;
-  this._webProgress = docShell.QueryInterface(Ci.nsIWebProgress);
-  this._webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_ALL);
-}
-
-HiddenWindowLoadListener.prototype = {
-  _window: null,
-  _callback: null,
-  _webProgress: null,
-
-  _destroy: function HiddenWindowLoadListener_destroy() {
-    this._webProgress.removeProgressListener(this);
-    this._window = null;
-    this._callback = null;
-    this._webProgress = null;
-  },
-
-  onStateChange:
-  function HiddenWindowLoadListener_onStateChange(aWebProgress, aRequest,
-                                                  aStateFlags, aStatus) {
-    if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
-        aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
-        aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW &&
-        this._window == aWebProgress.DOMWindow) {
-      this._callback();
-      this._destroy();
-    }
-  },
-
-  onStatusChange: function () {},
-  onLocationChange: function () {},
-  onProgressChange: function () {},
-  onSecurityChange: function () {},
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
-                                         Ci.nsISupportsWeakReference])
-};