Bug 1701001 - Part 2: Add "is popup" field to browsing context. r=smaug

Add BrowsingContext::FieldValues.mIsPopupRequested, and pass "is popup"
value calculated before opening window/tab to BrowsingContext::CreateDetached.

Other code path that is unrelated to content-priv window.open uses the
default value false.

Differential Revision: https://phabricator.services.mozilla.com/D129411
This commit is contained in:
Tooru Fujisawa 2021-11-06 01:19:14 +00:00
Родитель f11f62dcaf
Коммит 4d7bcb01be
10 изменённых файлов: 55 добавлений и 30 удалений

Просмотреть файл

@ -294,7 +294,7 @@ bool BrowsingContext::SameOriginWithTop() {
already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
bool aCreatedDynamically) {
bool aIsPopupRequested, bool aCreatedDynamically) {
if (aParent) {
MOZ_DIAGNOSTIC_ASSERT(aParent->GetWindowContext());
MOZ_DIAGNOSTIC_ASSERT(aParent->GetBrowsingContext()->mType == aType);
@ -410,6 +410,8 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
fields.mAllowJavascript = inherit ? inherit->GetAllowJavascript() : true;
fields.mIsPopupRequested = aIsPopupRequested;
if (!parentBC) {
fields.mShouldDelayMediaFromStart =
StaticPrefs::media_block_autoplay_until_in_foreground();
@ -454,7 +456,7 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateIndependent(
"BCs created in the content process must be related to "
"some BrowserChild");
RefPtr<BrowsingContext> bc(
CreateDetached(nullptr, nullptr, nullptr, u""_ns, aType));
CreateDetached(nullptr, nullptr, nullptr, u""_ns, aType, false));
bc->mWindowless = bc->IsContent();
bc->mEmbeddedByThisProcess = true;
bc->EnsureAttached();

Просмотреть файл

@ -156,6 +156,14 @@ enum class ExplicitActiveStatus : uint8_t {
FIELD(ForceEnableTrackingProtection, bool) \
FIELD(UseGlobalHistory, bool) \
FIELD(FullscreenAllowedByOwner, bool) \
/* \
* "is popup" in the spec. \
* Set only on top browsing contexts. \
* This doesn't indicate whether this is actually a popup or not, \
* but whether this browsing context is created by requesting popup or not. \
* See also: nsWindowWatcher::ShouldOpenPopup. \
*/ \
FIELD(IsPopupRequested, bool) \
/* These field are used to store the states of autoplay media request on \
* GeckoView only, and it would only be modified on the top level browsing \
* context. */ \
@ -283,7 +291,7 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
static already_AddRefed<BrowsingContext> CreateDetached(
nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
bool aCreatedDynamically = false);
bool aIsPopupRequested, bool aCreatedDynamically = false);
void EnsureAttached();

Просмотреть файл

@ -345,9 +345,9 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
// for the BrowsingContext, and cause no end of trouble.
if (IsTopContent(parentBC, aOwner)) {
// Create toplevel context without a parent & as Type::Content.
return BrowsingContext::CreateDetached(nullptr, opener, aSpecificGroup,
frameName,
BrowsingContext::Type::Content);
return BrowsingContext::CreateDetached(
nullptr, opener, aSpecificGroup, frameName,
BrowsingContext::Type::Content, false);
}
MOZ_ASSERT(!aOpenWindowInfo,
@ -356,7 +356,7 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
MOZ_ASSERT(!aSpecificGroup,
"Can't force BrowsingContextGroup for non-toplevel context");
return BrowsingContext::CreateDetached(parentInner, nullptr, nullptr,
frameName, parentBC->GetType(),
frameName, parentBC->GetType(), false,
!aNetworkCreated);
}

Просмотреть файл

@ -818,7 +818,7 @@ BrowserChild::ProvideWindow(nsIOpenWindowInfo* aOpenWindowInfo,
uint32_t aChromeFlags, bool aCalledFromJS,
nsIURI* aURI, const nsAString& aName,
const nsACString& aFeatures, bool aForceNoOpener,
bool aForceNoReferrer,
bool aForceNoReferrer, bool aIsPopupRequested,
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
BrowsingContext** aReturn) {
*aReturn = nullptr;
@ -848,10 +848,10 @@ BrowserChild::ProvideWindow(nsIOpenWindowInfo* aOpenWindowInfo,
// open window call was canceled. It's important that we pass this error
// code back to our caller.
ContentChild* cc = ContentChild::GetSingleton();
return cc->ProvideWindowCommon(this, aOpenWindowInfo, aChromeFlags,
aCalledFromJS, aURI, aName, aFeatures,
aForceNoOpener, aForceNoReferrer, aLoadState,
aWindowIsNew, aReturn);
return cc->ProvideWindowCommon(
this, aOpenWindowInfo, aChromeFlags, aCalledFromJS, aURI, aName,
aFeatures, aForceNoOpener, aForceNoReferrer, aIsPopupRequested,
aLoadState, aWindowIsNew, aReturn);
}
void BrowserChild::DestroyWindow() {

Просмотреть файл

@ -968,7 +968,8 @@ nsresult ContentChild::ProvideWindowCommon(
BrowserChild* aTabOpener, nsIOpenWindowInfo* aOpenWindowInfo,
uint32_t aChromeFlags, bool aCalledFromJS, nsIURI* aURI,
const nsAString& aName, const nsACString& aFeatures, bool aForceNoOpener,
bool aForceNoReferrer, nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
bool aForceNoReferrer, bool aIsPopupRequested,
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
BrowsingContext** aReturn) {
MOZ_DIAGNOSTIC_ASSERT(aTabOpener, "We must have a tab opener");
@ -1058,7 +1059,8 @@ nsresult ContentChild::ProvideWindowCommon(
}
RefPtr<BrowsingContext> browsingContext = BrowsingContext::CreateDetached(
nullptr, openerBC, nullptr, aName, BrowsingContext::Type::Content);
nullptr, openerBC, nullptr, aName, BrowsingContext::Type::Content,
aIsPopupRequested);
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetRemoteTabs(true));
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetRemoteSubframes(useRemoteSubframes));
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetOriginAttributes(

Просмотреть файл

@ -115,8 +115,9 @@ class ContentChild final : public PContentChild,
BrowserChild* aTabOpener, nsIOpenWindowInfo* aOpenWindowInfo,
uint32_t aChromeFlags, bool aCalledFromJS, nsIURI* aURI,
const nsAString& aName, const nsACString& aFeatures, bool aForceNoOpener,
bool aForceNoReferrer, nsDocShellLoadState* aLoadState,
bool* aWindowIsNew, BrowsingContext** aReturn);
bool aForceNoReferrer, bool aIsPopupRequested,
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
BrowsingContext** aReturn);
void Init(base::ProcessId aParentPid, const char* aParentBuildID,
mozilla::ipc::ScopedPort aPort, uint64_t aChildID,

Просмотреть файл

@ -69,6 +69,10 @@ interface nsIWindowProvider : nsISupports
* the feature string to the window it returns in any way it sees fit.
* See the nsIWindowWatcher interface for details on feature strings.
*
* @param aIsPopupRequested True if this window is opened by window.open
* with requesting a popup window. This doesn't necessarily mean
* whether the actual window is shown as minimal popup or not.
*
* @param aLoadState Specify setup information of the load in the new window
*
* @param aWindowIsNew [out] Whether the window being returned was just
@ -99,6 +103,7 @@ interface nsIWindowProvider : nsISupports
in AUTF8String aFeatures,
in boolean aForceNoOpener,
in boolean aForceNoReferrer,
in boolean aIsPopupRequested,
in nsDocShellLoadStatePtr aLoadState,
out boolean aWindowIsNew);
};

Просмотреть файл

@ -520,7 +520,11 @@ nsWindowWatcher::OpenWindowWithRemoteTab(nsIRemoteTab* aRemoteTab,
SizeSpec sizeSpec;
CalcSizeSpec(features, false, sizeSpec);
uint32_t chromeFlags = CalculateChromeFlagsForContent(features);
// This is not initiated by window.open call in content context, and we
// don't need to propagate isPopupRequested out-parameter to the resulting
// browsing context.
bool unused = false;
uint32_t chromeFlags = CalculateChromeFlagsForContent(features, &unused);
if (isPrivateBrowsingWindow) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
@ -697,6 +701,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
SizeSpec sizeSpec;
CalcSizeSpec(features, hasChromeParent, sizeSpec);
bool isPopupRequested = false;
// Make sure we calculate the chromeFlags *before* we push the
// callee context onto the context stack so that
// the calculation sees the actual caller when doing its
@ -707,7 +713,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
} else {
MOZ_DIAGNOSTIC_ASSERT(parentBC && parentBC->IsContent(),
"content caller must provide content parent");
chromeFlags = CalculateChromeFlagsForContent(features);
chromeFlags = CalculateChromeFlagsForContent(features, &isPopupRequested);
if (aDialog) {
MOZ_ASSERT(XRE_IsParentProcess());
@ -841,8 +847,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
if (provider) {
rv = provider->ProvideWindow(
openWindowInfo, chromeFlags, aCalledFromJS, uriToLoad, name,
featuresStr, aForceNoOpener, aForceNoReferrer, aLoadState,
&windowIsNew, getter_AddRefs(newBC));
featuresStr, aForceNoOpener, aForceNoReferrer, isPopupRequested,
aLoadState, &windowIsNew, getter_AddRefs(newBC));
if (NS_SUCCEEDED(rv) && newBC) {
nsCOMPtr<nsIDocShell> newDocShell = newBC->GetDocShell();
@ -1762,11 +1768,13 @@ bool nsWindowWatcher::ShouldOpenPopup(const WindowFeatures& aFeatures) {
* from a child process. The feature string can only control whether to open a
* new tab or a new popup.
* @param aFeatures a string containing a list of named features
* @param aIsPopupRequested an out parameter that indicates whether a popup
* is requested by aFeatures
* @return the chrome bitmask
*/
// static
uint32_t nsWindowWatcher::CalculateChromeFlagsForContent(
const WindowFeatures& aFeatures) {
const WindowFeatures& aFeatures, bool* aIsPopupRequested) {
if (aFeatures.IsEmpty() || !ShouldOpenPopup(aFeatures)) {
// Open the current/new tab in the current/new window
// (depends on browser.link.open_newwindow).
@ -1774,6 +1782,7 @@ uint32_t nsWindowWatcher::CalculateChromeFlagsForContent(
}
// Open a minimal popup.
*aIsPopupRequested = true;
return nsIWebBrowserChrome::CHROME_MINIMAL_POPUP;
}

Просмотреть файл

@ -90,7 +90,7 @@ class nsWindowWatcher : public nsIWindowWatcher,
static bool ShouldOpenPopup(const mozilla::dom::WindowFeatures& aFeatures);
static uint32_t CalculateChromeFlagsForContent(
const mozilla::dom::WindowFeatures& aFeatures);
const mozilla::dom::WindowFeatures& aFeatures, bool* aIsPopupRequested);
static uint32_t CalculateChromeFlagsForSystem(
const mozilla::dom::WindowFeatures& aFeatures, bool aDialog,

Просмотреть файл

@ -519,14 +519,12 @@ NS_IMETHODIMP nsContentTreeOwner::SetTitle(const nsAString& aTitle) {
// nsContentTreeOwner: nsIWindowProvider
//*****************************************************************************
NS_IMETHODIMP
nsContentTreeOwner::ProvideWindow(nsIOpenWindowInfo* aOpenWindowInfo,
uint32_t aChromeFlags, bool aCalledFromJS,
nsIURI* aURI, const nsAString& aName,
const nsACString& aFeatures,
bool aForceNoOpener, bool aForceNoReferrer,
nsDocShellLoadState* aLoadState,
bool* aWindowIsNew,
dom::BrowsingContext** aReturn) {
nsContentTreeOwner::ProvideWindow(
nsIOpenWindowInfo* aOpenWindowInfo, uint32_t aChromeFlags,
bool aCalledFromJS, nsIURI* aURI, const nsAString& aName,
const nsACString& aFeatures, bool aForceNoOpener, bool aForceNoReferrer,
bool aIsPopupRequested, nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
dom::BrowsingContext** aReturn) {
NS_ENSURE_ARG_POINTER(aOpenWindowInfo);
RefPtr<dom::BrowsingContext> parent = aOpenWindowInfo->GetParent();