зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1914594 - Move docshell.newWindowTarget to be on LoadInfo, r=necko-reviewers,kershaw
Previously, this was passed around using the nsHashPropertyBag base
class on HTTP channels. In bug 1907269
, this base was added to
nsExtProtocolChannel to support reading this property for external
protocols.
This unfortunately ended up not working when a HTTP channel redirects to
an external protocol, as the hash property propagation logic in
nsHttpChannel happens after the check that the target channel is a HTTP
channel, so the property was lost when redirecting to an external
protocol.
Rather than refactoring HTTP redirect logic, this patch simplifies by
moving the property onto the LoadInfo where it will be trivially
preserved across redirects, and available in the places which need it.
Because the nsHashPropertyBag base is no longer required for
nsExtProtocolChannel, it is also removed.
Differential Revision: https://phabricator.services.mozilla.com/D220744
This commit is contained in:
Родитель
89124c63a1
Коммит
793f001a6e
|
@ -9709,6 +9709,8 @@ nsIPrincipal* nsDocShell::GetInheritedPrincipal(
|
|||
INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI));
|
||||
aLoadInfo->SetOriginalFrameSrcLoad(
|
||||
aLoadState->HasInternalLoadFlags(INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC));
|
||||
aLoadInfo->SetIsNewWindowTarget(
|
||||
aLoadState->HasInternalLoadFlags(INTERNAL_LOAD_FLAGS_FIRST_LOAD));
|
||||
|
||||
bool inheritAttrs = false;
|
||||
if (aLoadState->PrincipalToInherit()) {
|
||||
|
@ -9849,10 +9851,6 @@ nsIPrincipal* nsDocShell::GetInheritedPrincipal(
|
|||
// save true referrer for those who need it (e.g. xpinstall whitelisting)
|
||||
// Currently only http and ftp channels support this.
|
||||
props->SetPropertyAsInterface(u"docshell.internalReferrer"_ns, referrer);
|
||||
|
||||
if (aLoadState->HasInternalLoadFlags(INTERNAL_LOAD_FLAGS_FIRST_LOAD)) {
|
||||
props->SetPropertyAsBool(u"docshell.newWindowTarget"_ns, true);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICacheInfoChannel> cacheChannel(do_QueryInterface(channel));
|
||||
|
|
|
@ -4464,8 +4464,7 @@ ContentParent::AllocPExternalHelperAppParent(
|
|||
const uint32_t& aContentDispositionHint,
|
||||
const nsAString& aContentDispositionFilename, const bool& aForceSave,
|
||||
const int64_t& aContentLength, const bool& aWasFileChannel,
|
||||
nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
const bool& aShouldCloseWindow) {
|
||||
nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext) {
|
||||
RefPtr<ExternalHelperAppParent> parent = new ExternalHelperAppParent(
|
||||
uri, aContentLength, aWasFileChannel, aContentDisposition,
|
||||
aContentDispositionHint, aContentDispositionFilename);
|
||||
|
@ -4479,12 +4478,10 @@ mozilla::ipc::IPCResult ContentParent::RecvPExternalHelperAppConstructor(
|
|||
const uint32_t& aContentDispositionHint,
|
||||
const nsAString& aContentDispositionFilename, const bool& aForceSave,
|
||||
const int64_t& aContentLength, const bool& aWasFileChannel,
|
||||
nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
const bool& aShouldCloseWindow) {
|
||||
nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext) {
|
||||
BrowsingContext* context = aContext.IsDiscarded() ? nullptr : aContext.get();
|
||||
if (!static_cast<ExternalHelperAppParent*>(actor)->Init(
|
||||
loadInfoArgs, aMimeContentType, aForceSave, aReferrer, context,
|
||||
aShouldCloseWindow)) {
|
||||
loadInfoArgs, aMimeContentType, aForceSave, aReferrer, context)) {
|
||||
return IPC_FAIL(this, "Init failed.");
|
||||
}
|
||||
return IPC_OK();
|
||||
|
|
|
@ -913,8 +913,7 @@ class ContentParent final : public PContentParent,
|
|||
const uint32_t& aContentDispositionHint,
|
||||
const nsAString& aContentDispositionFilename, const bool& aForceSave,
|
||||
const int64_t& aContentLength, const bool& aWasFileChannel,
|
||||
nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
const bool& aShouldCloseWindow);
|
||||
nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvPExternalHelperAppConstructor(
|
||||
PExternalHelperAppParent* actor, nsIURI* uri,
|
||||
|
@ -923,8 +922,8 @@ class ContentParent final : public PContentParent,
|
|||
const uint32_t& aContentDispositionHint,
|
||||
const nsAString& aContentDispositionFilename, const bool& aForceSave,
|
||||
const int64_t& aContentLength, const bool& aWasFileChannel,
|
||||
nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
const bool& aShouldCloseWindow) override;
|
||||
nsIURI* aReferrer,
|
||||
const MaybeDiscarded<BrowsingContext>& aContext) override;
|
||||
|
||||
already_AddRefed<PHandlerServiceParent> AllocPHandlerServiceParent();
|
||||
|
||||
|
|
|
@ -1187,8 +1187,6 @@ parent:
|
|||
//
|
||||
// Pass true for aForceSave to always save this content to disk, regardless of
|
||||
// nsIMIMEInfo and other such influences.
|
||||
// Pass true for aShouldCloseWindow to specify that aContext was opened specifically
|
||||
// for this load, and should be closed once we've handled it.
|
||||
async PExternalHelperApp(nullable nsIURI uri,
|
||||
LoadInfoArgs loadInfoArgs,
|
||||
nsCString aMimeContentType,
|
||||
|
@ -1199,8 +1197,7 @@ parent:
|
|||
int64_t aContentLength,
|
||||
bool aWasFileChannel,
|
||||
nullable nsIURI aReferrer,
|
||||
MaybeDiscardedBrowsingContext aContext,
|
||||
bool aShouldCloseWindow);
|
||||
MaybeDiscardedBrowsingContext aContext);
|
||||
|
||||
async PHandlerService();
|
||||
|
||||
|
|
|
@ -597,7 +597,7 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
|
|||
aLoadInfo->GetStoragePermission(), overriddenFingerprintingSettingsArg,
|
||||
aLoadInfo->GetIsMetaRefresh(), aLoadInfo->GetLoadingEmbedderPolicy(),
|
||||
aLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(),
|
||||
unstrippedURI, interceptionInfoArg);
|
||||
unstrippedURI, interceptionInfoArg, aLoadInfo->GetIsNewWindowTarget());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -890,7 +890,8 @@ nsresult LoadInfoArgsToLoadInfo(const LoadInfoArgs& loadInfoArgs,
|
|||
loadInfoArgs.originTrialCoepCredentiallessEnabledForTopLevel(),
|
||||
loadInfoArgs.unstrippedURI(), interceptionInfo,
|
||||
loadInfoArgs.hasInjectedCookieForCookieBannerHandling(),
|
||||
loadInfoArgs.wasSchemelessInput(), loadInfoArgs.httpsUpgradeTelemetry());
|
||||
loadInfoArgs.wasSchemelessInput(), loadInfoArgs.httpsUpgradeTelemetry(),
|
||||
loadInfoArgs.isNewWindowTarget());
|
||||
|
||||
if (loadInfoArgs.isFromProcessingFrameAttributes()) {
|
||||
loadInfo->SetIsFromProcessingFrameAttributes();
|
||||
|
|
|
@ -693,7 +693,8 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
|
|||
mHasInjectedCookieForCookieBannerHandling(
|
||||
rhs.mHasInjectedCookieForCookieBannerHandling),
|
||||
mWasSchemelessInput(rhs.mWasSchemelessInput),
|
||||
mHttpsUpgradeTelemetry(rhs.mHttpsUpgradeTelemetry) {
|
||||
mHttpsUpgradeTelemetry(rhs.mHttpsUpgradeTelemetry),
|
||||
mIsNewWindowTarget(rhs.mIsNewWindowTarget) {
|
||||
}
|
||||
|
||||
LoadInfo::LoadInfo(
|
||||
|
@ -742,7 +743,8 @@ LoadInfo::LoadInfo(
|
|||
bool aIsOriginTrialCoepCredentiallessEnabledForTopLevel,
|
||||
nsIURI* aUnstrippedURI, nsIInterceptionInfo* aInterceptionInfo,
|
||||
bool aHasInjectedCookieForCookieBannerHandling, bool aWasSchemelessInput,
|
||||
nsILoadInfo::HTTPSUpgradeTelemetryType aHttpsUpgradeTelemetry)
|
||||
nsILoadInfo::HTTPSUpgradeTelemetryType aHttpsUpgradeTelemetry,
|
||||
bool aIsNewWindowTarget)
|
||||
: mLoadingPrincipal(aLoadingPrincipal),
|
||||
mTriggeringPrincipal(aTriggeringPrincipal),
|
||||
mPrincipalToInherit(aPrincipalToInherit),
|
||||
|
@ -823,7 +825,8 @@ LoadInfo::LoadInfo(
|
|||
mHasInjectedCookieForCookieBannerHandling(
|
||||
aHasInjectedCookieForCookieBannerHandling),
|
||||
mWasSchemelessInput(aWasSchemelessInput),
|
||||
mHttpsUpgradeTelemetry(aHttpsUpgradeTelemetry) {
|
||||
mHttpsUpgradeTelemetry(aHttpsUpgradeTelemetry),
|
||||
mIsNewWindowTarget(aIsNewWindowTarget) {
|
||||
// Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
|
||||
MOZ_ASSERT(mLoadingPrincipal ||
|
||||
aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
|
||||
|
@ -2461,4 +2464,16 @@ LoadInfo::SetHttpsUpgradeTelemetry(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadInfo::GetIsNewWindowTarget(bool* aIsNewWindowTarget) {
|
||||
*aIsNewWindowTarget = mIsNewWindowTarget;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadInfo::SetIsNewWindowTarget(bool aIsNewWindowTarget) {
|
||||
mIsNewWindowTarget = aIsNewWindowTarget;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla::net
|
||||
|
|
|
@ -259,7 +259,8 @@ class LoadInfo final : public nsILoadInfo {
|
|||
bool aIsOriginTrialCoepCredentiallessEnabledForTopLevel,
|
||||
nsIURI* aUnstrippedURI, nsIInterceptionInfo* aInterceptionInfo,
|
||||
bool aHasInjectedCookieForCookieBannerHandling, bool aWasSchemelessInput,
|
||||
nsILoadInfo::HTTPSUpgradeTelemetryType aHttpsUpgradeTelemetry);
|
||||
nsILoadInfo::HTTPSUpgradeTelemetryType aHttpsUpgradeTelemetry,
|
||||
bool aIsNewWindowTarget);
|
||||
|
||||
LoadInfo(const LoadInfo& rhs);
|
||||
|
||||
|
@ -415,6 +416,8 @@ class LoadInfo final : public nsILoadInfo {
|
|||
|
||||
nsILoadInfo::HTTPSUpgradeTelemetryType mHttpsUpgradeTelemetry =
|
||||
nsILoadInfo::NOT_INITIALIZED;
|
||||
|
||||
bool mIsNewWindowTarget = false;
|
||||
};
|
||||
|
||||
// This is exposed solely for testing purposes and should not be used outside of
|
||||
|
|
|
@ -903,5 +903,15 @@ TRRLoadInfo::SetHttpsUpgradeTelemetry(
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TRRLoadInfo::GetIsNewWindowTarget(bool* aIsNewWindowTarget) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TRRLoadInfo::SetIsNewWindowTarget(bool aIsNewWindowTarget) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -1590,4 +1590,9 @@ interface nsILoadInfo : nsISupports
|
|||
*/
|
||||
[infallible] attribute nsILoadInfo_HTTPSUpgradeTelemetryType httpsUpgradeTelemetry;
|
||||
|
||||
/**
|
||||
* Is this the first load in a new pop-up window/tab?
|
||||
*/
|
||||
[infallible] attribute boolean isNewWindowTarget;
|
||||
|
||||
};
|
||||
|
|
|
@ -1651,13 +1651,8 @@ void DocumentLoadListener::SerializeRedirectData(
|
|||
}
|
||||
|
||||
static bool IsFirstLoadInWindow(nsIChannel* aChannel) {
|
||||
if (nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(aChannel)) {
|
||||
bool tmp = false;
|
||||
nsresult rv =
|
||||
props->GetPropertyAsBool(u"docshell.newWindowTarget"_ns, &tmp);
|
||||
return NS_SUCCEEDED(rv) && tmp;
|
||||
}
|
||||
return false;
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
return loadInfo->GetIsNewWindowTarget();
|
||||
}
|
||||
|
||||
// Get where the document loaded by this nsIChannel should be rendered. This
|
||||
|
|
|
@ -196,6 +196,7 @@ struct LoadInfoArgs
|
|||
bool originTrialCoepCredentiallessEnabledForTopLevel;
|
||||
nullable nsIURI unstrippedURI;
|
||||
InterceptionInfoArg? interceptionInfo;
|
||||
bool isNewWindowTarget;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,8 +62,7 @@ ExternalHelperAppParent::ExternalHelperAppParent(
|
|||
bool ExternalHelperAppParent::Init(
|
||||
const mozilla::net::LoadInfoArgs& aLoadInfoArgs,
|
||||
const nsACString& aMimeContentType, const bool& aForceSave,
|
||||
nsIURI* aReferrer, BrowsingContext* aContext,
|
||||
const bool& aShouldCloseWindow) {
|
||||
nsIURI* aReferrer, BrowsingContext* aContext) {
|
||||
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(
|
||||
aLoadInfoArgs, ContentParent::Cast(Manager())->GetRemoteType(),
|
||||
getter_AddRefs(mLoadInfo));
|
||||
|
@ -95,18 +94,7 @@ bool ExternalHelperAppParent::Init(
|
|||
|
||||
helperAppService->CreateListener(aMimeContentType, this, aContext, aForceSave,
|
||||
nullptr, getter_AddRefs(mListener));
|
||||
if (!mListener) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aShouldCloseWindow) {
|
||||
RefPtr<nsExternalAppHandler> handler = do_QueryObject(mListener);
|
||||
if (handler) {
|
||||
handler->SetShouldCloseWindow();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return mListener != nullptr;
|
||||
}
|
||||
|
||||
void ExternalHelperAppParent::ActorDestroy(ActorDestroyReason why) {
|
||||
|
|
|
@ -87,8 +87,7 @@ class ExternalHelperAppParent
|
|||
const nsAString& aContentDispositionFilename);
|
||||
bool Init(const mozilla::net::LoadInfoArgs& aLoadInfoArgs,
|
||||
const nsACString& aMimeContentType, const bool& aForceSave,
|
||||
nsIURI* aReferrer, BrowsingContext* aContext,
|
||||
const bool& aShouldCloseWindow);
|
||||
nsIURI* aReferrer, BrowsingContext* aContext);
|
||||
|
||||
protected:
|
||||
virtual ~ExternalHelperAppParent();
|
||||
|
|
|
@ -719,14 +719,6 @@ nsresult nsExternalHelperAppService::DoContentContentProcessHelper(
|
|||
mozilla::net::LoadInfoArgs loadInfoArgs;
|
||||
MOZ_ALWAYS_SUCCEEDS(LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs));
|
||||
|
||||
nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(aChannel));
|
||||
// Determine whether a new window was opened specifically for this request
|
||||
bool shouldCloseWindow = false;
|
||||
if (props) {
|
||||
props->GetPropertyAsBool(u"docshell.newWindowTarget"_ns,
|
||||
&shouldCloseWindow);
|
||||
}
|
||||
|
||||
// Now we build a protocol for forwarding our data to the parent. The
|
||||
// protocol will act as a listener on the child-side and create a "real"
|
||||
// helperAppService listener on the parent-side, via another call to
|
||||
|
@ -735,7 +727,7 @@ nsresult nsExternalHelperAppService::DoContentContentProcessHelper(
|
|||
MOZ_ALWAYS_TRUE(child->SendPExternalHelperAppConstructor(
|
||||
childListener, uri, loadInfoArgs, nsCString(aMimeContentType), disp,
|
||||
contentDisposition, fileName, aForceSave, contentLength, wasFileChannel,
|
||||
referrer, aContentContext, shouldCloseWindow));
|
||||
referrer, aContentContext));
|
||||
|
||||
NS_ADDREF(*aStreamListener = childListener);
|
||||
|
||||
|
@ -1328,7 +1320,6 @@ nsExternalAppHandler::nsExternalAppHandler(
|
|||
mCanceled(false),
|
||||
mStopRequestIssued(false),
|
||||
mIsFileChannel(false),
|
||||
mShouldCloseWindow(false),
|
||||
mHandleInternally(false),
|
||||
mDialogShowing(false),
|
||||
mReason(aReason),
|
||||
|
@ -1645,15 +1636,12 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
|
|||
|
||||
if (mBrowsingContext) {
|
||||
mMaybeCloseWindowHelper = new MaybeCloseWindowHelper(mBrowsingContext);
|
||||
mMaybeCloseWindowHelper->SetShouldCloseWindow(mShouldCloseWindow);
|
||||
nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(request, &rv));
|
||||
|
||||
// Determine whether a new window was opened specifically for this request
|
||||
if (props) {
|
||||
bool tmp = false;
|
||||
if (NS_SUCCEEDED(
|
||||
props->GetPropertyAsBool(u"docshell.newWindowTarget"_ns, &tmp))) {
|
||||
mMaybeCloseWindowHelper->SetShouldCloseWindow(tmp);
|
||||
}
|
||||
if (aChannel) {
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
mMaybeCloseWindowHelper->SetShouldCloseWindow(
|
||||
loadInfo->GetIsNewWindowTarget());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -315,8 +315,6 @@ class nsExternalAppHandler final : public nsIStreamListener,
|
|||
*/
|
||||
void MaybeApplyDecodingForExtension(nsIRequest* request);
|
||||
|
||||
void SetShouldCloseWindow() { mShouldCloseWindow = true; }
|
||||
|
||||
protected:
|
||||
bool IsDownloadSpam(nsIChannel* aChannel);
|
||||
|
||||
|
@ -382,12 +380,6 @@ class nsExternalAppHandler final : public nsIStreamListener,
|
|||
|
||||
bool mIsFileChannel;
|
||||
|
||||
/**
|
||||
* True if the ExternalHelperAppChild told us that we should close the window
|
||||
* if we handle the content as a download.
|
||||
*/
|
||||
bool mShouldCloseWindow;
|
||||
|
||||
/**
|
||||
* True if the file should be handled internally.
|
||||
*/
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "nsNetUtil.h"
|
||||
#include "nsContentSecurityManager.h"
|
||||
#include "nsExternalHelperAppService.h"
|
||||
#include "nsHashPropertyBag.h"
|
||||
|
||||
// used to dispatch urls to default protocol handlers
|
||||
#include "nsCExternalHandlerService.h"
|
||||
|
@ -36,12 +35,11 @@ class nsILoadInfo;
|
|||
// OpenInputStream to calls in the OS for loading the url.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsExtProtocolChannel : public nsHashPropertyBag,
|
||||
public nsIChannel,
|
||||
class nsExtProtocolChannel : public nsIChannel,
|
||||
public nsIChildChannel,
|
||||
public nsIParentChannel {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
@ -75,17 +73,18 @@ class nsExtProtocolChannel : public nsHashPropertyBag,
|
|||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
};
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsExtProtocolChannel, nsHashPropertyBag)
|
||||
NS_IMPL_RELEASE_INHERITED(nsExtProtocolChannel, nsHashPropertyBag)
|
||||
NS_IMPL_ADDREF(nsExtProtocolChannel)
|
||||
NS_IMPL_RELEASE(nsExtProtocolChannel)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsExtProtocolChannel)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIChildChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIParentChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsExtProtocolChannel::nsExtProtocolChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo)
|
||||
: mUrl(aURI),
|
||||
|
@ -177,13 +176,10 @@ nsresult nsExtProtocolChannel::OpenURL() {
|
|||
mLoadInfo->RedirectChain().LastElement()->GetPrincipal(
|
||||
getter_AddRefs(redirectPrincipal));
|
||||
}
|
||||
bool newWindowTarget = false;
|
||||
GetPropertyAsBool(u"docshell.newWindowTarget"_ns, &newWindowTarget);
|
||||
|
||||
rv = extProtService->LoadURI(mUrl, triggeringPrincipal, redirectPrincipal,
|
||||
ctx, mLoadInfo->GetLoadTriggeredFromExternal(),
|
||||
mLoadInfo->GetHasValidUserGestureActivation(),
|
||||
newWindowTarget);
|
||||
mLoadInfo->GetIsNewWindowTarget());
|
||||
|
||||
if (NS_SUCCEEDED(rv) && mListener) {
|
||||
mStatus = NS_ERROR_NO_CONTENT;
|
||||
|
|
|
@ -528,3 +528,68 @@ add_task(async function iframe_popup_tab() {
|
|||
gBrowser.removeTab(tab);
|
||||
gBrowser.removeTab(newTab);
|
||||
});
|
||||
|
||||
/**
|
||||
* Check that when navigating to a http channel which redirects to a external
|
||||
* protocol in a noopener pop-up window, we show the dialog in the correct tab.
|
||||
*/
|
||||
add_task(async function redirect_popup_tab() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
"https://example.com/"
|
||||
);
|
||||
|
||||
// Wait for the chooser dialog to open in the background tab. It should not
|
||||
// open in the foreground tab which is unrelated to the external protocol
|
||||
// navigation.
|
||||
let dialogWindowPromise = waitForProtocolAppChooserDialog(gBrowser, true);
|
||||
|
||||
// Wait for the new tab to appear. The URI in this tab will never change from
|
||||
// `about:blank` as we're going to just end up opening a dialog, so we can't
|
||||
// use `waitForNewTab`, as that will wait for the tab to actually load
|
||||
// something.
|
||||
let newTabPromise = new Promise(resolve => {
|
||||
gBrowser.tabContainer.addEventListener(
|
||||
"TabOpen",
|
||||
openEvent => resolve(openEvent.target),
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
|
||||
info("Navigating to redirect to external proto in pop-up");
|
||||
await SpecialPowers.spawn(
|
||||
tab.linkedBrowser,
|
||||
[TEST_PATH + "redirect_helper.sjs?uri=mailto:example@example.com"],
|
||||
async function (popupUri) {
|
||||
content.eval("window.open('" + popupUri + "', '_blank', 'noopener');");
|
||||
}
|
||||
);
|
||||
|
||||
// Wait for the new tab to be opened.
|
||||
info("Waiting for new tab to appear");
|
||||
let newTab = await newTabPromise;
|
||||
|
||||
// Wait for dialog to open in one of the tabs.
|
||||
info("Waiting for dialog to appear");
|
||||
let dialog = await dialogWindowPromise;
|
||||
|
||||
is(
|
||||
gBrowser.getTabDialogBox(newTab.linkedBrowser)._tabDialogManager._topDialog,
|
||||
dialog,
|
||||
"Dialog opened in the background tab"
|
||||
);
|
||||
|
||||
is(
|
||||
dialog._frame.contentDocument.location.href,
|
||||
CONTENT_HANDLING_URL,
|
||||
"Opened dialog is appChooser dialog."
|
||||
);
|
||||
|
||||
// Close the dialog:
|
||||
let dialogClosedPromise = waitForProtocolAppChooserDialog(gBrowser, false);
|
||||
dialog.close();
|
||||
await dialogClosedPromise;
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
gBrowser.removeTab(newTab);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче