forked from mirrors/gecko-dev
Bug 1681457 - Allow non-auxiliary BrowsingContexts created by script to close themselves, r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D211792
This commit is contained in:
parent
a2741562b7
commit
524e4f032a
19 changed files with 143 additions and 44 deletions
|
|
@ -325,7 +325,7 @@ bool BrowsingContext::SameOriginWithTop() {
|
||||||
already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
|
already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
|
||||||
nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
|
nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
|
||||||
BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
|
BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
|
||||||
bool aIsPopupRequested, bool aCreatedDynamically) {
|
CreateDetachedOptions aOptions) {
|
||||||
if (aParent) {
|
if (aParent) {
|
||||||
MOZ_DIAGNOSTIC_ASSERT(aParent->GetWindowContext());
|
MOZ_DIAGNOSTIC_ASSERT(aParent->GetWindowContext());
|
||||||
MOZ_DIAGNOSTIC_ASSERT(aParent->GetBrowsingContext()->mType == aType);
|
MOZ_DIAGNOSTIC_ASSERT(aParent->GetBrowsingContext()->mType == aType);
|
||||||
|
|
@ -461,7 +461,10 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
|
||||||
fields.Get<IDX_AllowJavascript>() =
|
fields.Get<IDX_AllowJavascript>() =
|
||||||
inherit ? inherit->GetAllowJavascript() : true;
|
inherit ? inherit->GetAllowJavascript() : true;
|
||||||
|
|
||||||
fields.Get<IDX_IsPopupRequested>() = aIsPopupRequested;
|
fields.Get<IDX_IsPopupRequested>() = aOptions.isPopupRequested;
|
||||||
|
|
||||||
|
fields.Get<IDX_TopLevelCreatedByWebContent>() =
|
||||||
|
aOptions.topLevelCreatedByWebContent;
|
||||||
|
|
||||||
if (!parentBC) {
|
if (!parentBC) {
|
||||||
fields.Get<IDX_ShouldDelayMediaFromStart>() =
|
fields.Get<IDX_ShouldDelayMediaFromStart>() =
|
||||||
|
|
@ -480,7 +483,7 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
|
||||||
}
|
}
|
||||||
|
|
||||||
context->mEmbeddedByThisProcess = XRE_IsParentProcess() || aParent;
|
context->mEmbeddedByThisProcess = XRE_IsParentProcess() || aParent;
|
||||||
context->mCreatedDynamically = aCreatedDynamically;
|
context->mCreatedDynamically = aOptions.createdDynamically;
|
||||||
if (inherit) {
|
if (inherit) {
|
||||||
context->mPrivateBrowsingId = inherit->mPrivateBrowsingId;
|
context->mPrivateBrowsingId = inherit->mPrivateBrowsingId;
|
||||||
context->mUseRemoteTabs = inherit->mUseRemoteTabs;
|
context->mUseRemoteTabs = inherit->mUseRemoteTabs;
|
||||||
|
|
@ -507,7 +510,7 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateIndependent(
|
||||||
"BCs created in the content process must be related to "
|
"BCs created in the content process must be related to "
|
||||||
"some BrowserChild");
|
"some BrowserChild");
|
||||||
RefPtr<BrowsingContext> bc(
|
RefPtr<BrowsingContext> bc(
|
||||||
CreateDetached(nullptr, nullptr, nullptr, u""_ns, aType, false));
|
CreateDetached(nullptr, nullptr, nullptr, u""_ns, aType, {}));
|
||||||
bc->mWindowless = bc->IsContent();
|
bc->mWindowless = bc->IsContent();
|
||||||
bc->mEmbeddedByThisProcess = true;
|
bc->mEmbeddedByThisProcess = true;
|
||||||
bc->EnsureAttached();
|
bc->EnsureAttached();
|
||||||
|
|
@ -3162,8 +3165,8 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_UseGlobalHistory>,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto BrowsingContext::CanSet(FieldIndex<IDX_UserAgentOverride>,
|
auto BrowsingContext::CanSet(FieldIndex<IDX_UserAgentOverride>,
|
||||||
const nsString& aUserAgent, ContentParent* aSource)
|
const nsString& aUserAgent,
|
||||||
-> CanSetResult {
|
ContentParent* aSource) -> CanSetResult {
|
||||||
if (!IsTop()) {
|
if (!IsTop()) {
|
||||||
return CanSetResult::Deny;
|
return CanSetResult::Deny;
|
||||||
}
|
}
|
||||||
|
|
@ -3172,8 +3175,8 @@ auto BrowsingContext::CanSet(FieldIndex<IDX_UserAgentOverride>,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto BrowsingContext::CanSet(FieldIndex<IDX_PlatformOverride>,
|
auto BrowsingContext::CanSet(FieldIndex<IDX_PlatformOverride>,
|
||||||
const nsString& aPlatform, ContentParent* aSource)
|
const nsString& aPlatform,
|
||||||
-> CanSetResult {
|
ContentParent* aSource) -> CanSetResult {
|
||||||
if (!IsTop()) {
|
if (!IsTop()) {
|
||||||
return CanSetResult::Deny;
|
return CanSetResult::Deny;
|
||||||
}
|
}
|
||||||
|
|
@ -3207,8 +3210,8 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_EmbedderElementType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto BrowsingContext::CanSet(FieldIndex<IDX_CurrentInnerWindowId>,
|
auto BrowsingContext::CanSet(FieldIndex<IDX_CurrentInnerWindowId>,
|
||||||
const uint64_t& aValue, ContentParent* aSource)
|
const uint64_t& aValue,
|
||||||
-> CanSetResult {
|
ContentParent* aSource) -> CanSetResult {
|
||||||
// Generally allow clearing this. We may want to be more precise about this
|
// Generally allow clearing this. We may want to be more precise about this
|
||||||
// check in the future.
|
// check in the future.
|
||||||
if (aValue == 0) {
|
if (aValue == 0) {
|
||||||
|
|
@ -3534,6 +3537,12 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_PendingInitialization>,
|
||||||
return IsTop() && GetPendingInitialization() && !aNewValue;
|
return IsTop() && GetPendingInitialization() && !aNewValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BrowsingContext::CanSet(FieldIndex<IDX_TopLevelCreatedByWebContent>,
|
||||||
|
const bool& aNewValue, ContentParent* aSource) {
|
||||||
|
// Should only be set after creation in the parent process.
|
||||||
|
return XRE_IsParentProcess() && !aSource && IsTop();
|
||||||
|
}
|
||||||
|
|
||||||
bool BrowsingContext::CanSet(FieldIndex<IDX_HasRestoreData>, bool aNewValue,
|
bool BrowsingContext::CanSet(FieldIndex<IDX_HasRestoreData>, bool aNewValue,
|
||||||
ContentParent* aSource) {
|
ContentParent* aSource) {
|
||||||
return IsTop();
|
return IsTop();
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,10 @@ struct EmbedderColorSchemes {
|
||||||
FIELD(EmbedderInnerWindowId, uint64_t) \
|
FIELD(EmbedderInnerWindowId, uint64_t) \
|
||||||
FIELD(CurrentInnerWindowId, uint64_t) \
|
FIELD(CurrentInnerWindowId, uint64_t) \
|
||||||
FIELD(HadOriginalOpener, bool) \
|
FIELD(HadOriginalOpener, bool) \
|
||||||
|
/* Was this window created by a webpage through window.open or an anchor \
|
||||||
|
* link? In general, windows created this way may be manipulated (e.g. \
|
||||||
|
* closed, resized or moved) by content JS. */ \
|
||||||
|
FIELD(TopLevelCreatedByWebContent, bool) \
|
||||||
FIELD(IsPopupSpam, bool) \
|
FIELD(IsPopupSpam, bool) \
|
||||||
/* Hold the audio muted state and should be used on top level browsing \
|
/* Hold the audio muted state and should be used on top level browsing \
|
||||||
* contexts only */ \
|
* contexts only */ \
|
||||||
|
|
@ -331,6 +335,13 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
||||||
// it.
|
// it.
|
||||||
static already_AddRefed<BrowsingContext> CreateIndependent(Type aType);
|
static already_AddRefed<BrowsingContext> CreateIndependent(Type aType);
|
||||||
|
|
||||||
|
// Options which can be passed to CreateDetached.
|
||||||
|
struct CreateDetachedOptions {
|
||||||
|
bool isPopupRequested = false;
|
||||||
|
bool createdDynamically = false;
|
||||||
|
bool topLevelCreatedByWebContent = false;
|
||||||
|
};
|
||||||
|
|
||||||
// Create a brand-new BrowsingContext object, but does not immediately attach
|
// Create a brand-new BrowsingContext object, but does not immediately attach
|
||||||
// it. State such as OriginAttributes and PrivateBrowsingId may be customized
|
// it. State such as OriginAttributes and PrivateBrowsingId may be customized
|
||||||
// to configure the BrowsingContext before it is attached.
|
// to configure the BrowsingContext before it is attached.
|
||||||
|
|
@ -340,7 +351,7 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
||||||
static already_AddRefed<BrowsingContext> CreateDetached(
|
static already_AddRefed<BrowsingContext> CreateDetached(
|
||||||
nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
|
nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
|
||||||
BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
|
BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
|
||||||
bool aIsPopupRequested, bool aCreatedDynamically = false);
|
CreateDetachedOptions aOptions);
|
||||||
|
|
||||||
void EnsureAttached();
|
void EnsureAttached();
|
||||||
|
|
||||||
|
|
@ -1211,6 +1222,9 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
||||||
bool CanSet(FieldIndex<IDX_PendingInitialization>, bool aNewValue,
|
bool CanSet(FieldIndex<IDX_PendingInitialization>, bool aNewValue,
|
||||||
ContentParent* aSource);
|
ContentParent* aSource);
|
||||||
|
|
||||||
|
bool CanSet(FieldIndex<IDX_TopLevelCreatedByWebContent>,
|
||||||
|
const bool& aNewValue, ContentParent* aSource);
|
||||||
|
|
||||||
bool CanSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aNewValue,
|
bool CanSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aNewValue,
|
||||||
ContentParent* aSource);
|
ContentParent* aSource);
|
||||||
void DidSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aOldValue);
|
void DidSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aOldValue);
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,7 @@ void CanonicalBrowsingContext::ReplacedBy(
|
||||||
txn.SetBrowserId(GetBrowserId());
|
txn.SetBrowserId(GetBrowserId());
|
||||||
txn.SetIsAppTab(GetIsAppTab());
|
txn.SetIsAppTab(GetIsAppTab());
|
||||||
txn.SetHasSiblings(GetHasSiblings());
|
txn.SetHasSiblings(GetHasSiblings());
|
||||||
|
txn.SetTopLevelCreatedByWebContent(GetTopLevelCreatedByWebContent());
|
||||||
txn.SetHistoryID(GetHistoryID());
|
txn.SetHistoryID(GetHistoryID());
|
||||||
txn.SetExplicitActive(GetExplicitActive());
|
txn.SetExplicitActive(GetExplicitActive());
|
||||||
txn.SetEmbedderColorSchemes(GetEmbedderColorSchemes());
|
txn.SetEmbedderColorSchemes(GetEmbedderColorSchemes());
|
||||||
|
|
|
||||||
|
|
@ -18980,7 +18980,7 @@ bool Document::IsLikelyContentInaccessibleTopLevelAboutBlank() const {
|
||||||
// really reliable but doesn't affect the correctness of our page probes, so
|
// really reliable but doesn't affect the correctness of our page probes, so
|
||||||
// it's not too terrible.
|
// it's not too terrible.
|
||||||
BrowsingContext* bc = GetBrowsingContext();
|
BrowsingContext* bc = GetBrowsingContext();
|
||||||
return bc && bc->IsTop() && !bc->HadOriginalOpener();
|
return bc && bc->IsTop() && !bc->GetTopLevelCreatedByWebContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Document::ShouldIncludeInTelemetry() const {
|
bool Document::ShouldIncludeInTelemetry() const {
|
||||||
|
|
|
||||||
|
|
@ -337,10 +337,16 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
|
||||||
// it will wind up attached as a child of the currently active inner window
|
// it will wind up attached as a child of the currently active inner window
|
||||||
// for the BrowsingContext, and cause no end of trouble.
|
// for the BrowsingContext, and cause no end of trouble.
|
||||||
if (IsTopContent(parentBC, aOwner)) {
|
if (IsTopContent(parentBC, aOwner)) {
|
||||||
|
BrowsingContext::CreateDetachedOptions options;
|
||||||
|
if (aOpenWindowInfo) {
|
||||||
|
options.topLevelCreatedByWebContent =
|
||||||
|
aOpenWindowInfo->GetIsTopLevelCreatedByWebContent();
|
||||||
|
}
|
||||||
|
|
||||||
// Create toplevel context without a parent & as Type::Content.
|
// Create toplevel context without a parent & as Type::Content.
|
||||||
return BrowsingContext::CreateDetached(
|
return BrowsingContext::CreateDetached(
|
||||||
nullptr, opener, aSpecificGroup, frameName,
|
nullptr, opener, aSpecificGroup, frameName,
|
||||||
BrowsingContext::Type::Content, false);
|
BrowsingContext::Type::Content, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(!aOpenWindowInfo,
|
MOZ_ASSERT(!aOpenWindowInfo,
|
||||||
|
|
@ -348,9 +354,9 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
|
||||||
|
|
||||||
MOZ_ASSERT(!aSpecificGroup,
|
MOZ_ASSERT(!aSpecificGroup,
|
||||||
"Can't force BrowsingContextGroup for non-toplevel context");
|
"Can't force BrowsingContextGroup for non-toplevel context");
|
||||||
return BrowsingContext::CreateDetached(parentInner, nullptr, nullptr,
|
return BrowsingContext::CreateDetached(
|
||||||
frameName, parentBC->GetType(), false,
|
parentInner, nullptr, nullptr, frameName, parentBC->GetType(),
|
||||||
!aNetworkCreated);
|
{.createdDynamically = !aNetworkCreated});
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool InitialLoadIsRemote(Element* aOwner) {
|
static bool InitialLoadIsRemote(Element* aOwner) {
|
||||||
|
|
|
||||||
|
|
@ -4642,7 +4642,7 @@ bool nsGlobalWindowOuter::CanMoveResizeWindows(CallerType aCallerType) {
|
||||||
if (aCallerType != CallerType::System) {
|
if (aCallerType != CallerType::System) {
|
||||||
// Don't allow scripts to move or resize windows that were not opened by a
|
// Don't allow scripts to move or resize windows that were not opened by a
|
||||||
// script.
|
// script.
|
||||||
if (!mBrowsingContext->HadOriginalOpener()) {
|
if (!mBrowsingContext->GetTopLevelCreatedByWebContent()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6001,8 +6001,8 @@ void nsGlobalWindowOuter::CloseOuter(bool aTrustedCaller) {
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
NS_ENSURE_SUCCESS_VOID(rv);
|
||||||
|
|
||||||
if (!StringBeginsWith(url, u"about:neterror"_ns) &&
|
if (!StringBeginsWith(url, u"about:neterror"_ns) &&
|
||||||
!mBrowsingContext->HadOriginalOpener() && !aTrustedCaller &&
|
!mBrowsingContext->GetTopLevelCreatedByWebContent() &&
|
||||||
!IsOnlyTopLevelDocumentInSHistory()) {
|
!aTrustedCaller && !IsOnlyTopLevelDocumentInSHistory()) {
|
||||||
bool allowClose =
|
bool allowClose =
|
||||||
mAllowScriptsToClose ||
|
mAllowScriptsToClose ||
|
||||||
Preferences::GetBool("dom.allow_scripts_to_close_windows", true);
|
Preferences::GetBool("dom.allow_scripts_to_close_windows", true);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
type: windowopen,
|
type: windowopen,
|
||||||
noopener: true,
|
noopener: true,
|
||||||
shouldCloseWithoutHistory: true,
|
shouldCloseWithoutHistory: true,
|
||||||
shouldCloseWithHistory: false
|
shouldCloseWithHistory: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: windowopen,
|
type: windowopen,
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
type: link,
|
type: link,
|
||||||
noopener: true,
|
noopener: true,
|
||||||
shouldCloseWithoutHistory: true,
|
shouldCloseWithoutHistory: true,
|
||||||
shouldCloseWithHistory: false
|
shouldCloseWithHistory: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: link,
|
type: link,
|
||||||
|
|
|
||||||
|
|
@ -1034,7 +1034,8 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!nsContentUtils::IsSpecialName(name));
|
MOZ_DIAGNOSTIC_ASSERT(!nsContentUtils::IsSpecialName(name));
|
||||||
|
|
||||||
Unused << SendCreateWindowInDifferentProcess(
|
Unused << SendCreateWindowInDifferentProcess(
|
||||||
aTabOpener, parent, aChromeFlags, aCalledFromJS, aURI, features,
|
aTabOpener, parent, aChromeFlags, aCalledFromJS,
|
||||||
|
aOpenWindowInfo->GetIsTopLevelCreatedByWebContent(), aURI, features,
|
||||||
aModifiers, name, triggeringPrincipal, csp, referrerInfo,
|
aModifiers, name, triggeringPrincipal, csp, referrerInfo,
|
||||||
aOpenWindowInfo->GetOriginAttributes());
|
aOpenWindowInfo->GetOriginAttributes());
|
||||||
|
|
||||||
|
|
@ -1056,7 +1057,8 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||||
|
|
||||||
RefPtr<BrowsingContext> browsingContext = BrowsingContext::CreateDetached(
|
RefPtr<BrowsingContext> browsingContext = BrowsingContext::CreateDetached(
|
||||||
nullptr, openerBC, nullptr, aName, BrowsingContext::Type::Content,
|
nullptr, openerBC, nullptr, aName, BrowsingContext::Type::Content,
|
||||||
aIsPopupRequested);
|
{.isPopupRequested = aIsPopupRequested,
|
||||||
|
.topLevelCreatedByWebContent = true});
|
||||||
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetRemoteTabs(true));
|
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetRemoteTabs(true));
|
||||||
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetRemoteSubframes(useRemoteSubframes));
|
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetRemoteSubframes(useRemoteSubframes));
|
||||||
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetOriginAttributes(
|
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetOriginAttributes(
|
||||||
|
|
@ -1181,9 +1183,11 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||||
|
|
||||||
if (aForceNoOpener || !parent) {
|
if (aForceNoOpener || !parent) {
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!browsingContext->HadOriginalOpener());
|
MOZ_DIAGNOSTIC_ASSERT(!browsingContext->HadOriginalOpener());
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetTopLevelCreatedByWebContent());
|
||||||
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetOpenerId() == 0);
|
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetOpenerId() == 0);
|
||||||
} else {
|
} else {
|
||||||
MOZ_DIAGNOSTIC_ASSERT(browsingContext->HadOriginalOpener());
|
MOZ_DIAGNOSTIC_ASSERT(browsingContext->HadOriginalOpener());
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetTopLevelCreatedByWebContent());
|
||||||
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetOpenerId() == parent->Id());
|
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetOpenerId() == parent->Id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1236,8 +1240,9 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||||
|
|
||||||
SendCreateWindow(aTabOpener, parent, newChild, aChromeFlags, aCalledFromJS,
|
SendCreateWindow(aTabOpener, parent, newChild, aChromeFlags, aCalledFromJS,
|
||||||
aOpenWindowInfo->GetIsForPrinting(),
|
aOpenWindowInfo->GetIsForPrinting(),
|
||||||
aOpenWindowInfo->GetIsForWindowDotPrint(), aURI, features,
|
aOpenWindowInfo->GetIsForWindowDotPrint(),
|
||||||
aModifiers, triggeringPrincipal, csp, referrerInfo,
|
aOpenWindowInfo->GetIsTopLevelCreatedByWebContent(), aURI,
|
||||||
|
features, aModifiers, triggeringPrincipal, csp, referrerInfo,
|
||||||
aOpenWindowInfo->GetOriginAttributes(), std::move(resolve),
|
aOpenWindowInfo->GetOriginAttributes(), std::move(resolve),
|
||||||
std::move(reject));
|
std::move(reject));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5567,8 +5567,8 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
|
||||||
PBrowserParent* aThisTab, BrowsingContext& aParent, bool aSetOpener,
|
PBrowserParent* aThisTab, BrowsingContext& aParent, bool aSetOpener,
|
||||||
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
|
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
|
||||||
const bool& aForPrinting, const bool& aForWindowDotPrint,
|
const bool& aForPrinting, const bool& aForWindowDotPrint,
|
||||||
nsIURI* aURIToLoad, const nsACString& aFeatures,
|
const bool& aIsTopLevelCreatedByWebContent, nsIURI* aURIToLoad,
|
||||||
const UserActivation::Modifiers& aModifiers,
|
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
|
||||||
BrowserParent* aNextRemoteBrowser, const nsAString& aName,
|
BrowserParent* aNextRemoteBrowser, const nsAString& aName,
|
||||||
nsresult& aResult, nsCOMPtr<nsIRemoteTab>& aNewRemoteTab,
|
nsresult& aResult, nsCOMPtr<nsIRemoteTab>& aNewRemoteTab,
|
||||||
bool* aWindowIsNew, int32_t& aOpenLocation,
|
bool* aWindowIsNew, int32_t& aOpenLocation,
|
||||||
|
|
@ -5592,6 +5592,7 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
|
||||||
openInfo->mIsForWindowDotPrint = aForWindowDotPrint;
|
openInfo->mIsForWindowDotPrint = aForWindowDotPrint;
|
||||||
openInfo->mNextRemoteBrowser = aNextRemoteBrowser;
|
openInfo->mNextRemoteBrowser = aNextRemoteBrowser;
|
||||||
openInfo->mOriginAttributes = aOriginAttributes;
|
openInfo->mOriginAttributes = aOriginAttributes;
|
||||||
|
openInfo->mIsTopLevelCreatedByWebContent = aIsTopLevelCreatedByWebContent;
|
||||||
|
|
||||||
MOZ_ASSERT_IF(aForWindowDotPrint, aForPrinting);
|
MOZ_ASSERT_IF(aForWindowDotPrint, aForPrinting);
|
||||||
|
|
||||||
|
|
@ -5794,8 +5795,9 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindow(
|
||||||
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
|
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
|
||||||
PBrowserParent* aNewTab, const uint32_t& aChromeFlags,
|
PBrowserParent* aNewTab, const uint32_t& aChromeFlags,
|
||||||
const bool& aCalledFromJS, const bool& aForPrinting,
|
const bool& aCalledFromJS, const bool& aForPrinting,
|
||||||
const bool& aForWindowDotPrint, nsIURI* aURIToLoad,
|
const bool& aForWindowDotPrint, const bool& aIsTopLevelCreatedByWebContent,
|
||||||
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
|
nsIURI* aURIToLoad, const nsACString& aFeatures,
|
||||||
|
const UserActivation::Modifiers& aModifiers,
|
||||||
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
|
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
|
||||||
nsIReferrerInfo* aReferrerInfo, const OriginAttributes& aOriginAttributes,
|
nsIReferrerInfo* aReferrerInfo, const OriginAttributes& aOriginAttributes,
|
||||||
CreateWindowResolver&& aResolve) {
|
CreateWindowResolver&& aResolve) {
|
||||||
|
|
@ -5880,10 +5882,10 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindow(
|
||||||
int32_t openLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;
|
int32_t openLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;
|
||||||
mozilla::ipc::IPCResult ipcResult = CommonCreateWindow(
|
mozilla::ipc::IPCResult ipcResult = CommonCreateWindow(
|
||||||
aThisTab, *parent, newBCOpenerId != 0, aChromeFlags, aCalledFromJS,
|
aThisTab, *parent, newBCOpenerId != 0, aChromeFlags, aCalledFromJS,
|
||||||
aForPrinting, aForWindowDotPrint, aURIToLoad, aFeatures, aModifiers,
|
aForPrinting, aForWindowDotPrint, aIsTopLevelCreatedByWebContent,
|
||||||
newTab, VoidString(), rv, newRemoteTab, &cwi.windowOpened(), openLocation,
|
aURIToLoad, aFeatures, aModifiers, newTab, VoidString(), rv, newRemoteTab,
|
||||||
aTriggeringPrincipal, aReferrerInfo, /* aLoadUri = */ false, aCsp,
|
&cwi.windowOpened(), openLocation, aTriggeringPrincipal, aReferrerInfo,
|
||||||
aOriginAttributes);
|
/* aLoadUri = */ false, aCsp, aOriginAttributes);
|
||||||
if (!ipcResult) {
|
if (!ipcResult) {
|
||||||
return ipcResult;
|
return ipcResult;
|
||||||
}
|
}
|
||||||
|
|
@ -5916,7 +5918,8 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindow(
|
||||||
|
|
||||||
mozilla::ipc::IPCResult ContentParent::RecvCreateWindowInDifferentProcess(
|
mozilla::ipc::IPCResult ContentParent::RecvCreateWindowInDifferentProcess(
|
||||||
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
|
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
|
||||||
const uint32_t& aChromeFlags, const bool& aCalledFromJS, nsIURI* aURIToLoad,
|
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
|
||||||
|
const bool& aIsTopLevelCreatedByWebContent, nsIURI* aURIToLoad,
|
||||||
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
|
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
|
||||||
const nsAString& aName, nsIPrincipal* aTriggeringPrincipal,
|
const nsAString& aName, nsIPrincipal* aTriggeringPrincipal,
|
||||||
nsIContentSecurityPolicy* aCsp, nsIReferrerInfo* aReferrerInfo,
|
nsIContentSecurityPolicy* aCsp, nsIReferrerInfo* aReferrerInfo,
|
||||||
|
|
@ -5962,7 +5965,8 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindowInDifferentProcess(
|
||||||
mozilla::ipc::IPCResult ipcResult = CommonCreateWindow(
|
mozilla::ipc::IPCResult ipcResult = CommonCreateWindow(
|
||||||
aThisTab, *parent, /* aSetOpener = */ false, aChromeFlags, aCalledFromJS,
|
aThisTab, *parent, /* aSetOpener = */ false, aChromeFlags, aCalledFromJS,
|
||||||
/* aForPrinting = */ false,
|
/* aForPrinting = */ false,
|
||||||
/* aForPrintPreview = */ false, aURIToLoad, aFeatures, aModifiers,
|
/* aForWindowDotPrint = */ false, aIsTopLevelCreatedByWebContent,
|
||||||
|
aURIToLoad, aFeatures, aModifiers,
|
||||||
/* aNextRemoteBrowser = */ nullptr, aName, rv, newRemoteTab, &windowIsNew,
|
/* aNextRemoteBrowser = */ nullptr, aName, rv, newRemoteTab, &windowIsNew,
|
||||||
openLocation, aTriggeringPrincipal, aReferrerInfo,
|
openLocation, aTriggeringPrincipal, aReferrerInfo,
|
||||||
/* aLoadUri = */ true, aCsp, aOriginAttributes);
|
/* aLoadUri = */ true, aCsp, aOriginAttributes);
|
||||||
|
|
|
||||||
|
|
@ -474,8 +474,9 @@ class ContentParent final : public PContentParent,
|
||||||
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
|
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
|
||||||
PBrowserParent* aNewTab, const uint32_t& aChromeFlags,
|
PBrowserParent* aNewTab, const uint32_t& aChromeFlags,
|
||||||
const bool& aCalledFromJS, const bool& aForPrinting,
|
const bool& aCalledFromJS, const bool& aForPrinting,
|
||||||
const bool& aForWindowDotPrint, nsIURI* aURIToLoad,
|
const bool& aForWindowDotPrint, const bool& aTopLevelCreatedByWebContent,
|
||||||
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
|
nsIURI* aURIToLoad, const nsACString& aFeatures,
|
||||||
|
const UserActivation::Modifiers& aModifiers,
|
||||||
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
|
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
|
||||||
nsIReferrerInfo* aReferrerInfo, const OriginAttributes& aOriginAttributes,
|
nsIReferrerInfo* aReferrerInfo, const OriginAttributes& aOriginAttributes,
|
||||||
CreateWindowResolver&& aResolve);
|
CreateWindowResolver&& aResolve);
|
||||||
|
|
@ -483,10 +484,10 @@ class ContentParent final : public PContentParent,
|
||||||
mozilla::ipc::IPCResult RecvCreateWindowInDifferentProcess(
|
mozilla::ipc::IPCResult RecvCreateWindowInDifferentProcess(
|
||||||
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
|
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
|
||||||
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
|
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
|
||||||
nsIURI* aURIToLoad, const nsACString& aFeatures,
|
const bool& aTopLevelCreatedByWebContent, nsIURI* aURIToLoad,
|
||||||
const UserActivation::Modifiers& aModifiers, const nsAString& aName,
|
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
|
||||||
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
|
const nsAString& aName, nsIPrincipal* aTriggeringPrincipal,
|
||||||
nsIReferrerInfo* aReferrerInfo,
|
nsIContentSecurityPolicy* aCsp, nsIReferrerInfo* aReferrerInfo,
|
||||||
const OriginAttributes& aOriginAttributes);
|
const OriginAttributes& aOriginAttributes);
|
||||||
|
|
||||||
static void BroadcastBlobURLRegistration(
|
static void BroadcastBlobURLRegistration(
|
||||||
|
|
@ -700,8 +701,8 @@ class ContentParent final : public PContentParent,
|
||||||
PBrowserParent* aThisTab, BrowsingContext& aParent, bool aSetOpener,
|
PBrowserParent* aThisTab, BrowsingContext& aParent, bool aSetOpener,
|
||||||
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
|
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
|
||||||
const bool& aForPrinting, const bool& aForWindowDotPrint,
|
const bool& aForPrinting, const bool& aForWindowDotPrint,
|
||||||
nsIURI* aURIToLoad, const nsACString& aFeatures,
|
const bool& aIsTopLevelCreatedByWebContent, nsIURI* aURIToLoad,
|
||||||
const UserActivation::Modifiers& aModifiers,
|
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
|
||||||
BrowserParent* aNextRemoteBrowser, const nsAString& aName,
|
BrowserParent* aNextRemoteBrowser, const nsAString& aName,
|
||||||
nsresult& aResult, nsCOMPtr<nsIRemoteTab>& aNewRemoteTab,
|
nsresult& aResult, nsCOMPtr<nsIRemoteTab>& aNewRemoteTab,
|
||||||
bool* aWindowIsNew, int32_t& aOpenLocation,
|
bool* aWindowIsNew, int32_t& aOpenLocation,
|
||||||
|
|
|
||||||
|
|
@ -1533,6 +1533,7 @@ parent:
|
||||||
bool aCalledFromJS,
|
bool aCalledFromJS,
|
||||||
bool aForPrinting,
|
bool aForPrinting,
|
||||||
bool aForWindowDotPrint,
|
bool aForWindowDotPrint,
|
||||||
|
bool aTopLevelCreatedByContent,
|
||||||
nullable nsIURI aURIToLoad,
|
nullable nsIURI aURIToLoad,
|
||||||
nsCString aFeatures,
|
nsCString aFeatures,
|
||||||
Modifiers aModifiers,
|
Modifiers aModifiers,
|
||||||
|
|
@ -1547,6 +1548,7 @@ parent:
|
||||||
MaybeDiscardedBrowsingContext aParent,
|
MaybeDiscardedBrowsingContext aParent,
|
||||||
uint32_t aChromeFlags,
|
uint32_t aChromeFlags,
|
||||||
bool aCalledFromJS,
|
bool aCalledFromJS,
|
||||||
|
bool aTopLevelCreatedByContent,
|
||||||
nullable nsIURI aURIToLoad,
|
nullable nsIURI aURIToLoad,
|
||||||
nsCString aFeatures,
|
nsCString aFeatures,
|
||||||
Modifiers aModifiers,
|
Modifiers aModifiers,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<!doctype html>
|
||||||
|
<script>
|
||||||
|
let chan = new BroadcastChannel("close_noopener_beforeunload" + location.search);
|
||||||
|
onload = function() { window.close(); };
|
||||||
|
onbeforeunload = function() {
|
||||||
|
chan.postMessage({ name: "beforeunload", history: history.length });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<!doctype html>
|
||||||
|
<script>
|
||||||
|
onload = function() {
|
||||||
|
setTimeout(() => window.location = "close_noopener_beforeunload-1.html" + location.search, 0);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
<!doctype html>
|
||||||
|
<title>Running beforeunload handler in window.close() for noopener window</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
async_test(t => {
|
||||||
|
window.open("close_noopener_beforeunload-2.html?2", "", "noopener");
|
||||||
|
let chan = new BroadcastChannel("close_noopener_beforeunload?2");
|
||||||
|
chan.onmessage = t.step_func_done(function(event) {
|
||||||
|
assert_equals(event.data.name, "beforeunload", "correct message received");
|
||||||
|
assert_equals(event.data.history, 2, "session history has multiple entries");
|
||||||
|
});
|
||||||
|
}, "closing noopener window with 2 entries");
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
window.open("close_noopener_beforeunload-1.html?1", "", "noopener");
|
||||||
|
let chan = new BroadcastChannel("close_noopener_beforeunload?1");
|
||||||
|
chan.onmessage = t.step_func_done(function(event) {
|
||||||
|
assert_equals(event.data.name, "beforeunload", "correct message received");
|
||||||
|
assert_equals(event.data.history, 1, "session history has a single entry");
|
||||||
|
});
|
||||||
|
}, "closing noopener window with 1 entry");
|
||||||
|
</script>
|
||||||
|
|
@ -60,6 +60,10 @@ interface nsIOpenWindowInfo : nsISupports {
|
||||||
[infallible]
|
[infallible]
|
||||||
readonly attribute boolean isForWindowDotPrint;
|
readonly attribute boolean isForWindowDotPrint;
|
||||||
|
|
||||||
|
/** Whether this new window creation was prompted by web content */
|
||||||
|
[infallible]
|
||||||
|
readonly attribute boolean isTopLevelCreatedByWebContent;
|
||||||
|
|
||||||
/** BrowserParent instance to use in the new window */
|
/** BrowserParent instance to use in the new window */
|
||||||
[notxpcom, nostdcall]
|
[notxpcom, nostdcall]
|
||||||
BrowserParent getNextRemoteBrowser();
|
BrowserParent getNextRemoteBrowser();
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,12 @@ NS_IMETHODIMP nsOpenWindowInfo::GetForceNoOpener(bool* aForceNoOpener) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsOpenWindowInfo::GetIsTopLevelCreatedByWebContent(
|
||||||
|
bool* aIsTopLevelCreatedByWebContent) {
|
||||||
|
*aIsTopLevelCreatedByWebContent = mIsTopLevelCreatedByWebContent;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsOpenWindowInfo::GetScriptableOriginAttributes(
|
NS_IMETHODIMP nsOpenWindowInfo::GetScriptableOriginAttributes(
|
||||||
JSContext* aCx, JS::MutableHandle<JS::Value> aAttrs) {
|
JSContext* aCx, JS::MutableHandle<JS::Value> aAttrs) {
|
||||||
bool ok = ToJSValue(aCx, mOriginAttributes, aAttrs);
|
bool ok = ToJSValue(aCx, mOriginAttributes, aAttrs);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ class nsOpenWindowInfo : public nsIOpenWindowInfo {
|
||||||
bool mIsRemote = false;
|
bool mIsRemote = false;
|
||||||
bool mIsForPrinting = false;
|
bool mIsForPrinting = false;
|
||||||
bool mIsForWindowDotPrint = false;
|
bool mIsForWindowDotPrint = false;
|
||||||
|
bool mIsTopLevelCreatedByWebContent = false;
|
||||||
RefPtr<mozilla::dom::BrowserParent> mNextRemoteBrowser;
|
RefPtr<mozilla::dom::BrowserParent> mNextRemoteBrowser;
|
||||||
mozilla::OriginAttributes mOriginAttributes;
|
mozilla::OriginAttributes mOriginAttributes;
|
||||||
RefPtr<mozilla::dom::BrowsingContext> mParent;
|
RefPtr<mozilla::dom::BrowsingContext> mParent;
|
||||||
|
|
|
||||||
|
|
@ -884,6 +884,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
||||||
openWindowInfo->mParent = parentBC;
|
openWindowInfo->mParent = parentBC;
|
||||||
openWindowInfo->mIsForPrinting = aPrintKind != PRINT_NONE;
|
openWindowInfo->mIsForPrinting = aPrintKind != PRINT_NONE;
|
||||||
openWindowInfo->mIsForWindowDotPrint = aPrintKind == PRINT_WINDOW_DOT_PRINT;
|
openWindowInfo->mIsForWindowDotPrint = aPrintKind == PRINT_WINDOW_DOT_PRINT;
|
||||||
|
openWindowInfo->mIsTopLevelCreatedByWebContent =
|
||||||
|
!nsContentUtils::IsSystemOrExpandedPrincipal(subjectPrincipal);
|
||||||
|
|
||||||
// We're going to want the window to be immediately available, meaning we
|
// We're going to want the window to be immediately available, meaning we
|
||||||
// want it to match the current remoteness.
|
// want it to match the current remoteness.
|
||||||
|
|
@ -1077,6 +1079,12 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(
|
||||||
|
!windowIsNew || !targetBC->IsContent() ||
|
||||||
|
nsContentUtils::IsSystemOrExpandedPrincipal(subjectPrincipal) ||
|
||||||
|
targetBC->GetTopLevelCreatedByWebContent(),
|
||||||
|
"New BC not marked as created by web content, but it was");
|
||||||
|
|
||||||
// If our parent is sandboxed, set it as the one permitted sandboxed navigator
|
// If our parent is sandboxed, set it as the one permitted sandboxed navigator
|
||||||
// on the new window we're opening.
|
// on the new window we're opening.
|
||||||
if (activeDocsSandboxFlags && parentBC) {
|
if (activeDocsSandboxFlags && parentBC) {
|
||||||
|
|
|
||||||
|
|
@ -1061,7 +1061,7 @@ nsExternalHelperAppService::LoadURI(nsIURI* aURI,
|
||||||
|
|
||||||
// Also allow this load if the target is a toplevel BC and contains a
|
// Also allow this load if the target is a toplevel BC and contains a
|
||||||
// non-web-controlled about:blank document
|
// non-web-controlled about:blank document
|
||||||
if (bc->IsTop() && !bc->HadOriginalOpener() && wgp) {
|
if (bc->IsTop() && !bc->GetTopLevelCreatedByWebContent() && wgp) {
|
||||||
RefPtr<nsIURI> uri = wgp->GetDocumentURI();
|
RefPtr<nsIURI> uri = wgp->GetDocumentURI();
|
||||||
foundAccessibleFrame =
|
foundAccessibleFrame =
|
||||||
uri && uri->GetSpecOrDefault().EqualsLiteral("about:blank");
|
uri && uri->GetSpecOrDefault().EqualsLiteral("about:blank");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue