Bug 342596. Allow start/end of word to be specified for PeekOffset(). Necessary for upcoming nsIAccessibleText::GetText[At|Before|After]Offset() methods. r=uriber, sr=roc

This commit is contained in:
aaronleventhal%moonset.net 2006-07-11 22:11:02 +00:00
Родитель 3d57cab5e8
Коммит 2ded89ada9
3 изменённых файлов: 46 добавлений и 13 удалений

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

@ -205,9 +205,21 @@ NS_IMETHODIMP BRFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruc
//BR is also a whitespace, but sometimes GetNextWord() can't handle this
//See bug 304891
nsTextTransformer::Initialize();
if (nsTextTransformer::GetWordSelectEatSpaceAfter() &&
aPos->mDirection == eDirNext)
if (aPos->mWordMovementType != eDefaultBehavior) {
// aPos->mWordMovementType possible values:
// eEndWord: eat the space if we're moving backwards
// eStartWord: eat the space if we're moving forwards
if ((aPos->mWordMovementType == eEndWord) == (aPos->mDirection == eDirPrevious)) {
aPos->mEatingWS = PR_TRUE;
}
}
else if (aPos->mDirection == eDirNext && nsTextTransformer::GetWordSelectEatSpaceAfter()) {
// Use the hidden preference which is based on operating system behavior.
// This pref only affects whether moving forward by word should go to the end of this word or start of the next word.
// When going backwards, the start of the word is always used, on every operating system.
aPos->mEatingWS = PR_TRUE;
}
//offset of this content in its parents child list. base 0
PRInt32 offsetBegin = mContent->GetParent()->IndexOf(mContent);

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

@ -59,6 +59,8 @@ struct SelectionDetails
class nsIPresShell;
enum EWordMovementType { eStartWord, eEndWord, eDefaultBehavior };
/*PeekOffsetStruct
* @param mShell is used to get the PresContext useful for measuring text etc.
* @param mDesiredX is the "desired" location of the new caret
@ -72,6 +74,10 @@ class nsIPresShell;
* @param mPreferLeft true = prev line end, false = next line begin
* @param mJumpLines if this is true then it's ok to cross lines while peeking
* @param mScrollViewStop if this is true then stop peeking across scroll view boundary
* @param 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
* direction and the platform-based pref
* "layout.word_select.eat_space_to_next_word"
*/
struct nsPeekOffsetStruct
{
@ -85,7 +91,8 @@ struct nsPeekOffsetStruct
PRBool aJumpLines,
PRBool aScrollViewStop,
PRBool aIsKeyboardSelect,
PRBool aVisual)
PRBool aVisual,
EWordMovementType aWordMovementType = eDefaultBehavior )
{
mShell=aShell;
mDesiredX=aDesiredX;
@ -98,6 +105,7 @@ struct nsPeekOffsetStruct
mScrollViewStop = aScrollViewStop;
mIsKeyboardSelect = aIsKeyboardSelect;
mVisual = aVisual;
mWordMovementType = aWordMovementType;
}
nsIPresShell *mShell;
nscoord mDesiredX;
@ -114,6 +122,7 @@ struct nsPeekOffsetStruct
PRBool mScrollViewStop;
PRBool mIsKeyboardSelect;
PRBool mVisual;
EWordMovementType mWordMovementType;
};
struct nsPrevNextBidiLevels

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

@ -4817,7 +4817,19 @@ nsTextFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
PRBool found = PR_FALSE;
PRBool isWhitespace, wasTransformed;
PRInt32 wordLen, contentLen;
PRBool wordSelectEatSpaceAfter = aPos->mDirection == eDirNext && tx.GetWordSelectEatSpaceAfter();
PRBool wordSelectEatSpace;
if (aPos->mWordMovementType != eDefaultBehavior) {
// aPos->mWordMovementType possible values:
// eEndWord: eat the space if we're moving backwards
// eStartWord: eat the space if we're moving forwards
wordSelectEatSpace = ((aPos->mWordMovementType == eEndWord) == (aPos->mDirection == eDirPrevious));
}
else {
// Use the hidden preference which is based on operating system behavior.
// This pref only affects whether moving forward by word should go to the end of this word or start of the next word.
// When going backwards, the start of the word is always used, on every operating system.
wordSelectEatSpace = aPos->mDirection == eDirNext && nsTextTransformer::GetWordSelectEatSpaceAfter();
}
PRBool selectable;
PRUint8 selectStyle;
@ -4841,10 +4853,10 @@ nsTextFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
if (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace,
PR_FALSE, aPos->mIsKeyboardSelect) &&
(aPos->mStartOffset - contentLen >= mContentOffset) ){
if ((wordSelectEatSpaceAfter ? isWhitespace : !isWhitespace) || !aPos->mEatingWS){
if ((wordSelectEatSpace ? isWhitespace : !isWhitespace) || !aPos->mEatingWS){
aPos->mContentOffset = aPos->mStartOffset - contentLen;
keepSearching = PR_TRUE;
if (wordSelectEatSpaceAfter ? isWhitespace : !isWhitespace)
if (wordSelectEatSpace ? isWhitespace : !isWhitespace)
aPos->mEatingWS = PR_TRUE;
#ifdef IBMBIDI
wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;
@ -4852,12 +4864,12 @@ nsTextFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
while (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen,
&isWhitespace, PR_FALSE,
aPos->mIsKeyboardSelect)){
if (wordSelectEatSpaceAfter ? !isWhitespace : aPos->mEatingWS)
if (wordSelectEatSpace ? !isWhitespace : aPos->mEatingWS)
break;
if (aPos->mStartOffset - contentLen <= mContentOffset)
goto TryNextFrame;
aPos->mContentOffset -= contentLen;
if (wordSelectEatSpaceAfter ? isWhitespace : !isWhitespace)
if (wordSelectEatSpace ? isWhitespace : !isWhitespace)
aPos->mEatingWS = PR_TRUE;
#ifdef IBMBIDI
wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;
@ -4889,10 +4901,10 @@ nsTextFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
// On some platforms (mac, unix), we want the selection to end
// at the end of the word (not the beginning of the next one).
if ((wordSelectEatSpaceAfter ? isWhitespace : !isWhitespace) || !aPos->mEatingWS) {
if ((wordSelectEatSpace ? isWhitespace : !isWhitespace) || !aPos->mEatingWS) {
aPos->mContentOffset = aPos->mStartOffset + contentLen;
keepSearching = PR_TRUE;
if (wordSelectEatSpaceAfter ? isWhitespace : !isWhitespace)
if (wordSelectEatSpace ? isWhitespace : !isWhitespace)
aPos->mEatingWS = PR_TRUE;
#ifdef IBMBIDI
wordLen = (mState & NS_FRAME_IS_BIDI)
@ -4900,11 +4912,11 @@ nsTextFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
#endif // IBMBIDI
while (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE, aPos->mIsKeyboardSelect))
{
if (wordSelectEatSpaceAfter ? !isWhitespace : aPos->mEatingWS)
if (wordSelectEatSpace ? !isWhitespace : aPos->mEatingWS)
break;
if (aPos->mStartOffset + contentLen >= (mContentLength + mContentOffset))
goto TryNextFrame;
if (wordSelectEatSpaceAfter ? isWhitespace : !isWhitespace)
if (wordSelectEatSpace ? isWhitespace : !isWhitespace)
aPos->mEatingWS = PR_TRUE;
aPos->mContentOffset += contentLen;
#ifdef IBMBIDI
@ -4931,7 +4943,7 @@ TryNextFrame:
{
aPos->mContentOffset = PR_MIN(aPos->mContentOffset, mContentOffset + mContentLength);
aPos->mContentOffset = PR_MAX(aPos->mContentOffset, mContentOffset);
if (wordSelectEatSpaceAfter && aPos->mEatingWS) {
if (wordSelectEatSpace && aPos->mEatingWS) {
//If we want to stop at beginning of the next word
//GetFrameFromDirction should not return NS_ERROR_FAILURE at end of line
aPos->mEatingWS = PR_FALSE;