зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1077515 - part 3 - Change desiredX (nscoord) to desiredPos (nsPoint) in nsPeekOffsetStruct, to support maintaining either vertical or horizontal position on inter-line moves. r=roc
This commit is contained in:
Родитель
f5756b81ef
Коммит
9a00763a7b
|
@ -508,7 +508,7 @@ HyperTextAccessible::FindOffset(uint32_t aOffset, nsDirection aDirection,
|
|||
const bool kIsKeyboardSelect = true; // is keyboard selection
|
||||
const bool kIsVisualBidi = false; // use visual order for bidi text
|
||||
nsPeekOffsetStruct pos(aAmount, aDirection, innerContentOffset,
|
||||
0, kIsJumpLinesOk, kIsScrollViewAStop,
|
||||
nsPoint(0, 0), kIsJumpLinesOk, kIsScrollViewAStop,
|
||||
kIsKeyboardSelect, kIsVisualBidi,
|
||||
aWordMovementType);
|
||||
nsresult rv = frameAtOffset->PeekOffset(&pos);
|
||||
|
|
|
@ -635,7 +635,7 @@ CompareRangeWithContentOffset(nsRange* aRange,
|
|||
nsPeekOffsetStruct pos(eSelectCluster,
|
||||
dir,
|
||||
offset,
|
||||
0,
|
||||
nsPoint(0, 0),
|
||||
true,
|
||||
true, //limit on scrolled views
|
||||
false,
|
||||
|
|
|
@ -700,7 +700,9 @@ nsCaret::GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection,
|
|||
nsBidiLevel baseLevel = NS_GET_BASE_LEVEL(frameAfter);
|
||||
if (baseLevel != levelAfter)
|
||||
{
|
||||
nsPeekOffsetStruct pos(eSelectBeginLine, eDirPrevious, 0, 0, false, true, false, true);
|
||||
nsPeekOffsetStruct pos(eSelectBeginLine, eDirPrevious, 0,
|
||||
nsPoint(0, 0), false, true, false,
|
||||
true);
|
||||
if (NS_SUCCEEDED(frameAfter->PeekOffset(&pos))) {
|
||||
theFrame = pos.mResultFrame;
|
||||
theFrameOffset = pos.mContentOffset;
|
||||
|
@ -733,7 +735,9 @@ nsCaret::GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection,
|
|||
nsBidiLevel baseLevel = NS_GET_BASE_LEVEL(frameBefore);
|
||||
if (baseLevel != levelBefore)
|
||||
{
|
||||
nsPeekOffsetStruct pos(eSelectEndLine, eDirNext, 0, 0, false, true, false, true);
|
||||
nsPeekOffsetStruct pos(eSelectEndLine, eDirNext, 0,
|
||||
nsPoint(0, 0), false, true, false,
|
||||
true);
|
||||
if (NS_SUCCEEDED(frameBefore->PeekOffset(&pos))) {
|
||||
theFrame = pos.mResultFrame;
|
||||
theFrameOffset = pos.mContentOffset;
|
||||
|
|
|
@ -3091,7 +3091,7 @@ nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
|
|||
nsPeekOffsetStruct pos(eSelectCharacter,
|
||||
eDirNext,
|
||||
aStartPos,
|
||||
0,
|
||||
nsPoint(0, 0),
|
||||
aJumpLines,
|
||||
true, //limit on scrolled views
|
||||
false,
|
||||
|
@ -3107,7 +3107,7 @@ nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
|
|||
nsPeekOffsetStruct startpos(aAmountBack,
|
||||
eDirPrevious,
|
||||
baseOffset,
|
||||
0,
|
||||
nsPoint(0, 0),
|
||||
aJumpLines,
|
||||
true, //limit on scrolled views
|
||||
false,
|
||||
|
@ -3119,7 +3119,7 @@ nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
|
|||
nsPeekOffsetStruct endpos(aAmountForward,
|
||||
eDirNext,
|
||||
aStartPos,
|
||||
0,
|
||||
nsPoint(0, 0),
|
||||
aJumpLines,
|
||||
true, //limit on scrolled views
|
||||
false,
|
||||
|
@ -6084,8 +6084,10 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
|||
nsPoint offset;
|
||||
nsView * view; //used for call of get offset from view
|
||||
aBlockFrame->GetOffsetFromView(offset,&view);
|
||||
nscoord newDesiredX = aPos->mDesiredX - offset.x;//get desired x into blockframe coordinates!
|
||||
result = it->FindFrameAt(searchingLine, newDesiredX, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
|
||||
nsPoint newDesiredPos =
|
||||
aPos->mDesiredPos - offset; //get desired position into blockframe coords
|
||||
result = it->FindFrameAt(searchingLine, newDesiredPos, &resultFrame,
|
||||
&isBeforeFirstFrame, &isAfterLastFrame);
|
||||
if(NS_FAILED(result))
|
||||
continue;
|
||||
}
|
||||
|
@ -6116,8 +6118,6 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
|||
nsIFrame *storeOldResultFrame = resultFrame;
|
||||
while ( !found ){
|
||||
nsPoint point;
|
||||
point.x = aPos->mDesiredX;
|
||||
|
||||
nsRect tempRect = resultFrame->GetRect();
|
||||
nsPoint offset;
|
||||
nsView * view; //used for call of get offset from view
|
||||
|
@ -6125,7 +6125,13 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
|||
if (!view) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
point.y = tempRect.height + offset.y;
|
||||
if (resultFrame->GetWritingMode().IsVertical()) {
|
||||
point.y = aPos->mDesiredPos.y;
|
||||
point.x = tempRect.width + offset.x;
|
||||
} else {
|
||||
point.y = tempRect.height + offset.y;
|
||||
point.x = aPos->mDesiredPos.x;
|
||||
}
|
||||
|
||||
//special check. if we allow non-text selection then we can allow a hit location to fall before a table.
|
||||
//otherwise there is no way to get and click signal to fall before a table (it being a line iterator itself)
|
||||
|
@ -6208,7 +6214,7 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
|||
);
|
||||
}
|
||||
while ( !found ){
|
||||
nsPoint point(aPos->mDesiredX, 0);
|
||||
nsPoint point = aPos->mDesiredPos;
|
||||
nsView* view;
|
||||
nsPoint offset;
|
||||
resultFrame->GetOffsetFromView(offset, &view);
|
||||
|
|
|
@ -63,7 +63,7 @@ struct MOZ_STACK_CLASS nsPeekOffsetStruct
|
|||
nsPeekOffsetStruct(nsSelectionAmount aAmount,
|
||||
nsDirection aDirection,
|
||||
int32_t aStartOffset,
|
||||
nscoord aDesiredX,
|
||||
nsPoint aDesiredPos,
|
||||
bool aJumpLines,
|
||||
bool aScrollViewStop,
|
||||
bool aIsKeyboardSelect,
|
||||
|
@ -96,9 +96,10 @@ struct MOZ_STACK_CLASS nsPeekOffsetStruct
|
|||
// Used with: eSelectCharacter, eSelectWord
|
||||
int32_t mStartOffset;
|
||||
|
||||
// mDesiredX: The desired x coordinate for the caret.
|
||||
// Used with: eSelectLine.
|
||||
nscoord mDesiredX;
|
||||
// mDesiredPos: The desired inline coordinate for the caret
|
||||
// (one of .x or .y will be used, depending on line's writing mode)
|
||||
// Used with: eSelectLine.
|
||||
nsPoint mDesiredPos;
|
||||
|
||||
// mWordMovementType: An enum that determines whether to prefer the start or end of a word
|
||||
// or to use the default beahvior, which is a combination of
|
||||
|
@ -645,9 +646,9 @@ private:
|
|||
nsSelectionAmount aAmount,
|
||||
CaretMovementStyle aMovementStyle);
|
||||
|
||||
nsresult FetchDesiredX(nscoord &aDesiredX); //the x position requested by the Key Handling for up down
|
||||
void InvalidateDesiredX(); //do not listen to mDesiredX you must get another.
|
||||
void SetDesiredX(nscoord aX); //set the mDesiredX
|
||||
nsresult FetchDesiredPos(nsPoint &aDesiredPos); //the position requested by the Key Handling for up down
|
||||
void InvalidateDesiredPos(); //do not listen to mDesiredPos you must get another.
|
||||
void SetDesiredPos(nsPoint aPos); //set the mDesiredPos
|
||||
|
||||
uint32_t GetBatching() const {return mBatching; }
|
||||
bool GetNotifyFrames() const { return mNotifyFrames; }
|
||||
|
@ -714,7 +715,7 @@ private:
|
|||
CaretAssociateHint mHint; //hint to tell if the selection is at the end of this line or beginning of next
|
||||
nsBidiLevel mCaretBidiLevel;
|
||||
|
||||
int32_t mDesiredX;
|
||||
nsPoint mDesiredPos;
|
||||
uint32_t mDelayedMouseEventClickCount;
|
||||
bool mDelayedMouseEventIsShift;
|
||||
bool mDelayedMouseEventValid;
|
||||
|
@ -724,7 +725,7 @@ private:
|
|||
bool mDragSelectingCells;
|
||||
bool mDragState; //for drag purposes
|
||||
bool mMouseDoubleDownState; //has the doubleclick down happened
|
||||
bool mDesiredXSet;
|
||||
bool mDesiredPosSet;
|
||||
|
||||
int8_t mCaretMovementStyle;
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#define nsILineIterator_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsPoint.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
class nsIFrame;
|
||||
|
@ -82,15 +82,16 @@ public:
|
|||
virtual int32_t FindLineContaining(nsIFrame* aFrame,
|
||||
int32_t aStartLine = 0) = 0;
|
||||
|
||||
// Given a line number and an X coordinate, find the frame on the
|
||||
// line that is nearest to the X coordinate. The
|
||||
// aXIsBeforeFirstFrame and aXIsAfterLastFrame flags are updated
|
||||
// Given a line number and a coordinate, find the frame on the line
|
||||
// that is nearest to aPos along the inline axis. (The block-axis coord
|
||||
// of aPos is irrelevant.)
|
||||
// The aPosIsBeforeFirstFrame and aPosIsAfterLastFrame flags are updated
|
||||
// appropriately.
|
||||
NS_IMETHOD FindFrameAt(int32_t aLineNumber,
|
||||
nscoord aX,
|
||||
nsPoint aPos,
|
||||
nsIFrame** aFrameFound,
|
||||
bool* aXIsBeforeFirstFrame,
|
||||
bool* aXIsAfterLastFrame) = 0;
|
||||
bool* aPosIsBeforeFirstFrame,
|
||||
bool* aPosIsAfterLastFrame) = 0;
|
||||
|
||||
// Give the line iterator implementor a chance todo something more complicated than
|
||||
// nsIFrame::GetNextSibling()
|
||||
|
|
|
@ -711,14 +711,14 @@ nsLineIterator::CheckLineOrder(int32_t aLine,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsLineIterator::FindFrameAt(int32_t aLineNumber,
|
||||
nscoord aX,
|
||||
nsPoint aPos,
|
||||
nsIFrame** aFrameFound,
|
||||
bool* aXIsBeforeFirstFrame,
|
||||
bool* aXIsAfterLastFrame)
|
||||
bool* aPosIsBeforeFirstFrame,
|
||||
bool* aPosIsAfterLastFrame)
|
||||
{
|
||||
NS_PRECONDITION(aFrameFound && aXIsBeforeFirstFrame && aXIsAfterLastFrame,
|
||||
NS_PRECONDITION(aFrameFound && aPosIsBeforeFirstFrame && aPosIsAfterLastFrame,
|
||||
"null OUT ptr");
|
||||
if (!aFrameFound || !aXIsBeforeFirstFrame || !aXIsAfterLastFrame) {
|
||||
if (!aFrameFound || !aPosIsBeforeFirstFrame || !aPosIsAfterLastFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if ((aLineNumber < 0) || (aLineNumber >= mNumLines)) {
|
||||
|
@ -728,8 +728,8 @@ nsLineIterator::FindFrameAt(int32_t aLineNumber,
|
|||
nsLineBox* line = mLines[aLineNumber];
|
||||
if (!line) {
|
||||
*aFrameFound = nullptr;
|
||||
*aXIsBeforeFirstFrame = true;
|
||||
*aXIsAfterLastFrame = false;
|
||||
*aPosIsBeforeFirstFrame = true;
|
||||
*aPosIsAfterLastFrame = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -737,51 +737,58 @@ nsLineIterator::FindFrameAt(int32_t aLineNumber,
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
nsIFrame* closestFromLeft = nullptr;
|
||||
nsIFrame* closestFromRight = nullptr;
|
||||
nsIFrame* closestFromStart = nullptr;
|
||||
nsIFrame* closestFromEnd = nullptr;
|
||||
|
||||
WritingMode wm = line->mWritingMode;
|
||||
nscoord cw = line->mContainerWidth;
|
||||
|
||||
LogicalPoint pos(wm, aPos, cw);
|
||||
|
||||
int32_t n = line->GetChildCount();
|
||||
while (n--) {
|
||||
nsRect rect = frame->GetRect();
|
||||
if (rect.width > 0) {
|
||||
// If aX is inside this frame - this is it
|
||||
if (rect.x <= aX && rect.XMost() > aX) {
|
||||
closestFromLeft = closestFromRight = frame;
|
||||
LogicalRect rect = frame->GetLogicalRect(wm, cw);
|
||||
if (rect.ISize(wm) > 0) {
|
||||
// If pos.I() is inside this frame - this is it
|
||||
if (rect.IStart(wm) <= pos.I(wm) && rect.IEnd(wm) > pos.I(wm)) {
|
||||
closestFromStart = closestFromEnd = frame;
|
||||
break;
|
||||
}
|
||||
if (rect.x < aX) {
|
||||
if (!closestFromLeft ||
|
||||
rect.XMost() > closestFromLeft->GetRect().XMost())
|
||||
closestFromLeft = frame;
|
||||
if (rect.IStart(wm) < pos.I(wm)) {
|
||||
if (!closestFromStart ||
|
||||
rect.IEnd(wm) > closestFromStart->GetLogicalRect(wm, cw).IEnd(wm))
|
||||
closestFromStart = frame;
|
||||
}
|
||||
else {
|
||||
if (!closestFromRight ||
|
||||
rect.x < closestFromRight->GetRect().x)
|
||||
closestFromRight = frame;
|
||||
if (!closestFromEnd ||
|
||||
rect.IStart(wm) < closestFromEnd->GetLogicalRect(wm, cw).IStart(wm))
|
||||
closestFromEnd = frame;
|
||||
}
|
||||
}
|
||||
frame = frame->GetNextSibling();
|
||||
}
|
||||
if (!closestFromLeft && !closestFromRight) {
|
||||
if (!closestFromStart && !closestFromEnd) {
|
||||
// All frames were zero-width. Just take the first one.
|
||||
closestFromLeft = closestFromRight = line->mFirstChild;
|
||||
closestFromStart = closestFromEnd = line->mFirstChild;
|
||||
}
|
||||
*aXIsBeforeFirstFrame = mRightToLeft ? !closestFromRight : !closestFromLeft;
|
||||
*aXIsAfterLastFrame = mRightToLeft ? !closestFromLeft : !closestFromRight;
|
||||
if (closestFromLeft == closestFromRight) {
|
||||
*aFrameFound = closestFromLeft;
|
||||
*aPosIsBeforeFirstFrame = mRightToLeft ? !closestFromEnd : !closestFromStart;
|
||||
*aPosIsAfterLastFrame = mRightToLeft ? !closestFromStart : !closestFromEnd;
|
||||
if (closestFromStart == closestFromEnd) {
|
||||
*aFrameFound = closestFromStart;
|
||||
}
|
||||
else if (!closestFromLeft) {
|
||||
*aFrameFound = closestFromRight;
|
||||
else if (!closestFromStart) {
|
||||
*aFrameFound = closestFromEnd;
|
||||
}
|
||||
else if (!closestFromRight) {
|
||||
*aFrameFound = closestFromLeft;
|
||||
else if (!closestFromEnd) {
|
||||
*aFrameFound = closestFromStart;
|
||||
}
|
||||
else { // we're between two frames
|
||||
nscoord delta = closestFromRight->GetRect().x - closestFromLeft->GetRect().XMost();
|
||||
if (aX < closestFromLeft->GetRect().XMost() + delta/2)
|
||||
*aFrameFound = closestFromLeft;
|
||||
nscoord delta = closestFromEnd->GetLogicalRect(wm, cw).IStart(wm) -
|
||||
closestFromStart->GetLogicalRect(wm, cw).IEnd(wm);
|
||||
if (pos.I(wm) < closestFromStart->GetLogicalRect(wm, cw).IEnd(wm) + delta/2)
|
||||
*aFrameFound = closestFromStart;
|
||||
else
|
||||
*aFrameFound = closestFromRight;
|
||||
*aFrameFound = closestFromEnd;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1705,10 +1705,10 @@ public:
|
|||
uint32_t* aLineFlags) MOZ_OVERRIDE;
|
||||
virtual int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0) MOZ_OVERRIDE;
|
||||
NS_IMETHOD FindFrameAt(int32_t aLineNumber,
|
||||
nscoord aX,
|
||||
nsPoint aPos,
|
||||
nsIFrame** aFrameFound,
|
||||
bool* aXIsBeforeFirstFrame,
|
||||
bool* aXIsAfterLastFrame) MOZ_OVERRIDE;
|
||||
bool* aPosIsBeforeFirstFrame,
|
||||
bool* aPosIsAfterLastFrame) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, int32_t aLineNumber) MOZ_OVERRIDE;
|
||||
NS_IMETHOD CheckLineOrder(int32_t aLine,
|
||||
|
|
|
@ -48,7 +48,6 @@ static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
|
||||
//included for desired x position;
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsCaret.h"
|
||||
|
@ -108,7 +107,7 @@ static void printRange(nsRange *aDomRange);
|
|||
nsPeekOffsetStruct::nsPeekOffsetStruct(nsSelectionAmount aAmount,
|
||||
nsDirection aDirection,
|
||||
int32_t aStartOffset,
|
||||
nscoord aDesiredX,
|
||||
nsPoint aDesiredPos,
|
||||
bool aJumpLines,
|
||||
bool aScrollViewStop,
|
||||
bool aIsKeyboardSelect,
|
||||
|
@ -117,7 +116,7 @@ nsPeekOffsetStruct::nsPeekOffsetStruct(nsSelectionAmount aAmount,
|
|||
: mAmount(aAmount)
|
||||
, mDirection(aDirection)
|
||||
, mStartOffset(aStartOffset)
|
||||
, mDesiredX(aDesiredX)
|
||||
, mDesiredPos(aDesiredPos)
|
||||
, mWordMovementType(aWordMovementType)
|
||||
, mJumpLines(aJumpLines)
|
||||
, mScrollViewStop(aScrollViewStop)
|
||||
|
@ -436,57 +435,55 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsFrameSelection, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsFrameSelection, Release)
|
||||
|
||||
|
||||
// Get the x (or y, in vertical writing mode) position requested
|
||||
// by the Key Handling for line-up/down
|
||||
nsresult
|
||||
nsFrameSelection::FetchDesiredX(nscoord &aDesiredX) //the x position requested by the Key Handling for up down
|
||||
nsFrameSelection::FetchDesiredPos(nsPoint &aDesiredPos)
|
||||
{
|
||||
if (!mShell)
|
||||
{
|
||||
NS_ERROR("fetch desired X failed");
|
||||
if (!mShell) {
|
||||
NS_ERROR("fetch desired position failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (mDesiredXSet)
|
||||
{
|
||||
aDesiredX = mDesiredX;
|
||||
if (mDesiredPosSet) {
|
||||
aDesiredPos = mDesiredPos;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsCaret> caret = mShell->GetCaret();
|
||||
if (!caret)
|
||||
if (!caret) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
int8_t index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
|
||||
caret->SetSelection(mDomSelections[index]);
|
||||
|
||||
nsRect coord;
|
||||
nsIFrame* caretFrame = caret->GetGeometry(&coord);
|
||||
if (!caretFrame)
|
||||
if (!caretFrame) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsPoint viewOffset(0, 0);
|
||||
nsView* view = nullptr;
|
||||
caretFrame->GetOffsetFromView(viewOffset, &view);
|
||||
if (view)
|
||||
coord.x += viewOffset.x;
|
||||
|
||||
aDesiredX = coord.x;
|
||||
if (view) {
|
||||
coord += viewOffset;
|
||||
}
|
||||
aDesiredPos = coord.TopLeft();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
nsFrameSelection::InvalidateDesiredX() //do not listen to mDesiredX you must get another.
|
||||
nsFrameSelection::InvalidateDesiredPos() // do not listen to mDesiredPos;
|
||||
// you must get another.
|
||||
{
|
||||
mDesiredXSet = false;
|
||||
mDesiredPosSet = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
nsFrameSelection::SetDesiredX(nscoord aX) //set the mDesiredX
|
||||
nsFrameSelection::SetDesiredPos(nsPoint aPos)
|
||||
{
|
||||
mDesiredX = aX;
|
||||
mDesiredXSet = true;
|
||||
mDesiredPos = aPos;
|
||||
mDesiredPosSet = true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -718,7 +715,7 @@ nsFrameSelection::Init(nsIPresShell *aShell, nsIContent *aLimiter)
|
|||
{
|
||||
mShell = aShell;
|
||||
mDragState = false;
|
||||
mDesiredXSet = false;
|
||||
mDesiredPosSet = false;
|
||||
mLimiter = aLimiter;
|
||||
mCaretMovementStyle =
|
||||
Preferences::GetInt("bidi.edit.caret_movement_style", 2);
|
||||
|
@ -766,7 +763,7 @@ nsFrameSelection::MoveCaret(nsDirection aDirection,
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
bool isCollapsed;
|
||||
nscoord desiredX = 0; //we must keep this around and revalidate it when its just UP/DOWN
|
||||
nsPoint desiredPos(0, 0); //we must keep this around and revalidate it when its just UP/DOWN
|
||||
|
||||
int8_t index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
|
||||
nsRefPtr<Selection> sel = mDomSelections[index];
|
||||
|
@ -786,13 +783,15 @@ nsFrameSelection::MoveCaret(nsDirection aDirection,
|
|||
}
|
||||
|
||||
nsresult result = sel->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(result))
|
||||
if (NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
if (aAmount == eSelectLine) {
|
||||
result = FetchDesiredX(desiredX);
|
||||
if (NS_FAILED(result))
|
||||
result = FetchDesiredPos(desiredPos);
|
||||
if (NS_FAILED(result)) {
|
||||
return result;
|
||||
SetDesiredX(desiredX);
|
||||
}
|
||||
SetDesiredPos(desiredPos);
|
||||
}
|
||||
|
||||
int32_t caretStyle = Preferences::GetInt("layout.selection.caret_style", 0);
|
||||
|
@ -850,7 +849,7 @@ nsFrameSelection::MoveCaret(nsDirection aDirection,
|
|||
|
||||
//set data using mLimiter to stop on scroll views. If we have a limiter then we stop peeking
|
||||
//when we hit scrollable views. If no limiter then just let it go ahead
|
||||
nsPeekOffsetStruct pos(aAmount, eDirPrevious, offsetused, desiredX,
|
||||
nsPeekOffsetStruct pos(aAmount, eDirPrevious, offsetused, desiredPos,
|
||||
true, mLimiter != nullptr, true, visualMovement);
|
||||
|
||||
nsBidiDirection paraDir = nsBidiPresUtils::ParagraphDirection(frame);
|
||||
|
@ -861,7 +860,7 @@ nsFrameSelection::MoveCaret(nsDirection aDirection,
|
|||
case eSelectCluster:
|
||||
case eSelectWord:
|
||||
case eSelectWordNoSpace:
|
||||
InvalidateDesiredX();
|
||||
InvalidateDesiredPos();
|
||||
pos.mAmount = aAmount;
|
||||
pos.mDirection = (visualMovement && paraDir == NSBIDI_RTL)
|
||||
? nsDirection(1 - aDirection) : aDirection;
|
||||
|
@ -872,7 +871,7 @@ nsFrameSelection::MoveCaret(nsDirection aDirection,
|
|||
break;
|
||||
case eSelectBeginLine:
|
||||
case eSelectEndLine:
|
||||
InvalidateDesiredX();
|
||||
InvalidateDesiredPos();
|
||||
pos.mAmount = aAmount;
|
||||
pos.mDirection = (visualMovement && paraDir == NSBIDI_RTL)
|
||||
? nsDirection(1 - aDirection) : aDirection;
|
||||
|
@ -1369,7 +1368,7 @@ nsFrameSelection::HandleClick(nsIContent* aNewFocus,
|
|||
if (!aNewFocus)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
InvalidateDesiredX();
|
||||
InvalidateDesiredPos();
|
||||
|
||||
if (!aContinueSelection) {
|
||||
mMaintainRange = nullptr;
|
||||
|
@ -1441,15 +1440,16 @@ nsFrameSelection::HandleDrag(nsIFrame *aFrame, nsPoint aPoint)
|
|||
if (frame && amount == eSelectWord && direction == eDirPrevious) {
|
||||
// To avoid selecting the previous word when at start of word,
|
||||
// first move one character forward.
|
||||
nsPeekOffsetStruct charPos(eSelectCharacter, eDirNext, offset, 0,
|
||||
false, mLimiter != nullptr, false, false);
|
||||
nsPeekOffsetStruct charPos(eSelectCharacter, eDirNext, offset,
|
||||
nsPoint(0, 0), false, mLimiter != nullptr,
|
||||
false, false);
|
||||
if (NS_SUCCEEDED(frame->PeekOffset(&charPos))) {
|
||||
frame = charPos.mResultFrame;
|
||||
offset = charPos.mContentOffset;
|
||||
}
|
||||
}
|
||||
|
||||
nsPeekOffsetStruct pos(amount, direction, offset, 0,
|
||||
nsPeekOffsetStruct pos(amount, direction, offset, nsPoint(0, 0),
|
||||
false, mLimiter != nullptr, false, false);
|
||||
|
||||
if (frame && NS_SUCCEEDED(frame->PeekOffset(&pos)) && pos.mResultContent) {
|
||||
|
@ -1538,17 +1538,16 @@ nsFrameSelection::TakeFocus(nsIContent* aNewFocus,
|
|||
mDomSelections[index]->AddRange(newRange);
|
||||
mBatching = batching;
|
||||
mChangesDuringBatching = changes;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool oldDesiredXSet = mDesiredXSet; //need to keep old desired X if it was set.
|
||||
} else {
|
||||
bool oldDesiredPosSet = mDesiredPosSet; //need to keep old desired position if it was set.
|
||||
mDomSelections[index]->Collapse(aNewFocus, aContentOffset);
|
||||
mDesiredXSet = oldDesiredXSet; //now reset desired X back.
|
||||
mDesiredPosSet = oldDesiredPosSet; //now reset desired pos back.
|
||||
mBatching = batching;
|
||||
mChangesDuringBatching = changes;
|
||||
}
|
||||
if (aContentEndOffset != aContentOffset)
|
||||
if (aContentEndOffset != aContentOffset) {
|
||||
mDomSelections[index]->Extend(aNewFocus, aContentEndOffset);
|
||||
}
|
||||
|
||||
//find out if we are inside a table. if so, find out which one and which cell
|
||||
//once we do that, the next time we get a takefocus, check the parent tree.
|
||||
|
@ -1857,10 +1856,11 @@ nsFrameSelection::CommonPageMove(bool aForward,
|
|||
return;
|
||||
|
||||
// find out where the caret is.
|
||||
// we should know mDesiredX value of nsFrameSelection, but I havent seen that behavior in other windows applications yet.
|
||||
// we should know mDesiredPos value of nsFrameSelection, but I havent seen that behavior in other windows applications yet.
|
||||
nsISelection* domSel = GetSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
if (!domSel)
|
||||
if (!domSel) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRect caretPos;
|
||||
nsIFrame* caretFrame = nsCaret::GetGeometry(domSel, &caretPos);
|
||||
|
@ -4592,7 +4592,7 @@ Selection::Collapse(nsINode& aParentNode, uint32_t aOffset, ErrorResult& aRv)
|
|||
|
||||
nsCOMPtr<nsINode> kungfuDeathGrip = &aParentNode;
|
||||
|
||||
mFrameSelection->InvalidateDesiredX();
|
||||
mFrameSelection->InvalidateDesiredPos();
|
||||
if (!IsValidSelectionPoint(mFrameSelection, &aParentNode)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
|
@ -5887,9 +5887,9 @@ Selection::SelectionLanguageChange(bool aLangRTL)
|
|||
mFrameSelection->SetCaretBidiLevel(levelAfter);
|
||||
}
|
||||
|
||||
// The caret might have moved, so invalidate the desired X position
|
||||
// The caret might have moved, so invalidate the desired position
|
||||
// for future usages of up-arrow or down-arrow
|
||||
mFrameSelection->InvalidateDesiredX();
|
||||
mFrameSelection->InvalidateDesiredPos();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1732,84 +1732,89 @@ nsTableRowGroupFrame::CheckLineOrder(int32_t aLine,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowGroupFrame::FindFrameAt(int32_t aLineNumber,
|
||||
nscoord aX,
|
||||
nsPoint aPos,
|
||||
nsIFrame** aFrameFound,
|
||||
bool* aXIsBeforeFirstFrame,
|
||||
bool* aXIsAfterLastFrame)
|
||||
bool* aPosIsBeforeFirstFrame,
|
||||
bool* aPosIsAfterLastFrame)
|
||||
{
|
||||
nsTableFrame* table = nsTableFrame::GetTableFrame(this);
|
||||
nsTableCellMap* cellMap = table->GetCellMap();
|
||||
|
||||
*aFrameFound = nullptr;
|
||||
*aXIsBeforeFirstFrame = true;
|
||||
*aXIsAfterLastFrame = false;
|
||||
nsTableFrame* table = nsTableFrame::GetTableFrame(this);
|
||||
nsTableCellMap* cellMap = table->GetCellMap();
|
||||
|
||||
aLineNumber += GetStartRowIndex();
|
||||
int32_t numCells = cellMap->GetNumCellsOriginatingInRow(aLineNumber);
|
||||
if (numCells == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
WritingMode wm = table->GetWritingMode();
|
||||
nscoord cw = table->GetRect().width;
|
||||
LogicalPoint pos(wm, aPos, cw);
|
||||
|
||||
nsIFrame* frame = nullptr;
|
||||
int32_t colCount = table->GetColCount();
|
||||
for (int32_t i = 0; i < colCount; i++) {
|
||||
CellData* data = cellMap->GetDataAt(aLineNumber, i);
|
||||
if (data && data->IsOrig()) {
|
||||
frame = (nsIFrame*)data->GetCellFrame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(frame, "cellmap is lying");
|
||||
bool isRTL = (NS_STYLE_DIRECTION_RTL ==
|
||||
table->StyleVisibility()->mDirection);
|
||||
|
||||
nsIFrame* closestFromLeft = nullptr;
|
||||
nsIFrame* closestFromRight = nullptr;
|
||||
int32_t n = numCells;
|
||||
nsIFrame* firstFrame = frame;
|
||||
while (n--) {
|
||||
nsRect rect = frame->GetRect();
|
||||
if (rect.width > 0) {
|
||||
// If aX is inside this frame - this is it
|
||||
if (rect.x <= aX && rect.XMost() > aX) {
|
||||
closestFromLeft = closestFromRight = frame;
|
||||
break;
|
||||
}
|
||||
if (rect.x < aX) {
|
||||
if (!closestFromLeft ||
|
||||
rect.XMost() > closestFromLeft->GetRect().XMost())
|
||||
closestFromLeft = frame;
|
||||
}
|
||||
else {
|
||||
if (!closestFromRight ||
|
||||
rect.x < closestFromRight->GetRect().x)
|
||||
closestFromRight = frame;
|
||||
}
|
||||
}
|
||||
frame = frame->GetNextSibling();
|
||||
}
|
||||
if (!closestFromLeft && !closestFromRight) {
|
||||
// All frames were zero-width. Just take the first one.
|
||||
closestFromLeft = closestFromRight = firstFrame;
|
||||
}
|
||||
*aXIsBeforeFirstFrame = isRTL ? !closestFromRight : !closestFromLeft;
|
||||
*aXIsAfterLastFrame = isRTL ? !closestFromLeft : !closestFromRight;
|
||||
if (closestFromLeft == closestFromRight) {
|
||||
*aFrameFound = closestFromLeft;
|
||||
}
|
||||
else if (!closestFromLeft) {
|
||||
*aFrameFound = closestFromRight;
|
||||
}
|
||||
else if (!closestFromRight) {
|
||||
*aFrameFound = closestFromLeft;
|
||||
}
|
||||
else { // we're between two frames
|
||||
nscoord delta = closestFromRight->GetRect().x -
|
||||
closestFromLeft->GetRect().XMost();
|
||||
if (aX < closestFromLeft->GetRect().XMost() + delta/2)
|
||||
*aFrameFound = closestFromLeft;
|
||||
else
|
||||
*aFrameFound = closestFromRight;
|
||||
*aFrameFound = nullptr;
|
||||
*aPosIsBeforeFirstFrame = true;
|
||||
*aPosIsAfterLastFrame = false;
|
||||
|
||||
aLineNumber += GetStartRowIndex();
|
||||
int32_t numCells = cellMap->GetNumCellsOriginatingInRow(aLineNumber);
|
||||
if (numCells == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame* frame = nullptr;
|
||||
int32_t colCount = table->GetColCount();
|
||||
for (int32_t i = 0; i < colCount; i++) {
|
||||
CellData* data = cellMap->GetDataAt(aLineNumber, i);
|
||||
if (data && data->IsOrig()) {
|
||||
frame = (nsIFrame*)data->GetCellFrame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(frame, "cellmap is lying");
|
||||
bool isRTL = (NS_STYLE_DIRECTION_RTL ==
|
||||
table->StyleVisibility()->mDirection);
|
||||
|
||||
nsIFrame* closestFromStart = nullptr;
|
||||
nsIFrame* closestFromEnd = nullptr;
|
||||
int32_t n = numCells;
|
||||
nsIFrame* firstFrame = frame;
|
||||
while (n--) {
|
||||
LogicalRect rect = frame->GetLogicalRect(wm, cw);
|
||||
if (rect.ISize(wm) > 0) {
|
||||
// If pos.I() is inside this frame - this is it
|
||||
if (rect.IStart(wm) <= pos.I(wm) && rect.IEnd(wm) > pos.I(wm)) {
|
||||
closestFromStart = closestFromEnd = frame;
|
||||
break;
|
||||
}
|
||||
if (rect.IStart(wm) < pos.I(wm)) {
|
||||
if (!closestFromStart ||
|
||||
rect.IEnd(wm) > closestFromStart->GetLogicalRect(wm, cw).IEnd(wm))
|
||||
closestFromStart = frame;
|
||||
}
|
||||
else {
|
||||
if (!closestFromEnd ||
|
||||
rect.IStart(wm) < closestFromEnd->GetLogicalRect(wm, cw).IStart(wm))
|
||||
closestFromEnd = frame;
|
||||
}
|
||||
}
|
||||
frame = frame->GetNextSibling();
|
||||
}
|
||||
if (!closestFromStart && !closestFromEnd) {
|
||||
// All frames were zero-width. Just take the first one.
|
||||
closestFromStart = closestFromEnd = firstFrame;
|
||||
}
|
||||
*aPosIsBeforeFirstFrame = isRTL ? !closestFromEnd : !closestFromStart;
|
||||
*aPosIsAfterLastFrame = isRTL ? !closestFromStart : !closestFromEnd;
|
||||
if (closestFromStart == closestFromEnd) {
|
||||
*aFrameFound = closestFromStart;
|
||||
}
|
||||
else if (!closestFromStart) {
|
||||
*aFrameFound = closestFromEnd;
|
||||
}
|
||||
else if (!closestFromEnd) {
|
||||
*aFrameFound = closestFromStart;
|
||||
}
|
||||
else { // we're between two frames
|
||||
nscoord delta = closestFromEnd->GetLogicalRect(wm, cw).IStart(wm) -
|
||||
closestFromStart->GetLogicalRect(wm, cw).IEnd(wm);
|
||||
if (pos.I(wm) < closestFromStart->GetLogicalRect(wm, cw).IEnd(wm) + delta/2) {
|
||||
*aFrameFound = closestFromStart;
|
||||
} else {
|
||||
*aFrameFound = closestFromEnd;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -228,21 +228,21 @@ public:
|
|||
virtual int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0) MOZ_OVERRIDE;
|
||||
|
||||
/** Find the orginating cell frame on a row that is the nearest to the
|
||||
* coordinate X.
|
||||
* inline-dir coordinate of aPos.
|
||||
* @param aLineNumber - the index of the row relative to the row group
|
||||
* @param aX - X coordinate in twips relative to the
|
||||
* @param aPos - coordinate in twips relative to the
|
||||
* origin of the row group
|
||||
* @param aFrameFound - pointer to the cellframe
|
||||
* @param aXIsBeforeFirstFrame - the point is before the first originating
|
||||
* @param aPosIsBeforeFirstFrame - the point is before the first originating
|
||||
* cellframe
|
||||
* @param aXIsAfterLastFrame - the point is after the last originating
|
||||
* @param aPosIsAfterLastFrame - the point is after the last originating
|
||||
* cellframe
|
||||
*/
|
||||
NS_IMETHOD FindFrameAt(int32_t aLineNumber,
|
||||
nscoord aX,
|
||||
nsPoint aPos,
|
||||
nsIFrame** aFrameFound,
|
||||
bool* aXIsBeforeFirstFrame,
|
||||
bool* aXIsAfterLastFrame) MOZ_OVERRIDE;
|
||||
bool* aPosIsBeforeFirstFrame,
|
||||
bool* aPosIsAfterLastFrame) MOZ_OVERRIDE;
|
||||
|
||||
/** Check whether visual and logical order of cell frames within a line are
|
||||
* identical. As the layout will reorder them this is always the case
|
||||
|
|
Загрузка…
Ссылка в новой задаче