Bug 320326: deCOMtaminate GetContentAndOffsetsFromPoint, plus some slight behavior changes. r+sr=roc.

This commit is contained in:
sharparrow1%yahoo.com 2006-02-27 05:57:37 +00:00
Родитель 276ede16dd
Коммит c85638a9e7
7 изменённых файлов: 184 добавлений и 226 удалений

Просмотреть файл

@ -323,20 +323,11 @@ nsDOMUIEvent::GetRangeParent(nsIDOMNode** aRangeParent)
*aRangeParent = nsnull;
if (targetFrame) {
nsCOMPtr<nsIContent> parent;
PRInt32 offset, endOffset;
PRBool beginOfContent;
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
targetFrame);
if (NS_SUCCEEDED(targetFrame->GetContentAndOffsetsFromPoint(mPresContext,
pt,
getter_AddRefs(parent),
offset,
endOffset,
beginOfContent))) {
if (parent) {
return CallQueryInterface(parent, aRangeParent);
}
targetFrame);
nsCOMPtr<nsIContent> parent = targetFrame->GetContentOffsetsFromPoint(pt).content;
if (parent) {
return CallQueryInterface(parent, aRangeParent);
}
}
@ -354,20 +345,10 @@ nsDOMUIEvent::GetRangeOffset(PRInt32* aRangeOffset)
}
if (targetFrame) {
nsIContent* parent = nsnull;
PRInt32 endOffset;
PRBool beginOfContent;
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
targetFrame);
if (NS_SUCCEEDED(targetFrame->GetContentAndOffsetsFromPoint(mPresContext,
pt,
&parent,
*aRangeOffset,
endOffset,
beginOfContent))) {
NS_IF_RELEASE(parent);
return NS_OK;
}
targetFrame);
*aRangeOffset = targetFrame->GetContentOffsetsFromPoint(pt).offset;
return NS_OK;
}
*aRangeOffset = 0;
return NS_OK;

Просмотреть файл

@ -53,12 +53,7 @@
class BRFrame : public nsFrame {
public:
// nsIFrame
// REVIEW: Removed debug-only Paint() method rather than porting it
NS_IMETHOD GetPositionHelper(const nsPoint& aPoint,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd);
virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
NS_IMETHOD PeekOffset(nsPresContext* aPresContext,
nsPeekOffsetStruct *aPos);
@ -184,21 +179,16 @@ BRFrame::GetType() const
return nsLayoutAtoms::brFrame;
}
NS_IMETHODIMP BRFrame::GetPositionHelper(const nsPoint& aPoint,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd)
nsIFrame::ContentOffsets BRFrame::CalcContentOffsetsFromFramePoint(nsPoint aPoint)
{
if (!mContent)
return NS_ERROR_NULL_POINTER;
NS_IF_ADDREF(*aNewContent = mContent->GetParent());
if (*aNewContent) {
aContentOffset = (*aNewContent)->IndexOf(mContent);
aContentOffsetEnd = aContentOffset;
return NS_OK;
ContentOffsets offsets;
offsets.content = mContent->GetParent();
if (offsets.content) {
offsets.offset = offsets.content->IndexOf(mContent);
offsets.secondaryOffset = offsets.offset;
offsets.associateWithNext = PR_TRUE;
}
return NS_ERROR_FAILURE;
return offsets;
}
NS_IMETHODIMP BRFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)

Просмотреть файл

@ -1814,17 +1814,11 @@ nsFrame::HandlePress(nsPresContext* aPresContext,
return HandleMultiplePress(aPresContext, aEvent, aEventStatus);
}
nsCOMPtr<nsIContent> content;
PRInt32 startOffset = 0, endOffset = 0;
PRBool beginFrameContent = PR_FALSE;
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
rv = GetContentAndOffsetsFromPoint(aPresContext, pt, getter_AddRefs(content),
startOffset, endOffset,
beginFrameContent);
ContentOffsets offsets = GetContentOffsetsFromPoint(pt);
if (NS_FAILED(rv))
return rv;
if (!offsets.content)
return NS_ERROR_FAILURE;
// Let Ctrl/Cmd+mouse down do table selection instead of drag initiation
nsCOMPtr<nsIContent>parentContent;
@ -1856,7 +1850,9 @@ nsFrame::HandlePress(nsPresContext* aPresContext,
if (isSelected)
{
rv = frameselection->LookUpSelection(content, 0, endOffset, &details, PR_FALSE);
rv = frameselection->LookUpSelection(offsets.content, 0,
offsets.EndOffset(), &details,
PR_FALSE);
if (NS_FAILED(rv))
return rv;
@ -1879,7 +1875,8 @@ nsFrame::HandlePress(nsPresContext* aPresContext,
// the spellcheck selection.
//
if (curDetail->mType != nsISelectionController::SELECTION_SPELLCHECK &&
curDetail->mStart <= startOffset && endOffset <= curDetail->mEnd)
curDetail->mStart <= offsets.StartOffset() &&
offsets.EndOffset() <= curDetail->mEnd)
{
delete details;
rv = frameselection->SetMouseDownState( PR_FALSE );
@ -1904,18 +1901,23 @@ nsFrame::HandlePress(nsPresContext* aPresContext,
return rv;
#if defined(XP_MAC) || defined(XP_MACOSX)
rv = frameselection->HandleClick(content, startOffset , endOffset, me->isShift, me->isMeta, beginFrameContent);
PRBool control = me->isMeta;
#else
rv = frameselection->HandleClick(content, startOffset , endOffset, me->isShift, me->isControl, beginFrameContent);
PRBool control = me->isControl;
#endif
rv = frameselection->HandleClick(offsets.content, offsets.StartOffset(),
offsets.EndOffset(), me->isShift, control,
offsets.associateWithNext);
if (NS_FAILED(rv))
return rv;
if (startOffset != endOffset)
if (offsets.offset != offsets.secondaryOffset)
frameselection->MaintainSelection();
if (isEditor && !me->isShift && (endOffset - startOffset) == 1)
if (isEditor && !me->isShift &&
(offsets.EndOffset() - offsets.StartOffset()) == 1)
{
// A single node is selected and we aren't extending an existing
// selection, which means the user clicked directly on an object (either
@ -1971,31 +1973,22 @@ nsFrame::HandleMultiplePress(nsPresContext* aPresContext,
return NS_OK;
}
PRInt32 startPos = 0;
PRInt32 contentOffsetEnd = 0;
nsCOMPtr<nsIContent> newContent;
PRBool beginContent = PR_FALSE;
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
rv = GetContentAndOffsetsFromPoint(aPresContext,
pt,
getter_AddRefs(newContent),
startPos,
contentOffsetEnd,
beginContent);
if (NS_FAILED(rv)) return rv;
ContentOffsets offsets = GetContentOffsetsFromPoint(pt);
if (!offsets.content) return NS_ERROR_FAILURE;
nsIFrame* result;
PRInt32 offset;
// Maybe make this a static helper?
rv = GetPresContext()->GetPresShell()->FrameSelection()->
GetFrameForNodeOffset(newContent, startPos,
nsIFrameSelection::HINT(beginContent),
GetFrameForNodeOffset(offsets.content, offsets.offset,
nsIFrameSelection::HINT(offsets.associateWithNext),
&result, &offset);
NS_ENSURE_SUCCESS(rv, rv);
nsFrame* frame = NS_STATIC_CAST(nsFrame*, result);
return frame->PeekBackwardAndForward(beginAmount, endAmount,
startPos, aPresContext,
offsets.offset, aPresContext,
beginAmount != eSelectWord);
}
@ -2208,13 +2201,14 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsPresContext* aPresContext,
PRBool beginFrameContent = PR_FALSE;
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
result = GetContentAndOffsetsFromPoint(aPresContext, pt,
getter_AddRefs(content),
startOffset, endOffset,
beginFrameContent);
if (NS_FAILED(result)) return result;
ContentOffsets offsets = GetContentOffsetsFromPoint(pt);
if (!offsets.content) return NS_ERROR_FAILURE;
result = frameselection->HandleClick(content, startOffset , endOffset, me->isShift, PR_FALSE, beginFrameContent);
result = frameselection->HandleClick(offsets.content,
offsets.StartOffset(),
offsets.EndOffset(),
me->isShift, PR_FALSE,
offsets.associateWithNext);
if (NS_FAILED(result)) return result;
}
else
@ -2249,8 +2243,8 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsPresContext* aPresContext,
return NS_OK;
}
struct ContentOffsets {
ContentOffsets(nsIContent* aContent, PRInt32 aStart, PRInt32 aEnd) :
struct FrameContentRange {
FrameContentRange(nsIContent* aContent, PRInt32 aStart, PRInt32 aEnd) :
content(aContent), start(aStart), end(aEnd) { }
nsCOMPtr<nsIContent> content;
PRInt32 start;
@ -2258,23 +2252,23 @@ struct ContentOffsets {
};
// Retrieve the content offsets of a frame
static ContentOffsets GetOffsetsOfFrame(nsIFrame* aFrame) {
static FrameContentRange GetRangeForFrame(nsIFrame* aFrame) {
nsCOMPtr<nsIContent> content, parent;
content = aFrame->GetContent();
if (!content) {
NS_WARNING("Frame has no content");
return ContentOffsets(nsnull, -1, -1);
return FrameContentRange(nsnull, -1, -1);
}
nsIAtom* type = aFrame->GetType();
if (type == nsLayoutAtoms::textFrame) {
PRInt32 offset, offsetEnd;
aFrame->GetOffsets(offset, offsetEnd);
return ContentOffsets(content, offset, offsetEnd);
return FrameContentRange(content, offset, offsetEnd);
}
if (type == nsLayoutAtoms::brFrame) {
parent = content->GetParent();
PRInt32 beginOffset = parent->IndexOf(content);
return ContentOffsets(parent, beginOffset, beginOffset);
return FrameContentRange(parent, beginOffset, beginOffset);
}
// Loop to deal with anonymous content, which has no index; this loop
// probably won't run more than twice under normal conditions
@ -2283,13 +2277,13 @@ static ContentOffsets GetOffsetsOfFrame(nsIFrame* aFrame) {
if (parent) {
PRInt32 beginOffset = parent->IndexOf(content);
if (beginOffset >= 0)
return ContentOffsets(parent, beginOffset, beginOffset + 1);
return FrameContentRange(parent, beginOffset, beginOffset + 1);
content = parent;
}
} while (parent);
// The root content node must act differently
return ContentOffsets(content, 0, content->GetChildCount());
return FrameContentRange(content, 0, content->GetChildCount());
}
// The FrameTarget represents the closest frame to a point that can be selected
@ -2576,16 +2570,46 @@ static FrameTarget GetSelectionClosestFrame(nsIFrame* aFrame, nsPoint aPoint)
return FrameTarget(aFrame, PR_FALSE, PR_FALSE);
}
nsresult nsFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
const nsPoint& aPoint,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd,
PRBool& aKeepWithAbove)
nsIFrame::ContentOffsets OffsetsForSingleFrame(nsIFrame* aFrame, nsPoint aPoint)
{
if (!aNewContent)
return NS_ERROR_NULL_POINTER;
nsIFrame::ContentOffsets offsets;
FrameContentRange range = GetRangeForFrame(aFrame);
offsets.content = range.content;
// If there are continuations (meaning it's not one rectangle), this is the
// best this function can do
if (aFrame->GetNextContinuation() || aFrame->GetPrevContinuation()) {
offsets.offset = range.start;
offsets.secondaryOffset = range.end;
offsets.associateWithNext = PR_TRUE;
return offsets;
}
// Figure out whether the offsets should be over, after, or before the frame
nsRect rect(nsPoint(0, 0), aFrame->GetSize());
PRBool isBlock = (aFrame->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE);
PRBool isRtl = (aFrame->GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL);
if ((isBlock && rect.y < aPoint.y) ||
(!isBlock && ((isRtl && rect.x + rect.width / 2 > aPoint.x) ||
(!isRtl && rect.x + rect.width / 2 < aPoint.x)))) {
offsets.offset = range.end;
if (rect.Contains(aPoint))
offsets.secondaryOffset = range.start;
else
offsets.secondaryOffset = range.end;
} else {
offsets.offset = range.start;
if (rect.Contains(aPoint))
offsets.secondaryOffset = range.end;
else
offsets.secondaryOffset = range.start;
}
offsets.associateWithNext = (offsets.offset == range.start);
return offsets;
}
nsIFrame::ContentOffsets nsIFrame::GetContentOffsetsFromPoint(nsPoint aPoint)
{
// This section of code deals with special selection styles. Note that
// -moz-none and -moz-all exist, even though they don't need to be explicitly
// handled.
@ -2610,16 +2634,10 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
// should lead to the whole frame being selected
if (adjustedFrame->GetStyleUIReset()->mUserSelect ==
NS_STYLE_USER_SELECT_ALL) {
ContentOffsets selectOffset = GetOffsetsOfFrame(adjustedFrame);
if (!selectOffset.content)
return NS_ERROR_NULL_POINTER;
NS_ADDREF(*aNewContent = selectOffset.content);
aContentOffset = selectOffset.start;
aContentOffsetEnd = selectOffset.end;
aKeepWithAbove = PR_FALSE;
return NS_OK;
return OffsetsForSingleFrame(adjustedFrame, aPoint +
this->GetOffsetTo(adjustedFrame));
}
// For other cases, try to find a closest frame starting from the parent of
// the unselectable frame
if (frameAdjusted)
@ -2628,68 +2646,32 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
nsPoint adjustedPoint = aPoint + this->GetOffsetTo(adjustedFrame);
FrameTarget closest = GetSelectionClosestFrame(adjustedFrame, adjustedPoint);
ContentOffsets offset = GetOffsetsOfFrame(closest.frame);
if (!offset.content)
return NS_ERROR_NULL_POINTER;
// If the correct offset is at one end of a frame, use offset-based
// calculation method
if (closest.frameEdge) {
NS_ADDREF(*aNewContent = offset.content);
if (closest.afterFrame) {
aContentOffset = offset.end;
aKeepWithAbove = PR_FALSE;
} else {
aContentOffset = offset.start;
aKeepWithAbove = PR_TRUE;
}
aContentOffsetEnd = aContentOffset;
return NS_OK;
ContentOffsets offsets;
FrameContentRange range = GetRangeForFrame(closest.frame);
offsets.content = range.content;
if (closest.afterFrame)
offsets.offset = range.end;
else
offsets.offset = range.start;
offsets.secondaryOffset = offsets.offset;
offsets.associateWithNext = (offsets.offset == range.start);
return offsets;
}
nsPoint pt = aPoint - closest.frame->GetOffsetTo(this);
nsresult rv = closest.frame->GetPositionHelper(pt, aNewContent,
aContentOffset,
aContentOffsetEnd);
NS_ENSURE_SUCCESS(rv, rv);
return NS_STATIC_CAST(nsFrame*, closest.frame)->CalcContentOffsetsFromFramePoint(pt);
// XXX should I add some kind of offset standardization?
// consider <b>xxxxx</b><i>zzzzz</i>; should any click between the last
// x and first z put the cursor in the same logical position in addition
// to the same visual position?
NS_ASSERTION(*aNewContent == offset.content,
"There should only be one possible content base");
aKeepWithAbove = (aContentOffset == offset.start);
return NS_OK;
}
NS_IMETHODIMP nsFrame::GetPositionHelper(const nsPoint& aPoint,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd)
nsIFrame::ContentOffsets nsFrame::CalcContentOffsetsFromFramePoint(nsPoint aPoint)
{
ContentOffsets offset = GetOffsetsOfFrame(this);
NS_IF_ADDREF(*aNewContent = offset.content);
// Figure out whether the offsets should be over, after, or before the frame
nsRect rect(nsPoint(0, 0), GetSize());
if (rect.Contains(aPoint)) {
aContentOffset = offset.start;
aContentOffsetEnd = offset.end;
} else {
PRBool isBlock = (GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE);
PRBool isRtl = (GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL);
if ((isBlock && rect.y < aPoint.y) ||
(!isBlock && ((isRtl && rect.x + rect.width < aPoint.x) ||
(!isRtl && rect.x < aPoint.x)))) {
aContentOffset = offset.end;
aContentOffsetEnd = offset.end;
} else {
aContentOffset = offset.start;
aContentOffsetEnd = offset.start;
}
}
return NS_OK;
return OffsetsForSingleFrame(this, aPoint);
}
NS_IMETHODIMP
@ -3908,7 +3890,6 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
nsISupports *isupports = nsnull;
nsIFrame *storeOldResultFrame = resultFrame;
while ( !found ){
nsPresContext *context = aPos->mShell->GetPresContext();
nsPoint point;
point.x = aPos->mDesiredX;
@ -3960,16 +3941,15 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
if (!resultFrame->HasView())
{
rect = resultFrame->GetRect();
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))
ContentOffsets offsets =
resultFrame->GetContentOffsetsFromPoint(point - offset);
aPos->mResultContent = offsets.content;
aPos->mContentOffset = offsets.offset;
aPos->mPreferLeft = offsets.associateWithNext;
if (offsets.content)
{
PRBool selectable;
resultFrame->IsSelectable(&selectable, nsnull);
@ -4002,19 +3982,16 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
aPresContext, resultFrame, aPos->mScrollViewStop);
}
while ( !found ){
nsPresContext *context = aPos->mShell->GetPresContext();
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
nsPoint point(aPos->mDesiredX, 0);
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))
ContentOffsets offsets =
resultFrame->GetContentOffsetsFromPoint(point - offset);
aPos->mResultContent = offsets.content;
aPos->mContentOffset = offsets.offset;
aPos->mPreferLeft = offsets.associateWithNext;
if (offsets.content)
{
PRBool selectable;
resultFrame->IsSelectable(&selectable, nsnull);
@ -4329,7 +4306,6 @@ nsFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
if (!aPos || !aPos->mShell)
return NS_ERROR_NULL_POINTER;
nsresult result = NS_ERROR_FAILURE;
PRInt32 endoffset;
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
@ -4385,11 +4361,11 @@ nsFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
nsIView* view;
nsPoint offset;
GetOffsetFromView(offset, &view);
result = GetContentAndOffsetsFromPoint(context,point - offset,
getter_AddRefs(aPos->mResultContent),
aPos->mContentOffset,
endoffset,
aPos->mPreferLeft);
ContentOffsets offsets = GetContentOffsetsFromPoint(point - offset);
aPos->mResultContent = offsets.content;
aPos->mContentOffset = offsets.offset;
aPos->mPreferLeft = offsets.associateWithNext;
result = offsets.content ? NS_OK : NS_ERROR_FAILURE;
}break;
case eSelectLine :
{

Просмотреть файл

@ -296,12 +296,6 @@ public:
nsGUIEvent * aEvent,
nsEventStatus* aEventStatus);
NS_IMETHOD GetContentAndOffsetsFromPoint(nsPresContext* aCX,
const nsPoint& aPoint,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd,
PRBool& aBeginFrameContent);
NS_IMETHOD PeekBackwardAndForward(nsSelectionAmount aAmountBack,
nsSelectionAmount aAmountForward,
PRInt32 aStartPos,
@ -309,11 +303,10 @@ public:
PRBool aJumpLines);
// Helper for GetContentAndOffsetsFromPoint
NS_IMETHOD GetPositionHelper(const nsPoint& aPoint,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd);
// Helper for GetContentAndOffsetsFromPoint; calculation of content offsets
// in this function assumes there is no child frame that can be targeted.
virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
// Box layout methods
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);

Просмотреть файл

@ -818,20 +818,37 @@ public:
nsEvent* aEvent,
nsIContent** aContent) = 0;
// This structure keeps track of the content node and offsets associated with
// a point; there is a primary and a secondary offset associated with any
// point. The primary and secondary offsets differ when the point is over a
// non-text object. The primary offset is the expected position of the
// cursor calculated from a point; the secondary offset, when it is different,
// indicates that the point is in the boundaries of some selectable object.
// Note that the primary offset can be after the secondary offset; for places
// that need the beginning and end of the object, the StartOffset and
// EndOffset helpers can be used.
struct ContentOffsets {
nsCOMPtr<nsIContent> content;
PRBool IsNull() { return !content; }
PRInt32 offset;
PRInt32 secondaryOffset;
// Helpers for places that need the ends of the offsets and expect them in
// numerical order, as opposed to wanting the primary and secondary offsets
PRInt32 StartOffset() { return PR_MIN(offset, secondaryOffset); }
PRInt32 EndOffset() { return PR_MAX(offset, secondaryOffset; }
// This boolean indicates whether the associated content is before or after
// the offset; the most visible use is to allow the caret to know which line
// to display on.
PRBool associateWithNext;
};
/**
* Find the content offset from a point. aPoint is in frame coordinates.
* This function calculates the content offsets for selection relative to
* a point. Note that this should generally only be callled on the event
* frame associated with an event because this function does not account
* for frame lists other than the primary one.
* @param aPoint point relative to this frame
*/
NS_IMETHOD GetContentAndOffsetsFromPoint(nsPresContext* aCX,
const nsPoint& aPoint,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd,
PRBool& aBeginFrameContent) = 0;
// Helper for GetContentAndOffsetsFromPoint
NS_IMETHOD GetPositionHelper(const nsPoint& aPoint,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd) = 0;
ContentOffsets GetContentOffsetsFromPoint(nsPoint aPoint);
/**
* This structure holds information about a cursor. mContainer represents a

Просмотреть файл

@ -2449,21 +2449,16 @@ nsSelection::HandleDrag(nsPresContext *aPresContext, nsIFrame *aFrame, nsPoint&
if (!newFrame)
return NS_ERROR_FAILURE;
PRInt32 startPos = 0;
PRInt32 contentOffsetEnd = 0;
PRBool beginOfContent;
nsCOMPtr<nsIContent> newContent;
result = newFrame->GetContentAndOffsetsFromPoint(aPresContext, newPoint,
getter_AddRefs(newContent),
startPos, contentOffsetEnd, beginOfContent);
nsIFrame::ContentOffsets offsets =
newFrame->GetContentOffsetsFromPoint(newPoint);
if ((newFrame->GetStateBits() & NS_FRAME_SELECTED_CONTENT) &&
AdjustForMaintainedSelection(newContent, startPos))
AdjustForMaintainedSelection(offsets.content, offsets.offset))
return NS_OK;
if (NS_SUCCEEDED(result))
{
// XXX Code not up to date
#ifdef VISUALSELECTION
if (aPresContext->BidiEnabled()) {
PRUint8 level;
@ -2486,8 +2481,8 @@ nsSelection::HandleDrag(nsPresContext *aPresContext, nsIFrame *aFrame, nsPoint&
}
else
#endif // VISUALSELECTION
result = HandleClick(newContent, startPos, contentOffsetEnd, PR_TRUE,
PR_FALSE, beginOfContent);
result = HandleClick(offsets.content, offsets.offset, offsets.offset,
PR_TRUE, PR_FALSE, offsets.associateWithNext);
}
return result;
@ -2917,28 +2912,22 @@ nsSelection::CommonPageMove(PRBool aForward,
}
// get a content at desired location
nsCOMPtr<nsIContent> content;
PRInt32 startOffset, endOffset;
PRBool beginFrameContent;
nsPoint desiredPoint;
desiredPoint.x = caretPos.x;
desiredPoint.y = caretPos.y + caretPos.height/2;
nsPresContext *context = mShell->GetPresContext();
result = mainframe->GetContentAndOffsetsFromPoint(context, desiredPoint, getter_AddRefs(content), startOffset, endOffset, beginFrameContent);
if (NS_FAILED(result))
return result;
if (!content)
nsIFrame::ContentOffsets offsets =
mainframe->GetContentOffsetsFromPoint(desiredPoint);
if (!offsets.content)
return NS_ERROR_UNEXPECTED;
// scroll one page
aScrollableView->ScrollByPages(0, aForward ? 1 : -1);
// place the caret
result = aFrameSel->HandleClick(content, startOffset, startOffset, aExtend, PR_FALSE, PR_TRUE);
result = aFrameSel->HandleClick(offsets.content, offsets.offset,
offsets.offset, aExtend, PR_FALSE, PR_TRUE);
return result;
}

Просмотреть файл

@ -322,6 +322,8 @@ public:
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd);
virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
NS_IMETHOD GetPositionSlowly(nsIRenderingContext * aRendContext,
const nsPoint& aPoint,
nsIContent ** aNewContent,
@ -4023,6 +4025,16 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext,
}
}
// XXX I don't really want to rewrite GetPositionHelper, so I'm doing this
// hack for now
nsIFrame::ContentOffsets nsTextFrame::CalcContentOffsetsFromFramePoint(nsPoint aPoint) {
ContentOffsets offsets;
GetPositionHelper(aPoint, getter_AddRefs(offsets.content), offsets.offset,
offsets.secondaryOffset);
offsets.associateWithNext = (mContentOffset == offsets.offset);
return offsets;
}
//---------------------------------------------------------------------------
// Uses a binary search to find the position of the cursor in the text.
// The "indices array is used to map from the compressed text back to the