mirror of
https://github.com/classilla/tenfourfox.git
synced 2026-04-24 08:18:31 +00:00
#522: basic window.open=noopener, refactor popup blocker M1267338 M1267339
This commit is contained in:
@@ -56,6 +56,12 @@ interface nsPIWindowWatcher : nsISupports
|
||||
nsITabParent is a remote tab belonging to aParent. Can
|
||||
be nullptr if this window is not being opened from a tab.
|
||||
@param aArgs Window argument
|
||||
@param aIsPopupSpam true if the window is a popup spam window; used for
|
||||
popup blocker internals.
|
||||
@param aForceNoOpener If true, force noopener behavior. This means not
|
||||
looking for existing windows with the given name,
|
||||
not setting an opener on the newly opened window,
|
||||
and returning null from this method.
|
||||
@return the new window
|
||||
|
||||
@note This method may examine the JS context stack for purposes of
|
||||
@@ -70,7 +76,9 @@ interface nsPIWindowWatcher : nsISupports
|
||||
in string aName, in string aFeatures,
|
||||
in boolean aCalledFromScript, in boolean aDialog,
|
||||
in boolean aNavigate, in nsITabParent aOpeningTab,
|
||||
in nsISupports aArgs);
|
||||
in nsISupports aArgs,
|
||||
in boolean aIsPopupSpam,
|
||||
in boolean aForceNoOpener);
|
||||
|
||||
/**
|
||||
* Find a named docshell tree item amongst all windows registered
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "nsJSUtils.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIBrowserDOMWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
@@ -366,7 +367,10 @@ nsWindowWatcher::OpenWindow(nsIDOMWindow* aParent,
|
||||
|
||||
return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
|
||||
/* calledFromJS = */ false, dialog,
|
||||
/* navigate = */ true, nullptr, argv, aResult);
|
||||
/* navigate = */ true, nullptr, argv,
|
||||
/* aIsPopupSpam = */ false,
|
||||
/* aForceNoOpener = */ false,
|
||||
aResult);
|
||||
}
|
||||
|
||||
struct SizeSpec
|
||||
@@ -424,6 +428,8 @@ nsWindowWatcher::OpenWindow2(nsIDOMWindow* aParent,
|
||||
bool aNavigate,
|
||||
nsITabParent* aOpeningTab,
|
||||
nsISupports* aArguments,
|
||||
bool aIsPopupSpam,
|
||||
bool aForceNoOpener,
|
||||
nsIDOMWindow** aResult)
|
||||
{
|
||||
nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments);
|
||||
@@ -443,7 +449,10 @@ nsWindowWatcher::OpenWindow2(nsIDOMWindow* aParent,
|
||||
|
||||
return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
|
||||
aCalledFromScript, dialog,
|
||||
aNavigate, aOpeningTab, argv, aResult);
|
||||
aNavigate, aOpeningTab, argv,
|
||||
aIsPopupSpam,
|
||||
aForceNoOpener,
|
||||
aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -456,6 +465,8 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent,
|
||||
bool aNavigate,
|
||||
nsITabParent* aOpeningTab,
|
||||
nsIArray* aArgv,
|
||||
bool aIsPopupSpam,
|
||||
bool aForceNoOpener,
|
||||
nsIDOMWindow** aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
@@ -531,7 +542,8 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent,
|
||||
// know or care about names - unless we're opening named windows from chrome.
|
||||
if (!aOpeningTab) {
|
||||
// try to find an extant window with the given name
|
||||
nsCOMPtr<nsIDOMWindow> foundWindow = SafeGetWindowByName(name, aParent);
|
||||
nsCOMPtr<nsIDOMWindow> foundWindow =
|
||||
SafeGetWindowByName(name, aForceNoOpener, aParent);
|
||||
GetWindowTreeItem(foundWindow, getter_AddRefs(newDocShellItem));
|
||||
}
|
||||
|
||||
@@ -828,7 +840,8 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent,
|
||||
}
|
||||
}
|
||||
|
||||
rv = ReadyOpenedDocShellItem(newDocShellItem, aParent, windowIsNew, aResult);
|
||||
rv = ReadyOpenedDocShellItem(newDocShellItem, aParent, windowIsNew,
|
||||
aForceNoOpener, aResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@@ -900,6 +913,16 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent,
|
||||
// SetInitialPrincipalToSubject is safe to call multiple times.
|
||||
if (newWindow) {
|
||||
newWindow->SetInitialPrincipalToSubject();
|
||||
if (aIsPopupSpam) {
|
||||
nsGlobalWindow* globalWin = static_cast<nsGlobalWindow*>(newWindow.get());
|
||||
MOZ_ASSERT(!globalWin->IsPopupSpamWindow(),
|
||||
"Who marked it as popup spam already???");
|
||||
if (!globalWin->IsPopupSpamWindow()) { // Make sure we don't mess up our
|
||||
// counter even if the above
|
||||
// assert fails.
|
||||
globalWin->SetIsPopupSpamWindow(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1069,6 +1092,10 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent,
|
||||
}
|
||||
}
|
||||
|
||||
if (aForceNoOpener && windowIsNew) {
|
||||
NS_RELEASE(*aResult);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -1857,8 +1884,18 @@ nsWindowWatcher::GetCallerTreeItem(nsIDocShellTreeItem* aParentItem)
|
||||
|
||||
nsPIDOMWindow*
|
||||
nsWindowWatcher::SafeGetWindowByName(const nsAString& aName,
|
||||
bool aForceNoOpener,
|
||||
nsIDOMWindow* aCurrentWindow)
|
||||
{
|
||||
if (aForceNoOpener) {
|
||||
if (!aName.LowerCaseEqualsLiteral("_self") &&
|
||||
!aName.LowerCaseEqualsLiteral("_top") &&
|
||||
!aName.LowerCaseEqualsLiteral("_parent")) {
|
||||
// Ignore all other names in the noopener case.
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> startItem;
|
||||
GetWindowTreeItem(aCurrentWindow, getter_AddRefs(startItem));
|
||||
|
||||
@@ -1887,6 +1924,7 @@ nsresult
|
||||
nsWindowWatcher::ReadyOpenedDocShellItem(nsIDocShellTreeItem* aOpenedItem,
|
||||
nsIDOMWindow* aParent,
|
||||
bool aWindowIsNew,
|
||||
bool aForceNoOpener,
|
||||
nsIDOMWindow** aOpenedWindow)
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
@@ -1897,7 +1935,9 @@ nsWindowWatcher::ReadyOpenedDocShellItem(nsIDocShellTreeItem* aOpenedItem,
|
||||
nsCOMPtr<nsPIDOMWindow> piOpenedWindow = aOpenedItem->GetWindow();
|
||||
if (piOpenedWindow) {
|
||||
if (aParent) {
|
||||
piOpenedWindow->SetOpenerWindow(aParent, aWindowIsNew); // damnit
|
||||
if (!aForceNoOpener) {
|
||||
piOpenedWindow->SetOpenerWindow(aParent, aWindowIsNew); // damnit
|
||||
}
|
||||
|
||||
if (aWindowIsNew) {
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -70,7 +70,9 @@ protected:
|
||||
|
||||
// Unlike GetWindowByName this will look for a caller on the JS
|
||||
// stack, and then fall back on aCurrentWindow if it can't find one.
|
||||
// It also knows to not look for things if aForceNoOpener is set.
|
||||
nsPIDOMWindow* SafeGetWindowByName(const nsAString& aName,
|
||||
bool aForceNoOpener,
|
||||
nsIDOMWindow* aCurrentWindow);
|
||||
|
||||
// Just like OpenWindowJS, but knows whether it got called via OpenWindowJS
|
||||
@@ -84,6 +86,8 @@ protected:
|
||||
bool aNavigate,
|
||||
nsITabParent* aOpeningTab,
|
||||
nsIArray* aArgv,
|
||||
bool aIsPopupSpam,
|
||||
bool aForceNoOpener,
|
||||
nsIDOMWindow** aResult);
|
||||
|
||||
static nsresult URIfromURL(const char* aURL,
|
||||
@@ -105,6 +109,7 @@ protected:
|
||||
static nsresult ReadyOpenedDocShellItem(nsIDocShellTreeItem* aOpenedItem,
|
||||
nsIDOMWindow* aParent,
|
||||
bool aWindowIsNew,
|
||||
bool aForceNoOpener,
|
||||
nsIDOMWindow** aOpenedWindow);
|
||||
static void SizeOpenedDocShellItem(nsIDocShellTreeItem* aDocShellItem,
|
||||
nsIDOMWindow* aParent,
|
||||
|
||||
Reference in New Issue
Block a user