Bug 1335281 - Use frame loader for same process browsers. r=mrbkap
This changes the `relatedBrowser` property which held a <xul:browser> to the
more explicit `sameProcessAsFrameLoader` which takes an nsIFrameLoader.
This clarifies the purpose of the property and also (by switching to the frame
loader) makes it easier to set in some contexts.
MozReview-Commit-ID: LnEvSP8zkto
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2362,17 +2362,17 @@ function BrowserViewSourceOfDocument(aAr
// descriptor for the tab (when possible) or fallback to the network if
// that fails. Either way, the view source module will manage the tab's
// location, so use "about:blank" here to avoid unnecessary redundant
// requests.
let tab = tabBrowser.loadOneTab("about:blank", {
relatedToCurrent: true,
inBackground: false,
preferredRemoteType,
- relatedBrowser: args.browser
+ sameProcessAsFrameLoader: args.browser ? args.browser.frameLoader : null
});
args.viewSourceBrowser = tabBrowser.getBrowserForTab(tab);
top.gViewSourceUtils.viewSourceInBrowser(args);
} else {
top.gViewSourceUtils.viewSource(args);
}
}
@@ -3342,29 +3342,31 @@ var PrintPreviewListener = {
_tabBeforePrintPreview: null,
_simplifyPageTab: null,
getPrintPreviewBrowser() {
if (!this._printPreviewTab) {
let browser = gBrowser.selectedBrowser;
let preferredRemoteType = browser.remoteType;
this._tabBeforePrintPreview = gBrowser.selectedTab;
- this._printPreviewTab = gBrowser.loadOneTab("about:blank",
- { inBackground: false,
- preferredRemoteType,
- relatedBrowser: browser });
+ this._printPreviewTab = gBrowser.loadOneTab("about:blank", {
+ inBackground: false,
+ preferredRemoteType,
+ sameProcessAsFrameLoader: browser.frameLoader
+ });
gBrowser.selectedTab = this._printPreviewTab;
}
return gBrowser.getBrowserForTab(this._printPreviewTab);
},
createSimplifiedBrowser() {
let browser = this._tabBeforePrintPreview.linkedBrowser;
- this._simplifyPageTab = gBrowser.loadOneTab("about:blank",
- { inBackground: true,
- relatedBrowser: browser });
+ this._simplifyPageTab = gBrowser.loadOneTab("about:blank", {
+ inBackground: true,
+ sameProcessAsFrameLoader: browser.frameLoader
+ });
return this.getSimplifiedSourceBrowser();
},
getSourceBrowser() {
return this._tabBeforePrintPreview ?
this._tabBeforePrintPreview.linkedBrowser : gBrowser.selectedBrowser;
},
getSimplifiedSourceBrowser() {
return this._simplifyPageTab ?
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1506,42 +1506,42 @@
var aFromExternal;
var aRelatedToCurrent;
var aAllowMixedContent;
var aSkipAnimation;
var aForceNotRemote;
var aPreferredRemoteType;
var aNoReferrer;
var aUserContextId;
- var aRelatedBrowser;
+ var aSameProcessAsFrameLoader;
var aOriginPrincipal;
var aOpener;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
let params = arguments[1];
- aTriggeringPrincipal = params.triggeringPrincipal
- aReferrerURI = params.referrerURI;
- aReferrerPolicy = params.referrerPolicy;
- aCharset = params.charset;
- aPostData = params.postData;
- aLoadInBackground = params.inBackground;
- aAllowThirdPartyFixup = params.allowThirdPartyFixup;
- aFromExternal = params.fromExternal;
- aRelatedToCurrent = params.relatedToCurrent;
- aAllowMixedContent = params.allowMixedContent;
- aSkipAnimation = params.skipAnimation;
- aForceNotRemote = params.forceNotRemote;
- aPreferredRemoteType = params.preferredRemoteType;
- aNoReferrer = params.noReferrer;
- aUserContextId = params.userContextId;
- aRelatedBrowser = params.relatedBrowser;
- aOriginPrincipal = params.originPrincipal;
- aOpener = params.opener;
- aIsPrerendered = params.isPrerendered;
+ aTriggeringPrincipal = params.triggeringPrincipal
+ aReferrerURI = params.referrerURI;
+ aReferrerPolicy = params.referrerPolicy;
+ aCharset = params.charset;
+ aPostData = params.postData;
+ aLoadInBackground = params.inBackground;
+ aAllowThirdPartyFixup = params.allowThirdPartyFixup;
+ aFromExternal = params.fromExternal;
+ aRelatedToCurrent = params.relatedToCurrent;
+ aAllowMixedContent = params.allowMixedContent;
+ aSkipAnimation = params.skipAnimation;
+ aForceNotRemote = params.forceNotRemote;
+ aPreferredRemoteType = params.preferredRemoteType;
+ aNoReferrer = params.noReferrer;
+ aUserContextId = params.userContextId;
+ aSameProcessAsFrameLoader = params.sameProcessAsFrameLoader;
+ aOriginPrincipal = params.originPrincipal;
+ aOpener = params.opener;
+ aIsPrerendered = params.isPrerendered;
}
var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
Services.prefs.getBoolPref("browser.tabs.loadInBackground");
var owner = bgLoad ? null : this.selectedTab;
var tab = this.addTab(aURI, {
triggeringPrincipal: aTriggeringPrincipal,
@@ -1555,17 +1555,17 @@
relatedToCurrent: aRelatedToCurrent,
skipAnimation: aSkipAnimation,
allowMixedContent: aAllowMixedContent,
forceNotRemote: aForceNotRemote,
preferredRemoteType: aPreferredRemoteType,
noReferrer: aNoReferrer,
userContextId: aUserContextId,
originPrincipal: aOriginPrincipal,
- relatedBrowser: aRelatedBrowser,
+ sameProcessAsFrameLoader: aSameProcessAsFrameLoader,
opener: aOpener,
isPrerendered: aIsPrerendered });
if (!bgLoad)
this.selectedTab = tab;
return tab;
]]>
</body>
@@ -1731,19 +1731,19 @@
let oldUserTypedValue = aBrowser.userTypedValue;
let hadStartedLoad = aBrowser.didStartLoadSinceLastUserTyping();
// Make sure the browser is destroyed so it unregisters from observer notifications
aBrowser.destroy();
// Make sure to restore the original droppedLinkHandler and
- // relatedBrowser.
+ // sameProcessAsFrameLoader.
let droppedLinkHandler = aBrowser.droppedLinkHandler;
- let relatedBrowser = aBrowser.relatedBrowser;
+ let sameProcessAsFrameLoader = aBrowser.sameProcessAsFrameLoader;
// Change the "remote" attribute.
let parent = aBrowser.parentNode;
parent.removeChild(aBrowser);
if (aShouldBeRemote) {
aBrowser.setAttribute("remote", "true");
aBrowser.setAttribute("remoteType", aOptions.remoteType);
} else {
@@ -1751,17 +1751,17 @@
aBrowser.removeAttribute("remoteType");
}
// NB: This works with the hack in the browser constructor that
// turns this normal property into a field. When switching remote
// type copying related browser would stop the switch and the
// previously related browser will no longer be relevant.
if (!aShouldBeRemote || currentRemoteType == aOptions.remoteType) {
- aBrowser.relatedBrowser = relatedBrowser;
+ aBrowser.sameProcessAsFrameLoader = sameProcessAsFrameLoader;
}
if (aOptions.opener) {
// Set the opener window on the browser, such that when the frame
// loader is created the opener is set correctly.
aBrowser.presetOpenerWindow(aOptions.opener);
}
@@ -1991,18 +1991,18 @@
b.setAttribute("selectmenulist", this.getAttribute("selectmenulist"));
if (this.hasAttribute("datetimepicker")) {
b.setAttribute("datetimepicker", this.getAttribute("datetimepicker"));
}
b.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
- if (aParams.relatedBrowser) {
- b.relatedBrowser = aParams.relatedBrowser;
+ if (aParams.sameProcessAsFrameLoader) {
+ b.sameProcessAsFrameLoader = aParams.sameProcessAsFrameLoader;
}
// Create the browserStack container
var stack = document.createElementNS(NS_XUL, "stack");
stack.className = "browserStack";
stack.appendChild(b);
stack.setAttribute("flex", "1");
@@ -2073,17 +2073,17 @@
}
if (!browser) {
// No preloaded browser found, create one.
browser = this._createBrowser({permanentKey: aTab.permanentKey,
remoteType,
uriIsAboutBlank,
userContextId: aParams.userContextId,
- relatedBrowser: aParams.relatedBrowser,
+ sameProcessAsFrameLoader: aParams.sameProcessAsFrameLoader,
opener: aParams.opener,
isPrerendered: aParams.isPrerendered});
}
let notificationbox = this.getNotificationBox(browser);
let uniqueId = this._generateUniquePanelID();
notificationbox.id = uniqueId;
aTab.linkedPanel = uniqueId;
@@ -2152,17 +2152,17 @@
var aRelatedToCurrent;
var aSkipAnimation;
var aAllowMixedContent;
var aForceNotRemote;
var aPreferredRemoteType;
var aNoReferrer;
var aUserContextId;
var aEventDetail;
- var aRelatedBrowser;
+ var aSameProcessAsFrameLoader;
var aOriginPrincipal;
var aDisallowInheritPrincipal;
var aOpener;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
let params = arguments[1];
aTriggeringPrincipal = params.triggeringPrincipal;
@@ -2176,17 +2176,17 @@
aRelatedToCurrent = params.relatedToCurrent;
aSkipAnimation = params.skipAnimation;
aAllowMixedContent = params.allowMixedContent;
aForceNotRemote = params.forceNotRemote;
aPreferredRemoteType = params.preferredRemoteType;
aNoReferrer = params.noReferrer;
aUserContextId = params.userContextId;
aEventDetail = params.eventDetail;
- aRelatedBrowser = params.relatedBrowser;
+ aSameProcessAsFrameLoader = params.sameProcessAsFrameLoader;
aOriginPrincipal = params.originPrincipal;
aDisallowInheritPrincipal = params.disallowInheritPrincipal;
aOpener = params.opener;
aIsPrerendered = params.isPrerendered;
}
// if we're adding tabs, we're past interrupt mode, ditch the owner
if (this.mCurrentTab.owner)
@@ -2268,17 +2268,17 @@
// state to be exploited for startup optimization. Note that for
// now this must occur before "TabOpen" event is fired, as that will
// trigger SessionStore.jsm to run code that expects the existence
// of tab.linkedBrowser.
let browserParams = {
forceNotRemote: aForceNotRemote,
preferredRemoteType: aPreferredRemoteType,
userContextId: aUserContextId,
- relatedBrowser: aRelatedBrowser,
+ sameProcessAsFrameLoader: aSameProcessAsFrameLoader,
opener: aOpener,
isPrerendered: aIsPrerendered,
};
let { usingPreloadedContent } = this._linkBrowserToTab(t, aURI, browserParams);
let b = t.linkedBrowser;
// Dispatch a new tab notification. We do this once we're
// entirely done, so that things are in a consistent state
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -2819,25 +2819,22 @@ static
ContentParent*
GetContentParent(Element* aBrowser)
{
nsCOMPtr<nsIBrowser> browser = do_QueryInterface(aBrowser);
if (!browser) {
return nullptr;
}
- nsCOMPtr<nsIDOMElement> related;
- browser->GetRelatedBrowser(getter_AddRefs(related));
-
- nsCOMPtr<nsIFrameLoaderOwner> otherOwner = do_QueryInterface(related);
- if (!otherOwner) {
+ nsCOMPtr<nsIFrameLoader> otherLoader;
+ browser->GetSameProcessAsFrameLoader(getter_AddRefs(otherLoader));
+ if (!otherLoader) {
return nullptr;
}
- nsCOMPtr<nsIFrameLoader> otherLoader = otherOwner->GetFrameLoader();
TabParent* tabParent = TabParent::GetFrom(otherLoader);
if (tabParent &&
tabParent->Manager() &&
tabParent->Manager()->IsContentParent()) {
return tabParent->Manager()->AsContentParent();
}
return nullptr;
--- a/dom/interfaces/base/nsIBrowser.idl
+++ b/dom/interfaces/base/nsIBrowser.idl
@@ -1,24 +1,26 @@
/* 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/. */
#include "nsISupports.idl"
-interface nsIDOMElement;
+interface nsIFrameLoader;
[scriptable, uuid(14e5a0cb-e223-4202-95e8-fe53275193ea)]
interface nsIBrowser : nsISupports
{
/**
- * Gets a related browser for a given browser (if any). If this exists, then
- * we should attempt to use the same content parent as its frameLoader
- * for any new tab parents.
+ * Gets an optional frame loader that is "related" to this browser.
+ * If this exists, then we should attempt to use the same content parent as
+ * this frame loader for any new tab parents. For example, view source
+ * browsers set this to the frame loader for the original content to ensure
+ * they are loaded in the same process as the content.
*/
- readonly attribute nsIDOMElement relatedBrowser;
+ readonly attribute nsIFrameLoader sameProcessAsFrameLoader;
/*
* Called by the child to inform the parent that links are dropped into
* content area.
*
* @param linksCount length of links
* @param links a flat array of url, name, and type for each link
*/
--- a/toolkit/components/passwordmgr/test/browser/browser_hasInsecureLoginForms_streamConverter.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_hasInsecureLoginForms_streamConverter.js
@@ -78,17 +78,17 @@ function waitForInsecureLoginFormsStateC
*/
add_task(function* test_streamConverter() {
let originalBrowser = gBrowser.selectedTab.linkedBrowser;
yield ContentTask.spawn(originalBrowser, null, registerConverter);
let tab = gBrowser.addTab("http://example.com/browser/toolkit/components/" +
"passwordmgr/test/browser/streamConverter_content.sjs",
- { relatedBrowser: originalBrowser });
+ { sameProcessAsFrameLoader: originalBrowser.frameLoader });
let browser = tab.linkedBrowser;
yield Promise.all([
BrowserTestUtils.switchTab(gBrowser, tab),
BrowserTestUtils.browserLoaded(browser),
// One event is triggered by pageshow and one by DOMFormHasPassword.
waitForInsecureLoginFormsStateChange(browser, 2),
]);
--- a/toolkit/components/viewsource/ViewSourceBrowser.jsm
+++ b/toolkit/components/viewsource/ViewSourceBrowser.jsm
@@ -181,17 +181,17 @@ ViewSourceBrowser.prototype = {
* The line number to focus on once the source is loaded.
*/
loadViewSource({ URL, browser, outerWindowID, lineNumber }) {
if (!URL) {
throw new Error("Must supply a URL when opening view source.");
}
if (browser) {
- this.browser.relatedBrowser = browser;
+ this.browser.sameProcessAsFrameLoader = browser.frameLoader;
// If we're dealing with a remote browser, then the browser
// for view source needs to be remote as well.
this.updateBrowserRemoteness(browser.isRemoteBrowser, browser.remoteType);
} else if (outerWindowID) {
throw new Error("Must supply the browser if passing the outerWindowID");
}
--- a/toolkit/components/viewsource/content/viewSource.js
+++ b/toolkit/components/viewsource/content/viewSource.js
@@ -673,33 +673,33 @@ ViewSourceChrome.prototype = {
if (this.browser.isRemoteBrowser == shouldBeRemote &&
this.browser.remoteType == remoteType) {
return;
}
let parentNode = this.browser.parentNode;
let nextSibling = this.browser.nextSibling;
- // XX Removing and re-adding the browser from and to the DOM strips its
- // XBL properties. Save and restore relatedBrowser. Note that when we
- // restore relatedBrowser, there won't yet be a binding or setter. This
- // works in conjunction with the hack in <xul:browser>'s constructor to
- // re-get the weak reference to it.
- let relatedBrowser = this.browser.relatedBrowser;
+ // Removing and re-adding the browser from and to the DOM strips its XBL
+ // properties. Save and restore sameProcessAsFrameLoader. Note that when we
+ // restore sameProcessAsFrameLoader, there won't yet be a binding or
+ // setter. This works in conjunction with the hack in <xul:browser>'s
+ // constructor to re-get the weak reference to it.
+ let sameProcessAsFrameLoader = this.browser.sameProcessAsFrameLoader;
this.browser.remove();
if (shouldBeRemote) {
this.browser.setAttribute("remote", "true");
this.browser.setAttribute("remoteType", remoteType);
} else {
this.browser.removeAttribute("remote");
this.browser.removeAttribute("remoteType");
}
- this.browser.relatedBrowser = relatedBrowser;
+ this.browser.sameProcessAsFrameLoader = sameProcessAsFrameLoader;
// If nextSibling was null, this will put the browser at
// the end of the list.
parentNode.insertBefore(this.browser, nextSibling);
if (shouldBeRemote) {
// We're going to send a message down to the remote browser
// to load the source content - however, in order for the
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -231,26 +231,27 @@
onget="return this.contentDocument ? this.contentDocument.contentType : null;"
readonly="true"/>
<property name="preferences"
onget="return this.mPrefs.QueryInterface(Components.interfaces.nsIPrefService);"
readonly="true"/>
<!--
- Weak reference to the related browser (see
- nsIBrowser.getRelatedBrowser).
+ Weak reference to an optional frame loader that can be used to influence
+ process selection for this browser.
+ See nsIBrowser.sameProcessAsFrameLoader.
-->
- <field name="_relatedBrowser">null</field>
- <property name="relatedBrowser">
+ <field name="_sameProcessAsFrameLoader">null</field>
+ <property name="sameProcessAsFrameLoader">
<getter><![CDATA[
- return this._relatedBrowser && this._relatedBrowser.get();
+ return this._sameProcessAsFrameLoader && this._sameProcessAsFrameLoader.get();
]]></getter>
<setter><![CDATA[
- this._relatedBrowser = Cu.getWeakReference(val);
+ this._sameProcessAsFrameLoader = Cu.getWeakReference(val);
]]></setter>
</property>
<field name="_docShell">null</field>
<property name="docShell" readonly="true">
<getter><![CDATA[
if (this._docShell)
@@ -942,24 +943,24 @@
Components.utils.reportError(e);
}
try {
// Ensures the securityUI is initialized.
var securityUI = this.securityUI; // eslint-disable-line no-unused-vars
} catch (e) {
}
- // XXX tabbrowser.xml sets "relatedBrowser" as a direct property on
- // some browsers before they are put into a DOM (and get a binding).
- // This hack makes sure that we hold a weak reference to the other
- // browser (and go through the proper getter and setter).
- if (this.hasOwnProperty("relatedBrowser")) {
- var relatedBrowser = this.relatedBrowser;
- delete this.relatedBrowser;
- this.relatedBrowser = relatedBrowser;
+ // tabbrowser.xml sets "sameProcessAsFrameLoader" as a direct property
+ // on some browsers before they are put into a DOM (and get a
+ // binding). This hack makes sure that we hold a weak reference to
+ // the other browser (and go through the proper getter and setter).
+ if (this.hasOwnProperty("sameProcessAsFrameLoader")) {
+ var sameProcessAsFrameLoader = this.sameProcessAsFrameLoader;
+ delete this.sameProcessAsFrameLoader;
+ this.sameProcessAsFrameLoader = sameProcessAsFrameLoader;
}
if (!this.isRemoteBrowser) {
this.addEventListener("pagehide", this.onPageHide, true);
}
if (this.messageManager) {
this.messageManager.addMessageListener("PopupBlocking:UpdateBlockedPopups", this);