mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Fix for bug 83650 (textarea control has problems with caret positioning at end)
and bug 97207 (textarea pastes sometimes misplaced by failing to reposition). - Added new utility method GetOriginToViewOffset(). - Modified nsPresShell::HandleEvent(), nsBoxFrame::GetFrameForPoint(), and nsContainerFrame::GetFrameForPointUsing() to factor in the offset from GetOriginToViewOffset() to insure that the point used is always transformed into the correct coordinate system. Files modified: mozilla/layout/base/public/nsIFrame.h mozilla/layout/html/base/src/nsContainerFrame.cpp mozilla/layout/html/base/src/nsFrame.cpp mozilla/layout/html/base/src/nsFrame.h mozilla/layout/html/base/src/nsPresShell.cpp mozilla/layout/xul/base/src/nsBoxFrame.cpp r=kmcclusk@netscape.com sr=sfraser@netscape.com
This commit is contained in:
parent
ef530159bd
commit
d38cee3cd4
@ -5880,13 +5880,27 @@ PresShell::HandleEvent(nsIView *aView,
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is because we want to give the point in the same
|
||||
// coordinates as the frame's own Rect, so mRect.Contains(aPoint)
|
||||
// works. However, this point is relative to the frame's rect, so
|
||||
// we need to add on the origin of the rect.
|
||||
// aEvent->point is relative to aView's upper left corner. We need
|
||||
// a point that is in the same coordinate system as frame's rect
|
||||
// so that the frame->mRect.Contains(aPoint) calls in
|
||||
// GetFrameForPoint() work. The assumption here is that frame->GetView()
|
||||
// will return aView, and frame's parent view is aView's parent.
|
||||
|
||||
nsPoint eventPoint;
|
||||
frame->GetOrigin(eventPoint);
|
||||
eventPoint += aEvent->point;
|
||||
|
||||
nsPoint originOffset;
|
||||
nsIView *view = nsnull;
|
||||
frame->GetOriginToViewOffset(mPresContext, originOffset, &view);
|
||||
|
||||
#ifdef DEBUG_kin
|
||||
NS_ASSERTION(view == aView, "view != aView");
|
||||
#endif // DEBUG_kin
|
||||
|
||||
if (view == aView)
|
||||
eventPoint -= originOffset;
|
||||
|
||||
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_FOREGROUND, &mCurrentEventFrame);
|
||||
if (rv != NS_OK) {
|
||||
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_FLOATERS, &mCurrentEventFrame);
|
||||
|
@ -961,6 +961,18 @@ public:
|
||||
nsPoint& aOffset,
|
||||
nsIView** aView) const = 0;
|
||||
|
||||
/**
|
||||
* Returns the offset from this frame's upper left corner to the upper
|
||||
* left corner of the view returned by a call to GetView(). aOffset
|
||||
* will contain the offset to the view or (0,0) if the frame has no
|
||||
* view. aView will contain a pointer to the view returned by GetView().
|
||||
* aView is optional, that is, you may pass null if you are not interested
|
||||
* in getting a pointer to the view.
|
||||
*/
|
||||
NS_IMETHOD GetOriginToViewOffset(nsIPresContext* aPresContext,
|
||||
nsPoint& aOffset,
|
||||
nsIView** aView) const = 0;
|
||||
|
||||
/**
|
||||
* Returns the window that contains this frame. If this frame has a
|
||||
* view and the view has a window, then this frames window is
|
||||
|
@ -293,8 +293,16 @@ nsContainerFrame::GetFrameForPointUsing(nsIPresContext* aPresContext,
|
||||
FirstChild(aPresContext, aList, &kid);
|
||||
*aFrame = nsnull;
|
||||
tmp.MoveTo(aPoint.x - mRect.x, aPoint.y - mRect.y);
|
||||
|
||||
nsPoint originOffset;
|
||||
nsIView *view = nsnull;
|
||||
nsresult rv = GetOriginToViewOffset(aPresContext, originOffset, &view);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && view)
|
||||
tmp += originOffset;
|
||||
|
||||
while (nsnull != kid) {
|
||||
nsresult rv = kid->GetFrameForPoint(aPresContext, tmp, aWhichLayer, &hit);
|
||||
rv = kid->GetFrameForPoint(aPresContext, tmp, aWhichLayer, &hit);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && hit) {
|
||||
*aFrame = hit;
|
||||
|
@ -2042,6 +2042,62 @@ NS_IMETHODIMP nsFrame::GetOffsetFromView(nsIPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The (x,y) value of the frame's upper left corner is always
|
||||
// relative to its parentFrame's upper left corner, unless
|
||||
// its parentFrame has a view associated with it, in which case, it
|
||||
// will be relative to the upper left corner of the view returned
|
||||
// by a call to parentFrame->GetView().
|
||||
//
|
||||
// This means that while drilling down the frame hierarchy, from
|
||||
// parent to child frame, we sometimes need to take into account
|
||||
// crossing these view boundaries, because the coordinate system
|
||||
// changes from parent frame coordinate system, to the associated
|
||||
// view's coordinate system.
|
||||
//
|
||||
// GetOriginToViewOffset() is a utility method that returns the
|
||||
// offset necessary to map a point, relative to the frame's upper
|
||||
// left corner, into the coordinate system of the view associated
|
||||
// with the frame.
|
||||
//
|
||||
// If there is no view associated with the frame, the offset
|
||||
// returned will always be (0,0).
|
||||
|
||||
NS_IMETHODIMP nsFrame::GetOriginToViewOffset(nsIPresContext* aPresContext,
|
||||
nsPoint& aOffset,
|
||||
nsIView** aView) const
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPresContext);
|
||||
|
||||
aOffset.MoveTo(0,0);
|
||||
|
||||
if (aView)
|
||||
*aView = nsnull;
|
||||
|
||||
nsIView *view = nsnull;
|
||||
nsresult rv = GetView(aPresContext, &view);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && view) {
|
||||
nsIView *parentView = nsnull;
|
||||
nsPoint offsetToParentView;
|
||||
rv = GetOffsetFromView(aPresContext, offsetToParentView, &parentView);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsPoint viewPos;
|
||||
rv = view->GetPosition(&viewPos.x, &viewPos.y);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aOffset = offsetToParentView - viewPos;
|
||||
|
||||
if (aView)
|
||||
*aView = view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsFrame::GetWindow(nsIPresContext* aPresContext,
|
||||
nsIWidget** aWindow) const
|
||||
{
|
||||
|
@ -249,6 +249,7 @@ public:
|
||||
NS_IMETHOD SetView(nsIPresContext* aPresContext, nsIView* aView);
|
||||
NS_IMETHOD GetParentWithView(nsIPresContext* aPresContext, nsIFrame** aParent) const;
|
||||
NS_IMETHOD GetOffsetFromView(nsIPresContext* aPresContext, nsPoint& aOffset, nsIView** aView) const;
|
||||
NS_IMETHOD GetOriginToViewOffset(nsIPresContext *aPresContext, nsPoint& aOffset, nsIView **aView) const;
|
||||
NS_IMETHOD GetWindow(nsIPresContext* aPresContext, nsIWidget**) const;
|
||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||
NS_IMETHOD IsPercentageBase(PRBool& aBase) const;
|
||||
|
@ -961,6 +961,18 @@ public:
|
||||
nsPoint& aOffset,
|
||||
nsIView** aView) const = 0;
|
||||
|
||||
/**
|
||||
* Returns the offset from this frame's upper left corner to the upper
|
||||
* left corner of the view returned by a call to GetView(). aOffset
|
||||
* will contain the offset to the view or (0,0) if the frame has no
|
||||
* view. aView will contain a pointer to the view returned by GetView().
|
||||
* aView is optional, that is, you may pass null if you are not interested
|
||||
* in getting a pointer to the view.
|
||||
*/
|
||||
NS_IMETHOD GetOriginToViewOffset(nsIPresContext* aPresContext,
|
||||
nsPoint& aOffset,
|
||||
nsIView** aView) const = 0;
|
||||
|
||||
/**
|
||||
* Returns the window that contains this frame. If this frame has a
|
||||
* view and the view has a window, then this frames window is
|
||||
|
@ -293,8 +293,16 @@ nsContainerFrame::GetFrameForPointUsing(nsIPresContext* aPresContext,
|
||||
FirstChild(aPresContext, aList, &kid);
|
||||
*aFrame = nsnull;
|
||||
tmp.MoveTo(aPoint.x - mRect.x, aPoint.y - mRect.y);
|
||||
|
||||
nsPoint originOffset;
|
||||
nsIView *view = nsnull;
|
||||
nsresult rv = GetOriginToViewOffset(aPresContext, originOffset, &view);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && view)
|
||||
tmp += originOffset;
|
||||
|
||||
while (nsnull != kid) {
|
||||
nsresult rv = kid->GetFrameForPoint(aPresContext, tmp, aWhichLayer, &hit);
|
||||
rv = kid->GetFrameForPoint(aPresContext, tmp, aWhichLayer, &hit);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && hit) {
|
||||
*aFrame = hit;
|
||||
|
@ -2042,6 +2042,62 @@ NS_IMETHODIMP nsFrame::GetOffsetFromView(nsIPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The (x,y) value of the frame's upper left corner is always
|
||||
// relative to its parentFrame's upper left corner, unless
|
||||
// its parentFrame has a view associated with it, in which case, it
|
||||
// will be relative to the upper left corner of the view returned
|
||||
// by a call to parentFrame->GetView().
|
||||
//
|
||||
// This means that while drilling down the frame hierarchy, from
|
||||
// parent to child frame, we sometimes need to take into account
|
||||
// crossing these view boundaries, because the coordinate system
|
||||
// changes from parent frame coordinate system, to the associated
|
||||
// view's coordinate system.
|
||||
//
|
||||
// GetOriginToViewOffset() is a utility method that returns the
|
||||
// offset necessary to map a point, relative to the frame's upper
|
||||
// left corner, into the coordinate system of the view associated
|
||||
// with the frame.
|
||||
//
|
||||
// If there is no view associated with the frame, the offset
|
||||
// returned will always be (0,0).
|
||||
|
||||
NS_IMETHODIMP nsFrame::GetOriginToViewOffset(nsIPresContext* aPresContext,
|
||||
nsPoint& aOffset,
|
||||
nsIView** aView) const
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPresContext);
|
||||
|
||||
aOffset.MoveTo(0,0);
|
||||
|
||||
if (aView)
|
||||
*aView = nsnull;
|
||||
|
||||
nsIView *view = nsnull;
|
||||
nsresult rv = GetView(aPresContext, &view);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && view) {
|
||||
nsIView *parentView = nsnull;
|
||||
nsPoint offsetToParentView;
|
||||
rv = GetOffsetFromView(aPresContext, offsetToParentView, &parentView);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsPoint viewPos;
|
||||
rv = view->GetPosition(&viewPos.x, &viewPos.y);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aOffset = offsetToParentView - viewPos;
|
||||
|
||||
if (aView)
|
||||
*aView = view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsFrame::GetWindow(nsIPresContext* aPresContext,
|
||||
nsIWidget** aWindow) const
|
||||
{
|
||||
|
@ -249,6 +249,7 @@ public:
|
||||
NS_IMETHOD SetView(nsIPresContext* aPresContext, nsIView* aView);
|
||||
NS_IMETHOD GetParentWithView(nsIPresContext* aPresContext, nsIFrame** aParent) const;
|
||||
NS_IMETHOD GetOffsetFromView(nsIPresContext* aPresContext, nsPoint& aOffset, nsIView** aView) const;
|
||||
NS_IMETHOD GetOriginToViewOffset(nsIPresContext *aPresContext, nsPoint& aOffset, nsIView **aView) const;
|
||||
NS_IMETHOD GetWindow(nsIPresContext* aPresContext, nsIWidget**) const;
|
||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||
NS_IMETHOD IsPercentageBase(PRBool& aBase) const;
|
||||
|
@ -5880,13 +5880,27 @@ PresShell::HandleEvent(nsIView *aView,
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is because we want to give the point in the same
|
||||
// coordinates as the frame's own Rect, so mRect.Contains(aPoint)
|
||||
// works. However, this point is relative to the frame's rect, so
|
||||
// we need to add on the origin of the rect.
|
||||
// aEvent->point is relative to aView's upper left corner. We need
|
||||
// a point that is in the same coordinate system as frame's rect
|
||||
// so that the frame->mRect.Contains(aPoint) calls in
|
||||
// GetFrameForPoint() work. The assumption here is that frame->GetView()
|
||||
// will return aView, and frame's parent view is aView's parent.
|
||||
|
||||
nsPoint eventPoint;
|
||||
frame->GetOrigin(eventPoint);
|
||||
eventPoint += aEvent->point;
|
||||
|
||||
nsPoint originOffset;
|
||||
nsIView *view = nsnull;
|
||||
frame->GetOriginToViewOffset(mPresContext, originOffset, &view);
|
||||
|
||||
#ifdef DEBUG_kin
|
||||
NS_ASSERTION(view == aView, "view != aView");
|
||||
#endif // DEBUG_kin
|
||||
|
||||
if (view == aView)
|
||||
eventPoint -= originOffset;
|
||||
|
||||
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_FOREGROUND, &mCurrentEventFrame);
|
||||
if (rv != NS_OK) {
|
||||
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_FLOATERS, &mCurrentEventFrame);
|
||||
|
@ -1977,7 +1977,8 @@ nsBoxFrame::GetFrameForPoint(nsIPresContext* aPresContext,
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIView* view = nsnull;
|
||||
GetView(aPresContext, &view);
|
||||
nsPoint originOffset;
|
||||
GetOriginToViewOffset(aPresContext, originOffset, &view);
|
||||
|
||||
// get the debug frame.
|
||||
if (view || (mState & NS_STATE_IS_ROOT))
|
||||
@ -2002,6 +2003,10 @@ nsBoxFrame::GetFrameForPoint(nsIPresContext* aPresContext,
|
||||
FirstChild(aPresContext, nsnull, &kid);
|
||||
*aFrame = nsnull;
|
||||
tmp.MoveTo(aPoint.x - mRect.x, aPoint.y - mRect.y);
|
||||
|
||||
if (view)
|
||||
tmp += originOffset;
|
||||
|
||||
while (nsnull != kid) {
|
||||
// have we hit a child before
|
||||
PRBool haveKid = (hit != nsnull);
|
||||
|
Loading…
Reference in New Issue
Block a user