import changes from wicknix/Arctic-Fox:

- Backport of Mozilla Bug 1267338. Remove dead codepath for the case when we opened a window even though popupState was openAbused, since we never open a window in that situation (4930e3bb7)
- slightly modernize code, use nsPIDOMWindow and prepare for next patch (37e709eca) (with missed win32 code plugged in)
- Backport of Mozilla Bug 1222516 part 1. Add a window API for opening a window with navigation and a given docshell loadinfo to use for the navigation. (d4c222d45)
- Backport of Mozilla Bug 1222516 part 2. Add a window API for opening a window passing through a boolean indicating that no opener should be set on the result. (c3259462b)
- first batch to transition nsIDOMWindow to nsPIDOMWindow at about TenFourFox level (dba07065a)
- update also GetOpener to nsPIDOMWindow (701c46ecb)
- Backport of Mozilla Bug 1207245 - part 1 - move RefCounted<T> to its own file (1acef0a1d)
- Bug 1207245 - part 2 followup - add more mozilla/RefCounted.h (31cad506d)
- Bug 1207245 - part 0 - fix why-did-we-allow-that tests in TestRefPtr.cpp (cad11cb06)
This commit is contained in:
2019-01-10 12:06:49 +08:00
parent fbf8f290b8
commit ba81dbdaa6
37 changed files with 560 additions and 578 deletions
+2
View File
@@ -139,6 +139,8 @@ ImageAccessible::DoAction(uint8_t aIndex)
nsCOMPtr<nsIDOMWindow> tmp;
return NS_SUCCEEDED(win->Open(spec, EmptyString(), EmptyString(),
/* aLoadInfo = */ nullptr,
/* aForceNoOpener = */ false,
getter_AddRefs(tmp)));
}
+2 -3
View File
@@ -307,7 +307,7 @@ nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel,
// window, if we're not the top. X-F-O: SAMEORIGIN requires that the
// document must be same-origin with top window. X-F-O: DENY requires that
// the document must never be framed.
nsCOMPtr<nsIDOMWindow> thisWindow = mDocShell->GetWindow();
nsCOMPtr<nsPIDOMWindow> thisWindow = mDocShell->GetWindow();
// If we don't have DOMWindow there is no risk of clickjacking
if (!thisWindow) {
return true;
@@ -315,8 +315,7 @@ nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel,
// GetScriptableTop, not GetTop, because we want this to respect
// <iframe mozbrowser> boundaries.
nsCOMPtr<nsIDOMWindow> topWindow;
thisWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> topWindow = thisWindow->GetScriptableTop();
// if the document is in the top window, it's not in a frame.
if (thisWindow == topWindow) {
+13 -17
View File
@@ -3194,7 +3194,7 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(GetAsSupports(this));
nsCOMPtr<nsPIDOMWindow> domWin = do_GetInterface(GetAsSupports(this));
if (aCreate) {
return manager->CreateStorage(domWin, aPrincipal, aDocumentURI,
@@ -3702,14 +3702,13 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem,
return false;
}
nsCOMPtr<nsIDOMWindow> targetWindow = aTargetItem->GetWindow();
nsCOMPtr<nsPIDOMWindow> targetWindow = aTargetItem->GetWindow();
if (!targetWindow) {
NS_ERROR("This should not happen, really");
return false;
}
nsCOMPtr<nsIDOMWindow> targetOpener;
targetWindow->GetOpener(getter_AddRefs(targetOpener));
nsCOMPtr<nsIDOMWindow> targetOpener = targetWindow->GetOpener();
nsCOMPtr<nsIWebNavigation> openerWebNav(do_GetInterface(targetOpener));
nsCOMPtr<nsIDocShellTreeItem> openerItem(do_QueryInterface(openerWebNav));
@@ -3723,7 +3722,7 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem,
static bool
ItemIsActive(nsIDocShellTreeItem* aItem)
{
nsCOMPtr<nsIDOMWindow> window = aItem->GetWindow();
nsCOMPtr<nsPIDOMWindow> window = aItem->GetWindow();
if (window) {
bool isClosed;
@@ -3983,7 +3982,7 @@ PrintDocTree(nsIDocShellTreeItem* aParentNode, int aLevel)
parentAsDocShell->GetPresContext(getter_AddRefs(presContext));
nsIDocument* doc = presShell->GetDocument();
nsCOMPtr<nsIDOMWindow> domwin(doc->GetWindow());
nsCOMPtr<nsPIDOMWindow> domwin(doc->GetWindow());
nsCOMPtr<nsIWidget> widget;
nsViewManager* vm = presShell->GetViewManager();
@@ -9982,7 +9981,7 @@ nsDocShell::InternalLoad2(nsIURI* aURI,
// So, the best we can do, is to tear down the new window
// that was just created!
//
nsCOMPtr<nsIDOMWindow> domWin = targetDocShell->GetWindow();
nsCOMPtr<nsPIDOMWindow> domWin = targetDocShell->GetWindow();
if (domWin) {
domWin->Close();
}
@@ -13256,10 +13255,11 @@ nsDocShell::GetAssociatedWindow(nsIDOMWindow** aWindow)
NS_IMETHODIMP
nsDocShell::GetTopWindow(nsIDOMWindow** aWindow)
{
nsCOMPtr<nsIDOMWindow> win = GetWindow();
nsCOMPtr<nsPIDOMWindow> win = GetWindow();
if (win) {
win->GetTop(aWindow);
win = win->GetTop();
}
win.forget(aWindow);
return NS_OK;
}
@@ -13267,23 +13267,19 @@ NS_IMETHODIMP
nsDocShell::GetTopFrameElement(nsIDOMElement** aElement)
{
*aElement = nullptr;
nsCOMPtr<nsIDOMWindow> win = GetWindow();
nsCOMPtr<nsPIDOMWindow> win = GetWindow();
if (!win) {
return NS_OK;
}
nsCOMPtr<nsIDOMWindow> top;
win->GetScriptableTop(getter_AddRefs(top));
nsCOMPtr<nsPIDOMWindow> top = win->GetScriptableTop();
NS_ENSURE_TRUE(top, NS_ERROR_FAILURE);
nsCOMPtr<nsPIDOMWindow> piTop = do_QueryInterface(top);
NS_ENSURE_TRUE(piTop, NS_ERROR_FAILURE);
// GetFrameElementInternal, /not/ GetScriptableFrameElement -- if |top| is
// inside <iframe mozbrowser>, we want to return the iframe, not null.
// And we want to cross the content/chrome boundary.
nsCOMPtr<nsIDOMElement> elt =
do_QueryInterface(piTop->GetFrameElementInternal());
do_QueryInterface(top->GetFrameElementInternal());
elt.forget(aElement);
return NS_OK;
}
@@ -13398,7 +13394,7 @@ nsDocShell::EnsureCommandHandler()
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIDOMWindow> domWindow = GetWindow();
nsCOMPtr<nsPIDOMWindow> domWindow = GetWindow();
nsresult rv = commandUpdater->Init(domWindow);
if (NS_SUCCEEDED(rv)) {
mCommandManager = do_QueryInterface(commandUpdater);
+10 -9
View File
@@ -138,13 +138,12 @@ ThirdPartyUtil::IsThirdPartyWindow(nsIDOMWindow* aWindow,
}
}
nsCOMPtr<nsIDOMWindow> current = aWindow, parent;
nsCOMPtr<nsPIDOMWindow> current = do_QueryInterface(aWindow), parent;
nsCOMPtr<nsIURI> parentURI;
do {
// We use GetScriptableParent rather than GetParent because we consider
// <iframe mozbrowser/mozapp> to be a top-level frame.
rv = current->GetScriptableParent(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(rv, rv);
parent = current->GetScriptableParent();
if (SameCOMIdentity(parent, current)) {
// We're at the topmost content window. We already know the answer.
@@ -267,13 +266,14 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
// to the channel. This is limited to loads of certain types of resources. If
// those loads require cookies, the forceAllowThirdPartyCookie property should
// be set on the channel.
nsCOMPtr<nsIDOMWindow> ourWin, parentWin;
nsCOMPtr<nsIDOMWindow> ourWin;
ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
if (!ourWin) return NS_ERROR_INVALID_ARG;
// We use GetScriptableParent rather than GetParent because we consider
// <iframe mozbrowser/mozapp> to be a top-level frame.
ourWin->GetScriptableParent(getter_AddRefs(parentWin));
nsCOMPtr<nsPIDOMWindow> ourPWin = do_QueryInterface(ourWin);
nsCOMPtr<nsPIDOMWindow> parentWin = ourPWin->GetScriptableParent();
NS_ENSURE_TRUE(parentWin, NS_ERROR_INVALID_ARG);
// Check whether this is the document channel for this window (representing a
@@ -311,7 +311,6 @@ ThirdPartyUtil::GetTopWindowForChannel(nsIChannel* aChannel, nsIDOMWindow** aWin
{
NS_ENSURE_ARG(aWin);
nsresult rv;
// Find the associated window and its parent window.
nsCOMPtr<nsILoadContext> ctx;
NS_QueryNotificationCallbacks(aChannel, ctx);
@@ -320,13 +319,15 @@ ThirdPartyUtil::GetTopWindowForChannel(nsIChannel* aChannel, nsIDOMWindow** aWin
}
nsCOMPtr<nsIDOMWindow> window;
rv = ctx->GetAssociatedWindow(getter_AddRefs(window));
ctx->GetAssociatedWindow(getter_AddRefs(window));
nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(window);
if (!window) {
return NS_ERROR_INVALID_ARG;
}
rv = window->GetTop(aWin);
return rv;
top = top->GetTop();
top.forget(aWin);
return NS_OK;
}
// Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be
+3 -6
View File
@@ -6759,7 +6759,7 @@ nsContentUtils::GetFullscreenAncestor(nsIDocument* aDoc)
/* static */
bool
nsContentUtils::IsInPointerLockContext(nsIDOMWindow* aWin)
nsContentUtils::IsInPointerLockContext(nsPIDOMWindow* aWin)
{
if (!aWin) {
return false;
@@ -6771,11 +6771,8 @@ nsContentUtils::IsInPointerLockContext(nsIDOMWindow* aWin)
return false;
}
nsCOMPtr<nsIDOMWindow> lockTop;
pointerLockedDoc->GetWindow()->GetScriptableTop(getter_AddRefs(lockTop));
nsCOMPtr<nsIDOMWindow> top;
aWin->GetScriptableTop(getter_AddRefs(top));
nsCOMPtr<nsPIDOMWindow> lockTop = pointerLockedDoc->GetWindow()->GetScriptableTop();
nsCOMPtr<nsPIDOMWindow> top = aWin->GetScriptableTop();
return top == lockTop;
}
+1 -1
View File
@@ -2035,7 +2035,7 @@ public:
* Returns true if aWin and the current pointer lock document
* have common scriptable top window.
*/
static bool IsInPointerLockContext(nsIDOMWindow* aWin);
static bool IsInPointerLockContext(nsPIDOMWindow* aWin);
/**
* Returns the time limit on handling user input before
+4 -10
View File
@@ -12325,18 +12325,15 @@ nsDocument::ShouldLockPointer(Element* aElement, Element* aCurrentLock,
return false;
}
nsCOMPtr<nsIDOMWindow> top;
ownerWindow->GetScriptableTop(getter_AddRefs(top));
nsCOMPtr<nsPIDOMWindow> piTop = do_QueryInterface(top);
if (!piTop || !piTop->GetExtantDoc() ||
piTop->GetExtantDoc()->Hidden()) {
nsCOMPtr<nsPIDOMWindow> top = ownerWindow->GetScriptableTop();
if (!top || !top->GetExtantDoc() || top->GetExtantDoc()->Hidden()) {
NS_WARNING("ShouldLockPointer(): Top document isn't visible.");
return false;
}
if (!aNoFocusCheck) {
mozilla::ErrorResult rv;
if (!piTop->GetExtantDoc()->HasFocus(rv)) {
if (!top->GetExtantDoc()->HasFocus(rv)) {
NS_WARNING("ShouldLockPointer(): Top document isn't focused.");
return false;
}
@@ -12899,10 +12896,7 @@ nsAutoSyncOperation::nsAutoSyncOperation(nsIDocument* aDoc)
if (aDoc) {
nsPIDOMWindow* win = aDoc->GetWindow();
if (win) {
nsCOMPtr<nsIDOMWindow> topWindow;
win->GetTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(topWindow);
if (top) {
if (nsCOMPtr<nsPIDOMWindow> top = win->GetTop()) {
nsCOMPtr<nsIDocument> doc = top->GetExtantDoc();
MarkDocumentTreeToBeInSyncOperation(doc, &mDocuments);
}
+165 -150
View File
@@ -45,6 +45,7 @@
#include "nsJSUtils.h"
#include "jsapi.h" // for JSAutoRequest
#include "jswrapper.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsReadableUtils.h"
#include "nsDOMClassInfo.h"
#include "nsJSEnvironment.h"
@@ -2284,7 +2285,7 @@ CreateNativeGlobalForInner(JSContext* aCx,
nsGlobalWindow *top = nullptr;
if (aNewInner->GetOuterWindow()) {
top = aNewInner->GetTop();
top = aNewInner->GetTopInternal();
}
JS::CompartmentOptions options;
@@ -2883,9 +2884,8 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
// window root object that will function as a chrome event
// handler and receive all events that occur anywhere inside
// our window.
nsCOMPtr<nsIDOMWindow> parentWindow;
GetParent(getter_AddRefs(parentWindow));
if (parentWindow.get() != static_cast<nsIDOMWindow*>(this)) {
nsCOMPtr<nsPIDOMWindow> parentWindow = GetParent();
if (parentWindow.get() != static_cast<nsPIDOMWindow*>(this)) {
nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(parentWindow));
mChromeEventHandler = piWindow->GetChromeEventHandler();
}
@@ -2964,7 +2964,7 @@ nsGlobalWindow::DetachFromDocShell()
}
void
nsGlobalWindow::SetOpenerWindow(nsIDOMWindow* aOpener,
nsGlobalWindow::SetOpenerWindow(nsPIDOMWindow* aOpener,
bool aOriginalOpener)
{
FORWARD_TO_OUTER_VOID(SetOpenerWindow, (aOpener, aOriginalOpener));
@@ -2975,10 +2975,6 @@ nsGlobalWindow::SetOpenerWindow(nsIDOMWindow* aOpener,
NS_ASSERTION(aOpener || !aOriginalOpener,
"Shouldn't set mHadOriginalOpener if aOpener is null");
#ifdef DEBUG
nsCOMPtr<nsPIDOMWindow> opener = do_QueryInterface(aOpener);
MOZ_ASSERT(!opener || opener->IsOuterWindow());
#endif
mOpener = do_GetWeakReference(aOpener);
NS_ASSERTION(mOpener || !aOpener, "Opener must support weak references!");
@@ -3022,7 +3018,7 @@ nsGlobalWindow::UpdateParentTarget()
TryGetTabChildGlobalAsEventTarget(frameElement);
if (!eventTarget) {
nsGlobalWindow* topWin = GetScriptableTop();
nsGlobalWindow* topWin = GetScriptableTopInternal();
if (topWin) {
frameElement = topWin->GetFrameElementInternal();
eventTarget = TryGetTabChildGlobalAsEventTarget(frameElement);
@@ -3131,7 +3127,7 @@ nsGlobalWindow::ShouldPromptToBlockDialogs()
{
MOZ_ASSERT(IsOuterWindow());
nsGlobalWindow *topWindow = GetScriptableTop();
nsGlobalWindow *topWindow = GetScriptableTopInternal();
if (!topWindow) {
NS_ASSERTION(!mDocShell, "ShouldPromptToBlockDialogs() called without a top window?");
return true;
@@ -3150,7 +3146,7 @@ nsGlobalWindow::AreDialogsEnabled()
{
MOZ_ASSERT(IsOuterWindow());
nsGlobalWindow *topWindow = GetScriptableTop();
nsGlobalWindow *topWindow = GetScriptableTopInternal();
if (!topWindow) {
NS_ERROR("AreDialogsEnabled() called without a top window?");
return false;
@@ -3242,7 +3238,7 @@ nsGlobalWindow::ConfirmDialogIfNeeded()
void
nsGlobalWindow::DisableDialogs()
{
nsGlobalWindow *topWindow = GetScriptableTop();
nsGlobalWindow *topWindow = GetScriptableTopInternal();
if (!topWindow) {
NS_ERROR("DisableDialogs() called without a top window?");
return;
@@ -3258,7 +3254,7 @@ nsGlobalWindow::DisableDialogs()
void
nsGlobalWindow::EnableDialogs()
{
nsGlobalWindow *topWindow = GetScriptableTop();
nsGlobalWindow *topWindow = GetScriptableTopInternal();
if (!topWindow) {
NS_ERROR("EnableDialogs() called without a top window?");
return;
@@ -3686,15 +3682,13 @@ nsPIDOMWindow::CreatePerformanceObjectIfNeeded()
// If we are dealing with an iframe, we will need the parent's performance
// object (so we can add the iframe as a resource of that page).
nsPerformance* parentPerformance = nullptr;
nsCOMPtr<nsIDOMWindow> parentWindow;
GetScriptableParent(getter_AddRefs(parentWindow));
nsCOMPtr<nsPIDOMWindow> parentPWindow = do_GetInterface(parentWindow);
if (GetOuterWindow() != parentPWindow) {
if (parentPWindow && !parentPWindow->IsInnerWindow()) {
parentPWindow = parentPWindow->GetCurrentInnerWindow();
nsCOMPtr<nsPIDOMWindow> parentWindow = GetScriptableParent();
if (GetOuterWindow() != parentWindow) {
if (parentWindow && !parentWindow->IsInnerWindow()) {
parentWindow = parentWindow->GetCurrentInnerWindow();
}
if (parentPWindow) {
parentPerformance = parentPWindow->GetPerformance();
if (parentWindow) {
parentPerformance = parentWindow->GetPerformance();
}
}
mPerformance =
@@ -3771,8 +3765,7 @@ nsPIDOMWindow::GetAudioGlobalVolume()
globalVolume *= window->GetAudioVolume();
nsCOMPtr<nsIDOMWindow> win;
window->GetParent(getter_AddRefs(win));
nsCOMPtr<nsPIDOMWindow> win = window->GetParent();
if (window == win) {
break;
}
@@ -3826,9 +3819,9 @@ nsGlobalWindow::GetSpeechSynthesis(ErrorResult& aError)
#endif
already_AddRefed<nsIDOMWindow>
nsGlobalWindow::GetParent(ErrorResult& aError)
nsGlobalWindow::GetParentOuter()
{
FORWARD_TO_OUTER_OR_THROW(GetParent, (aError), aError, nullptr);
MOZ_RELEASE_ASSERT(IsOuterWindow());
if (!mDocShell) {
return nullptr;
@@ -3838,12 +3831,18 @@ nsGlobalWindow::GetParent(ErrorResult& aError)
if (mDocShell->GetIsBrowserOrApp()) {
parent = this;
} else {
aError = GetRealParent(getter_AddRefs(parent));
parent = GetParent();
}
return parent.forget();
}
already_AddRefed<nsIDOMWindow>
nsGlobalWindow::GetParent(ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetParentOuter, (), aError, nullptr);
}
/**
* GetScriptableParent is called when script reads window.parent.
*
@@ -3851,28 +3850,27 @@ nsGlobalWindow::GetParent(ErrorResult& aError)
* mozbrowser> boundaries, so if |this| is contained by an <iframe
* mozbrowser>, we will return |this| as its own parent.
*/
NS_IMETHODIMP
nsGlobalWindow::GetScriptableParent(nsIDOMWindow** aParent)
nsPIDOMWindow*
nsGlobalWindow::GetScriptableParent()
{
ErrorResult rv;
nsCOMPtr<nsIDOMWindow> parent = GetParent(rv);
parent.forget(aParent);
FORWARD_TO_OUTER(GetScriptableParent, (), nullptr);
return rv.ErrorCode();
nsCOMPtr<nsIDOMWindow> parent = GetParentOuter();
nsCOMPtr<nsPIDOMWindow> piParent = do_QueryInterface(parent);
return piParent.get();
}
/**
* nsIDOMWindow::GetParent (when called from C++) is just a wrapper around
* GetRealParent.
*/
NS_IMETHODIMP
nsGlobalWindow::GetRealParent(nsIDOMWindow** aParent)
already_AddRefed<nsPIDOMWindow>
nsGlobalWindow::GetParent()
{
FORWARD_TO_OUTER(GetRealParent, (aParent), NS_ERROR_NOT_INITIALIZED);
MOZ_ASSERT(IsOuterWindow());
*aParent = nullptr;
if (!mDocShell) {
return NS_OK;
return nullptr;
}
nsCOMPtr<nsIDocShell> parent;
@@ -3880,24 +3878,22 @@ nsGlobalWindow::GetRealParent(nsIDOMWindow** aParent)
if (parent) {
nsCOMPtr<nsPIDOMWindow> win = parent->GetWindow();
win.forget(aParent);
return win.forget();
}
else {
*aParent = static_cast<nsIDOMWindow*>(this);
NS_ADDREF(*aParent);
}
return NS_OK;
nsCOMPtr<nsPIDOMWindow> win(this);
return win.forget();
}
static nsresult
GetTopImpl(nsGlobalWindow* aWin, nsIDOMWindow** aTop, bool aScriptable)
GetTopImpl(nsGlobalWindow* aWin, nsPIDOMWindow** aTop, bool aScriptable)
{
*aTop = nullptr;
// Walk up the parent chain.
nsCOMPtr<nsIDOMWindow> prevParent = aWin;
nsCOMPtr<nsIDOMWindow> parent = aWin;
nsCOMPtr<nsPIDOMWindow> prevParent = aWin;
nsCOMPtr<nsPIDOMWindow> parent = aWin;
do {
if (!parent) {
break;
@@ -3905,15 +3901,14 @@ GetTopImpl(nsGlobalWindow* aWin, nsIDOMWindow** aTop, bool aScriptable)
prevParent = parent;
nsCOMPtr<nsIDOMWindow> newParent;
nsCOMPtr<nsPIDOMWindow> newParent;
nsresult rv;
if (aScriptable) {
rv = parent->GetScriptableParent(getter_AddRefs(newParent));
newParent = parent->GetScriptableParent();
}
else {
rv = parent->GetParent(getter_AddRefs(newParent));
newParent = parent->GetParent();
}
NS_ENSURE_SUCCESS(rv, rv);
parent = newParent;
@@ -3933,31 +3928,23 @@ GetTopImpl(nsGlobalWindow* aWin, nsIDOMWindow** aTop, bool aScriptable)
* boundaries. If we encounter a window owned by an <iframe mozbrowser> while
* walking up the window hierarchy, we'll stop and return that window.
*/
NS_IMETHODIMP
nsGlobalWindow::GetScriptableTop(nsIDOMWindow **aTop)
nsPIDOMWindow*
nsGlobalWindow::GetScriptableTop()
{
FORWARD_TO_OUTER(GetScriptableTop, (aTop), NS_ERROR_NOT_INITIALIZED);
return GetTopImpl(this, aTop, /* aScriptable = */ true);
FORWARD_TO_OUTER(GetScriptableTop, (), nullptr);
nsCOMPtr<nsPIDOMWindow> window;
GetTopImpl(this, getter_AddRefs(window), /* aScriptable = */ true);
return window.get();
}
/**
* nsIDOMWindow::GetTop (when called from C++) is just a wrapper around
* GetRealTop.
*/
NS_IMETHODIMP
nsGlobalWindow::GetRealTop(nsIDOMWindow** aTop)
already_AddRefed<nsPIDOMWindow>
nsGlobalWindow::GetTop()
{
nsGlobalWindow* outer;
if (IsInnerWindow()) {
outer = GetOuterWindowInternal();
if (!outer) {
NS_WARNING("No outer window available!");
return NS_ERROR_NOT_INITIALIZED;
}
} else {
outer = this;
}
return GetTopImpl(outer, aTop, /* aScriptable = */ false);
MOZ_ASSERT(IsOuterWindow());
nsCOMPtr<nsPIDOMWindow> window;
GetTopImpl(this, getter_AddRefs(window), /* aScriptable = */ false);
return window.forget();
}
void
@@ -4000,7 +3987,7 @@ nsGlobalWindow::GetContentInternal(ErrorResult& aError)
// If we're contained in <iframe mozbrowser> or <iframe mozapp>, then
// GetContent is the same as window.top.
if (mDocShell && mDocShell->GetIsInBrowserOrApp()) {
return GetTop(aError);
return GetTopOuter();
}
nsCOMPtr<nsIDocShellTreeItem> primaryContent;
@@ -4495,7 +4482,7 @@ nsGlobalWindow::GetControllers(nsIControllers** aResult)
return rv.ErrorCode();
}
nsIDOMWindow*
nsPIDOMWindow*
nsGlobalWindow::GetOpenerWindow(ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetOpenerWindow, (aError), aError, nullptr);
@@ -4566,13 +4553,16 @@ nsGlobalWindow::GetScriptableOpener(JSContext* aCx,
return rv.ErrorCode();
}
NS_IMETHODIMP
nsGlobalWindow::GetOpener(nsIDOMWindow** aOpener)
already_AddRefed<nsPIDOMWindow>
nsGlobalWindow::GetOpener()
{
ErrorResult rv;
nsCOMPtr<nsIDOMWindow> opener = GetOpenerWindow(rv);
opener.forget(aOpener);
return rv.ErrorCode();
FORWARD_TO_INNER(GetOpener, (), nullptr);
ErrorResult dummy;
nsCOMPtr<nsPIDOMWindow> opener = GetOpenerWindow(dummy);
dummy.SuppressException();
return opener.forget();
}
void
@@ -4645,12 +4635,6 @@ nsGlobalWindow::SetScriptableOpener(JSContext* aCx,
return rv.ErrorCode();
}
NS_IMETHODIMP
nsGlobalWindow::SetOpener(nsIDOMWindow* aOpener)
{
SetOpenerWindow(aOpener, false);
return NS_OK;
}
void
nsGlobalWindow::GetStatus(nsAString& aStatus, ErrorResult& aError)
@@ -5845,6 +5829,21 @@ nsGlobalWindow::GetLength(uint32_t* aLength)
return NS_OK;
}
already_AddRefed<nsIDOMWindow>
nsGlobalWindow::GetTopOuter()
{
MOZ_ASSERT(IsOuterWindow());
nsCOMPtr<nsPIDOMWindow> top = GetScriptableTop();
return top.forget();
}
already_AddRefed<nsIDOMWindow>
nsGlobalWindow::GetTop(mozilla::ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetTopOuter, (), aError, nullptr);
}
nsPIDOMWindow*
nsGlobalWindow::GetChildWindow(const nsAString& aName)
{
@@ -6577,8 +6576,7 @@ nsGlobalWindow::Focus(ErrorResult& aError)
nsCOMPtr<nsPIDOMWindow> caller = do_QueryInterface(GetEntryGlobal());
caller = caller ? caller->GetOuterWindow() : nullptr;
nsCOMPtr<nsIDOMWindow> opener;
GetOpener(getter_AddRefs(opener));
nsCOMPtr<nsIDOMWindow> opener = GetOpener();
// Enforce dom.disable_window_flip (for non-chrome), but still allow the
// window which opened us to raise us at times when popups are allowed
@@ -7542,13 +7540,6 @@ nsGlobalWindow::FirePopupBlockedEvent(nsIDocument* aDoc,
aDoc->DispatchEvent(event, &defaultActionEnabled);
}
static void FirePopupWindowEvent(nsIDocument* aDoc)
{
// Fire a "PopupWindow" event
nsContentUtils::DispatchTrustedEvent(aDoc, aDoc,
NS_LITERAL_STRING("PopupWindow"),
true, true);
}
// static
bool
@@ -7570,17 +7561,13 @@ nsGlobalWindow::PopupWhitelisted()
if (!IsPopupBlocked(mDoc))
return true;
nsCOMPtr<nsIDOMWindow> parent;
if (NS_FAILED(GetParent(getter_AddRefs(parent))) ||
parent == static_cast<nsIDOMWindow*>(this))
nsCOMPtr<nsPIDOMWindow> parent = GetParent();
if (parent == static_cast<nsPIDOMWindow*>(this))
{
return false;
}
return static_cast<nsGlobalWindow*>
(static_cast<nsIDOMWindow*>
(parent.get()))->PopupWhitelisted();
return static_cast<nsGlobalWindow*>(parent.get())->PopupWhitelisted();
}
/*
@@ -7622,21 +7609,15 @@ nsGlobalWindow::RevisePopupAbuseLevel(PopupControlState aControl)
return abuse;
}
/* If a window open is blocked, fire the appropriate DOM events.
aBlocked signifies we just blocked a popup.
aWindow signifies we just opened what is probably a popup.
*/
/* If a window open is blocked, fire the appropriate DOM events. */
void
nsGlobalWindow::FireAbuseEvents(bool aBlocked, bool aWindow,
const nsAString &aPopupURL,
nsGlobalWindow::FireAbuseEvents(const nsAString &aPopupURL,
const nsAString &aPopupWindowName,
const nsAString &aPopupWindowFeatures)
{
// fetch the URI of the window requesting the opened window
nsCOMPtr<nsIDOMWindow> topWindow;
GetTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(topWindow);
nsCOMPtr<nsPIDOMWindow> window = GetTop();
if (!window) {
return;
}
@@ -7662,12 +7643,8 @@ nsGlobalWindow::FireAbuseEvents(bool aBlocked, bool aWindow,
getter_AddRefs(popupURI));
// fire an event chock full of informative URIs
if (aBlocked) {
FirePopupBlockedEvent(topDoc, popupURI, aPopupWindowName,
aPopupWindowFeatures);
}
if (aWindow)
FirePopupWindowEvent(topDoc);
FirePopupBlockedEvent(topDoc, popupURI, aPopupWindowName,
aPopupWindowFeatures);
}
already_AddRefed<nsIDOMWindow>
@@ -7681,22 +7658,32 @@ nsGlobalWindow::Open(const nsAString& aUrl, const nsAString& aName,
return window.forget();
}
NS_IMETHODIMP
nsresult
nsGlobalWindow::Open(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions, nsIDOMWindow **_retval)
const nsAString& aOptions, nsIDocShellLoadInfo* aLoadInfo,
bool aForceNoOpener, nsPIDOMWindow **_retval)
{
FORWARD_TO_OUTER(Open, (aUrl, aName, aOptions, _retval),
FORWARD_TO_OUTER(Open, (aUrl, aName, aOptions, aLoadInfo, aForceNoOpener,
_retval),
NS_ERROR_NOT_INITIALIZED);
return OpenInternal(aUrl, aName, aOptions,
false, // aDialog
false, // aContentModal
true, // aCalledNoScript
false, // aDoJSFixups
true, // aNavigate
nullptr, nullptr, // No args
GetPrincipal(), // aCalleePrincipal
nullptr, // aJSCallerContext
_retval);
nsCOMPtr<nsIDOMWindow> window;
nsresult rv = OpenInternal(aUrl, aName, aOptions,
false, // aDialog
false, // aContentModal
true, // aCalledNoScript
false, // aDoJSFixups
true, // aNavigate
nullptr, nullptr, // No args
aLoadInfo,
aForceNoOpener,
GetPrincipal(), // aCalleePrincipal
nullptr, // aJSCallerContext
getter_AddRefs(window));
if (NS_SUCCEEDED(rv) && window) {
return CallQueryInterface(window, _retval);
}
return rv;
}
NS_IMETHODIMP
@@ -7712,6 +7699,8 @@ nsGlobalWindow::OpenJS(const nsAString& aUrl, const nsAString& aName,
true, // aDoJSFixups
true, // aNavigate
nullptr, nullptr, // No args
nullptr, // aLoadInfo
false, // aForceNoOpener
GetPrincipal(), // aCalleePrincipal
nsContentUtils::GetCurrentJSContext(), // aJSCallerContext
_retval);
@@ -7719,7 +7708,7 @@ nsGlobalWindow::OpenJS(const nsAString& aUrl, const nsAString& aName,
// like Open, but attaches to the new window any extra parameters past
// [features] as a JS property named "arguments"
NS_IMETHODIMP
nsresult
nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions,
nsISupports* aExtraArgument, nsIDOMWindow** _retval)
@@ -7732,9 +7721,11 @@ nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
true, // aCalledNoScript
false, // aDoJSFixups
true, // aNavigate
nullptr, aExtraArgument, // Arguments
GetPrincipal(), // aCalleePrincipal
nullptr, // aJSCallerContext
nullptr, aExtraArgument, // Arguments
nullptr, // aLoadInfo
false, // aForceNoOpener
GetPrincipal(), // aCalleePrincipal
nullptr, // aJSCallerContext
_retval);
}
@@ -7753,6 +7744,8 @@ nsGlobalWindow::OpenNoNavigate(const nsAString& aUrl,
false, // aDoJSFixups
false, // aNavigate
nullptr, nullptr, // No args
nullptr, // aLoadInfo
false, // aForceNoOpener
GetPrincipal(), // aCalleePrincipal
nullptr, // aJSCallerContext
_retval);
@@ -7785,6 +7778,8 @@ nsGlobalWindow::OpenDialog(JSContext* aCx, const nsAString& aUrl,
false, // aDoJSFixups
true, // aNavigate
argvArray, nullptr, // Arguments
nullptr, // aLoadInfo
false, // aForceNoOpener
GetPrincipal(), // aCalleePrincipal
aCx, // aJSCallerContext
getter_AddRefs(dialog));
@@ -7836,6 +7831,8 @@ nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
false, // aDoJSFixups
true, // aNavigate
argvArray, nullptr, // Arguments
nullptr, // aLoadInfo
false, // aForceNoOpener
GetPrincipal(), // aCalleePrincipal
cx, // aJSCallerContext
_retval);
@@ -8700,7 +8697,7 @@ nsGlobalWindow::EnterModalState()
// GetScriptableTop, not GetTop, so that EnterModalState works properly with
// <iframe mozbrowser>.
nsGlobalWindow* topWin = GetScriptableTop();
nsGlobalWindow* topWin = GetScriptableTopInternal();
if (!topWin) {
NS_ERROR("Uh, EnterModalState() called w/o a reachable top window?");
@@ -8831,7 +8828,7 @@ nsGlobalWindow::LeaveModalState()
{
MOZ_ASSERT(IsOuterWindow(), "Modal state is maintained on outer windows");
nsGlobalWindow* topWin = GetScriptableTop();
nsGlobalWindow* topWin = GetScriptableTopInternal();
if (!topWin) {
NS_ERROR("Uh, LeaveModalState() called w/o a reachable top window?");
@@ -8872,7 +8869,7 @@ nsGlobalWindow::LeaveModalState()
bool
nsGlobalWindow::IsInModalState()
{
nsGlobalWindow *topWin = GetScriptableTop();
nsGlobalWindow *topWin = GetScriptableTopInternal();
if (!topWin) {
NS_ERROR("Uh, IsInModalState() called w/o a reachable top window?");
@@ -9379,6 +9376,8 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aUrl, nsIVariant* aArgument,
true, // aDoJSFixups
true, // aNavigate
nullptr, argHolder, // args
nullptr, // aLoadInfo
false, // aForceNoOpener
GetPrincipal(), // aCalleePrincipal
nullptr, // aJSCallerContext
getter_AddRefs(dlgWin));
@@ -9852,10 +9851,9 @@ nsGlobalWindow::GetPrivateParent()
{
MOZ_ASSERT(IsOuterWindow());
nsCOMPtr<nsIDOMWindow> parent;
GetParent(getter_AddRefs(parent));
nsCOMPtr<nsPIDOMWindow> parent = GetParent();
if (static_cast<nsIDOMWindow *>(this) == parent.get()) {
if (static_cast<nsPIDOMWindow *>(this) == parent.get()) {
nsCOMPtr<nsIContent> chromeElement(do_QueryInterface(mChromeEventHandler));
if (!chromeElement)
return nullptr; // This is ok, just means a null parent.
@@ -9887,16 +9885,15 @@ nsGlobalWindow::GetPrivateRoot()
return outer->GetPrivateRoot();
}
nsCOMPtr<nsIDOMWindow> top;
GetTop(getter_AddRefs(top));
nsCOMPtr<nsPIDOMWindow> top = GetTop();
nsCOMPtr<nsIContent> chromeElement(do_QueryInterface(mChromeEventHandler));
if (chromeElement) {
nsIDocument* doc = chromeElement->GetComposedDoc();
if (doc) {
nsIDOMWindow *parent = doc->GetWindow();
nsCOMPtr<nsPIDOMWindow> parent = doc->GetWindow();
if (parent) {
parent->GetTop(getter_AddRefs(top));
top = parent->GetTop();
}
}
}
@@ -11844,10 +11841,9 @@ nsGlobalWindow::GetParentInternal()
return outer->GetParentInternal();
}
nsCOMPtr<nsIDOMWindow> parent;
GetParent(getter_AddRefs(parent));
nsCOMPtr<nsPIDOMWindow> parent = GetParent();
if (parent && parent != static_cast<nsIDOMWindow *>(this)) {
if (parent && parent != static_cast<nsPIDOMWindow *>(this)) {
return parent;
}
@@ -11886,6 +11882,8 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
bool aDoJSFixups, bool aNavigate,
nsIArray *argv,
nsISupports *aExtraArgument,
nsIDocShellLoadInfo* aLoadInfo,
bool aForceNoOpener,
nsIPrincipal *aCalleePrincipal,
JSContext *aJSCallerContext,
nsIDOMWindow **aReturn)
@@ -11927,6 +11925,21 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
nsIPrincipal::APP_STATUS_INSTALLED;
}
bool forceNoOpener = aForceNoOpener;
if (!forceNoOpener) {
// Unlike other window flags, "noopener" comes from splitting on commas with
// HTML whitespace trimming...
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tok(
aOptions, ',');
while (tok.hasMoreTokens()) {
if (tok.nextToken().EqualsLiteral("noopener")) {
forceNoOpener = true;
break;
}
}
}
const bool checkForPopup = !nsContentUtils::IsCallerChrome() &&
!isApp && !aDialog && !WindowExists(aName, !aCalledNoScript);
@@ -11971,7 +11984,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
}
}
FireAbuseEvents(true, false, aUrl, aName, aOptions);
FireAbuseEvents(aUrl, aName, aOptions);
return aDoJSFixups ? NS_OK : NS_ERROR_FAILURE;
}
}
@@ -12003,6 +12016,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
/* aCalledFromScript = */ true,
aDialog, aNavigate, nullptr, argv,
aLoadInfo,
getter_AddRefs(domReturn));
} else {
// Force a system caller here so that the window watcher won't screw us
@@ -12023,6 +12037,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
/* aCalledFromScript = */ false,
aDialog, aNavigate, nullptr, aExtraArgument,
aLoadInfo,
getter_AddRefs(domReturn));
}
@@ -12057,6 +12072,8 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
}
if (checkForPopup) {
MOZ_ASSERT(abuseLevel < openAbused, "Why didn't we take the early return?");
if (abuseLevel >= openControlled) {
nsGlobalWindow *opened = static_cast<nsGlobalWindow *>(*aReturn);
if (!opened->IsPopupSpamWindow()) {
@@ -12064,8 +12081,6 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
++gOpenPopupSpamCount;
}
}
if (abuseLevel >= openAbused)
FireAbuseEvents(false, true, aUrl, aName, aOptions);
}
return rv;
+34 -31
View File
@@ -402,7 +402,7 @@ public:
bool aUseCapture,
const mozilla::dom::Nullable<bool>& aWantsUntrusted,
mozilla::ErrorResult& aRv) override;
virtual nsIDOMWindow* GetOwnerGlobalForBindings() override
virtual nsPIDOMWindow* GetOwnerGlobalForBindings() override
{
if (IsOuterWindow()) {
return this;
@@ -461,7 +461,7 @@ public:
// Outer windows only.
void DispatchDOMWindowCreated();
virtual void SetOpenerWindow(nsIDOMWindow* aOpener,
virtual void SetOpenerWindow(nsPIDOMWindow* aOpener,
bool aOriginalOpener) override;
// Outer windows only.
@@ -525,30 +525,22 @@ public:
return FromSupports(wrapper->Native());
}
/**
* Wrap nsIDOMWindow::GetTop so we can overload the inline GetTop()
* implementation below. (nsIDOMWindow::GetTop simply calls
* nsIDOMWindow::GetRealTop().)
*/
nsresult GetTop(nsIDOMWindow **aWindow)
already_AddRefed<nsIDOMWindow> GetTopOuter();
already_AddRefed<nsPIDOMWindow> GetTop() override;
nsPIDOMWindow* GetScriptableTop() override;
inline nsGlobalWindow *GetTopInternal()
{
return nsIDOMWindow::GetTop(aWindow);
}
inline nsGlobalWindow *GetTop()
{
nsCOMPtr<nsIDOMWindow> top;
GetTop(getter_AddRefs(top));
nsGlobalWindow* outer = IsOuterWindow() ? this : GetOuterWindowInternal();
nsCOMPtr<nsPIDOMWindow> top = outer ? outer->GetTop() : nullptr;
if (top)
return static_cast<nsGlobalWindow *>(top.get());
return nullptr;
}
inline nsGlobalWindow* GetScriptableTop()
inline nsGlobalWindow* GetScriptableTopInternal()
{
nsCOMPtr<nsIDOMWindow> top;
GetScriptableTop(getter_AddRefs(top));
return static_cast<nsGlobalWindow *>(top.get());
nsPIDOMWindow* top = GetScriptableTop();
return static_cast<nsGlobalWindow*>(top);
}
nsPIDOMWindow* GetChildWindow(const nsAString& aName);
@@ -848,29 +840,32 @@ public:
void Blur(mozilla::ErrorResult& aError);
already_AddRefed<nsIDOMWindow> GetFrames(mozilla::ErrorResult& aError);
uint32_t Length();
already_AddRefed<nsIDOMWindow> GetTop(mozilla::ErrorResult& aError)
{
nsCOMPtr<nsIDOMWindow> top;
aError = GetScriptableTop(getter_AddRefs(top));
return top.forget();
}
already_AddRefed<nsIDOMWindow> GetTop(mozilla::ErrorResult& aError);
protected:
explicit nsGlobalWindow(nsGlobalWindow *aOuterWindow);
nsIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError);
nsPIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError);
// Initializes the mWasOffline member variable
void InitWasOffline();
public:
void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
already_AddRefed<nsPIDOMWindow> GetOpener() override;
void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
mozilla::ErrorResult& aError);
using nsIDOMWindow::GetParent;
already_AddRefed<nsIDOMWindow> GetParentOuter();
already_AddRefed<nsIDOMWindow> GetParent(mozilla::ErrorResult& aError);
already_AddRefed<nsPIDOMWindow> GetParent() override;
nsPIDOMWindow* GetScriptableParent() override;
mozilla::dom::Element* GetFrameElement(mozilla::ErrorResult& aError);
already_AddRefed<nsIDOMWindow> Open(const nsAString& aUrl,
const nsAString& aName,
const nsAString& aOptions,
mozilla::ErrorResult& aError);
nsresult Open(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions,
nsIDocShellLoadInfo* aLoadInfo,
bool aForceNoOpener,
nsPIDOMWindow **_retval) override;
mozilla::dom::Navigator* GetNavigator(mozilla::ErrorResult& aError);
nsIDOMOfflineResourceList* GetApplicationCache(mozilla::ErrorResult& aError);
@@ -1027,6 +1022,10 @@ public:
const nsAString& aOptions,
const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
mozilla::ErrorResult& aError);
nsresult
OpenDialog(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions,
nsISupports* aExtraArgument, nsIDOMWindow** _retval) override;
void GetContent(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& aError);
@@ -1197,11 +1196,14 @@ private:
* three args, if present, will be aUrl, aName, and aOptions. So this
* param only matters if there are more than 3 arguments.
*
* @param argc The number of arguments in argv.
*
* @param aExtraArgument Another way to pass arguments in. This is mutually
* exclusive with the argv/argc approach.
*
* @param aLoadInfo to be passed on along to the windowwatcher.
* @param aForceNoOpener if true, will act as if "noopener" were passed in
* aOptions, but without affecting any other window
* features.
*
* @param aJSCallerContext The calling script's context. This must be null
* when aCalledNoScript is true.
*
@@ -1219,6 +1221,8 @@ private:
bool aNavigate,
nsIArray *argv,
nsISupports *aExtraArgument,
nsIDocShellLoadInfo* aLoadInfo,
bool aForceNoOpener,
nsIPrincipal *aCalleePrincipal,
JSContext *aJSCallerContext,
nsIDOMWindow **aReturn);
@@ -1273,8 +1277,7 @@ public:
bool PopupWhitelisted();
PopupControlState RevisePopupAbuseLevel(PopupControlState);
void FireAbuseEvents(bool aBlocked, bool aWindow,
const nsAString &aPopupURL,
void FireAbuseEvents(const nsAString &aPopupURL,
const nsAString &aPopupWindowName,
const nsAString &aPopupWindowFeatures);
void FireOfflineStatusEventIfChanged();
+5 -8
View File
@@ -3263,17 +3263,14 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentTyp
MOZ_ASSERT(thisContent);
nsIDocument* ownerDoc = thisContent->OwnerDoc();
nsCOMPtr<nsIDOMWindow> window = ownerDoc->GetWindow();
nsCOMPtr<nsPIDOMWindow> window = ownerDoc->GetWindow();
if (!window) {
return false;
}
nsCOMPtr<nsIDOMWindow> topWindow;
rv = window->GetTop(getter_AddRefs(topWindow));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIDOMDocument> topDocument;
rv = topWindow->GetDocument(getter_AddRefs(topDocument));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIDocument> topDoc = do_QueryInterface(topDocument);
nsCOMPtr<nsPIDOMWindow> topWindow = window->GetTop();
NS_ENSURE_TRUE(topWindow, false);
nsCOMPtr<nsIDocument> topDoc = topWindow->GetDoc();
NS_ENSURE_TRUE(topDoc, false);
nsCOMPtr<nsIPermissionManager> permissionManager = services::GetPermissionManager();
NS_ENSURE_TRUE(permissionManager, false);
+32 -1
View File
@@ -23,6 +23,7 @@
class nsIArray;
class nsIContent;
class nsIDocShell;
class nsIDocShellLoadInfo;
class nsIDocument;
class nsIIdleObserver;
class nsIPrincipal;
@@ -77,6 +78,23 @@ public:
virtual void ActivateOrDeactivate(bool aActivate) = 0;
// this is called GetTopWindowRoot to avoid conflicts with nsIDOMWindow::GetWindowRoot
/**
* |top| gets the root of the window hierarchy.
*
* This function does not cross chrome-content boundaries, so if this
* window's parent is of a different type, |top| will return this window.
*
* When script reads the top property, we run GetScriptableTop, which
* will not cross an <iframe mozbrowser> boundary.
*
* In contrast, C++ calls to GetTop are forwarded to GetRealTop, which
* ignores <iframe mozbrowser> boundaries.
*/
virtual already_AddRefed<nsPIDOMWindow> GetTop() = 0; // Outer only
virtual already_AddRefed<nsPIDOMWindow> GetParent() = 0;
virtual nsPIDOMWindow* GetScriptableTop() = 0;
virtual nsPIDOMWindow* GetScriptableParent() = 0;
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() = 0;
// Inner windows only.
@@ -389,7 +407,7 @@ public:
* SetOpenerWindow is called. It might never be true, of course, if the
* window does not have an opener when it's created.
*/
virtual void SetOpenerWindow(nsIDOMWindow* aOpener,
virtual void SetOpenerWindow(nsPIDOMWindow* aOpener,
bool aOriginalOpener) = 0;
virtual void EnsureSizeUpToDate() = 0;
@@ -762,6 +780,19 @@ public:
// SetRequestNotifyAfterRemotePaint().
void SendAfterRemotePaintIfRequested();
virtual already_AddRefed<nsPIDOMWindow> GetOpener() = 0;
// aLoadInfo will be passed on through to the windowwatcher.
// aForceNoOpener will act just like a "noopener" feature in aOptions except
// will not affect any other window features.
virtual nsresult Open(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions,
nsIDocShellLoadInfo* aLoadInfo,
bool aForceNoOpener,
nsPIDOMWindow **_retval) = 0;
virtual nsresult OpenDialog(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions,
nsISupports* aExtraArgument, nsIDOMWindow** _retval) = 0;
protected:
// The nsPIDOMWindow constructor. The aOuterWindow argument should
// be null if and only if the created window itself is an outer
+3 -3
View File
@@ -253,7 +253,7 @@ CollectWindowReports(nsGlobalWindow *aWindow,
if (aWindow->GetOuterWindow()) {
// Our window should have a null top iff it has a null docshell.
MOZ_ASSERT(!!aWindow->GetTop() == !!aWindow->GetDocShell());
top = aWindow->GetTop();
top = aWindow->GetTopInternal();
if (top) {
location = GetWindowURI(top);
}
@@ -763,7 +763,7 @@ CheckForGhostWindowsEnumerator(nsISupports *aKey, TimeStamp& aTimeStamp,
// overflow.
nsCOMPtr<nsIDOMWindow> top;
if (window->GetOuterWindow()) {
window->GetTop(getter_AddRefs(top));
top = window->GetOuterWindow()->GetTop();
}
if (top) {
@@ -820,7 +820,7 @@ GetNonDetachedWindowDomainsEnumerator(const uint64_t& aId, nsGlobalWindow* aWind
// Null outer window implies null top, but calling GetTop() when there's no
// outer window causes us to spew debug warnings.
if (!aWindow->GetOuterWindow() || !aWindow->GetTop()) {
if (!aWindow->GetOuterWindow() || !aWindow->GetTopInternal()) {
// This window is detached, so we don't care about its domain.
return PL_DHASH_NEXT;
}
+1 -2
View File
@@ -3099,8 +3099,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
nsCOMPtr<nsIDocument> suspendedDoc;
nsCOMPtr<nsIRunnable> resumeTimeoutRunnable;
if (GetOwner()) {
nsCOMPtr<nsIDOMWindow> topWindow;
if (NS_SUCCEEDED(GetOwner()->GetTop(getter_AddRefs(topWindow)))) {
if (nsCOMPtr<nsPIDOMWindow> topWindow = GetOwner()->GetOuterWindow()->GetTop()) {
nsCOMPtr<nsPIDOMWindow> suspendedWindow(do_QueryInterface(topWindow));
if (suspendedWindow &&
(suspendedWindow = suspendedWindow->GetCurrentInnerWindow())) {
+2 -4
View File
@@ -260,10 +260,8 @@ BrowserElementParent::OpenWindowInProcess(nsIDOMWindow* aOpenerWindow,
// GetScriptableTop gets us the <iframe mozbrowser>'s window; we'll use its
// frame element, rather than aOpenerWindow's frame element, as our "opener
// frame element" below.
nsCOMPtr<nsIDOMWindow> topWindow;
aOpenerWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(topWindow);
nsCOMPtr<nsPIDOMWindow> openerWindow = do_QueryInterface(aOpenerWindow);
nsCOMPtr<nsPIDOMWindow> win = openerWindow->GetScriptableTop();
nsCOMPtr<Element> openerFrameElement = win->GetFrameElementInternal();
NS_ENSURE_TRUE(openerFrameElement, BrowserElementParent::OPEN_WINDOW_IGNORED);
+8 -8
View File
@@ -2953,17 +2953,17 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
EnsureDocument(mPresContext);
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (mDocument && fm) {
nsCOMPtr<nsIDOMWindow> currentWindow;
fm->GetFocusedWindow(getter_AddRefs(currentWindow));
nsCOMPtr<nsIDOMWindow> window;
fm->GetFocusedWindow(getter_AddRefs(window));
nsCOMPtr<nsPIDOMWindow> currentWindow = do_QueryInterface(window);
if (currentWindow && mDocument->GetWindow() &&
currentWindow != mDocument->GetWindow() &&
!nsContentUtils::IsChromeDoc(mDocument)) {
nsCOMPtr<nsIDOMWindow> currentTop;
nsCOMPtr<nsIDOMWindow> newTop;
currentWindow->GetTop(getter_AddRefs(currentTop));
mDocument->GetWindow()->GetTop(getter_AddRefs(newTop));
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(currentWindow);
nsCOMPtr<nsIDocument> currentDoc = win->GetExtantDoc();
nsCOMPtr<nsPIDOMWindow> currentTop;
nsCOMPtr<nsPIDOMWindow> newTop;
currentTop = currentWindow->GetTop();
newTop = mDocument->GetWindow()->GetTop();
nsCOMPtr<nsIDocument> currentDoc = currentWindow->GetExtantDoc();
if (nsContentUtils::IsChromeDoc(currentDoc) ||
(currentTop && newTop && currentTop != newTop)) {
fm->SetFocusedWindow(mDocument->GetWindow());
+2 -4
View File
@@ -135,10 +135,8 @@ public:
}
// Trying to found the top window (equivalent to window.top).
nsCOMPtr<nsIDOMWindow> top;
window->GetTop(getter_AddRefs(top));
if (top) {
window = static_cast<nsPIDOMWindow*>(top.get());
if (nsCOMPtr<nsPIDOMWindow> top = window->GetTop()) {
window = top;
}
if (window->GetFocusedNode()) {
-82
View File
@@ -92,70 +92,10 @@ interface nsIDOMWindow : nsISupports
/* [replaceable] length */
readonly attribute unsigned long length;
/**
* |top| gets the root of the window hierarchy.
*
* This function does not cross chrome-content boundaries, so if this
* window's parent is of a different type, |top| will return this window.
*
* When script reads the top property, we run GetScriptableTop, which
* will not cross an <iframe mozbrowser> boundary.
*
* In contrast, C++ calls to GetTop are forwarded to GetRealTop, which
* ignores <iframe mozbrowser> boundaries.
*
* This property is "replaceable" in JavaScript.
*/
[binaryname(ScriptableTop)]
readonly attribute nsIDOMWindow top;
/**
* You shouldn't need to call this function directly; call GetTop instead.
*/
[noscript]
readonly attribute nsIDOMWindow realTop;
%{C++
nsresult GetTop(nsIDOMWindow **aWindow)
{
return GetRealTop(aWindow);
}
%}
/**
* |parent| gets this window's parent window. If this window has no parent,
* we return the window itself.
*
* This property does not cross chrome-content boundaries, so if this
* window's parent is of a different type, we return the window itself as its
* parent.
*
* When script reads the property (or when C++ calls ScriptableTop), this
* property does not cross <iframe mozbrowser> boundaries. In contrast, when
* C++ calls GetParent, we ignore the mozbrowser attribute.
*/
[binaryname(ScriptableParent)]
readonly attribute nsIDOMWindow parent;
/**
* You shouldn't need to read this property directly; call GetParent instead.
*/
[noscript]
readonly attribute nsIDOMWindow realParent;
%{C++
inline nsresult GetParent(nsIDOMWindow **aWindow)
{
return GetRealParent(aWindow);
}
%}
[implicit_jscontext, binaryname(ScriptableOpener)]
attribute jsval opener;
[noscript, binaryname(Opener)]
attribute nsIDOMWindow openerWindow;
/**
* |frameElement| gets this window's <iframe> or <frame> element, if it has
* one.
@@ -404,28 +344,6 @@ interface nsIDOMWindow : nsISupports
void resizeTo(in long width, in long height);
void resizeBy(in long widthDif, in long heightDif);
/**
* Open a new window with this one as the parent. This method will
* NOT examine the JS stack for purposes of determining a caller.
* This window will be used for security checks during the search by
* name and the default character set on the newly opened window
* will just be the default character set of this window.
*/
[noscript] nsIDOMWindow open(in DOMString url, in DOMString name,
in DOMString options);
/**
* This method works like open except that aExtraArgument gets
* converted into the array window.arguments in JS, if
* aExtraArgument is a nsISupportsArray then the individual items in
* the array are inserted into window.arguments, and primitive
* nsISupports (nsISupportsPrimitives) types are converted to native
* JS types when possible.
*/
[noscript] nsIDOMWindow openDialog(in DOMString url, in DOMString name,
in DOMString options,
in nsISupports aExtraArgument);
// XXX Should this be in nsIDOMChromeWindow?
void updateCommands(in DOMString action,
[optional] in nsISelection sel,
+1 -1
View File
@@ -644,7 +644,7 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
rv = pwwatch->OpenWindow2(parent, finalURIString.get(),
NS_ConvertUTF16toUTF8(aName).get(),
NS_ConvertUTF16toUTF8(aFeatures).get(), aCalledFromJS,
false, false, this, nullptr, getter_AddRefs(window));
false, false, this, nullptr, nullptr, getter_AddRefs(window));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(window);
+2 -5
View File
@@ -2891,11 +2891,8 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
#ifndef XP_MACOSX
// If we're running in the content process, we need a remote widget created in chrome.
if (XRE_GetProcessType() == GoannaProcessType_Content) {
nsCOMPtr<nsIDOMWindow> window = doc->GetWindow();
if (window) {
nsCOMPtr<nsIDOMWindow> topWindow;
window->GetTop(getter_AddRefs(topWindow));
if (topWindow) {
if (nsCOMPtr<nsPIDOMWindow> window = doc->GetWindow()) {
if (nsCOMPtr<nsIDOMWindow> topWindow = window->GetTop()) {
dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
if (tc) {
// This returns a PluginWidgetProxy which remotes a number of calls.
@@ -93,12 +93,15 @@ NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(nsIDOMWindow *parent,
nsCOMPtr<nsIDOMWindow> ownerWindow = do_GetInterface(ownerXULWindow);
NS_ENSURE_STATE(ownerWindow);
nsCOMPtr<nsPIDOMWindow> piOwnerWindow = do_QueryInterface(ownerWindow);
MOZ_ASSERT(piOwnerWindow);
// Open the dialog.
nsCOMPtr<nsIDOMWindow> newWindow;
rv = ownerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
NS_LITERAL_STRING("_blank"),
NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
NS_LITERAL_STRING("_blank"),
NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
array, getter_AddRefs(newWindow));
}
@@ -121,11 +121,14 @@ NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(nsIDOMWindow *parent,
nsCOMPtr<nsIDOMWindow> ownerWindow = do_GetInterface(ownerXULWindow);
NS_ENSURE_STATE(ownerWindow);
nsCOMPtr<nsPIDOMWindow> piOwnerWindow = do_QueryInterface(ownerWindow);
MOZ_ASSERT(piOwnerWindow);
// Open the dialog.
nsCOMPtr<nsIDOMWindow> newWindow;
rv = ownerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
NS_LITERAL_STRING("_blank"),
NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
NS_LITERAL_STRING("_blank"),
NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
array, getter_AddRefs(newWindow));
}
@@ -16,8 +16,9 @@ interface nsIWebBrowserChrome;
interface nsIDocShellTreeItem;
interface nsIArray;
interface nsITabParent;
interface nsIDocShellLoadInfo;
[uuid(0f2d9d75-c46b-4114-802e-83b4655e61d2)]
[uuid(0f2d9d75-c46b-4114-802e-83b4655e61d3)]
interface nsPIWindowWatcher : nsISupports
{
@@ -55,6 +56,12 @@ interface nsPIWindowWatcher : nsISupports
@param aOpeningTab the nsITabParent that is opening the new window. The
nsITabParent is a remote tab belonging to aParent. Can
be nullptr if this window is not being opened from a tab.
@param aLoadInfo if aNavigate is true, this allows the caller to pass in
an nsIDocShellLoadInfo to use for the navigation.
Callers can pass in null if they want the windowwatcher
to just construct a loadinfo itself. If aNavigate is
false, this argument is ignored.
@param aArgs Window argument
@return the new window
@@ -70,7 +77,8 @@ 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 nsIDocShellLoadInfo aLoadInfo);
/**
* Find a named docshell tree item amongst all windows registered
@@ -344,7 +344,9 @@ nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent,
return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
/* calledFromJS = */ false, dialog,
/* navigate = */ true, nullptr, argv, _retval);
/* navigate = */ true, nullptr, argv,
/* aLoadInfo */ nullptr,
_retval);
}
struct SizeSpec {
@@ -398,6 +400,7 @@ nsWindowWatcher::OpenWindow2(nsIDOMWindow *aParent,
bool aNavigate,
nsITabParent *aOpeningTab,
nsISupports *aArguments,
nsIDocShellLoadInfo* aLoadInfo,
nsIDOMWindow **_retval)
{
nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments);
@@ -417,7 +420,9 @@ nsWindowWatcher::OpenWindow2(nsIDOMWindow *aParent,
return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
aCalledFromScript, dialog,
aNavigate, aOpeningTab, argv, _retval);
aNavigate, aOpeningTab, argv,
aLoadInfo,
_retval);
}
nsresult
@@ -430,6 +435,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
bool aNavigate,
nsITabParent *aOpeningTab,
nsIArray *argv,
nsIDocShellLoadInfo* aLoadInfo,
nsIDOMWindow **_retval)
{
nsresult rv = NS_OK;
@@ -770,7 +776,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
}
}
rv = ReadyOpenedDocShellItem(newDocShellItem, aParent, windowIsNew, _retval);
rv = ReadyOpenedDocShellItem(newDocShellItem, parentWindow, windowIsNew, _retval);
if (NS_FAILED(rv))
return rv;
@@ -883,8 +889,8 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
}
}
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
if (uriToLoad && aNavigate) {
nsCOMPtr<nsIDocShellLoadInfo> loadInfo =aLoadInfo;
if (uriToLoad && aNavigate && !loadInfo) {
newDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
@@ -1770,7 +1776,7 @@ nsWindowWatcher::SafeGetWindowByName(const nsAString& aName,
is acceptable. */
nsresult
nsWindowWatcher::ReadyOpenedDocShellItem(nsIDocShellTreeItem *aOpenedItem,
nsIDOMWindow *aParent,
nsPIDOMWindow *aParent,
bool aWindowIsNew,
nsIDOMWindow **aOpenedWindow)
{
@@ -22,7 +22,7 @@
class nsIURI;
class nsIDocShellTreeItem;
class nsIDocShellTreeOwner;
class nsPIDOMWindow;
class nsPIDOMWindow;
class nsIWebBrowserChrome;
class nsString;
class nsWatcherWindowEnumerator;
@@ -86,6 +86,7 @@ protected:
bool aNavigate,
nsITabParent *aOpeningTab,
nsIArray *argv,
nsIDocShellLoadInfo* aLoadInfo,
nsIDOMWindow **_retval);
static nsresult URIfromURL(const char *aURL,
@@ -104,7 +105,7 @@ protected:
/* Compute the right SizeSpec based on aFeatures */
static void CalcSizeSpec(const char* aFeatures, SizeSpec& aResult);
static nsresult ReadyOpenedDocShellItem(nsIDocShellTreeItem *aOpenedItem,
nsIDOMWindow *aParent,
nsPIDOMWindow *aParent,
bool aWindowIsNew,
nsIDOMWindow **aOpenedWindow);
static void SizeOpenedDocShellItem(nsIDocShellTreeItem *aDocShellItem,
+1
View File
@@ -11,6 +11,7 @@
#define MOZILLA_GENERICREFCOUNTED_H_
#include "mozilla/RefPtr.h"
#include "mozilla/RefCounted.h"
namespace mozilla {
+1
View File
@@ -43,6 +43,7 @@ typedef IOSurfacePtr (*CVPixelBufferGetIOSurfaceFunc)(
#import <OpenGL/OpenGL.h>
#include "2D.h"
#include "mozilla/RefPtr.h"
#include "mozilla/RefCounted.h"
struct _CGLContextObject;
+1
View File
@@ -16,6 +16,7 @@
#include "mozilla/Mutex.h"
#include "mozilla/Move.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/RefCounted.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsRefPtr.h"
+1
View File
@@ -9,6 +9,7 @@
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/RefCounted.h"
/* VolatileBuffer
*
+215
View File
@@ -0,0 +1,215 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* CRTP refcounting templates. Do not use unless you are an Expert. */
#ifndef mozilla_RefCounted_h
#define mozilla_RefCounted_h
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/Move.h"
#include "mozilla/RefCountType.h"
#include "mozilla/TypeTraits.h"
#if defined(MOZILLA_INTERNAL_API)
#include "nsXPCOM.h"
#endif
#if defined(MOZILLA_INTERNAL_API) && \
!defined(MOZILLA_XPCOMRT_API) && \
(defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING))
#define MOZ_REFCOUNTED_LEAK_CHECKING
#endif
namespace mozilla {
template<typename T> class RefPtr;
/**
* RefCounted<T> is a sort of a "mixin" for a class T. RefCounted
* manages, well, refcounting for T, and because RefCounted is
* parameterized on T, RefCounted<T> can call T's destructor directly.
* This means T doesn't need to have a virtual dtor and so doesn't
* need a vtable.
*
* RefCounted<T> is created with refcount == 0. Newly-allocated
* RefCounted<T> must immediately be assigned to a RefPtr to make the
* refcount > 0. It's an error to allocate and free a bare
* RefCounted<T>, i.e. outside of the RefPtr machinery. Attempts to
* do so will abort DEBUG builds.
*
* Live RefCounted<T> have refcount > 0. The lifetime (refcounts) of
* live RefCounted<T> are controlled by nsRefPtr<T> and
* nsRefPtr<super/subclass of T>. Upon a transition from refcounted==1
* to 0, the RefCounted<T> "dies" and is destroyed. The "destroyed"
* state is represented in DEBUG builds by refcount==0xffffdead. This
* state distinguishes use-before-ref (refcount==0) from
* use-after-destroy (refcount==0xffffdead).
*
* Note that when deriving from RefCounted or AtomicRefCounted, you
* should add MOZ_DECLARE_REFCOUNTED_TYPENAME(ClassName) to the public
* section of your class, where ClassName is the name of your class.
*/
namespace detail {
const MozRefCountType DEAD = 0xffffdead;
// When building code that gets compiled into Goanna, try to use the
// trace-refcount leak logging facilities.
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
class RefCountLogger
{
public:
static void logAddRef(const void* aPointer, MozRefCountType aRefCount,
const char* aTypeName, uint32_t aInstanceSize)
{
MOZ_ASSERT(aRefCount != DEAD);
NS_LogAddRef(const_cast<void*>(aPointer), aRefCount, aTypeName,
aInstanceSize);
}
static void logRelease(const void* aPointer, MozRefCountType aRefCount,
const char* aTypeName)
{
MOZ_ASSERT(aRefCount != DEAD);
NS_LogRelease(const_cast<void*>(aPointer), aRefCount, aTypeName);
}
};
#endif
// This is used WeakPtr.h as well as this file.
enum RefCountAtomicity
{
AtomicRefCount,
NonAtomicRefCount
};
template<typename T, RefCountAtomicity Atomicity>
class RefCounted
{
friend class RefPtr<T>;
protected:
RefCounted() : mRefCnt(0) {}
~RefCounted() { MOZ_ASSERT(mRefCnt == detail::DEAD); }
public:
// Compatibility with nsRefPtr.
void AddRef() const
{
// Note: this method must be thread safe for AtomicRefCounted.
MOZ_ASSERT(int32_t(mRefCnt) >= 0);
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
++mRefCnt;
#else
const char* type = static_cast<const T*>(this)->typeName();
uint32_t size = static_cast<const T*>(this)->typeSize();
const void* ptr = static_cast<const T*>(this);
MozRefCountType cnt = ++mRefCnt;
detail::RefCountLogger::logAddRef(ptr, cnt, type, size);
#endif
}
void Release() const
{
// Note: this method must be thread safe for AtomicRefCounted.
MOZ_ASSERT(int32_t(mRefCnt) > 0);
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
MozRefCountType cnt = --mRefCnt;
#else
const char* type = static_cast<const T*>(this)->typeName();
const void* ptr = static_cast<const T*>(this);
MozRefCountType cnt = --mRefCnt;
// Note: it's not safe to touch |this| after decrementing the refcount,
// except for below.
detail::RefCountLogger::logRelease(ptr, cnt, type);
#endif
if (0 == cnt) {
// Because we have atomically decremented the refcount above, only
// one thread can get a 0 count here, so as long as we can assume that
// everything else in the system is accessing this object through
// RefPtrs, it's safe to access |this| here.
#ifdef DEBUG
mRefCnt = detail::DEAD;
#endif
delete static_cast<const T*>(this);
}
}
// Compatibility with wtf::RefPtr.
void ref() { AddRef(); }
void deref() { Release(); }
MozRefCountType refCount() const { return mRefCnt; }
bool hasOneRef() const
{
MOZ_ASSERT(mRefCnt > 0);
return mRefCnt == 1;
}
private:
mutable typename Conditional<Atomicity == AtomicRefCount,
Atomic<MozRefCountType>,
MozRefCountType>::Type mRefCnt;
};
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
// Passing override for the optional argument marks the typeName and
// typeSize functions defined by this macro as overrides.
#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...) \
virtual const char* typeName() const __VA_ARGS__ { return #T; } \
virtual size_t typeSize() const __VA_ARGS__ { return sizeof(*this); }
#else
#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...)
#endif
// Note that this macro is expanded unconditionally because it declares only
// two small inline functions which will hopefully get eliminated by the linker
// in non-leak-checking builds.
#define MOZ_DECLARE_REFCOUNTED_TYPENAME(T) \
const char* typeName() const { return #T; } \
size_t typeSize() const { return sizeof(*this); }
} // namespace detail
template<typename T>
class RefCounted : public detail::RefCounted<T, detail::NonAtomicRefCount>
{
public:
~RefCounted()
{
static_assert(IsBaseOf<RefCounted, T>::value,
"T must derive from RefCounted<T>");
}
};
namespace external {
/**
* AtomicRefCounted<T> is like RefCounted<T>, with an atomically updated
* reference counter.
*
* NOTE: Please do not use this class, use NS_INLINE_DECL_THREADSAFE_REFCOUNTING
* instead.
*/
template<typename T>
class AtomicRefCounted :
public mozilla::detail::RefCounted<T, mozilla::detail::AtomicRefCount>
{
public:
~AtomicRefCounted()
{
static_assert(IsBaseOf<AtomicRefCounted, T>::value,
"T must derive from AtomicRefCounted<T>");
}
};
} // namespace external
} // namespace mozilla
#endif // mozilla_RefCounted_h
+1 -181
View File
@@ -13,6 +13,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/RefCounted.h"
#include "mozilla/RefCountType.h"
#include "mozilla/TypeTraits.h"
#if defined(MOZILLA_INTERNAL_API)
@@ -26,192 +27,11 @@
namespace mozilla {
template<typename T> class RefCounted;
template<typename T> class RefPtr;
template<typename T> class TemporaryRef;
template<typename T> class OutParamRef;
template<typename T> OutParamRef<T> byRef(RefPtr<T>&);
/**
* RefCounted<T> is a sort of a "mixin" for a class T. RefCounted
* manages, well, refcounting for T, and because RefCounted is
* parameterized on T, RefCounted<T> can call T's destructor directly.
* This means T doesn't need to have a virtual dtor and so doesn't
* need a vtable.
*
* RefCounted<T> is created with refcount == 0. Newly-allocated
* RefCounted<T> must immediately be assigned to a RefPtr to make the
* refcount > 0. It's an error to allocate and free a bare
* RefCounted<T>, i.e. outside of the RefPtr machinery. Attempts to
* do so will abort DEBUG builds.
*
* Live RefCounted<T> have refcount > 0. The lifetime (refcounts) of
* live RefCounted<T> are controlled by RefPtr<T> and
* RefPtr<super/subclass of T>. Upon a transition from refcounted==1
* to 0, the RefCounted<T> "dies" and is destroyed. The "destroyed"
* state is represented in DEBUG builds by refcount==0xffffdead. This
* state distinguishes use-before-ref (refcount==0) from
* use-after-destroy (refcount==0xffffdead).
*
* Note that when deriving from RefCounted or AtomicRefCounted, you
* should add MOZ_DECLARE_REFCOUNTED_TYPENAME(ClassName) to the public
* section of your class, where ClassName is the name of your class.
*/
namespace detail {
#ifdef DEBUG
const MozRefCountType DEAD = 0xffffdead;
#endif
// When building code that gets compiled into Goanna, try to use the
// trace-refcount leak logging facilities.
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
class RefCountLogger
{
public:
static void logAddRef(const void* aPointer, MozRefCountType aRefCount,
const char* aTypeName, uint32_t aInstanceSize)
{
MOZ_ASSERT(aRefCount != DEAD);
NS_LogAddRef(const_cast<void*>(aPointer), aRefCount, aTypeName,
aInstanceSize);
}
static void logRelease(const void* aPointer, MozRefCountType aRefCount,
const char* aTypeName)
{
MOZ_ASSERT(aRefCount != DEAD);
NS_LogRelease(const_cast<void*>(aPointer), aRefCount, aTypeName);
}
};
#endif
// This is used WeakPtr.h as well as this file.
enum RefCountAtomicity
{
AtomicRefCount,
NonAtomicRefCount
};
template<typename T, RefCountAtomicity Atomicity>
class RefCounted
{
friend class RefPtr<T>;
protected:
RefCounted() : mRefCnt(0) {}
~RefCounted() { MOZ_ASSERT(mRefCnt == detail::DEAD); }
public:
// Compatibility with nsRefPtr.
void AddRef() const
{
// Note: this method must be thread safe for AtomicRefCounted.
MOZ_ASSERT(int32_t(mRefCnt) >= 0);
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
++mRefCnt;
#else
const char* type = static_cast<const T*>(this)->typeName();
uint32_t size = static_cast<const T*>(this)->typeSize();
const void* ptr = static_cast<const T*>(this);
MozRefCountType cnt = ++mRefCnt;
detail::RefCountLogger::logAddRef(ptr, cnt, type, size);
#endif
}
void Release() const
{
// Note: this method must be thread safe for AtomicRefCounted.
MOZ_ASSERT(int32_t(mRefCnt) > 0);
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
MozRefCountType cnt = --mRefCnt;
#else
const char* type = static_cast<const T*>(this)->typeName();
const void* ptr = static_cast<const T*>(this);
MozRefCountType cnt = --mRefCnt;
// Note: it's not safe to touch |this| after decrementing the refcount,
// except for below.
detail::RefCountLogger::logRelease(ptr, cnt, type);
#endif
if (0 == cnt) {
// Because we have atomically decremented the refcount above, only
// one thread can get a 0 count here, so as long as we can assume that
// everything else in the system is accessing this object through
// RefPtrs, it's safe to access |this| here.
#ifdef DEBUG
mRefCnt = detail::DEAD;
#endif
delete static_cast<const T*>(this);
}
}
// Compatibility with wtf::RefPtr.
void ref() { AddRef(); }
void deref() { Release(); }
MozRefCountType refCount() const { return mRefCnt; }
bool hasOneRef() const
{
MOZ_ASSERT(mRefCnt > 0);
return mRefCnt == 1;
}
private:
mutable typename Conditional<Atomicity == AtomicRefCount,
Atomic<MozRefCountType>,
MozRefCountType>::Type mRefCnt;
};
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
// Passing override for the optional argument marks the typeName and
// typeSize functions defined by this macro as overrides.
#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...) \
virtual const char* typeName() const __VA_ARGS__ { return #T; } \
virtual size_t typeSize() const __VA_ARGS__ { return sizeof(*this); }
#else
#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...)
#endif
// Note that this macro is expanded unconditionally because it declares only
// two small inline functions which will hopefully get eliminated by the linker
// in non-leak-checking builds.
#define MOZ_DECLARE_REFCOUNTED_TYPENAME(T) \
const char* typeName() const { return #T; } \
size_t typeSize() const { return sizeof(*this); }
} // namespace detail
template<typename T>
class RefCounted : public detail::RefCounted<T, detail::NonAtomicRefCount>
{
public:
~RefCounted()
{
static_assert(IsBaseOf<RefCounted, T>::value,
"T must derive from RefCounted<T>");
}
};
namespace external {
/**
* AtomicRefCounted<T> is like RefCounted<T>, with an atomically updated
* reference counter.
*
* NOTE: Please do not use this class, use NS_INLINE_DECL_THREADSAFE_REFCOUNTING
* instead.
*/
template<typename T>
class AtomicRefCounted :
public mozilla::detail::RefCounted<T, mozilla::detail::AtomicRefCount>
{
public:
~AtomicRefCounted()
{
static_assert(IsBaseOf<AtomicRefCounted, T>::value,
"T must derive from AtomicRefCounted<T>");
}
};
} // namespace external
/**
* RefPtr points to a refcounted thing that has AddRef and Release
+1
View File
@@ -70,6 +70,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/RefCounted.h"
#include "mozilla/RefPtr.h"
#include "mozilla/TypeTraits.h"
+1
View File
@@ -60,6 +60,7 @@ EXPORTS.mozilla = [
'Poison.h',
'Range.h',
'RangedPtr.h',
'RefCounted.h',
'RefCountType.h',
'ReentrancyGuard.h',
'RefPtr.h',
+6 -29
View File
@@ -5,6 +5,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/RefPtr.h"
#include "mozilla/RefCounted.h"
using mozilla::RefCounted;
using mozilla::RefPtr;
@@ -53,22 +54,12 @@ GetNewFoo(Foo** aFoo)
(*aFoo)->AddRef();
}
void
GetPassedFoo(Foo** aFoo)
{
// Kids, don't try this at home
(*aFoo)->AddRef();
}
void
GetNewFoo(RefPtr<Foo>* aFoo)
{
*aFoo = new Bar();
}
void
GetPassedFoo(RefPtr<Foo>* aFoo)
{}
TemporaryRef<Foo>
GetNullFoo()
@@ -124,37 +115,23 @@ main()
}
MOZ_RELEASE_ASSERT(8 == Foo::sNumDestroyed);
{
RefPtr<Foo> f = new Foo();
GetPassedFoo(byRef(f));
MOZ_RELEASE_ASSERT(8 == Foo::sNumDestroyed);
}
MOZ_RELEASE_ASSERT(9 == Foo::sNumDestroyed);
{
RefPtr<Foo> f = new Foo();
GetNewFoo(&f);
MOZ_RELEASE_ASSERT(10 == Foo::sNumDestroyed);
MOZ_RELEASE_ASSERT(9 == Foo::sNumDestroyed);
}
MOZ_RELEASE_ASSERT(11 == Foo::sNumDestroyed);
{
RefPtr<Foo> f = new Foo();
GetPassedFoo(&f);
MOZ_RELEASE_ASSERT(11 == Foo::sNumDestroyed);
}
MOZ_RELEASE_ASSERT(12 == Foo::sNumDestroyed);
MOZ_RELEASE_ASSERT(10 == Foo::sNumDestroyed);
{
RefPtr<Foo> f1 = new Bar();
}
MOZ_RELEASE_ASSERT(13 == Foo::sNumDestroyed);
MOZ_RELEASE_ASSERT(11 == Foo::sNumDestroyed);
{
RefPtr<Foo> f = GetNullFoo();
MOZ_RELEASE_ASSERT(13 == Foo::sNumDestroyed);
MOZ_RELEASE_ASSERT(11 == Foo::sNumDestroyed);
}
MOZ_RELEASE_ASSERT(13 == Foo::sNumDestroyed);
MOZ_RELEASE_ASSERT(11 == Foo::sNumDestroyed);
return 0;
}
+1
View File
@@ -8,6 +8,7 @@
#include <vector>
#include <dlfcn.h>
#include <signal.h>
#include "mozilla/RefCounted.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "Zip.h"
+1
View File
@@ -11,6 +11,7 @@
#include <zlib.h>
#include "Utils.h"
#include "mozilla/Assertions.h"
#include "mozilla/RefCounted.h"
#include "mozilla/RefPtr.h"
/**
+1 -4
View File
@@ -918,10 +918,7 @@ nsDocLoader::GetIsTopLevel(bool *aResult)
nsCOMPtr<nsPIDOMWindow> piwindow = do_QueryInterface(window);
NS_ENSURE_STATE(piwindow);
nsCOMPtr<nsIDOMWindow> topWindow;
nsresult rv = piwindow->GetTop(getter_AddRefs(topWindow));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsPIDOMWindow> topWindow = piwindow->GetTop();
*aResult = piwindow == topWindow;
}
@@ -2498,14 +2498,13 @@ bool nsExternalAppHandler::GetNeverAskFlagFromPref(const char * prefName, const
nsresult nsExternalAppHandler::MaybeCloseWindow()
{
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mContentContext);
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mContentContext);
NS_ENSURE_STATE(window);
if (mShouldCloseWindow) {
// Reset the window context to the opener window so that the dependent
// dialogs have a parent
nsCOMPtr<nsIDOMWindow> opener;
window->GetOpener(getter_AddRefs(opener));
nsCOMPtr<nsPIDOMWindow> opener = window->GetOpener();
bool isClosed;
if (opener && NS_SUCCEEDED(opener->GetClosed(&isClosed)) && !isClosed) {