mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
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:
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define MOZILLA_GENERICREFCOUNTED_H_
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ typedef IOSurfacePtr (*CVPixelBufferGetIOSurfaceFunc)(
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#include "2D.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
|
||||
struct _CGLContextObject;
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
|
||||
/* VolatileBuffer
|
||||
*
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ EXPORTS.mozilla = [
|
||||
'Poison.h',
|
||||
'Range.h',
|
||||
'RangedPtr.h',
|
||||
'RefCounted.h',
|
||||
'RefCountType.h',
|
||||
'ReentrancyGuard.h',
|
||||
'RefPtr.h',
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <zlib.h>
|
||||
#include "Utils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user