Bug 1967520 - Add WindowMediatorFilter r=asuth
Differential Revision: https://phabricator.services.mozilla.com/D250305
This commit is contained in:
committed by
krosylight@mozilla.com
parent
e3a4c6903b
commit
85d13ee19d
@@ -6858,6 +6858,20 @@ nsContentUtils::GetMostRecentNonPBWindow() {
|
||||
return pwindow.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsPIDOMWindowOuter> nsContentUtils::GetMostRecentWindowBy(
|
||||
WindowMediatorFilter aFilter) {
|
||||
nsCOMPtr<nsIWindowMediator> wm = do_GetService(NS_WINDOWMEDIATOR_CONTRACTID);
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> window;
|
||||
wm->GetMostRecentWindowBy(u"navigator:browser", static_cast<uint8_t>(aFilter),
|
||||
getter_AddRefs(window));
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwindow;
|
||||
pwindow = do_QueryInterface(window);
|
||||
|
||||
return pwindow.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void nsContentUtils::WarnScriptWasIgnored(Document* aDocument) {
|
||||
nsAutoString msg;
|
||||
|
||||
@@ -121,6 +121,7 @@ class nsPresContext;
|
||||
class nsTextFragment;
|
||||
class nsView;
|
||||
class nsWrapperCache;
|
||||
enum class WindowMediatorFilter : uint8_t;
|
||||
|
||||
struct JSContext;
|
||||
struct nsPoint;
|
||||
@@ -2297,6 +2298,11 @@ class nsContentUtils {
|
||||
// not in private browsing mode.
|
||||
static already_AddRefed<nsPIDOMWindowOuter> GetMostRecentNonPBWindow();
|
||||
|
||||
// Returns the browser window with the most recent time stamp, filtered by the
|
||||
// parameter.
|
||||
static already_AddRefed<nsPIDOMWindowOuter> GetMostRecentWindowBy(
|
||||
WindowMediatorFilter aFilter);
|
||||
|
||||
/**
|
||||
* Call this function if !IsSafeToRunScript() and we fail to run the script
|
||||
* (rather than using AddScriptRunner as we usually do). |aDocument| is
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "nsIBrowser.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsNetUtil.h"
|
||||
@@ -214,8 +215,14 @@ void OpenWindow(const ClientOpenWindowArgsParsed& aArgsValidated,
|
||||
// [[6.1 Open Window]]
|
||||
|
||||
// Find the most recent browser window and open a new tab in it.
|
||||
WindowMediatorFilter filter = WindowMediatorFilter::SkipClosed;
|
||||
if (aArgsValidated.principal->GetIsInPrivateBrowsing()) {
|
||||
filter |= WindowMediatorFilter::SkipNonPrivateBrowsing;
|
||||
} else {
|
||||
filter |= WindowMediatorFilter::SkipPrivateBrowsing;
|
||||
}
|
||||
nsCOMPtr<nsPIDOMWindowOuter> browserWindow =
|
||||
nsContentUtils::GetMostRecentNonPBWindow();
|
||||
nsContentUtils::GetMostRecentWindowBy(filter);
|
||||
if (!browserWindow) {
|
||||
// It is possible to be running without a browser window on Mac OS, so
|
||||
// we need to open a new chrome window.
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
|
||||
#define NS_WINDOWMEDIATOR_CONTRACTID \
|
||||
"@mozilla.org/appshell/window-mediator;1"
|
||||
|
||||
enum class WindowMediatorFilter : uint8_t {
|
||||
None = 0,
|
||||
SkipPrivateBrowsing = 1 << 0,
|
||||
SkipClosed = 1 << 1,
|
||||
SkipNonPrivateBrowsing = 1 << 2,
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(WindowMediatorFilter)
|
||||
%}
|
||||
|
||||
interface mozIDOMWindow;
|
||||
@@ -79,6 +88,14 @@ interface nsIWindowMediator: nsISupports
|
||||
*/
|
||||
mozIDOMWindowProxy getMostRecentNonPBWindow(in wstring aWindowType);
|
||||
|
||||
/**
|
||||
* Same as getMostRecentWindow, but filters out based on the parameter.
|
||||
* @param aFilter The value based on the enum WindowMediatorFilter.
|
||||
*
|
||||
* (Not using WindowMediatorFilter directly it requires [builtinclass])
|
||||
*/
|
||||
mozIDOMWindowProxy getMostRecentWindowBy(in wstring aWindowType, in uint8_t aFilter);
|
||||
|
||||
/**
|
||||
* Return the outer window with the given ID, if any. Can return null.
|
||||
*/
|
||||
|
||||
@@ -236,7 +236,7 @@ nsWindowMediator::GetMostRecentWindow(const char16_t* inType,
|
||||
|
||||
// Find the most window with the highest time stamp that matches
|
||||
// the requested type
|
||||
nsWindowInfo* info = MostRecentWindowInfo(inType, false);
|
||||
nsWindowInfo* info = MostRecentWindowInfo(inType, WindowMediatorFilter::None);
|
||||
if (info && info->mWindow) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> DOMWindow;
|
||||
if (NS_SUCCEEDED(GetDOMWindow(info->mWindow, DOMWindow))) {
|
||||
@@ -278,7 +278,31 @@ nsWindowMediator::GetMostRecentNonPBWindow(const char16_t* aType,
|
||||
NS_ENSURE_ARG_POINTER(aWindow);
|
||||
*aWindow = nullptr;
|
||||
|
||||
nsWindowInfo* info = MostRecentWindowInfo(aType, true);
|
||||
nsWindowInfo* info =
|
||||
MostRecentWindowInfo(aType, WindowMediatorFilter::SkipPrivateBrowsing |
|
||||
WindowMediatorFilter::SkipClosed);
|
||||
nsCOMPtr<nsPIDOMWindowOuter> domWindow;
|
||||
if (info && info->mWindow) {
|
||||
GetDOMWindow(info->mWindow, domWindow);
|
||||
}
|
||||
|
||||
if (!domWindow) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
domWindow.forget(aWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowMediator::GetMostRecentWindowBy(const char16_t* aType, uint8_t aFilter,
|
||||
mozIDOMWindowProxy** aWindow) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(aWindow);
|
||||
*aWindow = nullptr;
|
||||
|
||||
nsWindowInfo* info =
|
||||
MostRecentWindowInfo(aType, static_cast<WindowMediatorFilter>(aFilter));
|
||||
nsCOMPtr<nsPIDOMWindowOuter> domWindow;
|
||||
if (info && info->mWindow) {
|
||||
GetDOMWindow(info->mWindow, domWindow);
|
||||
@@ -293,7 +317,7 @@ nsWindowMediator::GetMostRecentNonPBWindow(const char16_t* aType,
|
||||
}
|
||||
|
||||
nsWindowInfo* nsWindowMediator::MostRecentWindowInfo(
|
||||
const char16_t* inType, bool aSkipPrivateBrowsingOrClosed) {
|
||||
const char16_t* inType, WindowMediatorFilter aFilter) {
|
||||
int32_t lastTimeStamp = -1;
|
||||
nsAutoString typeString(inType);
|
||||
bool allWindows = !inType || typeString.IsEmpty();
|
||||
@@ -315,16 +339,30 @@ nsWindowInfo* nsWindowMediator::MostRecentWindowInfo(
|
||||
if (!searchInfo->mWindow) {
|
||||
continue;
|
||||
}
|
||||
if (aSkipPrivateBrowsingOrClosed) {
|
||||
if (aFilter != WindowMediatorFilter::None) {
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
searchInfo->mWindow->GetDocShell(getter_AddRefs(docShell));
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
|
||||
if (!loadContext || loadContext->UsePrivateBrowsing()) {
|
||||
if (!loadContext) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((aFilter & WindowMediatorFilter::SkipNonPrivateBrowsing) &&
|
||||
!loadContext->UsePrivateBrowsing()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((aFilter & WindowMediatorFilter::SkipPrivateBrowsing) &&
|
||||
loadContext->UsePrivateBrowsing()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> piwindow = docShell->GetWindow();
|
||||
if (!piwindow || piwindow->Closed()) {
|
||||
if (!piwindow) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((aFilter & WindowMediatorFilter::SkipClosed) && piwindow->Closed()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,9 @@ class nsWindowMediator : public nsIWindowMediator,
|
||||
private:
|
||||
void AddEnumerator(nsAppShellWindowEnumerator* inEnumerator);
|
||||
int32_t RemoveEnumerator(nsAppShellWindowEnumerator* inEnumerator);
|
||||
|
||||
nsWindowInfo* MostRecentWindowInfo(const char16_t* inType,
|
||||
bool aSkipPrivateBrowsingOrClosed = false);
|
||||
WindowMediatorFilter aFilter);
|
||||
|
||||
nsresult UnregisterWindow(nsWindowInfo* inInfo);
|
||||
nsWindowInfo* GetInfoFor(nsIAppWindow* aWindow);
|
||||
|
||||
Reference in New Issue
Block a user