Commit 4391c8d2 authored by Kagami Sascha Rosylight's avatar Kagami Sascha Rosylight Committed by krosylight@mozilla.com
Browse files

Bug 1967520 - Add WindowMediatorFilter r=asuth

parent 6cd82ebd
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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
+8 −1
Original line number Diff line number Diff line
@@ -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.
+17 −0
Original line number Diff line number Diff line
@@ -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.
   */
+44 −6
Original line number Diff line number Diff line
@@ -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;
      }
    }
Loading