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:
roc+%cs.cmu.edu 2005-09-04 20:04:23 +00:00
parent 1b0e63378d
commit 60903ce73c
8 changed files with 49 additions and 133 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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()
{

View File

@ -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);
}

View File

@ -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,

View File

@ -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);