Skip to content

Commit

Permalink
Bug 1873330 - Part 4: Add UserActivation::Modifiers getters. r=smaug
Browse files Browse the repository at this point in the history
In order to use the modifiers in nsGlobalWindowOuter::OpenInternal, add accessor
methods to BrowsingContext, Document, and WindowContext.
Those accessors behave in the same way as ConsumeTransientUserGestureActivation
and RevisePopupAbuseLevel, except for checking the PopupBlocker state.

Differential Revision: https://phabricator.services.mozilla.com/D197862
  • Loading branch information
arai-a committed Jan 11, 2024
1 parent 1eb9eb9 commit da72302
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 25 deletions.
62 changes: 37 additions & 25 deletions docshell/base/BrowsingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2172,12 +2172,28 @@ void BrowsingContext::Close(CallerType aCallerType, ErrorResult& aError) {
}
}

/*
* Examine the current document state to see if we're in a way that is
* typically abused by web designers. The window.open code uses this
* routine to determine whether to allow the new window.
* Returns a value from the PopupControlState enum.
*/
template <typename FuncT>
inline bool ApplyToDocumentsForPopup(Document* doc, FuncT func) {
// HACK: Some pages using bogus library + UA sniffing call window.open()
// from a blank iframe, only on Firefox, see bug 1685056.
//
// This is a hack-around to preserve behavior in that particular and
// specific case, by consuming activation on the parent document, so we
// don't care about the InProcessParent bits not being fission-safe or what
// not.
if (func(doc)) {
return true;
}
if (!doc->IsInitialDocument()) {
return false;
}
Document* parentDoc = doc->GetInProcessParentDocument();
if (!parentDoc || !parentDoc->NodePrincipal()->Equals(doc->NodePrincipal())) {
return false;
}
return func(parentDoc);
}

PopupBlocker::PopupControlState BrowsingContext::RevisePopupAbuseLevel(
PopupBlocker::PopupControlState aControl) {
if (!IsContent()) {
Expand Down Expand Up @@ -2220,27 +2236,11 @@ PopupBlocker::PopupControlState BrowsingContext::RevisePopupAbuseLevel(
// If we're currently in-process, attempt to consume transient user gesture
// activations.
if (doc) {
// HACK: Some pages using bogus library + UA sniffing call window.open()
// from a blank iframe, only on Firefox, see bug 1685056.
//
// This is a hack-around to preserve behavior in that particular and
// specific case, by consuming activation on the parent document, so we
// don't care about the InProcessParent bits not being fission-safe or what
// not.
auto ConsumeTransientUserActivationForMultiplePopupBlocking =
[&]() -> bool {
if (doc->ConsumeTransientUserGestureActivation()) {
return true;
}
if (!doc->IsInitialDocument()) {
return false;
}
Document* parentDoc = doc->GetInProcessParentDocument();
if (!parentDoc ||
!parentDoc->NodePrincipal()->Equals(doc->NodePrincipal())) {
return false;
}
return parentDoc->ConsumeTransientUserGestureActivation();
return ApplyToDocumentsForPopup(doc, [](Document* doc) {
return doc->ConsumeTransientUserGestureActivation();
});
};

// If this popup is allowed, let's block any other for this event, forcing
Expand All @@ -2259,6 +2259,18 @@ PopupBlocker::PopupControlState BrowsingContext::RevisePopupAbuseLevel(
return abuse;
}

void BrowsingContext::GetUserActivationModifiersForPopup(
UserActivation::Modifiers* aModifiers) {
RefPtr<Document> doc = GetExtantDocument();
if (doc) {
// Unlike RevisePopupAbuseLevel, modifiers can always be used regardless
// of PopupControlState.
(void)ApplyToDocumentsForPopup(doc, [&](Document* doc) {
return doc->GetTransientUserGestureActivationModifiers(aModifiers);
});
}
}

void BrowsingContext::IncrementHistoryEntryCountForBrowsingContext() {
Unused << SetHistoryEntryCount(GetHistoryEntryCount() + 1);
}
Expand Down
10 changes: 10 additions & 0 deletions docshell/base/BrowsingContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -906,9 +906,19 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {

bool CanBlurCheck(CallerType aCallerType);

// Examine the current document state to see if we're in a way that is
// typically abused by web designers. The window.open code uses this
// routine to determine whether to allow the new window.
// Returns a value from the PopupControlState enum.
PopupBlocker::PopupControlState RevisePopupAbuseLevel(
PopupBlocker::PopupControlState aControl);

// Get the modifiers associated with the user activation for relevant
// documents. The window.open code uses this routine to determine where the
// new window should be located.
void GetUserActivationModifiersForPopup(
UserActivation::Modifiers* aModifiers);

void IncrementHistoryEntryCountForBrowsingContext();

bool ServiceWorkersTestingEnabled() const {
Expand Down
12 changes: 12 additions & 0 deletions docshell/base/WindowContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,18 @@ bool WindowContext::ConsumeTransientUserGestureActivation() {
return true;
}

bool WindowContext::GetTransientUserGestureActivationModifiers(
UserActivation::Modifiers* aModifiers) {
if (!HasValidTransientUserGestureActivation()) {
return false;
}

auto stateAndModifiers =
UserActivation::StateAndModifiers(GetUserActivationStateAndModifiers());
*aModifiers = stateAndModifiers.GetModifiers();
return true;
}

bool WindowContext::CanShowPopup() {
uint32_t permit = GetPopupPermission();
if (permit == nsIPermissionManager::ALLOW_ACTION) {
Expand Down
3 changes: 3 additions & 0 deletions docshell/base/WindowContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ class WindowContext : public nsISupports, public nsWrapperCache {
// successfully.
bool ConsumeTransientUserGestureActivation();

bool GetTransientUserGestureActivationModifiers(
UserActivation::Modifiers* aModifiers);

bool CanShowPopup();

bool AllowJavascript() const { return GetAllowJavascript(); }
Expand Down
6 changes: 6 additions & 0 deletions dom/base/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16842,6 +16842,12 @@ bool Document::ConsumeTransientUserGestureActivation() {
return wc && wc->ConsumeTransientUserGestureActivation();
}

bool Document::GetTransientUserGestureActivationModifiers(
UserActivation::Modifiers* aModifiers) {
RefPtr<WindowContext> wc = GetWindowContext();
return wc && wc->GetTransientUserGestureActivationModifiers(aModifiers);
}

void Document::SetDocTreeHadMedia() {
RefPtr<WindowContext> topWc = GetTopLevelWindowContext();
if (topWc && !topWc->IsDiscarded() && !topWc->GetDocTreeHadMedia()) {
Expand Down
3 changes: 3 additions & 0 deletions dom/base/Document.h
Original file line number Diff line number Diff line change
Expand Up @@ -3665,6 +3665,9 @@ class Document : public nsINode,
// and consume the activation.
bool ConsumeTransientUserGestureActivation();

bool GetTransientUserGestureActivationModifiers(
UserActivation::Modifiers* aModifiers);

BrowsingContext* GetBrowsingContext() const;

// This document is a WebExtension page, it might be a background page, a
Expand Down

0 comments on commit da72302

Please sign in to comment.