diff --git a/dom/base/ChromeUtils.cpp b/dom/base/ChromeUtils.cpp index 7377f2ccfa56..bdd1b7fd1eb8 100644 --- a/dom/base/ChromeUtils.cpp +++ b/dom/base/ChromeUtils.cpp @@ -770,5 +770,34 @@ constexpr auto kSkipSelfHosted = JS::SavedFrameSelfHosted::Exclude; NS_ConvertUTF16toUTF8(aOrigin)); } +/* static */ PopupBlockerState ChromeUtils::GetPopupControlState( + GlobalObject& aGlobal) { + switch (PopupBlocker::GetPopupControlState()) { + case PopupBlocker::PopupControlState::openAllowed: + return PopupBlockerState::OpenAllowed; + + case PopupBlocker::PopupControlState::openControlled: + return PopupBlockerState::OpenControlled; + + case PopupBlocker::PopupControlState::openBlocked: + return PopupBlockerState::OpenBlocked; + + case PopupBlocker::PopupControlState::openAbused: + return PopupBlockerState::OpenAbused; + + case PopupBlocker::PopupControlState::openOverridden: + return PopupBlockerState::OpenOverridden; + + default: + MOZ_CRASH( + "PopupBlocker::PopupControlState and PopupBlockerState are out of " + "sync"); + } +} + +/* static */ bool ChromeUtils::IsPopupTokenUnused(GlobalObject& aGlobal) { + return PopupBlocker::IsPopupOpeningTokenUnused(); +} + } // namespace dom } // namespace mozilla diff --git a/dom/base/ChromeUtils.h b/dom/base/ChromeUtils.h index a0fbdf8556f6..d41a92e728b6 100644 --- a/dom/base/ChromeUtils.h +++ b/dom/base/ChromeUtils.h @@ -172,6 +172,10 @@ class ChromeUtils { static bool HasReportingHeaderForOrigin(GlobalObject& global, const nsAString& aOrigin, ErrorResult& aRv); + + static PopupBlockerState GetPopupControlState(GlobalObject& aGlobal); + + static bool IsPopupTokenUnused(GlobalObject& aGlobal); }; } // namespace dom diff --git a/dom/base/PopupBlocker.cpp b/dom/base/PopupBlocker.cpp index bc117aad078a..a18cfbbe3a2d 100644 --- a/dom/base/PopupBlocker.cpp +++ b/dom/base/PopupBlocker.cpp @@ -141,6 +141,10 @@ PopupBlocker::GetPopupControlState() { return false; } +/* static */ bool PopupBlocker::IsPopupOpeningTokenUnused() { + return sUnusedPopupToken; +} + /* static */ void PopupBlocker::PopupStatePusherCreated() { ++sPopupStatePusherCount; } diff --git a/dom/base/PopupBlocker.h b/dom/base/PopupBlocker.h index bb897865e01d..1d72d764224d 100644 --- a/dom/base/PopupBlocker.h +++ b/dom/base/PopupBlocker.h @@ -20,6 +20,7 @@ class PopupBlocker final { // permissive to least permissive so that it's safe to push state in // all situations. Pushing popup state onto the stack never makes the // current popup state less permissive. + // Keep this in sync with PopupBlockerState webidl dictionary! enum PopupControlState { openAllowed = 0, // open that window without worries openControlled, // it's a popup, but allow it @@ -47,6 +48,8 @@ class PopupBlocker final { // allowed per event. static bool TryUsePopupOpeningToken(); + static bool IsPopupOpeningTokenUnused(); + static PopupBlocker::PopupControlState GetEventPopupControlState( WidgetEvent* aEvent, Event* aDOMEvent = nullptr); diff --git a/dom/chrome-webidl/ChromeUtils.webidl b/dom/chrome-webidl/ChromeUtils.webidl index 3c3b1970e478..136a428f094d 100644 --- a/dom/chrome-webidl/ChromeUtils.webidl +++ b/dom/chrome-webidl/ChromeUtils.webidl @@ -379,6 +379,12 @@ partial namespace ChromeUtils { [ChromeOnly, Throws] boolean hasReportingHeaderForOrigin(DOMString aOrigin); + + [ChromeOnly] + PopupBlockerState getPopupControlState(); + + [ChromeOnly] + boolean isPopupTokenUnused(); }; /** @@ -537,3 +543,12 @@ dictionary Base64URLDecodeOptions { /** Specifies the padding mode for decoding the input. */ required Base64URLDecodePadding padding; }; + +// Keep this in sync with PopupBlocker::PopupControlState! +enum PopupBlockerState { + "openAllowed", + "openControlled", + "openBlocked", + "openAbused", + "openOverridden", +};