mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 780123 - [New Tab Page] Use the hiddenWindow to preload a single newtab page that then serves multiple windows; r=jaws
This commit is contained in:
parent
509b7e87b9
commit
273585b878
@ -154,11 +154,8 @@ XPCOMUtils.defineLazyGetter(this, "SafeBrowsing", function() {
|
||||
});
|
||||
#endif
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gBrowserNewTabPreloader", function () {
|
||||
let tmp = {};
|
||||
Cu.import("resource:///modules/BrowserNewTabPreloader.jsm", tmp);
|
||||
return new tmp.BrowserNewTabPreloader();
|
||||
});
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "gBrowserNewTabPreloader",
|
||||
"resource://gre/modules/BrowserNewTabPreloader.jsm", "BrowserNewTabPreloader");
|
||||
|
||||
let gInitialPages = [
|
||||
"about:blank",
|
||||
@ -1409,12 +1406,6 @@ var gBrowserInit = {
|
||||
gSyncUI.init();
|
||||
#endif
|
||||
|
||||
// Don't preload new tab pages when the toolbar is hidden
|
||||
// (i.e. when the current window is a popup window).
|
||||
if (window.toolbar.visible) {
|
||||
gBrowserNewTabPreloader.init(window);
|
||||
}
|
||||
|
||||
gBrowserThumbnails.init();
|
||||
TabView.init();
|
||||
|
||||
@ -1563,10 +1554,6 @@ var gBrowserInit = {
|
||||
|
||||
Services.obs.removeObserver(gPluginHandler.pluginCrashed, "plugin-crashed");
|
||||
|
||||
if (!__lookupGetter__("gBrowserNewTabPreloader")) {
|
||||
gBrowserNewTabPreloader.uninit();
|
||||
}
|
||||
|
||||
try {
|
||||
gBrowser.removeProgressListener(window.XULBrowserWindow);
|
||||
gBrowser.removeTabsProgressListener(window.TabsProgressListener);
|
||||
|
14
browser/base/content/newtab/preload.xhtml
Normal file
14
browser/base/content/newtab/preload.xhtml
Normal file
@ -0,0 +1,14 @@
|
||||
<?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>
|
@ -46,6 +46,7 @@ browser.jar:
|
||||
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)
|
||||
|
@ -38,6 +38,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils",
|
||||
"resource:///modules/NewTabUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "BrowserNewTabPreloader",
|
||||
"resource:///modules/BrowserNewTabPreloader.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PdfJs",
|
||||
"resource://pdf.js/PdfJs.jsm");
|
||||
|
||||
@ -345,6 +348,7 @@ BrowserGlue.prototype = {
|
||||
webappsUI.init();
|
||||
PageThumbs.init();
|
||||
NewTabUtils.init();
|
||||
BrowserNewTabPreloader.init();
|
||||
SignInToWebsiteUX.init();
|
||||
PdfJs.init();
|
||||
|
||||
@ -370,6 +374,7 @@ BrowserGlue.prototype = {
|
||||
this._shutdownPlaces();
|
||||
this._sanitizer.onShutdown();
|
||||
PageThumbs.uninit();
|
||||
BrowserNewTabPreloader.uninit();
|
||||
},
|
||||
|
||||
// All initial windows have opened.
|
||||
|
@ -7,154 +7,218 @@
|
||||
let EXPORTED_SYMBOLS = ["BrowserNewTabPreloader"];
|
||||
|
||||
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 PREF_NEWTAB_URL = "browser.newtab.url";
|
||||
const PREF_NEWTAB_PRELOAD = "browser.newtab.preload";
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const PREF_BRANCH = "browser.newtab.";
|
||||
|
||||
function BrowserNewTabPreloader() {
|
||||
}
|
||||
let BrowserNewTabPreloader = {
|
||||
init: function Preloader_init() {
|
||||
Preferences.init();
|
||||
|
||||
BrowserNewTabPreloader.prototype = {
|
||||
_url: null,
|
||||
_window: null,
|
||||
_browser: null,
|
||||
_enabled: null,
|
||||
|
||||
init: function Preloader_init(aWindow) {
|
||||
if (this._window) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._window = aWindow;
|
||||
this._enabled = Preferences.enabled;
|
||||
this._url = Preferences.url;
|
||||
Preferences.addObserver(this);
|
||||
|
||||
if (this._enabled) {
|
||||
this._createBrowser();
|
||||
if (Preferences.enabled) {
|
||||
HiddenBrowser.create();
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function Preloader_uninit() {
|
||||
if (!this._window) {
|
||||
return;
|
||||
HostFrame.destroy();
|
||||
Preferences.uninit();
|
||||
HiddenBrowser.destroy();
|
||||
},
|
||||
|
||||
newTab: function Preloader_newTab(aTab) {
|
||||
HiddenBrowser.swapWithNewTab(aTab);
|
||||
}
|
||||
};
|
||||
|
||||
Object.freeze(BrowserNewTabPreloader);
|
||||
|
||||
let Preferences = {
|
||||
_enabled: null,
|
||||
_branch: null,
|
||||
_url: null,
|
||||
|
||||
get enabled() {
|
||||
if (this._enabled === null) {
|
||||
this._enabled = this._branch.getBoolPref("preload") &&
|
||||
!this._branch.prefHasUserValue("url") &&
|
||||
this.url && this.url != "about:blank";
|
||||
}
|
||||
|
||||
return this._enabled;
|
||||
},
|
||||
|
||||
get url() {
|
||||
if (this._url === null) {
|
||||
this._url = this._branch.getCharPref("url");
|
||||
}
|
||||
|
||||
return this._url;
|
||||
},
|
||||
|
||||
init: function Preferences_init() {
|
||||
this._branch = Services.prefs.getBranch(PREF_BRANCH);
|
||||
this._branch.addObserver("", this, false);
|
||||
},
|
||||
|
||||
uninit: function Preferences_uninit() {
|
||||
this._branch.removeObserver("", this);
|
||||
this._branch = null;
|
||||
},
|
||||
|
||||
observe: function Preferences_observe(aSubject, aTopic, aData) {
|
||||
let {url, enabled} = this;
|
||||
this._url = this._enabled = null;
|
||||
|
||||
if (enabled && !this.enabled) {
|
||||
HiddenBrowser.destroy();
|
||||
} else if (!enabled && this.enabled) {
|
||||
HiddenBrowser.create();
|
||||
} else if (this._browser && url != this.url) {
|
||||
HiddenBrowser.update(this.url);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let HiddenBrowser = {
|
||||
get isPreloaded() {
|
||||
return this._browser &&
|
||||
this._browser.contentDocument &&
|
||||
this._browser.contentDocument.readyState == "complete" &&
|
||||
this._browser.currentURI.spec == Preferences.url;
|
||||
},
|
||||
|
||||
swapWithNewTab: function HiddenBrowser_swapWithNewTab(aTab) {
|
||||
if (this.isPreloaded) {
|
||||
let tabbrowser = aTab.ownerDocument.defaultView.gBrowser;
|
||||
if (tabbrowser) {
|
||||
tabbrowser.swapNewTabWithBrowser(aTab, this._browser);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
create: function HiddenBrowser_create() {
|
||||
HostFrame.getFrame(function (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));
|
||||
},
|
||||
|
||||
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,
|
||||
|
||||
_privilegedContentTypes: {
|
||||
"application/vnd.mozilla.xul+xml": true,
|
||||
"application/xhtml+xml": true
|
||||
},
|
||||
|
||||
get _frame() {
|
||||
delete this._frame;
|
||||
return this._frame = Services.appShell.hiddenDOMWindow;
|
||||
},
|
||||
|
||||
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);
|
||||
},
|
||||
|
||||
getFrame: function HostFrame_getFrame(aCallback) {
|
||||
if (this._isReady && !this._isPrivileged) {
|
||||
this._createPrivilegedFrame();
|
||||
}
|
||||
|
||||
if (this._isReady) {
|
||||
aCallback(this._frame);
|
||||
} else {
|
||||
this._waitUntilLoaded(aCallback);
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function HostFrame_destroy() {
|
||||
delete this._frame;
|
||||
this._listener = null;
|
||||
},
|
||||
|
||||
_createPrivilegedFrame: function HostFrame_createPrivilegedFrame() {
|
||||
let doc = this._frame.document;
|
||||
let iframe = doc.createElement("iframe");
|
||||
iframe.setAttribute("src", "chrome://browser/content/newtab/preload.xhtml");
|
||||
doc.documentElement.appendChild(iframe);
|
||||
this._frame = iframe.contentWindow;
|
||||
},
|
||||
|
||||
_waitUntilLoaded: function HostFrame_waitUntilLoaded(aCallback) {
|
||||
this._listener = new HiddenWindowLoadListener(this._frame, function () {
|
||||
HostFrame.getFrame(aCallback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
Preferences.removeObserver(this);
|
||||
this._callback = null;
|
||||
this._webProgress = null;
|
||||
},
|
||||
|
||||
newTab: function Preloader_newTab(aTab) {
|
||||
if (!this._window || !this._enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tabbrowser = this._window.gBrowser;
|
||||
if (tabbrowser && this._isPreloaded()) {
|
||||
tabbrowser.swapNewTabWithBrowser(aTab, this._browser);
|
||||
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();
|
||||
}
|
||||
},
|
||||
|
||||
observe: function Preloader_observe(aEnabled, aURL) {
|
||||
if (this._url != aURL) {
|
||||
this._url = aURL;
|
||||
onStatusChange: function () {},
|
||||
onLocationChange: function () {},
|
||||
onProgressChange: function () {},
|
||||
onSecurityChange: function () {},
|
||||
|
||||
if (this._enabled && aEnabled) {
|
||||
// We're still enabled but the newtab URL has changed.
|
||||
this._browser.setAttribute("src", aURL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this._enabled && !aEnabled) {
|
||||
// We got disabled. Remove the browser.
|
||||
this._browser.parentNode.removeChild(this._browser);
|
||||
this._browser = null;
|
||||
this._enabled = false;
|
||||
} else if (!this._enabled && aEnabled) {
|
||||
// We got enabled. Create a browser and start preloading.
|
||||
this._createBrowser();
|
||||
this._enabled = true;
|
||||
}
|
||||
},
|
||||
|
||||
_createBrowser: function Preloader_createBrowser() {
|
||||
let document = this._window.document;
|
||||
this._browser = document.createElement("browser");
|
||||
this._browser.setAttribute("type", "content");
|
||||
this._browser.setAttribute("src", this._url);
|
||||
this._browser.collapsed = true;
|
||||
|
||||
let panel = document.getElementById("browser-panel");
|
||||
panel.appendChild(this._browser);
|
||||
},
|
||||
|
||||
_isPreloaded: function Preloader_isPreloaded() {
|
||||
return this._browser &&
|
||||
this._browser.contentDocument &&
|
||||
this._browser.contentDocument.readyState == "complete" &&
|
||||
this._browser.currentURI.spec == this._url;
|
||||
}
|
||||
};
|
||||
|
||||
let Preferences = {
|
||||
_observers: [],
|
||||
|
||||
get _branch() {
|
||||
delete this._branch;
|
||||
return this._branch = Services.prefs.getBranch("browser.newtab.");
|
||||
},
|
||||
|
||||
get enabled() {
|
||||
if (!this._branch.getBoolPref("preload")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._branch.prefHasUserValue("url")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let url = this.url;
|
||||
return url && url != "about:blank";
|
||||
},
|
||||
|
||||
get url() {
|
||||
return this._branch.getCharPref("url");
|
||||
},
|
||||
|
||||
addObserver: function Preferences_addObserver(aObserver) {
|
||||
let index = this._observers.indexOf(aObserver);
|
||||
if (index == -1) {
|
||||
if (this._observers.length == 0) {
|
||||
this._branch.addObserver("", this, false);
|
||||
}
|
||||
this._observers.push(aObserver);
|
||||
}
|
||||
},
|
||||
|
||||
removeObserver: function Preferences_removeObserver(aObserver) {
|
||||
let index = this._observers.indexOf(aObserver);
|
||||
if (index > -1) {
|
||||
if (this._observers.length == 1) {
|
||||
this._branch.removeObserver("", this);
|
||||
}
|
||||
this._observers.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
observe: function Preferences_observe(aSubject, aTopic, aData) {
|
||||
let url = this.url;
|
||||
let enabled = this.enabled;
|
||||
|
||||
for (let obs of this._observers) {
|
||||
obs.observe(enabled, url);
|
||||
}
|
||||
}
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user