mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 21:28:55 +00:00
Bug 306222. Make nsIFrame::GetContentAndOffsetsFromPoint, and nsIFrameSelection::HandleDrag, take coordinates relative to the current frame, not some random view. r+sr=roc,patch by Eli Friedman
This commit is contained in:
parent
1b0e63378d
commit
60903ce73c
@ -326,7 +326,7 @@ nsDOMUIEvent::GetRangeParent(nsIDOMNode** aRangeParent)
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
PRInt32 offset, endOffset;
|
||||
PRBool beginOfContent;
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesForNearestView(mEvent,
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
|
||||
targetFrame);
|
||||
if (NS_SUCCEEDED(targetFrame->GetContentAndOffsetsFromPoint(mPresContext,
|
||||
pt,
|
||||
@ -357,7 +357,7 @@ nsDOMUIEvent::GetRangeOffset(PRInt32* aRangeOffset)
|
||||
nsIContent* parent = nsnull;
|
||||
PRInt32 endOffset;
|
||||
PRBool beginOfContent;
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesForNearestView(mEvent,
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
|
||||
targetFrame);
|
||||
if (NS_SUCCEEDED(targetFrame->GetContentAndOffsetsFromPoint(mPresContext,
|
||||
pt,
|
||||
|
@ -190,7 +190,7 @@ public:
|
||||
/** HandleDrag extends the selection to contain the frame closest to aPoint.
|
||||
* @param aPresContext is the context to use when figuring out what frame contains the point.
|
||||
* @param aFrame is the parent of all frames to use when searching for the closest frame to the point.
|
||||
* @param aPoint is relative to aFrame's parent view.
|
||||
* @param aPoint is relative to aFrame
|
||||
*/
|
||||
NS_IMETHOD HandleDrag(nsPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint) = 0;
|
||||
|
||||
|
@ -6588,11 +6588,15 @@ nsBlockFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
if (NS_FAILED(result = GetClosestLine(it, pt, closestLine)))
|
||||
return result;
|
||||
|
||||
// XXX mDesiredX needs to be in GetOffsetFromView coords
|
||||
nsPoint offset;
|
||||
nsIView* view;
|
||||
mainframe->GetOffsetFromView(offset, &view);
|
||||
//we will now ask where to go. if we cant find what we want"aka another block frame"
|
||||
//we drill down again
|
||||
pos.mShell = shell;
|
||||
pos.mDirection = eDirNext;
|
||||
pos.mDesiredX = pt.x;
|
||||
pos.mDesiredX = pt.x + offset.x;
|
||||
pos.mScrollViewStop = PR_FALSE;
|
||||
pos.mIsKeyboardSelect = PR_FALSE;
|
||||
result = nsFrame::GetNextPrevLineFromeBlockFrame(aPresContext,
|
||||
|
@ -1361,7 +1361,7 @@ nsFrame::HandlePress(nsPresContext* aPresContext,
|
||||
PRInt32 startOffset = 0, endOffset = 0;
|
||||
PRBool beginFrameContent = PR_FALSE;
|
||||
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesForNearestView(aEvent, this);
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
|
||||
rv = GetContentAndOffsetsFromPoint(aPresContext, pt, getter_AddRefs(content),
|
||||
startOffset, endOffset,
|
||||
beginFrameContent);
|
||||
@ -1601,7 +1601,7 @@ nsFrame::HandleMultiplePress(nsPresContext* aPresContext,
|
||||
nsCOMPtr<nsIContent> newContent;
|
||||
PRBool beginContent = PR_FALSE;
|
||||
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesForNearestView(aEvent, this);
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
|
||||
|
||||
rv = GetContentAndOffsetsFromPoint(aPresContext,
|
||||
pt,
|
||||
@ -1753,7 +1753,7 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsPresContext* aPresContext,
|
||||
if (NS_SUCCEEDED(result) && parentContent) {
|
||||
frameselection->HandleTableSelection(parentContent, contentOffset, target, me);
|
||||
} else {
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesForNearestView(aEvent, this);
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
|
||||
frameselection->HandleDrag(aPresContext, this, pt);
|
||||
}
|
||||
|
||||
@ -1850,8 +1850,7 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsPresContext* aPresContext,
|
||||
PRInt32 startOffset = 0, endOffset = 0;
|
||||
PRBool beginFrameContent = PR_FALSE;
|
||||
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesForNearestView(me,
|
||||
this);
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(me, this);
|
||||
result = GetContentAndOffsetsFromPoint(aPresContext, pt,
|
||||
getter_AddRefs(content),
|
||||
startOffset, endOffset,
|
||||
@ -1919,7 +1918,6 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
// to if it fails the getposition call, make it yourself also only
|
||||
// look at primary list
|
||||
nsIFrame *closestFrame = nsnull;
|
||||
nsIView *view = GetClosestView();
|
||||
nsIFrame *kid = GetFirstChild(nsnull);
|
||||
|
||||
if (kid) {
|
||||
@ -1934,30 +1932,6 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
// that don't have a proper parent-child relationship!
|
||||
|
||||
PRBool skipThisKid = (kid->GetStateBits() & NS_FRAME_GENERATED_CONTENT) != 0;
|
||||
#if 0
|
||||
if (!skipThisKid) {
|
||||
// The frame's content is not generated. Now check
|
||||
// if it is anonymous content!
|
||||
|
||||
nsIContent* kidContent = kid->GetContent();
|
||||
if (kidContent) {
|
||||
nsCOMPtr<nsIContent> content = kidContent->GetParent();
|
||||
|
||||
if (content) {
|
||||
PRInt32 kidCount = content->ChildCount();
|
||||
PRInt32 kidIndex = content->IndexOf(kidContent);
|
||||
|
||||
// IndexOf() should return -1 for the index if it doesn't
|
||||
// find kidContent in it's child list.
|
||||
|
||||
if (kidIndex < 0 || kidIndex >= kidCount) {
|
||||
// Must be anonymous content! So skip it!
|
||||
skipThisKid = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //XXX we USED to skip anonymous content i dont think we should anymore leaving this here as a flah
|
||||
|
||||
if (skipThisKid) {
|
||||
kid = kid->GetNextSibling();
|
||||
@ -1968,13 +1942,7 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
// relationship. Now see if the aPoint inside it's bounding
|
||||
// rect or close by.
|
||||
|
||||
nsPoint offsetPoint(0,0);
|
||||
nsIView * kidView = nsnull;
|
||||
kid->GetOffsetFromView(offsetPoint, &kidView);
|
||||
|
||||
nsRect rect = kid->GetRect();
|
||||
rect.x = offsetPoint.x;
|
||||
rect.y = offsetPoint.y;
|
||||
|
||||
nscoord fromTop = aPoint.y - rect.y;
|
||||
nscoord fromBottom = aPoint.y - rect.y - rect.height;
|
||||
@ -2030,29 +1998,18 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
// the coordinates because GetPosition() expects
|
||||
// them to be relative to the closest view.
|
||||
|
||||
nsPoint newPoint = aPoint;
|
||||
nsIView *closestView = closestFrame->GetClosestView();
|
||||
|
||||
if (closestView && view != closestView)
|
||||
newPoint -= closestView->GetOffsetTo(view);
|
||||
|
||||
// printf(" 0x%.8x 0x%.8x %4d %4d\n",
|
||||
// closestFrame, closestView, closestXDistance, closestYDistance);
|
||||
|
||||
return closestFrame->GetContentAndOffsetsFromPoint(aCX, newPoint, aNewContent,
|
||||
aContentOffset, aContentOffsetEnd,aBeginFrameContent);
|
||||
nsPoint newPoint = aPoint - closestFrame->GetOffsetTo(this);
|
||||
return closestFrame->GetContentAndOffsetsFromPoint(aCX, newPoint,
|
||||
aNewContent,
|
||||
aContentOffset,
|
||||
aContentOffsetEnd,
|
||||
aBeginFrameContent);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mContent)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsPoint offsetPoint;
|
||||
GetOffsetFromView(offsetPoint, &view);
|
||||
nsRect thisRect = GetRect();
|
||||
thisRect.x = offsetPoint.x;
|
||||
thisRect.y = offsetPoint.y;
|
||||
|
||||
NS_IF_ADDREF(*aNewContent = mContent->GetParent());
|
||||
if (*aNewContent){
|
||||
|
||||
@ -2066,6 +2023,7 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
aContentOffset = contentOffset; //its clear save the result
|
||||
|
||||
aBeginFrameContent = PR_TRUE;
|
||||
nsRect thisRect(nsPoint(0, 0), GetSize());
|
||||
if (thisRect.Contains(aPoint))
|
||||
aContentOffsetEnd = aContentOffset +1;
|
||||
else
|
||||
@ -3336,12 +3294,16 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
||||
rect = resultFrame->GetRect();
|
||||
if (!rect.width || !rect.height)
|
||||
result = NS_ERROR_FAILURE;
|
||||
else
|
||||
result = resultFrame->GetContentAndOffsetsFromPoint(context,point,
|
||||
else {
|
||||
nsIView* view;
|
||||
nsPoint offset;
|
||||
resultFrame->GetOffsetFromView(offset, &view);
|
||||
result = resultFrame->GetContentAndOffsetsFromPoint(context,point - offset,
|
||||
getter_AddRefs(aPos->mResultContent),
|
||||
aPos->mContentOffset,
|
||||
aPos->mContentOffsetEnd,
|
||||
aPos->mPreferLeft);
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
PRBool selectable;
|
||||
@ -3381,7 +3343,10 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
||||
point.x = aPos->mDesiredX;
|
||||
point.y = 0;
|
||||
|
||||
result = resultFrame->GetContentAndOffsetsFromPoint(context,point,
|
||||
nsIView* view;
|
||||
nsPoint offset;
|
||||
resultFrame->GetOffsetFromView(offset, &view);
|
||||
result = resultFrame->GetContentAndOffsetsFromPoint(context,point - offset,
|
||||
getter_AddRefs(aPos->mResultContent), aPos->mContentOffset,
|
||||
aPos->mContentOffsetEnd, aPos->mPreferLeft);
|
||||
if (NS_SUCCEEDED(result))
|
||||
@ -3679,7 +3644,6 @@ DrillDownToEndOfLine(nsIFrame* aFrame, PRInt32 aLineFrameCount,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
|
||||
{
|
||||
@ -3726,7 +3690,10 @@ nsFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
|
||||
nsPresContext *context = aPos->mShell->GetPresContext();
|
||||
if (!context)
|
||||
return NS_OK;
|
||||
result = GetContentAndOffsetsFromPoint(context,point,
|
||||
nsIView* view;
|
||||
nsPoint offset;
|
||||
GetOffsetFromView(offset, &view);
|
||||
result = GetContentAndOffsetsFromPoint(context,point - offset,
|
||||
getter_AddRefs(aPos->mResultContent),
|
||||
aPos->mContentOffset,
|
||||
endoffset,
|
||||
|
@ -1406,25 +1406,6 @@ nsGfxScrollFrameInner::NeedsClipWidget() const
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGfxScrollFrameInner::GetChildContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
const nsPoint& aPoint,
|
||||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent)
|
||||
{
|
||||
// We need to overrride this to ensure that scrollbars are ignored
|
||||
|
||||
// Since we definitely have a view, aPoint is relative to this frame's view. We
|
||||
// need to make it relative to the scrolled frame.
|
||||
nsPoint point = aPoint - mScrollableView->View()->GetOffsetTo(mOuter->GetView());
|
||||
|
||||
return mScrolledFrame->GetContentAndOffsetsFromPoint(aCX, point, aNewContent,
|
||||
aContentOffset, aContentOffsetEnd,
|
||||
aBeginFrameContent);
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::CreateScrollableView()
|
||||
{
|
||||
|
@ -80,13 +80,6 @@ public:
|
||||
void PostScrollPortEvent(PRBool aOverflow, nsScrollPortEvent::orientType aType);
|
||||
void PostOverflowEvents();
|
||||
|
||||
nsresult GetChildContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
const nsPoint& aPoint,
|
||||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent);
|
||||
|
||||
// nsIScrollPositionListener
|
||||
|
||||
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
|
||||
@ -235,17 +228,6 @@ public:
|
||||
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
|
||||
NS_IMETHOD GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
const nsPoint& aPoint,
|
||||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent) {
|
||||
return mInner.GetChildContentAndOffsetsFromPoint(aCX, aPoint, aNewContent, aContentOffset,
|
||||
aContentOffsetEnd, aBeginFrameContent);
|
||||
}
|
||||
|
||||
virtual nsIView* GetParentViewForChildFrame(nsIFrame* aFrame) const {
|
||||
return mInner.GetParentViewForChildFrame(aFrame);
|
||||
}
|
||||
@ -381,17 +363,6 @@ public:
|
||||
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
|
||||
NS_IMETHOD GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
const nsPoint& aPoint,
|
||||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent) {
|
||||
return mInner.GetChildContentAndOffsetsFromPoint(aCX, aPoint, aNewContent, aContentOffset,
|
||||
aContentOffsetEnd, aBeginFrameContent);
|
||||
}
|
||||
|
||||
virtual nsIView* GetParentViewForChildFrame(nsIFrame* aFrame) const {
|
||||
return mInner.GetParentViewForChildFrame(aFrame);
|
||||
}
|
||||
|
@ -751,6 +751,9 @@ public:
|
||||
nsEvent* aEvent,
|
||||
nsIContent** aContent) = 0;
|
||||
|
||||
/**
|
||||
* Find the content offset from a point. aPoint is in frame coordinates.
|
||||
*/
|
||||
NS_IMETHOD GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
const nsPoint& aPoint,
|
||||
nsIContent ** aNewContent,
|
||||
|
@ -2762,9 +2762,6 @@ nsTextFrame::GetPositionSlowly(nsPresContext* aPresContext,
|
||||
if (!ts.mSmallCaps && !ts.mWordSpacing && !ts.mLetterSpacing && !ts.mJustifying) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsIView * view;
|
||||
nsPoint origin;
|
||||
GetOffsetFromView(origin, &view);
|
||||
|
||||
/* This if clause is the cause of much pain. If aNewContent is set, then any
|
||||
* code path that returns an error must set aNewContent to null before returning,
|
||||
@ -2782,7 +2779,7 @@ nsTextFrame::GetPositionSlowly(nsPresContext* aPresContext,
|
||||
* If this clause is removed, then some of the bullet-proofing code
|
||||
* prefaced with "bug 56704" comments can be removed as well.
|
||||
*/
|
||||
if (aPoint.x - origin.x < 0)
|
||||
if (aPoint.x < 0)
|
||||
{
|
||||
*aNewContent = mContent;
|
||||
aOffset =0;
|
||||
@ -2839,12 +2836,12 @@ nsTextFrame::GetPositionSlowly(nsPresContext* aPresContext,
|
||||
|
||||
if (prefInt)
|
||||
{
|
||||
if (aPoint.y < origin.y)//above rectangle
|
||||
if (aPoint.y < 0)//above rectangle
|
||||
{
|
||||
aOffset = mContentOffset;
|
||||
outofstylehandled = PR_TRUE;
|
||||
}
|
||||
else if ((aPoint.y - origin.y) > mRect.height)
|
||||
else if (aPoint.y > mRect.height)
|
||||
{
|
||||
aOffset = mContentOffset + mContentLength;
|
||||
outofstylehandled = PR_TRUE;
|
||||
@ -2855,7 +2852,7 @@ nsTextFrame::GetPositionSlowly(nsPresContext* aPresContext,
|
||||
//END STYLE RULE
|
||||
{
|
||||
//the following will first get the index into the PAINTBUFFER then the actual content
|
||||
nscoord adjustedX = PR_MAX(0,aPoint.x-origin.x);
|
||||
nscoord adjustedX = PR_MAX(0,aPoint.x);
|
||||
|
||||
#ifdef IBMBIDI
|
||||
if (isOddLevel)
|
||||
@ -3818,10 +3815,6 @@ nsTextFrame::GetPosition(nsPresContext* aPresContext,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsPoint origin;
|
||||
nsIView * view;
|
||||
GetOffsetFromView(origin, &view);
|
||||
|
||||
//IF STYLE SAYS TO SELECT TO END OF FRAME HERE...
|
||||
PRInt32 prefInt =
|
||||
nsContentUtils::GetIntPref("browser.drag_out_of_frame_style");
|
||||
@ -3829,13 +3822,13 @@ nsTextFrame::GetPosition(nsPresContext* aPresContext,
|
||||
|
||||
if (prefInt)
|
||||
{
|
||||
if ((aPoint.y - origin.y) < 0)//above rectangle
|
||||
if (aPoint.y < 0)//above rectangle
|
||||
{
|
||||
aContentOffset = mContentOffset;
|
||||
aContentOffsetEnd = aContentOffset;
|
||||
outofstylehandled = PR_TRUE;
|
||||
}
|
||||
else if ((aPoint.y - origin.y) > mRect.height)
|
||||
else if (aPoint.y > mRect.height)
|
||||
{
|
||||
aContentOffset = mContentOffset + mContentLength;
|
||||
aContentOffsetEnd = aContentOffset;
|
||||
@ -3857,24 +3850,21 @@ nsTextFrame::GetPosition(nsPresContext* aPresContext,
|
||||
rendContext->GetHints(clusterHint);
|
||||
clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS;
|
||||
if (clusterHint) {
|
||||
nsPoint pt;
|
||||
pt.x = aPoint.x - origin.x;
|
||||
pt.y = aPoint.y - origin.y;
|
||||
indx = rendContext->GetPosition(text, textLength, pt);
|
||||
indx = rendContext->GetPosition(text, textLength, aPoint);
|
||||
}
|
||||
else {
|
||||
#ifdef IBMBIDI
|
||||
PRBool getReversedPos = NS_GET_EMBEDDING_LEVEL(this) & 1;
|
||||
nscoord posX = (getReversedPos) ?
|
||||
(mRect.width + origin.x) - (aPoint.x - origin.x) : aPoint.x;
|
||||
(mRect.width) - (aPoint.x) : aPoint.x;
|
||||
|
||||
PRBool found = BinarySearchForPosition(rendContext, text, origin.x, 0, 0,
|
||||
PRBool found = BinarySearchForPosition(rendContext, text, 0, 0, 0,
|
||||
PRInt32(textLength),
|
||||
PRInt32(posX) , //go to local coordinates
|
||||
indx, textWidth);
|
||||
|
||||
#else
|
||||
PRBool found = BinarySearchForPosition(rendContext, text, origin.x, 0, 0,
|
||||
PRBool found = BinarySearchForPosition(rendContext, text, 0, 0, 0,
|
||||
PRInt32(textLength),
|
||||
PRInt32(aPoint.x) , //go to local coordinates
|
||||
indx, textWidth);
|
||||
@ -3889,13 +3879,13 @@ nsTextFrame::GetPosition(nsPresContext* aPresContext,
|
||||
|
||||
#ifdef IBMBIDI
|
||||
if (getReversedPos) {
|
||||
if (mRect.width - aPoint.x + origin.x > textWidth+charWidth ) {
|
||||
if (mRect.width - aPoint.x> textWidth+charWidth ) {
|
||||
indx++;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // IBMBIDI
|
||||
if ((aPoint.x - origin.x) > textWidth+charWidth) {
|
||||
if ((aPoint.x) > textWidth+charWidth) {
|
||||
indx++;
|
||||
}
|
||||
}
|
||||
@ -4851,7 +4841,7 @@ nsTextFrame::HandleMultiplePress(nsPresContext* aPresContext,
|
||||
PRInt32 startPos = 0;
|
||||
PRInt32 contentOffsetEnd = 0;
|
||||
nsCOMPtr<nsIContent> newContent;
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesForNearestView(aEvent, this);
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
|
||||
nsresult rv = GetPosition(aPresContext, pt,
|
||||
getter_AddRefs(newContent), startPos,
|
||||
contentOffsetEnd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user