Bug 674558 - Implement the HTML5 selectionDirection property for text controls (input and textarea); r=bzbarsky

This commit is contained in:
Ehsan Akhgari
2011-07-28 13:51:22 -04:00
parent 113e0acffb
commit cf84f69741
13 changed files with 395 additions and 76 deletions

View File

@@ -805,7 +805,8 @@ nsresult
nsTextControlFrame::SetSelectionInternal(nsIDOMNode *aStartNode,
PRInt32 aStartOffset,
nsIDOMNode *aEndNode,
PRInt32 aEndOffset)
PRInt32 aEndOffset,
nsITextControlFrame::SelectionDirection aDirection)
{
// Create a new range to represent the new selection.
// Note that we use a new range to avoid having to do
@@ -830,10 +831,24 @@ nsTextControlFrame::SetSelectionInternal(nsIDOMNode *aStartNode,
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsDirection direction;
if (aDirection == eNone) {
// Preserve the direction
direction = selPriv->GetSelectionDirection();
} else {
direction = (aDirection == eBackward) ? eDirPrevious : eDirNext;
}
rv = selection->RemoveAllRanges();
NS_ENSURE_SUCCESS(rv, rv);
rv = selection->AddRange(range); // NOTE: can destroy the world
NS_ENSURE_SUCCESS(rv, rv);
selPriv->SetSelectionDirection(direction);
return rv;
}
@@ -906,7 +921,8 @@ nsTextControlFrame::SelectAllOrCollapseToEndOfText(PRBool aSelect)
}
nsresult
nsTextControlFrame::SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd)
nsTextControlFrame::SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd,
nsITextControlFrame::SelectionDirection aDirection)
{
NS_ASSERTION(aSelStart <= aSelEnd, "Invalid selection offsets!");
@@ -936,11 +952,12 @@ nsTextControlFrame::SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd)
NS_ENSURE_SUCCESS(rv, rv);
}
return SetSelectionInternal(startNode, startOffset, endNode, endOffset);
return SetSelectionInternal(startNode, startOffset, endNode, endOffset, aDirection);
}
NS_IMETHODIMP
nsTextControlFrame::SetSelectionRange(PRInt32 aSelStart, PRInt32 aSelEnd)
nsTextControlFrame::SetSelectionRange(PRInt32 aSelStart, PRInt32 aSelEnd,
nsITextControlFrame::SelectionDirection aDirection)
{
nsresult rv = EnsureEditorInitialized();
NS_ENSURE_SUCCESS(rv, rv);
@@ -952,7 +969,7 @@ nsTextControlFrame::SetSelectionRange(PRInt32 aSelStart, PRInt32 aSelEnd)
aSelStart = aSelEnd;
}
return SetSelectionEndPoints(aSelStart, aSelEnd);
return SetSelectionEndPoints(aSelStart, aSelEnd, aDirection);
}
@@ -1110,14 +1127,23 @@ nsTextControlFrame::OffsetToDOMPoint(PRInt32 aOffset,
}
NS_IMETHODIMP
nsTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd)
nsTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart,
PRInt32* aSelectionEnd,
SelectionDirection* aDirection)
{
// make sure we have an editor
nsresult rv = EnsureEditorInitialized();
NS_ENSURE_SUCCESS(rv, rv);
*aSelectionStart = 0;
*aSelectionEnd = 0;
if (aSelectionStart) {
*aSelectionStart = 0;
}
if (aSelectionEnd) {
*aSelectionEnd = 0;
}
if (aDirection) {
*aDirection = eNone;
}
nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
NS_ASSERTION(txtCtrl, "Content not a text control element");
@@ -1136,6 +1162,24 @@ nsTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelect
// We only operate on the first range in the selection!
if (aDirection) {
nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection);
if (selPriv) {
nsDirection direction = selPriv->GetSelectionDirection();
if (direction == eDirNext) {
*aDirection = eForward;
} else if (direction == eDirPrevious) {
*aDirection = eBackward;
} else {
NS_NOTREACHED("Invalid nsDirection enum value");
}
}
}
if (!aSelectionStart || !aSelectionEnd) {
return NS_OK;
}
nsCOMPtr<nsIDOMRange> firstRange;
rv = selection->GetRangeAt(0, getter_AddRefs(firstRange));
NS_ENSURE_SUCCESS(rv, rv);