Issue #2721 - Create special case exception for <A>.Click() outside of DOM

This removes the requirement for there to be a non-null PresShell to
dispatch `Click()` events on `<A>` elements (only), since the exception
to the rule has propagated to the spec.

With these changes it should now be possible do create an anchor and
`Click()` on it from JS without actually first attaching it to the DOM
of the presented document, as abused by scripted downloads in pages
(instead of using the A attribute to custom-name downloads).
This commit is contained in:
Moonchild 2025-06-09 23:45:31 +02:00 committed by roytam1
commit 37de431ac0
15 changed files with 79 additions and 94 deletions

View file

@ -89,6 +89,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsCycleCollector.h"
#include "nsDataHashtable.h"
#include "nsDocShell.h"
#include "nsDocShellCID.h"
#include "nsDocument.h"
#include "nsDOMCID.h"
@ -5336,25 +5337,24 @@ nsContentUtils::CombineResourcePrincipals(nsCOMPtr<nsIPrincipal>* aResourcePrinc
/* static */
void
nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
nsContentUtils::TriggerLink(nsIContent *aContent,
nsIURI *aLinkURI, const nsString &aTargetSpec,
bool aClick, bool aIsUserTriggered,
bool aIsTrusted)
{
NS_ASSERTION(aPresContext, "Need a nsPresContext");
NS_PRECONDITION(aLinkURI, "No link URI");
if (aContent->IsEditable()) {
if (aContent->IsEditable() || !aContent->OwnerDoc()->LinkHandlingEnabled()) {
return;
}
nsILinkHandler *handler = aPresContext->GetLinkHandler();
if (!handler) {
nsCOMPtr<nsIDocShell> docShell = aContent->OwnerDoc()->GetDocShell();
if (!docShell) {
return;
}
if (!aClick) {
handler->OnOverLink(aContent, aLinkURI, aTargetSpec.get());
nsDocShell::Cast(docShell)->OnOverLink(aContent, aLinkURI, aTargetSpec.get());
return;
}
@ -5397,9 +5397,9 @@ nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
}
}
handler->OnLinkClick(aContent, aLinkURI,
fileName.IsVoid() ? aTargetSpec.get() : EmptyString().get(),
fileName, nullptr, nullptr, aIsTrusted, aContent->NodePrincipal());
nsDocShell::Cast(docShell)->OnLinkClick(aContent, aLinkURI,
fileName.IsVoid() ? aTargetSpec.get() : EmptyString().get(),
fileName, nullptr, nullptr, aIsTrusted, aContent->NodePrincipal());
}
}