Bug 1763672 - Introduce targetTopLevelLinkClicksToBlank on BrowsingContext. r=nika

This property defaults to false. When set to true, user-initiated link clicks in
the top-level BrowsingContext will default target to _blank. This is similar to what
we do for App Tabs, but is slightly more aggressive in that in will also occur for
same-origin navigations.

Differential Revision: https://phabricator.services.mozilla.com/D143374
This commit is contained in:
Mike Conley
2022-04-13 16:00:27 +00:00
parent 3384f9c880
commit 3970205f09
9 changed files with 355 additions and 13 deletions

View File

@@ -12860,7 +12860,8 @@ nsresult nsDocShell::OnLinkClick(
bool noOpenerImplied = false;
nsAutoString target(aTargetSpec);
if (ShouldOpenInBlankTarget(aTargetSpec, aURI, aContent)) {
if (aFileName.IsVoid() &&
ShouldOpenInBlankTarget(aTargetSpec, aURI, aContent, aIsUserTriggered)) {
target = u"_blank";
if (!aTargetSpec.Equals(target)) {
noOpenerImplied = true;
@@ -12886,17 +12887,9 @@ nsresult nsDocShell::OnLinkClick(
}
bool nsDocShell::ShouldOpenInBlankTarget(const nsAString& aOriginalTarget,
nsIURI* aLinkURI,
nsIContent* aContent) {
// Don't modify non-default targets.
if (!aOriginalTarget.IsEmpty()) {
return false;
}
// Only check targets that are in extension panels or app tabs.
// (isAppTab will be false for app tab subframes).
nsString mmGroup = mBrowsingContext->Top()->GetMessageManagerGroup();
if (!mmGroup.EqualsLiteral("webext-browsers") && !mIsAppTab) {
nsIURI* aLinkURI, nsIContent* aContent,
bool aIsUserTriggered) {
if (net::SchemeIsJavascript(aLinkURI)) {
return false;
}
@@ -12909,6 +12902,29 @@ bool nsDocShell::ShouldOpenInBlankTarget(const nsAString& aOriginalTarget,
return false;
}
// The targetTopLevelLinkClicksToBlank property on BrowsingContext allows
// privileged code to change the default targeting behaviour. In particular,
// if a user-initiated link click for the (or targetting the) top-level frame
// is detected, we default the target to "_blank" to give it a new
// top-level BrowsingContext.
if (mBrowsingContext->TargetTopLevelLinkClicksToBlank() && aIsUserTriggered &&
((aOriginalTarget.IsEmpty() && mBrowsingContext->IsTop()) ||
aOriginalTarget == u"_top"_ns)) {
return true;
}
// Don't modify non-default targets.
if (!aOriginalTarget.IsEmpty()) {
return false;
}
// Only check targets that are in extension panels or app tabs.
// (isAppTab will be false for app tab subframes).
nsString mmGroup = mBrowsingContext->Top()->GetMessageManagerGroup();
if (!mmGroup.EqualsLiteral("webext-browsers") && !mIsAppTab) {
return false;
}
nsCOMPtr<nsIURI> docURI = aContent->OwnerDoc()->GetDocumentURIObject();
if (!docURI) {
return false;