зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1303196 - Part 2: Connect the DocGroup and TabGroup objects to nsGlobalWindow and nsDocument, ensuring that Opener is set early enough that it is correct, r=smaug
MozReview-Commit-ID: 3rZfLw3dXkF
This commit is contained in:
Родитель
cec7ed92f4
Коммит
f9eea2d135
|
@ -4250,10 +4250,10 @@ var XULBrowserWindow = {
|
||||||
return initBrowser.frameLoader.tabParent;
|
return initBrowser.frameLoader.tabParent;
|
||||||
},
|
},
|
||||||
|
|
||||||
forceInitialBrowserNonRemote: function() {
|
forceInitialBrowserNonRemote: function(aOpener) {
|
||||||
let initBrowser =
|
let initBrowser =
|
||||||
document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
|
document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
|
||||||
gBrowser.updateBrowserRemoteness(initBrowser, false);
|
gBrowser.updateBrowserRemoteness(initBrowser, false, aOpener);
|
||||||
},
|
},
|
||||||
|
|
||||||
setDefaultStatus: function (status) {
|
setDefaultStatus: function (status) {
|
||||||
|
@ -4901,7 +4901,8 @@ nsBrowserAccess.prototype = {
|
||||||
|
|
||||||
_openURIInNewTab: function(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
|
_openURIInNewTab: function(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
|
||||||
aIsExternal, aForceNotRemote=false,
|
aIsExternal, aForceNotRemote=false,
|
||||||
aUserContextId=Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID) {
|
aUserContextId=Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID,
|
||||||
|
aOpener=null) {
|
||||||
let win, needToFocusWin;
|
let win, needToFocusWin;
|
||||||
|
|
||||||
// try the current window. if we're in a popup, fall back on the most recent browser window
|
// try the current window. if we're in a popup, fall back on the most recent browser window
|
||||||
|
@ -4931,7 +4932,9 @@ nsBrowserAccess.prototype = {
|
||||||
userContextId: aUserContextId,
|
userContextId: aUserContextId,
|
||||||
fromExternal: aIsExternal,
|
fromExternal: aIsExternal,
|
||||||
inBackground: loadInBackground,
|
inBackground: loadInBackground,
|
||||||
forceNotRemote: aForceNotRemote});
|
forceNotRemote: aForceNotRemote,
|
||||||
|
opener: aOpener,
|
||||||
|
});
|
||||||
let browser = win.gBrowser.getBrowserForTab(tab);
|
let browser = win.gBrowser.getBrowserForTab(tab);
|
||||||
|
|
||||||
if (needToFocusWin || (!loadInBackground && aIsExternal))
|
if (needToFocusWin || (!loadInBackground && aIsExternal))
|
||||||
|
@ -5006,7 +5009,8 @@ nsBrowserAccess.prototype = {
|
||||||
: Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID;
|
: Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID;
|
||||||
let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
|
let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
|
||||||
isPrivate, isExternal,
|
isPrivate, isExternal,
|
||||||
forceNotRemote, userContextId);
|
forceNotRemote, userContextId,
|
||||||
|
aOpener);
|
||||||
if (browser)
|
if (browser)
|
||||||
newWindow = browser.contentWindow;
|
newWindow = browser.contentWindow;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1503,6 +1503,7 @@
|
||||||
var aUserContextId;
|
var aUserContextId;
|
||||||
var aRelatedBrowser;
|
var aRelatedBrowser;
|
||||||
var aOriginPrincipal;
|
var aOriginPrincipal;
|
||||||
|
var aOpener;
|
||||||
if (arguments.length == 2 &&
|
if (arguments.length == 2 &&
|
||||||
typeof arguments[1] == "object" &&
|
typeof arguments[1] == "object" &&
|
||||||
!(arguments[1] instanceof Ci.nsIURI)) {
|
!(arguments[1] instanceof Ci.nsIURI)) {
|
||||||
|
@ -1522,6 +1523,7 @@
|
||||||
aUserContextId = params.userContextId;
|
aUserContextId = params.userContextId;
|
||||||
aRelatedBrowser = params.relatedBrowser;
|
aRelatedBrowser = params.relatedBrowser;
|
||||||
aOriginPrincipal = params.originPrincipal;
|
aOriginPrincipal = params.originPrincipal;
|
||||||
|
aOpener = params.opener;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
|
var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
|
||||||
|
@ -1542,7 +1544,8 @@
|
||||||
noReferrer: aNoReferrer,
|
noReferrer: aNoReferrer,
|
||||||
userContextId: aUserContextId,
|
userContextId: aUserContextId,
|
||||||
originPrincipal: aOriginPrincipal,
|
originPrincipal: aOriginPrincipal,
|
||||||
relatedBrowser: aRelatedBrowser });
|
relatedBrowser: aRelatedBrowser,
|
||||||
|
opener: aOpener });
|
||||||
if (!bgLoad)
|
if (!bgLoad)
|
||||||
this.selectedTab = tab;
|
this.selectedTab = tab;
|
||||||
|
|
||||||
|
@ -1655,11 +1658,27 @@
|
||||||
<method name="updateBrowserRemoteness">
|
<method name="updateBrowserRemoteness">
|
||||||
<parameter name="aBrowser"/>
|
<parameter name="aBrowser"/>
|
||||||
<parameter name="aShouldBeRemote"/>
|
<parameter name="aShouldBeRemote"/>
|
||||||
|
<parameter name="aOpener"/>
|
||||||
<body>
|
<body>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
let isRemote = aBrowser.getAttribute("remote") == "true";
|
let isRemote = aBrowser.getAttribute("remote") == "true";
|
||||||
if (isRemote == aShouldBeRemote)
|
|
||||||
|
// If we are passed an opener, we must be making the browser non-remote, and
|
||||||
|
// if the browser is _currently_ non-remote, we need the openers to match,
|
||||||
|
// because it is already too late to change it.
|
||||||
|
if (aOpener) {
|
||||||
|
if (aShouldBeRemote) {
|
||||||
|
throw new Exception("Cannot set an opener on a browser which should be remote!");
|
||||||
|
}
|
||||||
|
if (!isRemote && aBrowser.contentWindow.opener != aOpener) {
|
||||||
|
throw new Exception("Cannot change opener on an already non-remote browser!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abort if we're not going to change anything
|
||||||
|
if (isRemote == aShouldBeRemote) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let tab = this.getTabForBrowser(aBrowser);
|
let tab = this.getTabForBrowser(aBrowser);
|
||||||
let evt = document.createEvent("Events");
|
let evt = document.createEvent("Events");
|
||||||
|
@ -1700,6 +1719,10 @@
|
||||||
// turns this normal property into a field.
|
// turns this normal property into a field.
|
||||||
aBrowser.relatedBrowser = relatedBrowser;
|
aBrowser.relatedBrowser = relatedBrowser;
|
||||||
|
|
||||||
|
// Set the opener window on the browser, such that when the frame
|
||||||
|
// loader is created the opener is set correctly.
|
||||||
|
aBrowser.presetOpenerWindow(aOpener);
|
||||||
|
|
||||||
parent.appendChild(aBrowser);
|
parent.appendChild(aBrowser);
|
||||||
|
|
||||||
aBrowser.userTypedValue = oldUserTypedValue;
|
aBrowser.userTypedValue = oldUserTypedValue;
|
||||||
|
@ -1881,6 +1904,13 @@
|
||||||
b.setAttribute("remote", "true");
|
b.setAttribute("remote", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aParams.opener) {
|
||||||
|
if (aParams.remote) {
|
||||||
|
throw new Exception("Cannot set opener window on a remote browser!");
|
||||||
|
}
|
||||||
|
b.QueryInterface(Ci.nsIFrameLoaderOwner).presetOpenerWindow(aParams.opener);
|
||||||
|
}
|
||||||
|
|
||||||
if (window.gShowPageResizers && window.windowState == window.STATE_NORMAL) {
|
if (window.gShowPageResizers && window.windowState == window.STATE_NORMAL) {
|
||||||
b.setAttribute("showresizer", "true");
|
b.setAttribute("showresizer", "true");
|
||||||
}
|
}
|
||||||
|
@ -1981,7 +2011,8 @@
|
||||||
remote: remote,
|
remote: remote,
|
||||||
uriIsAboutBlank: uriIsAboutBlank,
|
uriIsAboutBlank: uriIsAboutBlank,
|
||||||
userContextId: aParams.userContextId,
|
userContextId: aParams.userContextId,
|
||||||
relatedBrowser: aParams.relatedBrowser});
|
relatedBrowser: aParams.relatedBrowser,
|
||||||
|
opener: aParams.opener});
|
||||||
}
|
}
|
||||||
|
|
||||||
let notificationbox = this.getNotificationBox(browser);
|
let notificationbox = this.getNotificationBox(browser);
|
||||||
|
@ -2057,6 +2088,7 @@
|
||||||
var aEventDetail;
|
var aEventDetail;
|
||||||
var aRelatedBrowser;
|
var aRelatedBrowser;
|
||||||
var aOriginPrincipal;
|
var aOriginPrincipal;
|
||||||
|
var aOpener;
|
||||||
if (arguments.length == 2 &&
|
if (arguments.length == 2 &&
|
||||||
typeof arguments[1] == "object" &&
|
typeof arguments[1] == "object" &&
|
||||||
!(arguments[1] instanceof Ci.nsIURI)) {
|
!(arguments[1] instanceof Ci.nsIURI)) {
|
||||||
|
@ -2077,6 +2109,7 @@
|
||||||
aEventDetail = params.eventDetail;
|
aEventDetail = params.eventDetail;
|
||||||
aRelatedBrowser = params.relatedBrowser;
|
aRelatedBrowser = params.relatedBrowser;
|
||||||
aOriginPrincipal = params.originPrincipal;
|
aOriginPrincipal = params.originPrincipal;
|
||||||
|
aOpener = params.opener;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're adding tabs, we're past interrupt mode, ditch the owner
|
// if we're adding tabs, we're past interrupt mode, ditch the owner
|
||||||
|
@ -2144,7 +2177,8 @@
|
||||||
let browserParams = {
|
let browserParams = {
|
||||||
forceNotRemote: aForceNotRemote,
|
forceNotRemote: aForceNotRemote,
|
||||||
userContextId: aUserContextId,
|
userContextId: aUserContextId,
|
||||||
relatedBrowser: aRelatedBrowser
|
relatedBrowser: aRelatedBrowser,
|
||||||
|
opener: aOpener,
|
||||||
};
|
};
|
||||||
let { usingPreloadedContent } = this._linkBrowserToTab(t, aURI, browserParams);
|
let { usingPreloadedContent } = this._linkBrowserToTab(t, aURI, browserParams);
|
||||||
let b = t.linkedBrowser;
|
let b = t.linkedBrowser;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "Navigator.h"
|
#include "Navigator.h"
|
||||||
#include "URIUtils.h"
|
#include "URIUtils.h"
|
||||||
|
#include "mozilla/dom/DocGroup.h"
|
||||||
|
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIContentInlines.h"
|
#include "nsIContentInlines.h"
|
||||||
|
|
|
@ -252,6 +252,8 @@
|
||||||
#include "mozilla/StyleSheet.h"
|
#include "mozilla/StyleSheet.h"
|
||||||
#include "mozilla/StyleSheetInlines.h"
|
#include "mozilla/StyleSheetInlines.h"
|
||||||
#include "mozilla/dom/SVGSVGElement.h"
|
#include "mozilla/dom/SVGSVGElement.h"
|
||||||
|
#include "mozilla/dom/DocGroup.h"
|
||||||
|
|
||||||
#include "mozilla/DocLoadingTimelineMarker.h"
|
#include "mozilla/DocLoadingTimelineMarker.h"
|
||||||
|
|
||||||
#include "nsISpeculativeConnect.h"
|
#include "nsISpeculativeConnect.h"
|
||||||
|
@ -1362,6 +1364,10 @@ nsIDocument::~nsIDocument()
|
||||||
mNodeInfoManager->DropDocumentReference();
|
mNodeInfoManager->DropDocumentReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDocGroup) {
|
||||||
|
mDocGroup->RemoveDocument(this);
|
||||||
|
}
|
||||||
|
|
||||||
UnlinkOriginalDocumentIfStatic();
|
UnlinkOriginalDocumentIfStatic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2848,6 +2854,36 @@ nsDocument::SetPrincipal(nsIPrincipal *aNewPrincipal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mNodeInfoManager->SetDocumentPrincipal(aNewPrincipal);
|
mNodeInfoManager->SetDocumentPrincipal(aNewPrincipal);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Validate that the docgroup is set correctly by calling its getter and
|
||||||
|
// triggering its sanity check.
|
||||||
|
//
|
||||||
|
// If we're setting the principal to null, we don't want to perform the check,
|
||||||
|
// as the document is entering an intermediate state where it does not have a
|
||||||
|
// principal. It will be given another real principal shortly which we will
|
||||||
|
// check. It's not unsafe to have a document which has a null principal in the
|
||||||
|
// same docgroup as another document, so this should not be a problem.
|
||||||
|
if (aNewPrincipal) {
|
||||||
|
GetDocGroup();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::dom::DocGroup*
|
||||||
|
nsIDocument::GetDocGroup()
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Sanity check that we have an up-to-date and accurate docgroup
|
||||||
|
if (mDocGroup) {
|
||||||
|
nsAutoCString docGroupKey;
|
||||||
|
mozilla::dom::DocGroup::GetKey(NodePrincipal(), docGroupKey);
|
||||||
|
MOZ_ASSERT(mDocGroup->MatchesKey(docGroupKey));
|
||||||
|
// XXX: Check that the TabGroup is correct as well!
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return mDocGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -4254,6 +4290,23 @@ nsDocument::SetScopeObject(nsIGlobalObject* aGlobal)
|
||||||
mScopeObject = do_GetWeakReference(aGlobal);
|
mScopeObject = do_GetWeakReference(aGlobal);
|
||||||
if (aGlobal) {
|
if (aGlobal) {
|
||||||
mHasHadScriptHandlingObject = true;
|
mHasHadScriptHandlingObject = true;
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
|
||||||
|
if (window) {
|
||||||
|
// We want to get the tabgroup unconditionally, such that we can make
|
||||||
|
// certain that it is cached in the inner window early enough.
|
||||||
|
mozilla::dom::TabGroup* tabgroup = nsGlobalWindow::Cast(window)->TabGroup();
|
||||||
|
// We should already have the principal, and now that we have been added to a
|
||||||
|
// window, we should be able to join a DocGroup!
|
||||||
|
nsAutoCString docGroupKey;
|
||||||
|
mozilla::dom::DocGroup::GetKey(NodePrincipal(), docGroupKey);
|
||||||
|
if (mDocGroup) {
|
||||||
|
MOZ_RELEASE_ASSERT(mDocGroup->MatchesKey(docGroupKey));
|
||||||
|
} else {
|
||||||
|
mDocGroup = tabgroup->AddDocument(docGroupKey, this);
|
||||||
|
MOZ_ASSERT(mDocGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4442,11 +4495,10 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
||||||
mScriptGlobalObject = aScriptGlobalObject;
|
mScriptGlobalObject = aScriptGlobalObject;
|
||||||
|
|
||||||
if (aScriptGlobalObject) {
|
if (aScriptGlobalObject) {
|
||||||
mHasHadScriptHandlingObject = true;
|
|
||||||
mHasHadDefaultView = true;
|
|
||||||
// Go back to using the docshell for the layout history state
|
// Go back to using the docshell for the layout history state
|
||||||
mLayoutHistoryState = nullptr;
|
mLayoutHistoryState = nullptr;
|
||||||
mScopeObject = do_GetWeakReference(aScriptGlobalObject);
|
SetScopeObject(aScriptGlobalObject);
|
||||||
|
mHasHadDefaultView = true;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (!mWillReparent) {
|
if (!mWillReparent) {
|
||||||
// We really shouldn't have a wrapper here but if we do we need to make sure
|
// We really shouldn't have a wrapper here but if we do we need to make sure
|
||||||
|
@ -4583,8 +4635,7 @@ nsDocument::SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject)
|
||||||
mScriptGlobalObject == aScriptObject,
|
mScriptGlobalObject == aScriptObject,
|
||||||
"Wrong script object!");
|
"Wrong script object!");
|
||||||
if (aScriptObject) {
|
if (aScriptObject) {
|
||||||
mScopeObject = do_GetWeakReference(aScriptObject);
|
SetScopeObject(aScriptObject);
|
||||||
mHasHadScriptHandlingObject = true;
|
|
||||||
mHasHadDefaultView = false;
|
mHasHadDefaultView = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
#include "nsAboutProtocolUtils.h"
|
#include "nsAboutProtocolUtils.h"
|
||||||
#include "nsCharTraits.h" // NS_IS_HIGH/LOW_SURROGATE
|
#include "nsCharTraits.h" // NS_IS_HIGH/LOW_SURROGATE
|
||||||
#include "PostMessageEvent.h"
|
#include "PostMessageEvent.h"
|
||||||
|
#include "DocGroup.h"
|
||||||
|
|
||||||
// Interfaces Needed
|
// Interfaces Needed
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
|
@ -1226,9 +1227,10 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||||
mCleanedUp(false),
|
mCleanedUp(false),
|
||||||
mDialogAbuseCount(0),
|
mDialogAbuseCount(0),
|
||||||
mAreDialogsEnabled(true),
|
mAreDialogsEnabled(true),
|
||||||
mCanSkipCCGeneration(0),
|
#ifdef DEBUG
|
||||||
mStaticConstellation(0),
|
mIsValidatingTabGroup(false),
|
||||||
mConstellation(NullCString())
|
#endif
|
||||||
|
mCanSkipCCGeneration(0)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
|
||||||
|
@ -1262,11 +1264,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||||
// |this| is an outer window. Outer windows start out frozen and
|
// |this| is an outer window. Outer windows start out frozen and
|
||||||
// remain frozen until they get an inner window.
|
// remain frozen until they get an inner window.
|
||||||
MOZ_ASSERT(IsFrozen());
|
MOZ_ASSERT(IsFrozen());
|
||||||
|
|
||||||
// As an outer window, we may be the root of a constellation. This initial
|
|
||||||
// static constellation may be overridden as this window is given a parent
|
|
||||||
// window or an opener.
|
|
||||||
mStaticConstellation = WindowID();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We could have failed the first time through trying
|
// We could have failed the first time through trying
|
||||||
|
@ -1430,6 +1427,11 @@ nsGlobalWindow::~nsGlobalWindow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't have to leave the tab group if we are an inner window.
|
||||||
|
if (mTabGroup && IsOuterWindow()) {
|
||||||
|
mTabGroup->Leave(AsOuter());
|
||||||
|
}
|
||||||
|
|
||||||
// Outer windows are always supposed to call CleanUp before letting themselves
|
// Outer windows are always supposed to call CleanUp before letting themselves
|
||||||
// be destroyed. And while CleanUp generally seems to be intended to clean up
|
// be destroyed. And while CleanUp generally seems to be intended to clean up
|
||||||
// outers, we've historically called it for both. Changing this would probably
|
// outers, we've historically called it for both. Changing this would probably
|
||||||
|
@ -2856,6 +2858,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||||
nsCOMPtr<nsIScriptContext> kungFuDeathGrip(mContext);
|
nsCOMPtr<nsIScriptContext> kungFuDeathGrip(mContext);
|
||||||
|
|
||||||
aDocument->SetScriptGlobalObject(newInnerWindow);
|
aDocument->SetScriptGlobalObject(newInnerWindow);
|
||||||
|
MOZ_ASSERT(newInnerWindow->mTabGroup,
|
||||||
|
"We must have a TabGroup cached at this point");
|
||||||
|
|
||||||
if (!aState) {
|
if (!aState) {
|
||||||
if (reUseInnerWindow) {
|
if (reUseInnerWindow) {
|
||||||
|
@ -3032,11 +3036,8 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
|
||||||
|
|
||||||
mDocShell = aDocShell; // Weak Reference
|
mDocShell = aDocShell; // Weak Reference
|
||||||
|
|
||||||
// Copy over the static constellation from our new parent.
|
nsCOMPtr<nsPIDOMWindowOuter> parentWindow = GetScriptableParentOrNull();
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> parentWindow = GetParent();
|
MOZ_RELEASE_ASSERT(!parentWindow || !mTabGroup || mTabGroup == Cast(parentWindow)->mTabGroup);
|
||||||
if (parentWindow) {
|
|
||||||
mStaticConstellation = Cast(parentWindow)->mStaticConstellation;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(!mNavigator, "Non-null mNavigator in outer window!");
|
NS_ASSERTION(!mNavigator, "Non-null mNavigator in outer window!");
|
||||||
|
|
||||||
|
@ -3141,19 +3142,24 @@ nsGlobalWindow::SetOpenerWindow(nsPIDOMWindowOuter* aOpener,
|
||||||
{
|
{
|
||||||
FORWARD_TO_OUTER_VOID(SetOpenerWindow, (aOpener, aOriginalOpener));
|
FORWARD_TO_OUTER_VOID(SetOpenerWindow, (aOpener, aOriginalOpener));
|
||||||
|
|
||||||
|
nsWeakPtr opener = do_GetWeakReference(aOpener);
|
||||||
|
if (opener == mOpener) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NS_ASSERTION(!aOriginalOpener || !mSetOpenerWindowCalled,
|
NS_ASSERTION(!aOriginalOpener || !mSetOpenerWindowCalled,
|
||||||
"aOriginalOpener is true, but not first call to "
|
"aOriginalOpener is true, but not first call to "
|
||||||
"SetOpenerWindow!");
|
"SetOpenerWindow!");
|
||||||
NS_ASSERTION(aOpener || !aOriginalOpener,
|
NS_ASSERTION(aOpener || !aOriginalOpener,
|
||||||
"Shouldn't set mHadOriginalOpener if aOpener is null");
|
"Shouldn't set mHadOriginalOpener if aOpener is null");
|
||||||
|
|
||||||
mOpener = do_GetWeakReference(aOpener);
|
mOpener = opener.forget();
|
||||||
NS_ASSERTION(mOpener || !aOpener, "Opener must support weak references!");
|
NS_ASSERTION(mOpener || !aOpener, "Opener must support weak references!");
|
||||||
|
|
||||||
// Copy over the static constellation from our new opener
|
// Check that the js visible opener matches!
|
||||||
if (aOpener) {
|
nsPIDOMWindowOuter* contentOpener = GetSanitizedOpener(aOpener);
|
||||||
mStaticConstellation = Cast(aOpener)->mStaticConstellation;
|
MOZ_RELEASE_ASSERT(!contentOpener || !mTabGroup ||
|
||||||
}
|
mTabGroup == Cast(contentOpener)->mTabGroup);
|
||||||
|
|
||||||
if (aOriginalOpener) {
|
if (aOriginalOpener) {
|
||||||
MOZ_ASSERT(!mHadOriginalOpener,
|
MOZ_ASSERT(!mHadOriginalOpener,
|
||||||
|
@ -4726,26 +4732,13 @@ nsGlobalWindow::GetControllers(nsIControllers** aResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPIDOMWindowOuter*
|
nsPIDOMWindowOuter*
|
||||||
nsGlobalWindow::GetOpenerWindowOuter()
|
nsGlobalWindow::GetSanitizedOpener(nsPIDOMWindowOuter* aOpener)
|
||||||
{
|
{
|
||||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
if (!aOpener) {
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> opener = do_QueryReferent(mOpener);
|
|
||||||
if (!opener) {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsGlobalWindow* win = nsGlobalWindow::Cast(opener);
|
nsGlobalWindow* win = nsGlobalWindow::Cast(aOpener);
|
||||||
|
|
||||||
// First, check if we were called from a privileged chrome script
|
|
||||||
if (nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
|
|
||||||
// Catch the case where we're chrome but the opener is not...
|
|
||||||
if (GetPrincipal() == nsContentUtils::GetSystemPrincipal() &&
|
|
||||||
win->GetPrincipal() != nsContentUtils::GetSystemPrincipal()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return opener;
|
|
||||||
}
|
|
||||||
|
|
||||||
// First, ensure that we're not handing back a chrome window to content:
|
// First, ensure that we're not handing back a chrome window to content:
|
||||||
if (win->IsChromeWindow()) {
|
if (win->IsChromeWindow()) {
|
||||||
|
@ -4755,7 +4748,7 @@ nsGlobalWindow::GetOpenerWindowOuter()
|
||||||
// We don't want to reveal the opener if the opener is a mail window,
|
// We don't want to reveal the opener if the opener is a mail window,
|
||||||
// because opener can be used to spoof the contents of a message (bug 105050).
|
// because opener can be used to spoof the contents of a message (bug 105050).
|
||||||
// So, we look in the opener's root docshell to see if it's a mail window.
|
// So, we look in the opener's root docshell to see if it's a mail window.
|
||||||
nsCOMPtr<nsIDocShell> openerDocShell = opener->GetDocShell();
|
nsCOMPtr<nsIDocShell> openerDocShell = aOpener->GetDocShell();
|
||||||
|
|
||||||
if (openerDocShell) {
|
if (openerDocShell) {
|
||||||
nsCOMPtr<nsIDocShellTreeItem> openerRootItem;
|
nsCOMPtr<nsIDocShellTreeItem> openerRootItem;
|
||||||
|
@ -4765,7 +4758,7 @@ nsGlobalWindow::GetOpenerWindowOuter()
|
||||||
uint32_t appType;
|
uint32_t appType;
|
||||||
nsresult rv = openerRootDocShell->GetAppType(&appType);
|
nsresult rv = openerRootDocShell->GetAppType(&appType);
|
||||||
if (NS_SUCCEEDED(rv) && appType != nsIDocShell::APP_TYPE_MAIL) {
|
if (NS_SUCCEEDED(rv) && appType != nsIDocShell::APP_TYPE_MAIL) {
|
||||||
return opener;
|
return aOpener;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4773,6 +4766,30 @@ nsGlobalWindow::GetOpenerWindowOuter()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsPIDOMWindowOuter*
|
||||||
|
nsGlobalWindow::GetOpenerWindowOuter()
|
||||||
|
{
|
||||||
|
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindowOuter> opener = do_QueryReferent(mOpener);
|
||||||
|
|
||||||
|
if (!opener) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, check if we were called from a privileged chrome script
|
||||||
|
if (nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
|
||||||
|
// Catch the case where we're chrome but the opener is not...
|
||||||
|
if (GetPrincipal() == nsContentUtils::GetSystemPrincipal() &&
|
||||||
|
nsGlobalWindow::Cast(opener)->GetPrincipal() != nsContentUtils::GetSystemPrincipal()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return opener;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetSanitizedOpener(opener);
|
||||||
|
}
|
||||||
|
|
||||||
nsPIDOMWindowOuter*
|
nsPIDOMWindowOuter*
|
||||||
nsGlobalWindow::GetOpenerWindow(ErrorResult& aError)
|
nsGlobalWindow::GetOpenerWindow(ErrorResult& aError)
|
||||||
{
|
{
|
||||||
|
@ -4797,11 +4814,9 @@ nsGlobalWindow::GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
|
||||||
already_AddRefed<nsPIDOMWindowOuter>
|
already_AddRefed<nsPIDOMWindowOuter>
|
||||||
nsGlobalWindow::GetOpener()
|
nsGlobalWindow::GetOpener()
|
||||||
{
|
{
|
||||||
FORWARD_TO_INNER(GetOpener, (), nullptr);
|
FORWARD_TO_OUTER(GetOpener, (), nullptr);
|
||||||
|
|
||||||
ErrorResult dummy;
|
nsCOMPtr<nsPIDOMWindowOuter> opener = GetOpenerWindowOuter();
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> opener = GetOpenerWindow(dummy);
|
|
||||||
dummy.SuppressException();
|
|
||||||
return opener.forget();
|
return opener.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13627,6 +13642,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGlobalChromeWindow,
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserDOMWindow)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserDOMWindow)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGroupMessageManagers)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGroupMessageManagers)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpenerForInitialContentBrowser)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
|
||||||
|
@ -13640,6 +13656,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGlobalChromeWindow,
|
||||||
}
|
}
|
||||||
tmp->DisconnectAndClearGroupMessageManagers();
|
tmp->DisconnectAndClearGroupMessageManagers();
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGroupMessageManagers)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGroupMessageManagers)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpenerForInitialContentBrowser)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
// QueryInterface implementation for nsGlobalChromeWindow
|
// QueryInterface implementation for nsGlobalChromeWindow
|
||||||
|
@ -14110,6 +14127,24 @@ nsGlobalWindow::GetGroupMessageManager(const nsAString& aGroup,
|
||||||
return messageManager;
|
return messageManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGlobalChromeWindow::SetOpenerForInitialContentBrowser(mozIDOMWindowProxy* aOpenerWindow)
|
||||||
|
{
|
||||||
|
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||||
|
MOZ_ASSERT(!mOpenerForInitialContentBrowser);
|
||||||
|
mOpenerForInitialContentBrowser = aOpenerWindow;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGlobalChromeWindow::TakeOpenerForInitialContentBrowser(mozIDOMWindowProxy** aOpenerWindow)
|
||||||
|
{
|
||||||
|
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||||
|
// Intentionally forget our own member
|
||||||
|
mOpenerForInitialContentBrowser.forget(aOpenerWindow);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// nsGlobalModalWindow implementation
|
// nsGlobalModalWindow implementation
|
||||||
|
|
||||||
// QueryInterface implementation for nsGlobalModalWindow
|
// QueryInterface implementation for nsGlobalModalWindow
|
||||||
|
@ -14593,44 +14628,105 @@ nsGlobalWindow::CheckForDPIChange()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
mozilla::dom::TabGroup*
|
||||||
nsGlobalWindow::GetConstellation(nsACString& aConstellation)
|
nsGlobalWindow::TabGroupOuter()
|
||||||
{
|
{
|
||||||
FORWARD_TO_INNER_VOID(GetConstellation, (aConstellation));
|
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||||
|
|
||||||
|
// This method is valid both on inner and outer windows, which is a
|
||||||
|
// Outer windows lazily join TabGroups when requested. This is usually done
|
||||||
|
// because a document is getting its NodePrincipal, and asking for the
|
||||||
|
// TabGroup to determine its DocGroup.
|
||||||
|
if (!mTabGroup) {
|
||||||
|
// Get mOpener ourselves, instead of relying on GetOpenerWindowOuter,
|
||||||
|
// because that way we dodge the LegacyIsCallerChromeOrNativeCode() call
|
||||||
|
// which we want to return false.
|
||||||
|
nsCOMPtr<nsPIDOMWindowOuter> piOpener = do_QueryReferent(mOpener);
|
||||||
|
nsGlobalWindow* opener = Cast(GetSanitizedOpener(piOpener));
|
||||||
|
nsGlobalWindow* parent = Cast(GetScriptableParentOrNull());
|
||||||
|
MOZ_ASSERT(!parent || !opener, "Only one of parent and opener may be provided");
|
||||||
|
|
||||||
|
mozilla::dom::TabGroup* toJoin = nullptr;
|
||||||
|
if (GetDocShell()->ItemType() == nsIDocShellTreeItem::typeChrome) {
|
||||||
|
toJoin = TabGroup::GetChromeTabGroup();
|
||||||
|
} else if (opener) {
|
||||||
|
toJoin = opener->TabGroup();
|
||||||
|
} else if (parent) {
|
||||||
|
toJoin = parent->TabGroup();
|
||||||
|
}
|
||||||
|
mTabGroup = mozilla::dom::TabGroup::Join(AsOuter(), toJoin);
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(mTabGroup);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
RefPtr<nsGlobalWindow> outer = GetOuterWindowInternal();
|
// Ensure that we don't recurse forever
|
||||||
MOZ_ASSERT(outer, "We should have an outer window");
|
if (!mIsValidatingTabGroup) {
|
||||||
RefPtr<nsGlobalWindow> top = outer->GetTopInternal();
|
mIsValidatingTabGroup = true;
|
||||||
RefPtr<nsPIDOMWindowOuter> opener = outer->GetOpener();
|
// We only need to do this check if we aren't in the chrome tab group
|
||||||
MOZ_ASSERT(!top || (top->mStaticConstellation ==
|
if (GetDocShell()->ItemType() == nsIDocShellTreeItem::typeChrome) {
|
||||||
outer->mStaticConstellation));
|
MOZ_ASSERT(mTabGroup == TabGroup::GetChromeTabGroup());
|
||||||
MOZ_ASSERT(!opener || (Cast(opener)->mStaticConstellation ==
|
} else {
|
||||||
outer->mStaticConstellation));
|
// Sanity check that our tabgroup matches our opener or parent.
|
||||||
|
RefPtr<nsPIDOMWindowOuter> parent = GetScriptableParentOrNull();
|
||||||
|
MOZ_ASSERT_IF(parent, Cast(parent)->TabGroup() == mTabGroup);
|
||||||
|
nsCOMPtr<nsPIDOMWindowOuter> piOpener = do_QueryReferent(mOpener);
|
||||||
|
nsGlobalWindow* opener = Cast(GetSanitizedOpener(piOpener));
|
||||||
|
MOZ_ASSERT_IF(opener && opener != this, opener->TabGroup() == mTabGroup);
|
||||||
|
}
|
||||||
|
mIsValidatingTabGroup = false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mConstellation.IsVoid()) {
|
return mTabGroup;
|
||||||
mConstellation.Truncate();
|
}
|
||||||
// The dynamic constellation part comes from the eTLD+1 for the principal's URI.
|
|
||||||
nsCOMPtr<nsIPrincipal> principal = GetPrincipal();
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
|
||||||
nsresult rv = principal->GetURI(getter_AddRefs(uri));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
nsCOMPtr<nsIEffectiveTLDService> tldService =
|
|
||||||
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
|
|
||||||
if (tldService) {
|
|
||||||
rv = tldService->GetBaseDomain(uri, 0, mConstellation);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
mConstellation.Truncate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the static constellation from the outer window object.
|
mozilla::dom::TabGroup*
|
||||||
mConstellation.AppendPrintf("^%llu", GetOuterWindowInternal()->mStaticConstellation);
|
nsGlobalWindow::TabGroupInner()
|
||||||
|
{
|
||||||
|
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||||
|
|
||||||
|
// If we don't have a TabGroup yet, try to get it from the outer window and
|
||||||
|
// cache it.
|
||||||
|
if (!mTabGroup) {
|
||||||
|
nsGlobalWindow* outer = GetOuterWindowInternal();
|
||||||
|
// This will never be called without either an outer window, or a cached tab group.
|
||||||
|
// This is because of the following:
|
||||||
|
// * This method is only called on inner windows
|
||||||
|
// * This method is called as a document is attached to it's script global
|
||||||
|
// by the document
|
||||||
|
// * Inner windows are created in nsGlobalWindow::SetNewDocument, which
|
||||||
|
// immediately sets a document, which will call this method, causing
|
||||||
|
// the TabGroup to be cached.
|
||||||
|
MOZ_RELEASE_ASSERT(outer, "Inner window without outer window has no cached tab group!");
|
||||||
|
mTabGroup = outer->TabGroup();
|
||||||
}
|
}
|
||||||
|
MOZ_ASSERT(mTabGroup);
|
||||||
|
|
||||||
aConstellation.Assign(mConstellation);
|
#ifdef DEBUG
|
||||||
|
nsGlobalWindow* outer = GetOuterWindowInternal();
|
||||||
|
MOZ_ASSERT_IF(outer, outer->TabGroup() == mTabGroup);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return mTabGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::dom::TabGroup*
|
||||||
|
nsGlobalWindow::TabGroup()
|
||||||
|
{
|
||||||
|
if (IsInnerWindow()) {
|
||||||
|
return TabGroupInner();
|
||||||
|
}
|
||||||
|
return TabGroupOuter();
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::dom::DocGroup*
|
||||||
|
nsGlobalWindow::GetDocGroup()
|
||||||
|
{
|
||||||
|
nsIDocument* doc = GetExtantDoc();
|
||||||
|
if (doc) {
|
||||||
|
return doc->GetDocGroup();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsGlobalWindow::TemporarilyDisableDialogs::TemporarilyDisableDialogs(
|
nsGlobalWindow::TemporarilyDisableDialogs::TemporarilyDisableDialogs(
|
||||||
|
|
|
@ -86,6 +86,7 @@ class nsIJSID;
|
||||||
class nsIScriptContext;
|
class nsIScriptContext;
|
||||||
class nsIScriptTimeoutHandler;
|
class nsIScriptTimeoutHandler;
|
||||||
class nsIWebBrowserChrome;
|
class nsIWebBrowserChrome;
|
||||||
|
class mozIDOMWindowProxy;
|
||||||
|
|
||||||
class nsDOMWindowList;
|
class nsDOMWindowList;
|
||||||
class nsScreen;
|
class nsScreen;
|
||||||
|
@ -106,6 +107,7 @@ struct ChannelPixelLayout;
|
||||||
class Console;
|
class Console;
|
||||||
class Crypto;
|
class Crypto;
|
||||||
class CustomElementRegistry;
|
class CustomElementRegistry;
|
||||||
|
class DocGroup;
|
||||||
class External;
|
class External;
|
||||||
class Function;
|
class Function;
|
||||||
class Gamepad;
|
class Gamepad;
|
||||||
|
@ -121,6 +123,7 @@ struct RequestInit;
|
||||||
class RequestOrUSVString;
|
class RequestOrUSVString;
|
||||||
class Selection;
|
class Selection;
|
||||||
class SpeechSynthesis;
|
class SpeechSynthesis;
|
||||||
|
class TabGroup;
|
||||||
class U2F;
|
class U2F;
|
||||||
class VRDisplay;
|
class VRDisplay;
|
||||||
class VREventObserver;
|
class VREventObserver;
|
||||||
|
@ -920,6 +923,9 @@ protected:
|
||||||
// Initializes the mWasOffline member variable
|
// Initializes the mWasOffline member variable
|
||||||
void InitWasOffline();
|
void InitWasOffline();
|
||||||
public:
|
public:
|
||||||
|
nsPIDOMWindowOuter*
|
||||||
|
GetSanitizedOpener(nsPIDOMWindowOuter* aOpener);
|
||||||
|
|
||||||
nsPIDOMWindowOuter* GetOpenerWindow(mozilla::ErrorResult& aError);
|
nsPIDOMWindowOuter* GetOpenerWindow(mozilla::ErrorResult& aError);
|
||||||
void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
|
void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
|
||||||
mozilla::ErrorResult& aError);
|
mozilla::ErrorResult& aError);
|
||||||
|
@ -1739,9 +1745,12 @@ private:
|
||||||
// IsSecureContext() for the inner window that corresponds to aDocument.
|
// IsSecureContext() for the inner window that corresponds to aDocument.
|
||||||
bool ComputeIsSecureContext(nsIDocument* aDocument);
|
bool ComputeIsSecureContext(nsIDocument* aDocument);
|
||||||
|
|
||||||
public:
|
mozilla::dom::TabGroup* TabGroupInner();
|
||||||
|
mozilla::dom::TabGroup* TabGroupOuter();
|
||||||
|
|
||||||
void GetConstellation(nsACString& aConstellation);
|
public:
|
||||||
|
mozilla::dom::TabGroup* TabGroup();
|
||||||
|
mozilla::dom::DocGroup* GetDocGroup();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// These members are only used on outer window objects. Make sure
|
// These members are only used on outer window objects. Make sure
|
||||||
|
@ -1946,6 +1955,13 @@ protected:
|
||||||
RefPtr<mozilla::dom::SpeechSynthesis> mSpeechSynthesis;
|
RefPtr<mozilla::dom::SpeechSynthesis> mSpeechSynthesis;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RefPtr<mozilla::dom::TabGroup> mTabGroup; // Outer window only
|
||||||
|
#ifdef DEBUG
|
||||||
|
// This member is used in the debug only assertions in TabGroup()
|
||||||
|
// to catch cyclic parent/opener trees and not overflow the stack.
|
||||||
|
bool mIsValidatingTabGroup;
|
||||||
|
#endif
|
||||||
|
|
||||||
// This is the CC generation the last time we called CanSkip.
|
// This is the CC generation the last time we called CanSkip.
|
||||||
uint32_t mCanSkipCCGeneration;
|
uint32_t mCanSkipCCGeneration;
|
||||||
|
|
||||||
|
@ -1954,9 +1970,6 @@ protected:
|
||||||
|
|
||||||
nsAutoPtr<mozilla::dom::VREventObserver> mVREventObserver;
|
nsAutoPtr<mozilla::dom::VREventObserver> mVREventObserver;
|
||||||
|
|
||||||
uint64_t mStaticConstellation; // Only used on outer windows
|
|
||||||
nsCString mConstellation; // Only used on inner windows
|
|
||||||
|
|
||||||
friend class nsDOMScriptableHelper;
|
friend class nsDOMScriptableHelper;
|
||||||
friend class nsDOMWindowUtils;
|
friend class nsDOMWindowUtils;
|
||||||
friend class mozilla::dom::PostMessageEvent;
|
friend class mozilla::dom::PostMessageEvent;
|
||||||
|
@ -2053,6 +2066,7 @@ public:
|
||||||
// The pointer being set indicates we've set the IsInFullscreenChange
|
// The pointer being set indicates we've set the IsInFullscreenChange
|
||||||
// flag on this pres shell.
|
// flag on this pres shell.
|
||||||
nsWeakPtr mFullscreenPresShell;
|
nsWeakPtr mFullscreenPresShell;
|
||||||
|
nsCOMPtr<mozIDOMWindowProxy> mOpenerForInitialContentBrowser;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -123,6 +123,7 @@ class BoxObject;
|
||||||
class CDATASection;
|
class CDATASection;
|
||||||
class Comment;
|
class Comment;
|
||||||
struct CustomElementDefinition;
|
struct CustomElementDefinition;
|
||||||
|
class DocGroup;
|
||||||
class DocumentFragment;
|
class DocumentFragment;
|
||||||
class DocumentTimeline;
|
class DocumentTimeline;
|
||||||
class DocumentType;
|
class DocumentType;
|
||||||
|
@ -2849,11 +2850,13 @@ public:
|
||||||
mozilla::dom::DOMIntersectionObserver* aObserver) = 0;
|
mozilla::dom::DOMIntersectionObserver* aObserver) = 0;
|
||||||
virtual void RemoveIntersectionObserver(
|
virtual void RemoveIntersectionObserver(
|
||||||
mozilla::dom::DOMIntersectionObserver* aObserver) = 0;
|
mozilla::dom::DOMIntersectionObserver* aObserver) = 0;
|
||||||
|
|
||||||
virtual void UpdateIntersectionObservations() = 0;
|
virtual void UpdateIntersectionObservations() = 0;
|
||||||
virtual void ScheduleIntersectionObserverNotification() = 0;
|
virtual void ScheduleIntersectionObserverNotification() = 0;
|
||||||
virtual void NotifyIntersectionObservers() = 0;
|
virtual void NotifyIntersectionObservers() = 0;
|
||||||
|
|
||||||
|
mozilla::dom::DocGroup* GetDocGroup();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool GetUseCounter(mozilla::UseCounter aUseCounter)
|
bool GetUseCounter(mozilla::UseCounter aUseCounter)
|
||||||
{
|
{
|
||||||
|
@ -3310,6 +3313,8 @@ protected:
|
||||||
bool mUserHasInteracted;
|
bool mUserHasInteracted;
|
||||||
|
|
||||||
mozilla::TimeStamp mPageUnloadingEventTimeStamp;
|
mozilla::TimeStamp mPageUnloadingEventTimeStamp;
|
||||||
|
|
||||||
|
RefPtr<mozilla::dom::DocGroup> mDocGroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
|
||||||
|
|
|
@ -1258,6 +1258,12 @@ nsObjectLoadingContent::GetParentApplication(mozIApplication** aApplication)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsObjectLoadingContent::PresetOpenerWindow(mozIDOMWindowProxy* aWindow, mozilla::ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsObjectLoadingContent::SetIsPrerendered()
|
nsObjectLoadingContent::SetIsPrerendered()
|
||||||
{
|
{
|
||||||
|
|
|
@ -256,6 +256,8 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||||
return mRewrittenYoutubeEmbed;
|
return mRewrittenYoutubeEmbed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PresetOpenerWindow(mozIDOMWindowProxy* aOpenerWindow, mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Begins loading the object when called
|
* Begins loading the object when called
|
||||||
|
|
|
@ -283,6 +283,10 @@ BrowserElementParent::OpenWindowInProcess(nsPIDOMWindowOuter* aOpenerWindow,
|
||||||
aURI->GetSpec(spec);
|
aURI->GetSpec(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorResult res;
|
||||||
|
popupFrameElement->PresetOpenerWindow(aOpenerWindow, res);
|
||||||
|
MOZ_ASSERT(!res.Failed());
|
||||||
|
|
||||||
OpenWindowResult opened =
|
OpenWindowResult opened =
|
||||||
DispatchOpenWindowEvent(openerFrameElement, popupFrameElement,
|
DispatchOpenWindowEvent(openerFrameElement, popupFrameElement,
|
||||||
NS_ConvertUTF8toUTF16(spec),
|
NS_ConvertUTF8toUTF16(spec),
|
||||||
|
|
|
@ -36,6 +36,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericHTMLFrameElement)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGenericHTMLFrameElement,
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGenericHTMLFrameElement,
|
||||||
nsGenericHTMLElement)
|
nsGenericHTMLElement)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpenerWindow)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserElementAPI)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserElementAPI)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserElementAudioChannels)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserElementAudioChannels)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
@ -47,6 +48,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGenericHTMLFrameElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameLoader)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameLoader)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpenerWindow)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserElementAPI)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserElementAPI)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserElementAudioChannels)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserElementAudioChannels)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
@ -153,6 +155,15 @@ nsGenericHTMLFrameElement::EnsureFrameLoader()
|
||||||
if (mIsPrerendered) {
|
if (mIsPrerendered) {
|
||||||
mFrameLoader->SetIsPrerendered();
|
mFrameLoader->SetIsPrerendered();
|
||||||
}
|
}
|
||||||
|
if (mOpenerWindow) {
|
||||||
|
nsCOMPtr<nsIDocShell> docShell;
|
||||||
|
mFrameLoader->GetDocShell(getter_AddRefs(docShell));
|
||||||
|
if (docShell) {
|
||||||
|
nsCOMPtr<nsPIDOMWindowOuter> outerWindow = docShell->GetWindow();
|
||||||
|
outerWindow->SetOpenerWindow(nsPIDOMWindowOuter::From(mOpenerWindow), true);
|
||||||
|
mOpenerWindow = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -212,6 +223,13 @@ nsGenericHTMLFrameElement::GetParentApplication(mozIApplication** aApplication)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsGenericHTMLFrameElement::PresetOpenerWindow(mozIDOMWindowProxy* aWindow, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!mFrameLoader);
|
||||||
|
mOpenerWindow = nsPIDOMWindowOuter::From(aWindow);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGenericHTMLFrameElement::SwapFrameLoaders(HTMLIFrameElement& aOtherLoaderOwner,
|
nsGenericHTMLFrameElement::SwapFrameLoaders(HTMLIFrameElement& aOtherLoaderOwner,
|
||||||
ErrorResult& rv)
|
ErrorResult& rv)
|
||||||
|
|
|
@ -83,6 +83,9 @@ public:
|
||||||
void SwapFrameLoaders(RefPtr<nsFrameLoader>& aOtherLoader,
|
void SwapFrameLoaders(RefPtr<nsFrameLoader>& aOtherLoader,
|
||||||
mozilla::ErrorResult& rv);
|
mozilla::ErrorResult& rv);
|
||||||
|
|
||||||
|
void PresetOpenerWindow(mozIDOMWindowProxy* aOpenerWindow,
|
||||||
|
mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
static bool BrowserFramesEnabled();
|
static bool BrowserFramesEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,6 +110,7 @@ protected:
|
||||||
already_AddRefed<nsPIDOMWindowOuter> GetContentWindow();
|
already_AddRefed<nsPIDOMWindowOuter> GetContentWindow();
|
||||||
|
|
||||||
RefPtr<nsFrameLoader> mFrameLoader;
|
RefPtr<nsFrameLoader> mFrameLoader;
|
||||||
|
nsCOMPtr<nsPIDOMWindowOuter> mOpenerWindow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True when the element is created by the parser using the
|
* True when the element is created by the parser using the
|
||||||
|
|
|
@ -9,6 +9,7 @@ interface nsIBrowserDOMWindow;
|
||||||
interface nsIDOMElement;
|
interface nsIDOMElement;
|
||||||
interface nsIDOMEvent;
|
interface nsIDOMEvent;
|
||||||
interface nsIMessageBroadcaster;
|
interface nsIMessageBroadcaster;
|
||||||
|
interface mozIDOMWindowProxy;
|
||||||
|
|
||||||
[scriptable, uuid(78bdcb41-1efa-409f-aaba-70842213f80f)]
|
[scriptable, uuid(78bdcb41-1efa-409f-aaba-70842213f80f)]
|
||||||
interface nsIDOMChromeWindow : nsISupports
|
interface nsIDOMChromeWindow : nsISupports
|
||||||
|
@ -63,4 +64,18 @@ interface nsIDOMChromeWindow : nsISupports
|
||||||
* doesn't support this.
|
* doesn't support this.
|
||||||
*/
|
*/
|
||||||
void beginWindowMove(in nsIDOMEvent mouseDownEvent, [optional] in nsIDOMElement panel);
|
void beginWindowMove(in nsIDOMEvent mouseDownEvent, [optional] in nsIDOMElement panel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These methods provide a way to specify the opener value for the content in
|
||||||
|
* the window before the content itself is created. This is important in order
|
||||||
|
* to set the DocGroup of a document, as the opener must be set before the
|
||||||
|
* document is created.
|
||||||
|
*
|
||||||
|
* SetOpenerForInitialContentBrowser is used to set which opener will be used,
|
||||||
|
* and TakeOpenerForInitialContentBrowser is used by nsXULElement in order to
|
||||||
|
* take the value set earlier, and null out the value in the
|
||||||
|
* nsIDOMChromeWindow.
|
||||||
|
*/
|
||||||
|
void setOpenerForInitialContentBrowser(in mozIDOMWindowProxy aOpener);
|
||||||
|
mozIDOMWindowProxy takeOpenerForInitialContentBrowser();
|
||||||
};
|
};
|
||||||
|
|
|
@ -826,6 +826,17 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
||||||
aTabOpener->mDefaultScale);
|
aTabOpener->mDefaultScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the opener window for this window before we start loading the document
|
||||||
|
// inside of it. We have to do this before loading the remote scripts, because
|
||||||
|
// they can poke at the document and cause the nsDocument to be created before
|
||||||
|
// the openerwindow
|
||||||
|
nsCOMPtr<mozIDOMWindowProxy> windowProxy = do_GetInterface(newChild->WebNavigation());
|
||||||
|
if (windowProxy && aParent) {
|
||||||
|
nsPIDOMWindowOuter* outer = nsPIDOMWindowOuter::From(windowProxy);
|
||||||
|
nsPIDOMWindowOuter* parent = nsPIDOMWindowOuter::From(aParent);
|
||||||
|
outer->SetOpenerWindow(parent, *aWindowIsNew);
|
||||||
|
}
|
||||||
|
|
||||||
// Unfortunately we don't get a window unless we've shown the frame. That's
|
// Unfortunately we don't get a window unless we've shown the frame. That's
|
||||||
// pretty bogus; see bug 763602.
|
// pretty bogus; see bug 763602.
|
||||||
newChild->DoFakeShow(textureFactoryIdentifier, layersId, renderFrame,
|
newChild->DoFakeShow(textureFactoryIdentifier, layersId, renderFrame,
|
||||||
|
|
|
@ -125,6 +125,9 @@ interface MozFrameLoaderOwner {
|
||||||
[ChromeOnly]
|
[ChromeOnly]
|
||||||
void setIsPrerendered();
|
void setIsPrerendered();
|
||||||
|
|
||||||
|
[ChromeOnly, Throws]
|
||||||
|
void presetOpenerWindow(WindowProxy? window);
|
||||||
|
|
||||||
[ChromeOnly, Throws]
|
[ChromeOnly, Throws]
|
||||||
void swapFrameLoaders(XULElement aOtherLoaderOwner);
|
void swapFrameLoaders(XULElement aOtherLoaderOwner);
|
||||||
|
|
||||||
|
|
|
@ -128,12 +128,6 @@ NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aEventObject)) {
|
|
||||||
d->SetScriptHandlingObject(sgo);
|
|
||||||
} else if (aEventObject){
|
|
||||||
d->SetScopeObject(aEventObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isHTML) {
|
if (isHTML) {
|
||||||
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(d);
|
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(d);
|
||||||
NS_ASSERTION(htmlDoc, "HTML Document doesn't implement nsIHTMLDocument?");
|
NS_ASSERTION(htmlDoc, "HTML Document doesn't implement nsIHTMLDocument?");
|
||||||
|
@ -147,6 +141,14 @@ NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
|
||||||
doc->SetPrincipal(aPrincipal);
|
doc->SetPrincipal(aPrincipal);
|
||||||
doc->SetBaseURI(aBaseURI);
|
doc->SetBaseURI(aBaseURI);
|
||||||
|
|
||||||
|
// We need to set the script handling object after we set the principal such
|
||||||
|
// that the doc group is assigned correctly.
|
||||||
|
if (nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aEventObject)) {
|
||||||
|
d->SetScriptHandlingObject(sgo);
|
||||||
|
} else if (aEventObject){
|
||||||
|
d->SetScopeObject(aEventObject);
|
||||||
|
}
|
||||||
|
|
||||||
// XMLDocuments and documents "created in memory" get to be UTF-8 by default,
|
// XMLDocuments and documents "created in memory" get to be UTF-8 by default,
|
||||||
// unlike the legacy HTML mess
|
// unlike the legacy HTML mess
|
||||||
doc->SetDocumentCharacterSet(NS_LITERAL_CSTRING("UTF-8"));
|
doc->SetDocumentCharacterSet(NS_LITERAL_CSTRING("UTF-8"));
|
||||||
|
|
|
@ -803,7 +803,6 @@ txMozillaXMLOutput::createResultDocument(const nsSubstring& aName, int32_t aNsID
|
||||||
nsIScriptGlobalObject* sgo =
|
nsIScriptGlobalObject* sgo =
|
||||||
source->GetScriptHandlingObject(hasHadScriptObject);
|
source->GetScriptHandlingObject(hasHadScriptObject);
|
||||||
NS_ENSURE_STATE(sgo || !hasHadScriptObject);
|
NS_ENSURE_STATE(sgo || !hasHadScriptObject);
|
||||||
mDocument->SetScriptHandlingObject(sgo);
|
|
||||||
|
|
||||||
mCurrentNode = mDocument;
|
mCurrentNode = mDocument;
|
||||||
mNodeInfoManager = mDocument->NodeInfoManager();
|
mNodeInfoManager = mDocument->NodeInfoManager();
|
||||||
|
@ -811,6 +810,10 @@ txMozillaXMLOutput::createResultDocument(const nsSubstring& aName, int32_t aNsID
|
||||||
// Reset and set up the document
|
// Reset and set up the document
|
||||||
URIUtils::ResetWithSource(mDocument, aSourceDocument);
|
URIUtils::ResetWithSource(mDocument, aSourceDocument);
|
||||||
|
|
||||||
|
// Make sure we set the script handling object after resetting with the
|
||||||
|
// source, so that we have the right principal.
|
||||||
|
mDocument->SetScriptHandlingObject(sgo);
|
||||||
|
|
||||||
// Set the charset
|
// Set the charset
|
||||||
if (!mOutputFormat.mEncoding.IsEmpty()) {
|
if (!mOutputFormat.mEncoding.IsEmpty()) {
|
||||||
nsAutoCString canonicalCharset;
|
nsAutoCString canonicalCharset;
|
||||||
|
|
|
@ -95,6 +95,7 @@
|
||||||
#include "nsIController.h"
|
#include "nsIController.h"
|
||||||
#include "nsQueryObject.h"
|
#include "nsQueryObject.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "nsIDOMChromeWindow.h"
|
||||||
|
|
||||||
// The XUL doc interface
|
// The XUL doc interface
|
||||||
#include "nsIDOMXULDocument.h"
|
#include "nsIDOMXULDocument.h"
|
||||||
|
@ -191,6 +192,8 @@ nsXULElement::nsXULSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
|
||||||
{
|
{
|
||||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mFrameLoader");
|
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mFrameLoader");
|
||||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIFrameLoader*, mFrameLoader));
|
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIFrameLoader*, mFrameLoader));
|
||||||
|
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mOpener");
|
||||||
|
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(mozIDOMWindowProxy*, mOpener));
|
||||||
}
|
}
|
||||||
|
|
||||||
nsINode::nsSlots*
|
nsINode::nsSlots*
|
||||||
|
@ -1585,6 +1588,30 @@ nsXULElement::LoadSrc()
|
||||||
slots->mFrameLoader = nsFrameLoader::Create(this, false);
|
slots->mFrameLoader = nsFrameLoader::Create(this, false);
|
||||||
NS_ENSURE_TRUE(slots->mFrameLoader, NS_OK);
|
NS_ENSURE_TRUE(slots->mFrameLoader, NS_OK);
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindowOuter> opener;
|
||||||
|
if (slots->mOpener) {
|
||||||
|
opener = nsPIDOMWindowOuter::From(slots->mOpener);
|
||||||
|
slots->mOpener = nullptr;
|
||||||
|
} else {
|
||||||
|
// If we are a content-primary xul-browser, we want to take the opener property!
|
||||||
|
nsCOMPtr<nsIDOMChromeWindow> chromeWindow = do_QueryInterface(OwnerDoc()->GetWindow());
|
||||||
|
if (AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
||||||
|
NS_LITERAL_STRING("content-primary"), eIgnoreCase) &&
|
||||||
|
chromeWindow) {
|
||||||
|
nsCOMPtr<mozIDOMWindowProxy> wp;
|
||||||
|
chromeWindow->TakeOpenerForInitialContentBrowser(getter_AddRefs(wp));
|
||||||
|
opener = nsPIDOMWindowOuter::From(wp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opener) {
|
||||||
|
nsCOMPtr<nsIDocShell> docShell;
|
||||||
|
nsresult rv = slots->mFrameLoader->GetDocShell(getter_AddRefs(docShell));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
nsCOMPtr<nsPIDOMWindowOuter> outerWindow = docShell->GetWindow();
|
||||||
|
outerWindow->SetOpenerWindow(opener, true);
|
||||||
|
}
|
||||||
|
|
||||||
(new AsyncEventDispatcher(this,
|
(new AsyncEventDispatcher(this,
|
||||||
NS_LITERAL_STRING("XULFrameLoaderCreated"),
|
NS_LITERAL_STRING("XULFrameLoaderCreated"),
|
||||||
/* aBubbles */ true))->RunDOMEventWhenSafe();
|
/* aBubbles */ true))->RunDOMEventWhenSafe();
|
||||||
|
@ -1628,6 +1655,15 @@ nsXULElement::GetParentApplication(mozIApplication** aApplication)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXULElement::PresetOpenerWindow(mozIDOMWindowProxy* aWindow, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
nsXULSlots* slots = static_cast<nsXULSlots*>(Slots());
|
||||||
|
MOZ_ASSERT(!slots->mFrameLoader, "Cannot SetOpenerWindow when a frame loader is present");
|
||||||
|
|
||||||
|
slots->mOpener = aWindow;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXULElement::SetIsPrerendered()
|
nsXULElement::SetIsPrerendered()
|
||||||
{
|
{
|
||||||
|
|
|
@ -412,6 +412,7 @@ public:
|
||||||
|
|
||||||
nsresult GetFrameLoaderXPCOM(nsIFrameLoader** aFrameLoader);
|
nsresult GetFrameLoaderXPCOM(nsIFrameLoader** aFrameLoader);
|
||||||
nsresult GetParentApplication(mozIApplication** aApplication);
|
nsresult GetParentApplication(mozIApplication** aApplication);
|
||||||
|
void PresetOpenerWindow(mozIDOMWindowProxy* aWindow, ErrorResult& aRv);
|
||||||
nsresult SetIsPrerendered();
|
nsresult SetIsPrerendered();
|
||||||
|
|
||||||
virtual void RecompileScriptEventListeners() override;
|
virtual void RecompileScriptEventListeners() override;
|
||||||
|
@ -616,6 +617,7 @@ protected:
|
||||||
void Traverse(nsCycleCollectionTraversalCallback &cb);
|
void Traverse(nsCycleCollectionTraversalCallback &cb);
|
||||||
|
|
||||||
RefPtr<nsFrameLoader> mFrameLoader;
|
RefPtr<nsFrameLoader> mFrameLoader;
|
||||||
|
nsCOMPtr<mozIDOMWindowProxy> mOpener;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual nsINode::nsSlots* CreateSlots() override;
|
virtual nsINode::nsSlots* CreateSlots() override;
|
||||||
|
|
|
@ -65,8 +65,10 @@
|
||||||
#include "mozilla/dom/DOMStorage.h"
|
#include "mozilla/dom/DOMStorage.h"
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
#include "mozilla/dom/TabParent.h"
|
#include "mozilla/dom/TabParent.h"
|
||||||
|
#include "mozilla/dom/DocGroup.h"
|
||||||
#include "nsIXULWindow.h"
|
#include "nsIXULWindow.h"
|
||||||
#include "nsIXULBrowserWindow.h"
|
#include "nsIXULBrowserWindow.h"
|
||||||
|
#include "nsGlobalWindow.h"
|
||||||
|
|
||||||
#ifdef USEWEAKREFS
|
#ifdef USEWEAKREFS
|
||||||
#include "nsIWeakReference.h"
|
#include "nsIWeakReference.h"
|
||||||
|
@ -483,6 +485,7 @@ nsWindowWatcher::CreateChromeWindow(const nsACString& aFeatures,
|
||||||
uint32_t aChromeFlags,
|
uint32_t aChromeFlags,
|
||||||
uint32_t aContextFlags,
|
uint32_t aContextFlags,
|
||||||
nsITabParent* aOpeningTabParent,
|
nsITabParent* aOpeningTabParent,
|
||||||
|
mozIDOMWindowProxy* aOpener,
|
||||||
nsIWebBrowserChrome** aResult)
|
nsIWebBrowserChrome** aResult)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIWindowCreator2> windowCreator2(do_QueryInterface(mWindowCreator));
|
nsCOMPtr<nsIWindowCreator2> windowCreator2(do_QueryInterface(mWindowCreator));
|
||||||
|
@ -501,7 +504,7 @@ nsWindowWatcher::CreateChromeWindow(const nsACString& aFeatures,
|
||||||
nsCOMPtr<nsIWebBrowserChrome> newWindowChrome;
|
nsCOMPtr<nsIWebBrowserChrome> newWindowChrome;
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
windowCreator2->CreateChromeWindow2(aParentChrome, aChromeFlags, aContextFlags,
|
windowCreator2->CreateChromeWindow2(aParentChrome, aChromeFlags, aContextFlags,
|
||||||
aOpeningTabParent, &cancel,
|
aOpeningTabParent, aOpener, &cancel,
|
||||||
getter_AddRefs(newWindowChrome));
|
getter_AddRefs(newWindowChrome));
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && cancel) {
|
if (NS_SUCCEEDED(rv) && cancel) {
|
||||||
|
@ -621,7 +624,7 @@ nsWindowWatcher::OpenWindowWithTabParent(nsITabParent* aOpeningTabParent,
|
||||||
nsCOMPtr<nsIWebBrowserChrome> newWindowChrome;
|
nsCOMPtr<nsIWebBrowserChrome> newWindowChrome;
|
||||||
|
|
||||||
CreateChromeWindow(aFeatures, parentChrome, chromeFlags, contextFlags,
|
CreateChromeWindow(aFeatures, parentChrome, chromeFlags, contextFlags,
|
||||||
aOpeningTabParent, getter_AddRefs(newWindowChrome));
|
aOpeningTabParent, nullptr, getter_AddRefs(newWindowChrome));
|
||||||
|
|
||||||
if (NS_WARN_IF(!newWindowChrome)) {
|
if (NS_WARN_IF(!newWindowChrome)) {
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
@ -996,7 +999,7 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent,
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = CreateChromeWindow(features, parentChrome, chromeFlags, contextFlags,
|
rv = CreateChromeWindow(features, parentChrome, chromeFlags, contextFlags,
|
||||||
nullptr, getter_AddRefs(newChrome));
|
nullptr, aParent, getter_AddRefs(newChrome));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
rv = mWindowCreator->CreateChromeWindow(parentChrome, chromeFlags,
|
rv = mWindowCreator->CreateChromeWindow(parentChrome, chromeFlags,
|
||||||
|
@ -1009,7 +1012,8 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent,
|
||||||
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWin;
|
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWin;
|
||||||
xulWin->GetXULBrowserWindow(getter_AddRefs(xulBrowserWin));
|
xulWin->GetXULBrowserWindow(getter_AddRefs(xulBrowserWin));
|
||||||
if (xulBrowserWin) {
|
if (xulBrowserWin) {
|
||||||
xulBrowserWin->ForceInitialBrowserNonRemote();
|
nsPIDOMWindowOuter* openerWindow = aForceNoOpener ? nullptr : parentWindow;
|
||||||
|
xulBrowserWin->ForceInitialBrowserNonRemote(openerWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* It might be a chrome nsXULWindow, in which case it won't have
|
/* It might be a chrome nsXULWindow, in which case it won't have
|
||||||
|
@ -2182,28 +2186,30 @@ nsWindowWatcher::ReadyOpenedDocShellItem(nsIDocShellTreeItem* aOpenedItem,
|
||||||
*aOpenedWindow = 0;
|
*aOpenedWindow = 0;
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> piOpenedWindow = aOpenedItem->GetWindow();
|
nsCOMPtr<nsPIDOMWindowOuter> piOpenedWindow = aOpenedItem->GetWindow();
|
||||||
if (piOpenedWindow) {
|
if (piOpenedWindow) {
|
||||||
if (aParent) {
|
if (!aForceNoOpener) {
|
||||||
if (!aForceNoOpener) {
|
piOpenedWindow->SetOpenerWindow(aParent, aWindowIsNew); // damnit
|
||||||
piOpenedWindow->SetOpenerWindow(aParent, aWindowIsNew); // damnit
|
} else if (aParent) {
|
||||||
}
|
MOZ_ASSERT(nsGlobalWindow::Cast(piOpenedWindow)->TabGroup() !=
|
||||||
|
nsGlobalWindow::Cast(aParent)->TabGroup(),
|
||||||
|
"If we're forcing no opener, they should be in different tab groups");
|
||||||
|
}
|
||||||
|
|
||||||
if (aWindowIsNew) {
|
if (aWindowIsNew) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Assert that we're not loading things right now. If we are, when
|
// Assert that we're not loading things right now. If we are, when
|
||||||
// that load completes it will clobber whatever principals we set up
|
// that load completes it will clobber whatever principals we set up
|
||||||
// on this new window!
|
// on this new window!
|
||||||
nsCOMPtr<nsIDocumentLoader> docloader = do_QueryInterface(aOpenedItem);
|
nsCOMPtr<nsIDocumentLoader> docloader = do_QueryInterface(aOpenedItem);
|
||||||
NS_ASSERTION(docloader, "How can we not have a docloader here?");
|
NS_ASSERTION(docloader, "How can we not have a docloader here?");
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> chan;
|
nsCOMPtr<nsIChannel> chan;
|
||||||
docloader->GetDocumentChannel(getter_AddRefs(chan));
|
docloader->GetDocumentChannel(getter_AddRefs(chan));
|
||||||
NS_ASSERTION(!chan, "Why is there a document channel?");
|
NS_ASSERTION(!chan, "Why is there a document channel?");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> doc = piOpenedWindow->GetExtantDoc();
|
nsCOMPtr<nsIDocument> doc = piOpenedWindow->GetExtantDoc();
|
||||||
if (doc) {
|
if (doc) {
|
||||||
doc->SetIsInitialDocument(true);
|
doc->SetIsInitialDocument(true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rv = CallQueryInterface(piOpenedWindow, aOpenedWindow);
|
rv = CallQueryInterface(piOpenedWindow, aOpenedWindow);
|
||||||
|
|
|
@ -130,6 +130,7 @@ private:
|
||||||
uint32_t aChromeFlags,
|
uint32_t aChromeFlags,
|
||||||
uint32_t aContextFlags,
|
uint32_t aContextFlags,
|
||||||
nsITabParent* aOpeningTabParent,
|
nsITabParent* aOpeningTabParent,
|
||||||
|
mozIDOMWindowProxy* aOpener,
|
||||||
nsIWebBrowserChrome** aResult);
|
nsIWebBrowserChrome** aResult);
|
||||||
|
|
||||||
void MaybeDisablePersistence(const nsACString& aFeatures,
|
void MaybeDisablePersistence(const nsACString& aFeatures,
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
interface nsITabParent;
|
interface nsITabParent;
|
||||||
interface nsIURI;
|
interface nsIURI;
|
||||||
interface nsIWebBrowserChrome;
|
interface nsIWebBrowserChrome;
|
||||||
|
interface mozIDOMWindowProxy;
|
||||||
|
|
||||||
[scriptable, uuid(b6c44689-f97e-4f32-a723-29eeddfbdc53)]
|
[scriptable, uuid(b6c44689-f97e-4f32-a723-29eeddfbdc53)]
|
||||||
|
|
||||||
|
@ -42,6 +43,8 @@ interface nsIWindowCreator2 : nsIWindowCreator {
|
||||||
@param contextFlags Flags about the context of the window being created.
|
@param contextFlags Flags about the context of the window being created.
|
||||||
@param aOpeningTab The TabParent that is trying to open this new chrome
|
@param aOpeningTab The TabParent that is trying to open this new chrome
|
||||||
window. Can be nullptr.
|
window. Can be nullptr.
|
||||||
|
@param aOpener The window which is trying to open this new chrome window.
|
||||||
|
Can be nullptr
|
||||||
@param cancel Return |true| to reject window creation. If true the
|
@param cancel Return |true| to reject window creation. If true the
|
||||||
implementation has determined the window should not
|
implementation has determined the window should not
|
||||||
be created at all. The caller should not default
|
be created at all. The caller should not default
|
||||||
|
@ -52,6 +55,7 @@ interface nsIWindowCreator2 : nsIWindowCreator {
|
||||||
in uint32_t chromeFlags,
|
in uint32_t chromeFlags,
|
||||||
in uint32_t contextFlags,
|
in uint32_t contextFlags,
|
||||||
in nsITabParent aOpeningTab,
|
in nsITabParent aOpeningTab,
|
||||||
|
in mozIDOMWindowProxy aOpener,
|
||||||
out boolean cancel);
|
out boolean cancel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -244,7 +244,7 @@ function plInit() {
|
||||||
// to this reinitialization on the switch.
|
// to this reinitialization on the switch.
|
||||||
if (browserWindow.gMultiProcessBrowser) {
|
if (browserWindow.gMultiProcessBrowser) {
|
||||||
if (!firstPageCanLoadAsRemote())
|
if (!firstPageCanLoadAsRemote())
|
||||||
browserWindow.XULBrowserWindow.forceInitialBrowserNonRemote();
|
browserWindow.XULBrowserWindow.forceInitialBrowserNonRemote(null);
|
||||||
// Implicit else: initial browser in e10s is remote by default.
|
// Implicit else: initial browser in e10s is remote by default.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -611,7 +611,7 @@ nsAppStartup::CreateChromeWindow(nsIWebBrowserChrome *aParent,
|
||||||
nsIWebBrowserChrome **_retval)
|
nsIWebBrowserChrome **_retval)
|
||||||
{
|
{
|
||||||
bool cancel;
|
bool cancel;
|
||||||
return CreateChromeWindow2(aParent, aChromeFlags, 0, nullptr, &cancel, _retval);
|
return CreateChromeWindow2(aParent, aChromeFlags, 0, nullptr, nullptr, &cancel, _retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -635,6 +635,7 @@ nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
|
||||||
uint32_t aChromeFlags,
|
uint32_t aChromeFlags,
|
||||||
uint32_t aContextFlags,
|
uint32_t aContextFlags,
|
||||||
nsITabParent *aOpeningTab,
|
nsITabParent *aOpeningTab,
|
||||||
|
mozIDOMWindowProxy* aOpener,
|
||||||
bool *aCancel,
|
bool *aCancel,
|
||||||
nsIWebBrowserChrome **_retval)
|
nsIWebBrowserChrome **_retval)
|
||||||
{
|
{
|
||||||
|
@ -654,7 +655,7 @@ nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
|
||||||
NS_ASSERTION(xulParent, "window created using non-XUL parent. that's unexpected, but may work.");
|
NS_ASSERTION(xulParent, "window created using non-XUL parent. that's unexpected, but may work.");
|
||||||
|
|
||||||
if (xulParent)
|
if (xulParent)
|
||||||
xulParent->CreateNewWindow(aChromeFlags, aOpeningTab, getter_AddRefs(newWindow));
|
xulParent->CreateNewWindow(aChromeFlags, aOpeningTab, aOpener, getter_AddRefs(newWindow));
|
||||||
// And if it fails, don't try again without a parent. It could fail
|
// And if it fails, don't try again without a parent. It could fail
|
||||||
// intentionally (bug 115969).
|
// intentionally (bug 115969).
|
||||||
} else { // try using basic methods:
|
} else { // try using basic methods:
|
||||||
|
@ -671,7 +672,7 @@ nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
|
||||||
appShell->CreateTopLevelWindow(0, 0, aChromeFlags,
|
appShell->CreateTopLevelWindow(0, 0, aChromeFlags,
|
||||||
nsIAppShellService::SIZE_TO_CONTENT,
|
nsIAppShellService::SIZE_TO_CONTENT,
|
||||||
nsIAppShellService::SIZE_TO_CONTENT,
|
nsIAppShellService::SIZE_TO_CONTENT,
|
||||||
aOpeningTab,
|
aOpeningTab, aOpener,
|
||||||
getter_AddRefs(newWindow));
|
getter_AddRefs(newWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ nsAppShellService::CreateHiddenWindowHelper(bool aIsPrivate)
|
||||||
if (!aIsPrivate) {
|
if (!aIsPrivate) {
|
||||||
rv = JustCreateTopWindow(nullptr, url,
|
rv = JustCreateTopWindow(nullptr, url,
|
||||||
chromeMask, initialWidth, initialHeight,
|
chromeMask, initialWidth, initialHeight,
|
||||||
true, nullptr, getter_AddRefs(newWindow));
|
true, nullptr, nullptr, getter_AddRefs(newWindow));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
mHiddenWindow.swap(newWindow);
|
mHiddenWindow.swap(newWindow);
|
||||||
|
@ -145,7 +145,7 @@ nsAppShellService::CreateHiddenWindowHelper(bool aIsPrivate)
|
||||||
|
|
||||||
rv = JustCreateTopWindow(nullptr, url,
|
rv = JustCreateTopWindow(nullptr, url,
|
||||||
chromeMask, initialWidth, initialHeight,
|
chromeMask, initialWidth, initialHeight,
|
||||||
true, nullptr, getter_AddRefs(newWindow));
|
true, nullptr, nullptr, getter_AddRefs(newWindow));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShell> docShell;
|
nsCOMPtr<nsIDocShell> docShell;
|
||||||
|
@ -190,6 +190,7 @@ nsAppShellService::CreateTopLevelWindow(nsIXULWindow *aParent,
|
||||||
int32_t aInitialWidth,
|
int32_t aInitialWidth,
|
||||||
int32_t aInitialHeight,
|
int32_t aInitialHeight,
|
||||||
nsITabParent *aOpeningTab,
|
nsITabParent *aOpeningTab,
|
||||||
|
mozIDOMWindowProxy *aOpenerWindow,
|
||||||
nsIXULWindow **aResult)
|
nsIXULWindow **aResult)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -197,12 +198,12 @@ nsAppShellService::CreateTopLevelWindow(nsIXULWindow *aParent,
|
||||||
|
|
||||||
StartupTimeline::RecordOnce(StartupTimeline::CREATE_TOP_LEVEL_WINDOW);
|
StartupTimeline::RecordOnce(StartupTimeline::CREATE_TOP_LEVEL_WINDOW);
|
||||||
|
|
||||||
nsWebShellWindow *newWindow = nullptr;
|
RefPtr<nsWebShellWindow> newWindow;
|
||||||
rv = JustCreateTopWindow(aParent, aUrl,
|
rv = JustCreateTopWindow(aParent, aUrl,
|
||||||
aChromeMask, aInitialWidth, aInitialHeight,
|
aChromeMask, aInitialWidth, aInitialHeight,
|
||||||
false, aOpeningTab, &newWindow); // addrefs
|
false, aOpeningTab, aOpenerWindow,
|
||||||
|
getter_AddRefs(newWindow));
|
||||||
*aResult = newWindow; // transfer ref
|
newWindow.forget(aResult);
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
// the addref resulting from this is the owning addref for this window
|
// the addref resulting from this is the owning addref for this window
|
||||||
|
@ -626,6 +627,7 @@ nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
|
||||||
int32_t aInitialHeight,
|
int32_t aInitialHeight,
|
||||||
bool aIsHiddenWindow,
|
bool aIsHiddenWindow,
|
||||||
nsITabParent *aOpeningTab,
|
nsITabParent *aOpeningTab,
|
||||||
|
mozIDOMWindowProxy *aOpenerWindow,
|
||||||
nsWebShellWindow **aResult)
|
nsWebShellWindow **aResult)
|
||||||
{
|
{
|
||||||
*aResult = nullptr;
|
*aResult = nullptr;
|
||||||
|
@ -739,7 +741,8 @@ nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
|
||||||
|
|
||||||
nsresult rv = window->Initialize(parent, center ? aParent : nullptr,
|
nsresult rv = window->Initialize(parent, center ? aParent : nullptr,
|
||||||
aUrl, aInitialWidth, aInitialHeight,
|
aUrl, aInitialWidth, aInitialHeight,
|
||||||
aIsHiddenWindow, aOpeningTab, widgetInitData);
|
aIsHiddenWindow, aOpeningTab,
|
||||||
|
aOpenerWindow, widgetInitData);
|
||||||
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ protected:
|
||||||
int32_t aInitialWidth, int32_t aInitialHeight,
|
int32_t aInitialWidth, int32_t aInitialHeight,
|
||||||
bool aIsHiddenWindow,
|
bool aIsHiddenWindow,
|
||||||
nsITabParent *aOpeningTab,
|
nsITabParent *aOpeningTab,
|
||||||
|
mozIDOMWindowProxy *aOpenerWindow,
|
||||||
nsWebShellWindow **aResult);
|
nsWebShellWindow **aResult);
|
||||||
uint32_t CalculateWindowZLevel(nsIXULWindow *aParent, uint32_t aChromeMask);
|
uint32_t CalculateWindowZLevel(nsIXULWindow *aParent, uint32_t aChromeMask);
|
||||||
|
|
||||||
|
|
|
@ -994,6 +994,9 @@ nsContentTreeOwner::ProvideWindow(mozIDOMWindowProxy* aParent,
|
||||||
|
|
||||||
// Get a new rendering area from the browserDOMWin. We don't want
|
// Get a new rendering area from the browserDOMWin. We don't want
|
||||||
// to be starting any loads here, so get it with a null URI.
|
// to be starting any loads here, so get it with a null URI.
|
||||||
|
//
|
||||||
|
// This method handles setting the opener for us, so we don't need to set it
|
||||||
|
// ourselves.
|
||||||
return browserDOMWin->OpenURI(nullptr, aParent, openLocation,
|
return browserDOMWin->OpenURI(nullptr, aParent, openLocation,
|
||||||
nsIBrowserDOMWindow::OPEN_NEW, aReturn);
|
nsIBrowserDOMWindow::OPEN_NEW, aReturn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ interface nsIAppShellService : nsISupports
|
||||||
* @param aInitialHeight like aInitialWidth, but subtly different.
|
* @param aInitialHeight like aInitialWidth, but subtly different.
|
||||||
* @param aOpeningTab The TabParent that requested that this window be opened.
|
* @param aOpeningTab The TabParent that requested that this window be opened.
|
||||||
* Can be left null.
|
* Can be left null.
|
||||||
|
* @param aOpenerWindow The Window Proxy which requested that this window be opened.
|
||||||
|
* Can be left null.
|
||||||
*/
|
*/
|
||||||
const long SIZE_TO_CONTENT = -1;
|
const long SIZE_TO_CONTENT = -1;
|
||||||
nsIXULWindow createTopLevelWindow(in nsIXULWindow aParent,
|
nsIXULWindow createTopLevelWindow(in nsIXULWindow aParent,
|
||||||
|
@ -45,7 +47,8 @@ interface nsIAppShellService : nsISupports
|
||||||
in uint32_t aChromeMask,
|
in uint32_t aChromeMask,
|
||||||
in long aInitialWidth,
|
in long aInitialWidth,
|
||||||
in long aInitialHeight,
|
in long aInitialHeight,
|
||||||
in nsITabParent aOpeningTab);
|
in nsITabParent aOpeningTab,
|
||||||
|
in mozIDOMWindowProxy aOpenerWindow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the constructor for creating an invisible DocShell.
|
* This is the constructor for creating an invisible DocShell.
|
||||||
|
|
|
@ -13,6 +13,7 @@ interface nsIDOMElement;
|
||||||
interface nsIInputStream;
|
interface nsIInputStream;
|
||||||
interface nsIDocShell;
|
interface nsIDocShell;
|
||||||
interface nsITabParent;
|
interface nsITabParent;
|
||||||
|
interface mozIDOMWindowProxy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The nsIXULBrowserWindow supplies the methods that may be called from the
|
* The nsIXULBrowserWindow supplies the methods that may be called from the
|
||||||
|
@ -48,7 +49,7 @@ interface nsIXULBrowserWindow : nsISupports
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
nsITabParent forceInitialBrowserRemote();
|
nsITabParent forceInitialBrowserRemote();
|
||||||
void forceInitialBrowserNonRemote();
|
void forceInitialBrowserNonRemote(in mozIDOMWindowProxy openerWindow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether a load should continue.
|
* Determines whether a load should continue.
|
||||||
|
|
|
@ -17,6 +17,7 @@ interface nsIDocShell;
|
||||||
interface nsIDocShellTreeItem;
|
interface nsIDocShellTreeItem;
|
||||||
interface nsIXULBrowserWindow;
|
interface nsIXULBrowserWindow;
|
||||||
interface nsITabParent;
|
interface nsITabParent;
|
||||||
|
interface mozIDOMWindowProxy;
|
||||||
|
|
||||||
[scriptable, uuid(d6d7a014-e28d-4c9d-8727-1cf6d870619b)]
|
[scriptable, uuid(d6d7a014-e28d-4c9d-8727-1cf6d870619b)]
|
||||||
interface nsIXULWindow : nsISupports
|
interface nsIXULWindow : nsISupports
|
||||||
|
@ -120,10 +121,12 @@ interface nsIXULWindow : nsISupports
|
||||||
* @param aChromeFlags see nsIWebBrowserChrome
|
* @param aChromeFlags see nsIWebBrowserChrome
|
||||||
* @param aOpeningTab the TabParent that requested this new window be opened.
|
* @param aOpeningTab the TabParent that requested this new window be opened.
|
||||||
* Can be left null.
|
* Can be left null.
|
||||||
|
* @param aOpener The window which is requesting that this new window be opened.
|
||||||
* @return the newly minted window
|
* @return the newly minted window
|
||||||
*/
|
*/
|
||||||
nsIXULWindow createNewWindow(in int32_t aChromeFlags,
|
nsIXULWindow createNewWindow(in int32_t aChromeFlags,
|
||||||
in nsITabParent aOpeningTab);
|
in nsITabParent aOpeningTab,
|
||||||
|
in mozIDOMWindowProxy aOpener);
|
||||||
|
|
||||||
attribute nsIXULBrowserWindow XULBrowserWindow;
|
attribute nsIXULBrowserWindow XULBrowserWindow;
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,7 @@ nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent,
|
||||||
int32_t aInitialHeight,
|
int32_t aInitialHeight,
|
||||||
bool aIsHiddenWindow,
|
bool aIsHiddenWindow,
|
||||||
nsITabParent *aOpeningTab,
|
nsITabParent *aOpeningTab,
|
||||||
|
mozIDOMWindowProxy *aOpenerWindow,
|
||||||
nsWidgetInitData& widgetInitData)
|
nsWidgetInitData& widgetInitData)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
@ -209,6 +210,12 @@ nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent,
|
||||||
webProgress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_NETWORK);
|
webProgress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_NETWORK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aOpenerWindow) {
|
||||||
|
nsPIDOMWindowOuter* window = mDocShell->GetWindow();
|
||||||
|
MOZ_ASSERT(window);
|
||||||
|
window->SetOpenerWindow(nsPIDOMWindowOuter::From(aOpenerWindow), true);
|
||||||
|
}
|
||||||
|
|
||||||
// Eagerly create an about:blank content viewer with the right principal here,
|
// Eagerly create an about:blank content viewer with the right principal here,
|
||||||
// rather than letting it happening in the upcoming call to
|
// rather than letting it happening in the upcoming call to
|
||||||
// SetInitialPrincipalToSubject. This avoids creating the about:blank document
|
// SetInitialPrincipalToSubject. This avoids creating the about:blank document
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
int32_t aInitialWidth, int32_t aInitialHeight,
|
int32_t aInitialWidth, int32_t aInitialHeight,
|
||||||
bool aIsHiddenWindow,
|
bool aIsHiddenWindow,
|
||||||
nsITabParent *aOpeningTab,
|
nsITabParent *aOpeningTab,
|
||||||
|
mozIDOMWindowProxy *aOpenerWIndow,
|
||||||
nsWidgetInitData& widgetInitData);
|
nsWidgetInitData& widgetInitData);
|
||||||
|
|
||||||
nsresult Toolbar();
|
nsresult Toolbar();
|
||||||
|
|
|
@ -1920,29 +1920,30 @@ NS_IMETHODIMP nsXULWindow::ExitModalLoop(nsresult aStatus)
|
||||||
// top-level function to create a new window
|
// top-level function to create a new window
|
||||||
NS_IMETHODIMP nsXULWindow::CreateNewWindow(int32_t aChromeFlags,
|
NS_IMETHODIMP nsXULWindow::CreateNewWindow(int32_t aChromeFlags,
|
||||||
nsITabParent *aOpeningTab,
|
nsITabParent *aOpeningTab,
|
||||||
|
mozIDOMWindowProxy *aOpener,
|
||||||
nsIXULWindow **_retval)
|
nsIXULWindow **_retval)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(_retval);
|
NS_ENSURE_ARG_POINTER(_retval);
|
||||||
|
|
||||||
if (aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)
|
if (aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)
|
||||||
return CreateNewChromeWindow(aChromeFlags, aOpeningTab, _retval);
|
return CreateNewChromeWindow(aChromeFlags, aOpeningTab, aOpener, _retval);
|
||||||
return CreateNewContentWindow(aChromeFlags, aOpeningTab, _retval);
|
return CreateNewContentWindow(aChromeFlags, aOpeningTab, aOpener, _retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags,
|
NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags,
|
||||||
nsITabParent *aOpeningTab,
|
nsITabParent *aOpeningTab,
|
||||||
|
mozIDOMWindowProxy *aOpener,
|
||||||
nsIXULWindow **_retval)
|
nsIXULWindow **_retval)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
||||||
NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
// Just do a normal create of a window and return.
|
// Just do a normal create of a window and return.
|
||||||
|
|
||||||
nsCOMPtr<nsIXULWindow> newWindow;
|
nsCOMPtr<nsIXULWindow> newWindow;
|
||||||
appShell->CreateTopLevelWindow(this, nullptr, aChromeFlags,
|
appShell->CreateTopLevelWindow(this, nullptr, aChromeFlags,
|
||||||
nsIAppShellService::SIZE_TO_CONTENT,
|
nsIAppShellService::SIZE_TO_CONTENT,
|
||||||
nsIAppShellService::SIZE_TO_CONTENT,
|
nsIAppShellService::SIZE_TO_CONTENT,
|
||||||
aOpeningTab,
|
aOpeningTab, aOpener,
|
||||||
getter_AddRefs(newWindow));
|
getter_AddRefs(newWindow));
|
||||||
|
|
||||||
NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
|
||||||
|
@ -1955,6 +1956,7 @@ NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags,
|
||||||
|
|
||||||
NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
|
NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
|
||||||
nsITabParent *aOpeningTab,
|
nsITabParent *aOpeningTab,
|
||||||
|
mozIDOMWindowProxy *aOpener,
|
||||||
nsIXULWindow **_retval)
|
nsIXULWindow **_retval)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
||||||
|
@ -1985,9 +1987,12 @@ NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
|
||||||
nsCOMPtr<nsIXULWindow> newWindow;
|
nsCOMPtr<nsIXULWindow> newWindow;
|
||||||
{
|
{
|
||||||
AutoNoJSAPI nojsapi;
|
AutoNoJSAPI nojsapi;
|
||||||
|
// We actually want this toplevel window which we are creating to have a
|
||||||
|
// null opener, as we will be creating the content xul:browser window inside
|
||||||
|
// of it, so we pass nullptr as our aOpener.
|
||||||
appShell->CreateTopLevelWindow(this, uri,
|
appShell->CreateTopLevelWindow(this, uri,
|
||||||
aChromeFlags, 615, 480,
|
aChromeFlags, 615, 480,
|
||||||
aOpeningTab,
|
aOpeningTab, nullptr,
|
||||||
getter_AddRefs(newWindow));
|
getter_AddRefs(newWindow));
|
||||||
NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -1997,6 +2002,17 @@ NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
|
||||||
(static_cast<nsIXULWindow*>
|
(static_cast<nsIXULWindow*>
|
||||||
(newWindow));
|
(newWindow));
|
||||||
|
|
||||||
|
if (aOpener) {
|
||||||
|
nsCOMPtr<nsIDocShell> docShell;
|
||||||
|
xulWin->GetDocShell(getter_AddRefs(docShell));
|
||||||
|
MOZ_ASSERT(docShell);
|
||||||
|
nsCOMPtr<nsIDOMChromeWindow> chromeWindow =
|
||||||
|
do_QueryInterface(docShell->GetWindow());
|
||||||
|
MOZ_ASSERT(chromeWindow);
|
||||||
|
|
||||||
|
chromeWindow->SetOpenerForInitialContentBrowser(aOpener);
|
||||||
|
}
|
||||||
|
|
||||||
xulWin->LockUntilChromeLoad();
|
xulWin->LockUntilChromeLoad();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -121,8 +121,8 @@ protected:
|
||||||
NS_IMETHOD SizeShellTo(nsIDocShellTreeItem* aShellItem, int32_t aCX,
|
NS_IMETHOD SizeShellTo(nsIDocShellTreeItem* aShellItem, int32_t aCX,
|
||||||
int32_t aCY);
|
int32_t aCY);
|
||||||
NS_IMETHOD ExitModalLoop(nsresult aStatus);
|
NS_IMETHOD ExitModalLoop(nsresult aStatus);
|
||||||
NS_IMETHOD CreateNewChromeWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, nsIXULWindow **_retval);
|
NS_IMETHOD CreateNewChromeWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, mozIDOMWindowProxy* aOpenerWindow, nsIXULWindow **_retval);
|
||||||
NS_IMETHOD CreateNewContentWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, nsIXULWindow **_retval);
|
NS_IMETHOD CreateNewContentWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, mozIDOMWindowProxy* aOpenerWindow, nsIXULWindow **_retval);
|
||||||
NS_IMETHOD GetHasPrimaryContent(bool* aResult);
|
NS_IMETHOD GetHasPrimaryContent(bool* aResult);
|
||||||
|
|
||||||
void EnableParent(bool aEnable);
|
void EnableParent(bool aEnable);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче