mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-09 21:00:42 +02:00
This value is determined in Parent process and passed down to nsDocShell. Delete the messages to pass the setting down and set it on the BrowsingContext in the Parent process. Refactor the code that determines to opt-out of using global history. Code inspection determines that windowless browsing contexts want to opt-out as well as any frame with `disableglobalhistory` attribute set on it. Differential Revision: https://phabricator.services.mozilla.com/D72279
123 lines
3.5 KiB
JavaScript
123 lines
3.5 KiB
JavaScript
/* 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/. */
|
|
|
|
"use strict";
|
|
|
|
var EXPORTED_SYMBOLS = ["HiddenFrame"];
|
|
|
|
const { PromiseUtils } = ChromeUtils.import(
|
|
"resource://gre/modules/PromiseUtils.jsm"
|
|
);
|
|
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
|
|
const XUL_PAGE = "chrome://global/content/win.xhtml";
|
|
|
|
const gAllHiddenFrames = new Set();
|
|
|
|
let cleanupRegistered = false;
|
|
function ensureCleanupRegistered() {
|
|
if (!cleanupRegistered) {
|
|
cleanupRegistered = true;
|
|
Services.obs.addObserver(function() {
|
|
for (let hiddenFrame of ChromeUtils.nondeterministicGetWeakSetKeys(
|
|
gAllHiddenFrames
|
|
)) {
|
|
hiddenFrame.destroy();
|
|
}
|
|
}, "xpcom-shutdown");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An hidden frame object. It takes care of creating a windowless browser and
|
|
* passing the window containing a blank XUL <window> back.
|
|
*/
|
|
function HiddenFrame() {}
|
|
|
|
HiddenFrame.prototype = {
|
|
_frame: null,
|
|
_browser: null,
|
|
_listener: null,
|
|
_webProgress: null,
|
|
_deferred: null,
|
|
|
|
/**
|
|
* Gets the |contentWindow| of the hidden frame. Creates the frame if needed.
|
|
* @returns Promise Returns a promise which is resolved when the hidden frame has finished
|
|
* loading.
|
|
*/
|
|
get() {
|
|
if (!this._deferred) {
|
|
this._deferred = PromiseUtils.defer();
|
|
this._create();
|
|
}
|
|
|
|
return this._deferred.promise;
|
|
},
|
|
|
|
/**
|
|
* Fetch a sync ref to the window inside the frame (needed for the add-on SDK).
|
|
*/
|
|
getWindow() {
|
|
this.get();
|
|
return this._browser.document.ownerGlobal;
|
|
},
|
|
|
|
destroy() {
|
|
if (this._browser) {
|
|
if (this._listener) {
|
|
this._webProgress.removeProgressListener(this._listener);
|
|
this._listener = null;
|
|
this._webProgress = null;
|
|
}
|
|
this._frame = null;
|
|
this._deferred = null;
|
|
|
|
gAllHiddenFrames.delete(this);
|
|
this._browser.close();
|
|
this._browser = null;
|
|
}
|
|
},
|
|
|
|
_create() {
|
|
ensureCleanupRegistered();
|
|
this._browser = Services.appShell.createWindowlessBrowser(true);
|
|
this._browser.QueryInterface(Ci.nsIInterfaceRequestor);
|
|
gAllHiddenFrames.add(this);
|
|
this._webProgress = this._browser.getInterface(Ci.nsIWebProgress);
|
|
this._listener = {
|
|
QueryInterface: ChromeUtils.generateQI([
|
|
Ci.nsIWebProgressListener,
|
|
Ci.nsIWebProgressListener2,
|
|
Ci.nsISupportsWeakReference,
|
|
]),
|
|
};
|
|
this._listener.onStateChange = (wbp, request, stateFlags, status) => {
|
|
if (!request) {
|
|
return;
|
|
}
|
|
if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
|
this._webProgress.removeProgressListener(this._listener);
|
|
this._listener = null;
|
|
this._webProgress = null;
|
|
// Get the window reference via the document.
|
|
this._frame = this._browser.document.ownerGlobal;
|
|
this._deferred.resolve(this._frame);
|
|
}
|
|
};
|
|
this._webProgress.addProgressListener(
|
|
this._listener,
|
|
Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT
|
|
);
|
|
let docShell = this._browser.docShell;
|
|
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
|
docShell.createAboutBlankContentViewer(systemPrincipal, systemPrincipal);
|
|
let browsingContext = this._browser.browsingContext;
|
|
browsingContext.useGlobalHistory = false;
|
|
let loadURIOptions = {
|
|
triggeringPrincipal: systemPrincipal,
|
|
};
|
|
this._browser.loadURI(XUL_PAGE, loadURIOptions);
|
|
},
|
|
};
|