mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1021466 - Part 2: Make it possible to pass in an nsITabParent when opening windows, and then stash that nsITabParent in the newly created chrome docshell. r=smaug.
This commit is contained in:
parent
1da1d37e14
commit
8697a1814f
@ -11644,7 +11644,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
||||
// !aCalledNoScript.
|
||||
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
|
||||
/* aCalledFromScript = */ true,
|
||||
aDialog, aNavigate, argv,
|
||||
aDialog, aNavigate, nullptr, argv,
|
||||
getter_AddRefs(domReturn));
|
||||
} else {
|
||||
// Force a system caller here so that the window watcher won't screw us
|
||||
@ -11664,7 +11664,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
||||
|
||||
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
|
||||
/* aCalledFromScript = */ false,
|
||||
aDialog, aNavigate, aExtraArgument,
|
||||
aDialog, aNavigate, nullptr, aExtraArgument,
|
||||
getter_AddRefs(domReturn));
|
||||
|
||||
}
|
||||
|
@ -17,10 +17,11 @@
|
||||
|
||||
#include "nsIWindowCreator.idl"
|
||||
|
||||
interface nsITabParent;
|
||||
interface nsIURI;
|
||||
interface nsIWebBrowserChrome;
|
||||
|
||||
[scriptable, uuid(f673ec81-a4b0-11d6-964b-eb5a2bf216fc)]
|
||||
[scriptable, uuid(e28f810b-9b49-4927-a4be-62a74fadfe21)]
|
||||
|
||||
interface nsIWindowCreator2 : nsIWindowCreator {
|
||||
|
||||
@ -44,6 +45,8 @@ interface nsIWindowCreator2 : nsIWindowCreator {
|
||||
may use the URL to help determine what sort of window
|
||||
to open or whether to cancel window creation. It will not
|
||||
load the URL.
|
||||
@param aOpeningTab The TabParent that is trying to open this new chrome
|
||||
window. Can be nullptr.
|
||||
@param cancel Return |true| to reject window creation. If true the
|
||||
implementation has determined the window should not
|
||||
be created at all. The caller should not default
|
||||
@ -54,5 +57,6 @@ interface nsIWindowCreator2 : nsIWindowCreator {
|
||||
in uint32_t chromeFlags,
|
||||
in uint32_t contextFlags,
|
||||
in nsIURI uri,
|
||||
in nsITabParent aOpeningTab,
|
||||
out boolean cancel);
|
||||
};
|
||||
|
@ -15,8 +15,9 @@ interface nsISimpleEnumerator;
|
||||
interface nsIWebBrowserChrome;
|
||||
interface nsIDocShellTreeItem;
|
||||
interface nsIArray;
|
||||
interface nsITabParent;
|
||||
|
||||
[uuid(00788A84-152F-4BD8-A814-FD8EB545DB29)]
|
||||
[uuid(0f2d9d75-c46b-4114-802e-83b4655e61d2)]
|
||||
|
||||
interface nsPIWindowWatcher : nsISupports
|
||||
{
|
||||
@ -51,6 +52,9 @@ interface nsPIWindowWatcher : nsISupports
|
||||
@param aDialog use dialog defaults (see nsIDOMWindow::openDialog)
|
||||
@param aNavigate true if we should navigate the new window to the
|
||||
specified URL.
|
||||
@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 aArgs Window argument
|
||||
@return the new window
|
||||
|
||||
@ -65,7 +69,8 @@ interface nsPIWindowWatcher : nsISupports
|
||||
nsIDOMWindow openWindow2(in nsIDOMWindow aParent, in string aUrl,
|
||||
in string aName, in string aFeatures,
|
||||
in boolean aCalledFromScript, in boolean aDialog,
|
||||
in boolean aNavigate, in nsISupports aArgs);
|
||||
in boolean aNavigate, in nsITabParent aOpeningTab,
|
||||
in nsISupports aArgs);
|
||||
|
||||
/**
|
||||
* Find a named docshell tree item amongst all windows registered
|
||||
|
@ -342,7 +342,7 @@ nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent,
|
||||
|
||||
return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
|
||||
/* calledFromJS = */ false, dialog,
|
||||
/* navigate = */ true, argv, _retval);
|
||||
/* navigate = */ true, nullptr, argv, _retval);
|
||||
}
|
||||
|
||||
struct SizeSpec {
|
||||
@ -394,6 +394,7 @@ nsWindowWatcher::OpenWindow2(nsIDOMWindow *aParent,
|
||||
bool aCalledFromScript,
|
||||
bool aDialog,
|
||||
bool aNavigate,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsISupports *aArguments,
|
||||
nsIDOMWindow **_retval)
|
||||
{
|
||||
@ -414,7 +415,7 @@ nsWindowWatcher::OpenWindow2(nsIDOMWindow *aParent,
|
||||
|
||||
return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
|
||||
aCalledFromScript, dialog,
|
||||
aNavigate, argv, _retval);
|
||||
aNavigate, aOpeningTab, argv, _retval);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -425,6 +426,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
|
||||
bool aCalledFromJS,
|
||||
bool aDialog,
|
||||
bool aNavigate,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsIArray *argv,
|
||||
nsIDOMWindow **_retval)
|
||||
{
|
||||
@ -698,7 +700,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
|
||||
bool cancel = false;
|
||||
rv = windowCreator2->CreateChromeWindow2(parentChrome, chromeFlags,
|
||||
contextFlags, uriToLoad,
|
||||
&cancel,
|
||||
aOpeningTab, &cancel,
|
||||
getter_AddRefs(newChrome));
|
||||
if (NS_SUCCEEDED(rv) && cancel) {
|
||||
newChrome = 0; // just in case
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsIWindowCreator.h" // for stupid compilers
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIPromptFactory.h"
|
||||
#include "nsITabParent.h"
|
||||
#include "nsPIWindowWatcher.h"
|
||||
#include "nsTArray.h"
|
||||
#include "js/TypeDecls.h"
|
||||
@ -77,6 +78,7 @@ protected:
|
||||
bool aCalledFromJS,
|
||||
bool aDialog,
|
||||
bool aNavigate,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsIArray *argv,
|
||||
nsIDOMWindow **_retval);
|
||||
|
||||
|
@ -612,7 +612,7 @@ nsAppStartup::CreateChromeWindow(nsIWebBrowserChrome *aParent,
|
||||
nsIWebBrowserChrome **_retval)
|
||||
{
|
||||
bool cancel;
|
||||
return CreateChromeWindow2(aParent, aChromeFlags, 0, 0, &cancel, _retval);
|
||||
return CreateChromeWindow2(aParent, aChromeFlags, 0, 0, nullptr, &cancel, _retval);
|
||||
}
|
||||
|
||||
|
||||
@ -625,6 +625,7 @@ nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
|
||||
uint32_t aChromeFlags,
|
||||
uint32_t aContextFlags,
|
||||
nsIURI *aURI,
|
||||
nsITabParent *aOpeningTab,
|
||||
bool *aCancel,
|
||||
nsIWebBrowserChrome **_retval)
|
||||
{
|
||||
@ -644,7 +645,7 @@ nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
|
||||
NS_ASSERTION(xulParent, "window created using non-XUL parent. that's unexpected, but may work.");
|
||||
|
||||
if (xulParent)
|
||||
xulParent->CreateNewWindow(aChromeFlags, getter_AddRefs(newWindow));
|
||||
xulParent->CreateNewWindow(aChromeFlags, aOpeningTab, getter_AddRefs(newWindow));
|
||||
// And if it fails, don't try again without a parent. It could fail
|
||||
// intentionally (bug 115969).
|
||||
} else { // try using basic methods:
|
||||
@ -657,10 +658,11 @@ nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
|
||||
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
||||
if (!appShell)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
appShell->CreateTopLevelWindow(0, 0, aChromeFlags,
|
||||
nsIAppShellService::SIZE_TO_CONTENT,
|
||||
nsIAppShellService::SIZE_TO_CONTENT,
|
||||
aOpeningTab,
|
||||
getter_AddRefs(newWindow));
|
||||
}
|
||||
|
||||
|
@ -407,7 +407,7 @@ Test4Internal(nsIAppShell* aAppShell)
|
||||
uint32_t flags = nsIWebBrowserChrome::CHROME_DEFAULT;
|
||||
|
||||
nsCOMPtr<nsIXULWindow> xulWindow;
|
||||
if (NS_FAILED(appService->CreateTopLevelWindow(nullptr, uri, flags, 100, 100,
|
||||
if (NS_FAILED(appService->CreateTopLevelWindow(nullptr, uri, flags, 100, 100, nullptr,
|
||||
getter_AddRefs(xulWindow)))) {
|
||||
fail("Failed to create new window");
|
||||
return false;
|
||||
|
@ -10,6 +10,7 @@ interface nsIWebNavigation;
|
||||
interface nsIURI;
|
||||
interface nsIDOMWindow;
|
||||
interface nsIAppShell;
|
||||
interface nsITabParent;
|
||||
|
||||
[ptr] native JSContext(JSContext);
|
||||
|
||||
@ -17,7 +18,7 @@ interface nsIAppShell;
|
||||
#include "js/TypeDecls.h"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(2fa2f813-c216-4efb-8a8c-de60108ce5e5)]
|
||||
[scriptable, uuid(41a2f0c6-3ca1-44f9-8efa-744a43aa399d)]
|
||||
interface nsIAppShellService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -35,14 +36,16 @@ interface nsIAppShellService : nsISupports
|
||||
* tag in the XUL. Set to NS_SIZETOCONTENT to force
|
||||
* the window to wrap to its contents.
|
||||
* @param aInitialHeight like aInitialWidth, but subtly different.
|
||||
* @param aResult the newly created window is returned here.
|
||||
* @param aOpeningTab The TabParent that requested that this window be opened.
|
||||
* Can be left null.
|
||||
*/
|
||||
const long SIZE_TO_CONTENT = -1;
|
||||
nsIXULWindow createTopLevelWindow(in nsIXULWindow aParent,
|
||||
in nsIURI aUrl,
|
||||
in uint32_t aChromeMask,
|
||||
in long aInitialWidth,
|
||||
in long aInitialHeight);
|
||||
in long aInitialHeight,
|
||||
in nsITabParent aOpeningTab);
|
||||
|
||||
/**
|
||||
* This is the constructor for creating an invisible DocShell.
|
||||
|
@ -16,8 +16,9 @@
|
||||
interface nsIDocShell;
|
||||
interface nsIDocShellTreeItem;
|
||||
interface nsIXULBrowserWindow;
|
||||
interface nsITabParent;
|
||||
|
||||
[scriptable, uuid(CCF9E98A-E442-4061-9F74-94539DD9FE9E)]
|
||||
[scriptable, uuid(a68a40b9-f7df-47ff-a874-2af3df7eb888)]
|
||||
interface nsIXULWindow : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -108,9 +109,12 @@ interface nsIXULWindow : nsISupports
|
||||
/**
|
||||
* Create a new window.
|
||||
* @param aChromeFlags see nsIWebBrowserChrome
|
||||
* @param aOpeningTab the TabParent that requested this new window be opened.
|
||||
* Can be left null.
|
||||
* @return the newly minted window
|
||||
*/
|
||||
nsIXULWindow createNewWindow(in int32_t aChromeFlags);
|
||||
nsIXULWindow createNewWindow(in int32_t aChromeFlags,
|
||||
in nsITabParent aOpeningTab);
|
||||
|
||||
attribute nsIXULBrowserWindow XULBrowserWindow;
|
||||
|
||||
|
@ -127,7 +127,7 @@ nsAppShellService::CreateHiddenWindowHelper(bool aIsPrivate)
|
||||
if (!aIsPrivate) {
|
||||
rv = JustCreateTopWindow(nullptr, url,
|
||||
chromeMask, initialWidth, initialHeight,
|
||||
true, getter_AddRefs(newWindow));
|
||||
true, nullptr, getter_AddRefs(newWindow));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mHiddenWindow.swap(newWindow);
|
||||
@ -137,7 +137,7 @@ nsAppShellService::CreateHiddenWindowHelper(bool aIsPrivate)
|
||||
|
||||
rv = JustCreateTopWindow(nullptr, url,
|
||||
chromeMask, initialWidth, initialHeight,
|
||||
true, getter_AddRefs(newWindow));
|
||||
true, nullptr, getter_AddRefs(newWindow));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
@ -181,6 +181,7 @@ nsAppShellService::CreateTopLevelWindow(nsIXULWindow *aParent,
|
||||
uint32_t aChromeMask,
|
||||
int32_t aInitialWidth,
|
||||
int32_t aInitialHeight,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsIXULWindow **aResult)
|
||||
|
||||
{
|
||||
@ -191,7 +192,7 @@ nsAppShellService::CreateTopLevelWindow(nsIXULWindow *aParent,
|
||||
nsWebShellWindow *newWindow = nullptr;
|
||||
rv = JustCreateTopWindow(aParent, aUrl,
|
||||
aChromeMask, aInitialWidth, aInitialHeight,
|
||||
false, &newWindow); // addrefs
|
||||
false, aOpeningTab, &newWindow); // addrefs
|
||||
|
||||
*aResult = newWindow; // transfer ref
|
||||
|
||||
@ -482,11 +483,12 @@ CheckForFullscreenWindow()
|
||||
*/
|
||||
nsresult
|
||||
nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
|
||||
nsIURI *aUrl,
|
||||
nsIURI *aUrl,
|
||||
uint32_t aChromeMask,
|
||||
int32_t aInitialWidth,
|
||||
int32_t aInitialHeight,
|
||||
bool aIsHiddenWindow,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsWebShellWindow **aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
@ -597,7 +599,7 @@ nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
|
||||
|
||||
nsresult rv = window->Initialize(parent, center ? aParent : nullptr,
|
||||
aUrl, aInitialWidth, aInitialHeight,
|
||||
aIsHiddenWindow, widgetInitData);
|
||||
aIsHiddenWindow, aOpeningTab, widgetInitData);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsWebShellWindow.h"
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsITabParent.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
// {0099907D-123C-4853-A46A-43098B5FB68C}
|
||||
@ -36,10 +37,11 @@ protected:
|
||||
void EnsurePrivateHiddenWindow();
|
||||
|
||||
nsresult JustCreateTopWindow(nsIXULWindow *aParent,
|
||||
nsIURI *aUrl,
|
||||
nsIURI *aUrl,
|
||||
uint32_t aChromeMask,
|
||||
int32_t aInitialWidth, int32_t aInitialHeight,
|
||||
bool aIsHiddenWindow,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsWebShellWindow **aResult);
|
||||
uint32_t CalculateWindowZLevel(nsIXULWindow *aParent, uint32_t aChromeMask);
|
||||
|
||||
|
@ -111,6 +111,7 @@ nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent,
|
||||
int32_t aInitialWidth,
|
||||
int32_t aInitialHeight,
|
||||
bool aIsHiddenWindow,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsWidgetInitData& widgetInitData)
|
||||
{
|
||||
nsresult rv;
|
||||
@ -183,6 +184,8 @@ nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent,
|
||||
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
|
||||
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
|
||||
|
||||
mDocShell->SetOpener(aOpeningTab);
|
||||
|
||||
// Make sure to set the item type on the docshell _before_ calling
|
||||
// Create() so it knows what type it is.
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXULWindow.h"
|
||||
#include "nsIWidgetListener.h"
|
||||
#include "nsITabParent.h"
|
||||
|
||||
/* Forward declarations.... */
|
||||
class nsIURI;
|
||||
@ -37,6 +38,7 @@ public:
|
||||
nsIURI* aUrl,
|
||||
int32_t aInitialWidth, int32_t aInitialHeight,
|
||||
bool aIsHiddenWindow,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsWidgetInitData& widgetInitData);
|
||||
|
||||
nsresult Toolbar();
|
||||
|
@ -1714,16 +1714,18 @@ NS_IMETHODIMP nsXULWindow::ExitModalLoop(nsresult aStatus)
|
||||
|
||||
// top-level function to create a new window
|
||||
NS_IMETHODIMP nsXULWindow::CreateNewWindow(int32_t aChromeFlags,
|
||||
nsIXULWindow **_retval)
|
||||
nsITabParent *aOpeningTab,
|
||||
nsIXULWindow **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
if (aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)
|
||||
return CreateNewChromeWindow(aChromeFlags, _retval);
|
||||
return CreateNewContentWindow(aChromeFlags, _retval);
|
||||
return CreateNewChromeWindow(aChromeFlags, aOpeningTab, _retval);
|
||||
return CreateNewContentWindow(aChromeFlags, aOpeningTab, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsIXULWindow **_retval)
|
||||
{
|
||||
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
||||
@ -1735,6 +1737,7 @@ NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags,
|
||||
appShell->CreateTopLevelWindow(this, nullptr, aChromeFlags,
|
||||
nsIAppShellService::SIZE_TO_CONTENT,
|
||||
nsIAppShellService::SIZE_TO_CONTENT,
|
||||
aOpeningTab,
|
||||
getter_AddRefs(newWindow));
|
||||
|
||||
NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
|
||||
@ -1746,6 +1749,7 @@ NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
|
||||
nsITabParent *aOpeningTab,
|
||||
nsIXULWindow **_retval)
|
||||
{
|
||||
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
||||
@ -1778,6 +1782,7 @@ NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
|
||||
AutoNoJSAPI nojsapi;
|
||||
appShell->CreateTopLevelWindow(this, uri,
|
||||
aChromeFlags, 615, 480,
|
||||
aOpeningTab,
|
||||
getter_AddRefs(newWindow));
|
||||
NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
|
||||
}
|
||||
@ -1798,7 +1803,16 @@ NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
|
||||
}
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(xulWin->mPrimaryContentShell);
|
||||
// If aOpeningTab is not null, it means that we're creating a new window
|
||||
// with a remote browser, which doesn't have a primary docshell. In that
|
||||
// case, we check for the chrome window docshell and make sure that a new
|
||||
// remote tab was opened and stashed in that docshell.
|
||||
if (aOpeningTab) {
|
||||
NS_ENSURE_STATE(xulWin->mDocShell);
|
||||
NS_ENSURE_STATE(xulWin->mDocShell->GetOpenedRemote());
|
||||
} else {
|
||||
NS_ENSURE_STATE(xulWin->mPrimaryContentShell);
|
||||
}
|
||||
|
||||
*_retval = newWindow;
|
||||
NS_ADDREF(*_retval);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "nsIXULBrowserWindow.h"
|
||||
#include "nsIWeakReference.h"
|
||||
#include "nsIWidgetListener.h"
|
||||
#include "nsITabParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -108,8 +109,8 @@ protected:
|
||||
NS_IMETHOD SizeShellTo(nsIDocShellTreeItem* aShellItem, int32_t aCX,
|
||||
int32_t aCY);
|
||||
NS_IMETHOD ExitModalLoop(nsresult aStatus);
|
||||
NS_IMETHOD CreateNewChromeWindow(int32_t aChromeFlags, nsIXULWindow **_retval);
|
||||
NS_IMETHOD CreateNewContentWindow(int32_t aChromeFlags, nsIXULWindow **_retval);
|
||||
NS_IMETHOD CreateNewChromeWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, nsIXULWindow **_retval);
|
||||
NS_IMETHOD CreateNewContentWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, nsIXULWindow **_retval);
|
||||
|
||||
void EnableParent(bool aEnable);
|
||||
bool ConstrainToZLevel(bool aImmediate, nsWindowZ *aPlacement,
|
||||
|
Loading…
Reference in New Issue
Block a user