зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
45d8ba4cf3
Коммит
5bff65e904
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче