mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Fix bidi behavior of ctrl+backspace and ctrl+del. bug=344226 r=smontagu sr=roc
This commit is contained in:
parent
de394c31ae
commit
3bef115769
@ -164,6 +164,12 @@ interface nsISelectionController : nsISelectionDisplay
|
||||
|
||||
void wordMove(in boolean forward, in boolean extend);
|
||||
|
||||
/** wordExtendForDelete will extend the selection one word forward/backward in the document.
|
||||
* this method is used internally for handling ctrl[option]-backspace and ctrl[option]-del.
|
||||
* @param aForward forward or backward if PR_FALSE
|
||||
*/
|
||||
[noscript] void wordExtendForDelete(in boolean forward);
|
||||
|
||||
/** LineMove will move the selection one line forward/backward in the document.
|
||||
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
|
||||
* the "point" of selection that is extended is considered the "focus" point.
|
||||
|
@ -637,34 +637,20 @@ NS_IMETHODIMP nsPlaintextEditor::DeleteSelection(nsIEditor::EDirection aAction)
|
||||
if (aAction == eNextWord || aAction == ePreviousWord
|
||||
|| aAction == eToBeginningOfLine || aAction == eToEndOfLine)
|
||||
{
|
||||
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
PRUint8 caretBidiLevel;
|
||||
result = ps->GetCaretBidiLevel(&caretBidiLevel);
|
||||
if (NS_FAILED(result)) return result;
|
||||
|
||||
nsCOMPtr<nsISelectionController> selCont (do_QueryReferent(mSelConWeak));
|
||||
if (!selCont)
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
// if caret has odd Bidi level, i.e. text is right-to-left,
|
||||
// reverse the effect of ePreviousWord and eNextWord
|
||||
case eNextWord:
|
||||
result = (caretBidiLevel & 1) ?
|
||||
selCont->WordMove(PR_FALSE, PR_TRUE) :
|
||||
selCont->WordMove(PR_TRUE, PR_TRUE);
|
||||
result = selCont->WordExtendForDelete(PR_TRUE);
|
||||
// DeleteSelectionImpl doesn't handle these actions
|
||||
// because it's inside batching, so don't confuse it:
|
||||
aAction = eNone;
|
||||
break;
|
||||
case ePreviousWord:
|
||||
result = (caretBidiLevel & 1) ?
|
||||
selCont->WordMove(PR_TRUE, PR_TRUE) :
|
||||
selCont->WordMove(PR_FALSE, PR_TRUE);
|
||||
result = selCont->WordExtendForDelete(PR_FALSE);
|
||||
aAction = eNone;
|
||||
break;
|
||||
case eToBeginningOfLine:
|
||||
|
@ -1205,6 +1205,7 @@ public:
|
||||
|
||||
NS_IMETHOD CharacterMove(PRBool aForward, PRBool aExtend);
|
||||
NS_IMETHOD WordMove(PRBool aForward, PRBool aExtend);
|
||||
NS_IMETHOD WordExtendForDelete(PRBool aForward);
|
||||
NS_IMETHOD LineMove(PRBool aForward, PRBool aExtend);
|
||||
NS_IMETHOD IntraLineMove(PRBool aForward, PRBool aExtend);
|
||||
NS_IMETHOD PageMove(PRBool aForward, PRBool aExtend);
|
||||
@ -3293,6 +3294,12 @@ PresShell::WordMove(PRBool aForward, PRBool aExtend)
|
||||
return mSelection->WordMove(aForward, aExtend);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::WordExtendForDelete(PRBool aForward)
|
||||
{
|
||||
return mSelection->WordExtendForDelete(aForward);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::LineMove(PRBool aForward, PRBool aExtend)
|
||||
{
|
||||
|
@ -610,6 +610,7 @@ public:
|
||||
NS_IMETHOD SetCaretVisibilityDuringSelection(PRBool aVisibility);
|
||||
NS_IMETHOD CharacterMove(PRBool aForward, PRBool aExtend);
|
||||
NS_IMETHOD WordMove(PRBool aForward, PRBool aExtend);
|
||||
NS_IMETHOD WordExtendForDelete(PRBool aForward);
|
||||
NS_IMETHOD LineMove(PRBool aForward, PRBool aExtend);
|
||||
NS_IMETHOD IntraLineMove(PRBool aForward, PRBool aExtend);
|
||||
NS_IMETHOD PageMove(PRBool aForward, PRBool aExtend);
|
||||
@ -830,6 +831,13 @@ nsTextInputSelectionImpl::WordMove(PRBool aForward, PRBool aExtend)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::WordExtendForDelete(PRBool aForward)
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->WordExtendForDelete(aForward);
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::LineMove(PRBool aForward, PRBool aExtend)
|
||||
|
@ -367,6 +367,12 @@ public:
|
||||
*/
|
||||
nsresult WordMove(PRBool aForward, PRBool aExtend);
|
||||
|
||||
/** WordExtendForDelete extends the selection backward or forward (logically) to the
|
||||
* next word boundary, so that the selected word can be deleted.
|
||||
* @param aForward select forward in document.
|
||||
*/
|
||||
nsresult WordExtendForDelete(PRBool aForward);
|
||||
|
||||
/** LineMove will generally be called from the nsiselectioncontroller implementations.
|
||||
* the effect being the selection will move one line up or down.
|
||||
* @param aForward move forward in document.
|
||||
|
@ -1203,9 +1203,12 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode,
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
nsPeekOffsetStruct pos;
|
||||
|
||||
PRBool visualMovement = mCaretMovementStyle == 1 ||
|
||||
(mCaretMovementStyle == 2 && !aContinueSelection);
|
||||
|
||||
PRBool visualMovement =
|
||||
(aKeycode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE ||
|
||||
aKeycode == nsIDOMKeyEvent::DOM_VK_DELETE) ?
|
||||
PR_FALSE : // Delete operations are always logical
|
||||
mCaretMovementStyle == 1 || (mCaretMovementStyle == 2 && !aContinueSelection);
|
||||
|
||||
//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
|
||||
pos.SetData(aAmount, eDirPrevious, offsetused, desiredX,
|
||||
@ -1219,16 +1222,25 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode,
|
||||
InvalidateDesiredX();
|
||||
pos.mDirection = (baseLevel & 1) ? eDirPrevious : eDirNext;
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_LEFT : //no break
|
||||
case nsIDOMKeyEvent::DOM_VK_LEFT :
|
||||
InvalidateDesiredX();
|
||||
pos.mDirection = (baseLevel & 1) ? eDirNext : eDirPrevious;
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_DELETE :
|
||||
InvalidateDesiredX();
|
||||
pos.mDirection = eDirNext;
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_BACK_SPACE :
|
||||
InvalidateDesiredX();
|
||||
pos.mDirection = eDirPrevious;
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_DOWN :
|
||||
pos.mAmount = eSelectLine;
|
||||
pos.mDirection = eDirNext;//no break here
|
||||
pos.mDirection = eDirNext;
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_UP :
|
||||
pos.mAmount = eSelectLine;
|
||||
pos.mDirection = eDirPrevious;
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_HOME :
|
||||
InvalidateDesiredX();
|
||||
@ -1237,7 +1249,7 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode,
|
||||
case nsIDOMKeyEvent::DOM_VK_END :
|
||||
InvalidateDesiredX();
|
||||
pos.mAmount = eSelectEndLine;
|
||||
break;
|
||||
break;
|
||||
default :return NS_ERROR_FAILURE;
|
||||
}
|
||||
PostReason(nsISelectionListener::KEYPRESS_REASON);
|
||||
@ -1246,8 +1258,7 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode,
|
||||
nsIFrame *theFrame;
|
||||
PRInt32 currentOffset, frameStart, frameEnd;
|
||||
|
||||
if (aKeycode == nsIDOMKeyEvent::DOM_VK_RIGHT ||
|
||||
aKeycode == nsIDOMKeyEvent::DOM_VK_LEFT)
|
||||
if (aAmount == eSelectCharacter || aAmount == eSelectWord)
|
||||
{
|
||||
// For left/right, PeekOffset() sets pos.mResultFrame correctly, but does not set pos.mAttachForward,
|
||||
// so determine the hint here based on the result frame and offset:
|
||||
@ -2760,6 +2771,15 @@ nsFrameSelection::WordMove(PRBool aForward, PRBool aExtend)
|
||||
return MoveCaret(nsIDOMKeyEvent::DOM_VK_LEFT,aExtend,eSelectWord);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameSelection::WordExtendForDelete(PRBool aForward)
|
||||
{
|
||||
if (aForward)
|
||||
return MoveCaret(nsIDOMKeyEvent::DOM_VK_DELETE, PR_TRUE, eSelectWord);
|
||||
else
|
||||
return MoveCaret(nsIDOMKeyEvent::DOM_VK_BACK_SPACE, PR_TRUE, eSelectWord);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameSelection::LineMove(PRBool aForward, PRBool aExtend)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user