Bug 263309 PresShell::CompleteMove simulates a mouse click and assumes LTRness, patch by Eyal Rozenberg <eyalroz@technion.ac.il>, r+sr=roc.

This commit is contained in:
smontagu%smontagu.org 2004-11-29 20:28:46 +00:00
Родитель 45d8ba4cf3
Коммит 5bff65e904
8 изменённых файлов: 162 добавлений и 80 удалений

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

@ -3239,47 +3239,13 @@ PresShell::CompleteMove(PRBool aForward, PRBool aExtend)
if (!frame)
return NS_ERROR_FAILURE; //could not find an area frame.
PRInt8 outsideLimit = -1;//search from beginning
nsPeekOffsetStruct pos;
pos.mAmount = eSelectLine;
pos.mShell = this;
pos.mContentOffset = 0;
pos.mContentOffsetEnd = 0;
pos.mScrollViewStop = PR_FALSE;//dont stop on scrolled views.
pos.mIsKeyboardSelect = PR_TRUE;
if (aForward)
{
outsideLimit = 1;//search from end
pos.mDesiredX = frame->GetRect().width * 2;//search way off to right of line
pos.mDirection = eDirPrevious; //seach backwards from the end
}
else
{
pos.mDesiredX = -1; //start before line
pos.mDirection = eDirNext; //search forwards from before beginning
}
nsPeekOffsetStruct pos = frame->GetExtremeCaretPosition(!aForward);
// we 'prefer left' (i.e. prefer the beginning of the next line)
// iff we're moving to the end of the content
pos.mPreferLeft = aForward;
do
{
result = nsFrame::GetNextPrevLineFromeBlockFrame(mPresContext,
&pos,
frame,
0, //irrelavent since we set outsidelimit
outsideLimit
);
if (NS_POSITION_BEFORE_TABLE == result) //NS_POSITION_BEFORE_TABLE should ALSO break
break;
if (NS_FAILED (result) || !pos.mResultFrame )
return result?result:NS_ERROR_FAILURE;
nsCOMPtr<nsILineIteratorNavigator> newIt;
//check to see if this is ANOTHER blockframe inside the other one if so then call into its lines
result = pos.mResultFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(newIt));
if (NS_SUCCEEDED(result) && newIt)
frame = pos.mResultFrame;
}
while (NS_SUCCEEDED(result));//end 'do'
mSelection->HandleClick(pos.mResultContent ,pos.mContentOffset ,pos.mContentOffsetEnd ,aExtend, PR_FALSE, pos.mPreferLeft);
mSelection->HandleClick(pos.mResultContent ,pos.mContentOffset ,pos.mContentOffset/*End*/ ,aExtend, PR_FALSE, pos.mPreferLeft);
return ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL, nsISelectionController::SELECTION_FOCUS_REGION, PR_TRUE);
}

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

@ -1423,6 +1423,19 @@ NS_PTR_TO_INT32(frame->GetProperty(nsLayoutAtoms::embeddingLevel))
// The above methods have been migrated from nsIBox and are in the process of
// being refactored. DO NOT USE OUTSIDE OF XUL.
/**
* gets the first or last possible caret position within the frame
*
* @param [in] aStart
* true for getting the first possible caret position
* false for getting the last possible caret position
* @return The caret position in an nsPeekOffsetStruct (the
* fields set are mResultContent and mContentOffset;
* the returned value is a 'best effort' in case errors
* are encountered rummaging through the frame.
*/
nsPeekOffsetStruct GetExtremeCaretPosition(PRBool aStart);
protected:
// Members
nsRect mRect;

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

@ -3381,6 +3381,63 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
return NS_OK;
}
nsPeekOffsetStruct nsIFrame::GetExtremeCaretPosition(PRBool aStart)
{
nsPeekOffsetStruct result;
result.mResultContent = this->GetContent();
result.mContentOffset = 0;
nsIFrame *resultFrame = this;
if (aStart)
nsFrame::GetFirstLeaf(GetPresContext(), &resultFrame);
else
nsFrame::GetLastLeaf(GetPresContext(), &resultFrame);
NS_ASSERTION(resultFrame,"result frame for carent positioning is Null!");
if (!resultFrame)
return result;
// there should be some more validity checks here, or earlier in the code,
// in case we get to to some 'dummy' frames at the end of the content
nsIContent* content = resultFrame->GetContent();
NS_ASSERTION(resultFrame,"result frame content for carent positioning is Null!");
if (!content)
return result;
// special case: if this is a br element, position the caret before it,
// not after it (perhaps the same exception should be made for some
// other elements?)
nsIAtom* tag = content->Tag();
if (tag == nsHTMLAtoms::br) {
// special case in effect
nsIContent* parent = content->GetParent();
NS_ASSERTION(parent,"<br> element has no parent!");
if (parent) {
result.mResultContent = parent;
result.mContentOffset = parent->IndexOf(content);
return result;
}
}
result.mResultContent = content;
PRInt32 start, end;
nsresult rv;
rv = GetOffsets(start,end);
if (NS_SUCCEEDED(rv)) {
result.mContentOffset = aStart ? start : end;
}
return result;
}
// Get a frame which can contain a line iterator
// (which generally means it's a block frame).
static nsILineIterator*

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

@ -493,9 +493,14 @@ protected:
//return the line number of the aFrame
static PRInt32 GetLineNumber(nsIFrame *aFrame);
public:
//given a frame five me the first/last leaf available
//XXX Robert O'Callahan wants to move these elsewhere
static void GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
static void GetFirstLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
protected:
// Test if we are selecting a table object:
// Most table/cell selection requires that Ctrl (Cmd on Mac) key is down

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

@ -1423,6 +1423,19 @@ NS_PTR_TO_INT32(frame->GetProperty(nsLayoutAtoms::embeddingLevel))
// The above methods have been migrated from nsIBox and are in the process of
// being refactored. DO NOT USE OUTSIDE OF XUL.
/**
* gets the first or last possible caret position within the frame
*
* @param [in] aStart
* true for getting the first possible caret position
* false for getting the last possible caret position
* @return The caret position in an nsPeekOffsetStruct (the
* fields set are mResultContent and mContentOffset;
* the returned value is a 'best effort' in case errors
* are encountered rummaging through the frame.
*/
nsPeekOffsetStruct GetExtremeCaretPosition(PRBool aStart);
protected:
// Members
nsRect mRect;

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

@ -3381,6 +3381,63 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
return NS_OK;
}
nsPeekOffsetStruct nsIFrame::GetExtremeCaretPosition(PRBool aStart)
{
nsPeekOffsetStruct result;
result.mResultContent = this->GetContent();
result.mContentOffset = 0;
nsIFrame *resultFrame = this;
if (aStart)
nsFrame::GetFirstLeaf(GetPresContext(), &resultFrame);
else
nsFrame::GetLastLeaf(GetPresContext(), &resultFrame);
NS_ASSERTION(resultFrame,"result frame for carent positioning is Null!");
if (!resultFrame)
return result;
// there should be some more validity checks here, or earlier in the code,
// in case we get to to some 'dummy' frames at the end of the content
nsIContent* content = resultFrame->GetContent();
NS_ASSERTION(resultFrame,"result frame content for carent positioning is Null!");
if (!content)
return result;
// special case: if this is a br element, position the caret before it,
// not after it (perhaps the same exception should be made for some
// other elements?)
nsIAtom* tag = content->Tag();
if (tag == nsHTMLAtoms::br) {
// special case in effect
nsIContent* parent = content->GetParent();
NS_ASSERTION(parent,"<br> element has no parent!");
if (parent) {
result.mResultContent = parent;
result.mContentOffset = parent->IndexOf(content);
return result;
}
}
result.mResultContent = content;
PRInt32 start, end;
nsresult rv;
rv = GetOffsets(start,end);
if (NS_SUCCEEDED(rv)) {
result.mContentOffset = aStart ? start : end;
}
return result;
}
// Get a frame which can contain a line iterator
// (which generally means it's a block frame).
static nsILineIterator*

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

@ -493,9 +493,14 @@ protected:
//return the line number of the aFrame
static PRInt32 GetLineNumber(nsIFrame *aFrame);
public:
//given a frame five me the first/last leaf available
//XXX Robert O'Callahan wants to move these elsewhere
static void GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
static void GetFirstLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
protected:
// Test if we are selecting a table object:
// Most table/cell selection requires that Ctrl (Cmd on Mac) key is down

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

@ -3239,47 +3239,13 @@ PresShell::CompleteMove(PRBool aForward, PRBool aExtend)
if (!frame)
return NS_ERROR_FAILURE; //could not find an area frame.
PRInt8 outsideLimit = -1;//search from beginning
nsPeekOffsetStruct pos;
pos.mAmount = eSelectLine;
pos.mShell = this;
pos.mContentOffset = 0;
pos.mContentOffsetEnd = 0;
pos.mScrollViewStop = PR_FALSE;//dont stop on scrolled views.
pos.mIsKeyboardSelect = PR_TRUE;
if (aForward)
{
outsideLimit = 1;//search from end
pos.mDesiredX = frame->GetRect().width * 2;//search way off to right of line
pos.mDirection = eDirPrevious; //seach backwards from the end
}
else
{
pos.mDesiredX = -1; //start before line
pos.mDirection = eDirNext; //search forwards from before beginning
}
nsPeekOffsetStruct pos = frame->GetExtremeCaretPosition(!aForward);
// we 'prefer left' (i.e. prefer the beginning of the next line)
// iff we're moving to the end of the content
pos.mPreferLeft = aForward;
do
{
result = nsFrame::GetNextPrevLineFromeBlockFrame(mPresContext,
&pos,
frame,
0, //irrelavent since we set outsidelimit
outsideLimit
);
if (NS_POSITION_BEFORE_TABLE == result) //NS_POSITION_BEFORE_TABLE should ALSO break
break;
if (NS_FAILED (result) || !pos.mResultFrame )
return result?result:NS_ERROR_FAILURE;
nsCOMPtr<nsILineIteratorNavigator> newIt;
//check to see if this is ANOTHER blockframe inside the other one if so then call into its lines
result = pos.mResultFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(newIt));
if (NS_SUCCEEDED(result) && newIt)
frame = pos.mResultFrame;
}
while (NS_SUCCEEDED(result));//end 'do'
mSelection->HandleClick(pos.mResultContent ,pos.mContentOffset ,pos.mContentOffsetEnd ,aExtend, PR_FALSE, pos.mPreferLeft);
mSelection->HandleClick(pos.mResultContent ,pos.mContentOffset ,pos.mContentOffset/*End*/ ,aExtend, PR_FALSE, pos.mPreferLeft);
return ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL, nsISelectionController::SELECTION_FOCUS_REGION, PR_TRUE);
}