Bug 629878 - Part 2: Do not scroll the selection into view when restoring the selection offsets for a text control after a reframe; r=roc a=blocking-final+

Previously, we used to scroll the text control's selection into view after a
reframe.  This had two problems: it was not precise (in case the selection was
modified by the mouse, for example), and it lead to problems such as bug 629878
if the control's frame was reconstructed because of the control being moved
inside the DOM.

This patch disables that behavior by wrapping the selection scroll function
into nsITextControlFrame::ScrollSelectionIntoView, so that APIs such as
setSelectionRange on the text control's content node can still call it
explicitly (since they actually need this behavior), but other callers of
nsITextControlFrame::SetSelectionRange (such as the nsTextEditorState
object's selection offset restoring mechanism) don't get this behavior as
an undesired side-effect.
This commit is contained in:
Ehsan Akhgari 2011-02-04 19:29:29 -05:00
Родитель cb4cdacce5
Коммит 15bb64e5e7
5 изменённых файлов: 53 добавлений и 17 удалений

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

@ -2857,8 +2857,12 @@ nsHTMLInputElement::SetSelectionRange(PRInt32 aSelectionStart,
if (formControlFrame) {
nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
if (textControlFrame)
if (textControlFrame) {
rv = textControlFrame->SetSelectionRange(aSelectionStart, aSelectionEnd);
if (NS_SUCCEEDED(rv)) {
rv = textControlFrame->ScrollSelectionIntoView();
}
}
}
return rv;
@ -2881,8 +2885,12 @@ nsHTMLInputElement::SetSelectionStart(PRInt32 aSelectionStart)
if (formControlFrame) {
nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
if (textControlFrame)
if (textControlFrame) {
rv = textControlFrame->SetSelectionStart(aSelectionStart);
if (NS_SUCCEEDED(rv)) {
rv = textControlFrame->ScrollSelectionIntoView();
}
}
}
return rv;
@ -2906,8 +2914,12 @@ nsHTMLInputElement::SetSelectionEnd(PRInt32 aSelectionEnd)
if (formControlFrame) {
nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
if (textControlFrame)
if (textControlFrame) {
rv = textControlFrame->SetSelectionEnd(aSelectionEnd);
if (NS_SUCCEEDED(rv)) {
rv = textControlFrame->ScrollSelectionIntoView();
}
}
}
return rv;

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

@ -879,8 +879,12 @@ nsHTMLTextAreaElement::SetSelectionStart(PRInt32 aSelectionStart)
if (formControlFrame){
nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
if (textControlFrame)
if (textControlFrame) {
rv = textControlFrame->SetSelectionStart(aSelectionStart);
if (NS_SUCCEEDED(rv)) {
rv = textControlFrame->ScrollSelectionIntoView();
}
}
}
return rv;
@ -903,8 +907,12 @@ nsHTMLTextAreaElement::SetSelectionEnd(PRInt32 aSelectionEnd)
if (formControlFrame) {
nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
if (textControlFrame)
if (textControlFrame) {
rv = textControlFrame->SetSelectionEnd(aSelectionEnd);
if (NS_SUCCEEDED(rv)) {
rv = textControlFrame->ScrollSelectionIntoView();
}
}
}
return rv;
@ -934,8 +942,12 @@ nsHTMLTextAreaElement::SetSelectionRange(PRInt32 aSelectionStart, PRInt32 aSelec
if (formControlFrame) {
nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
if (textControlFrame)
if (textControlFrame) {
rv = textControlFrame->SetSelectionRange(aSelectionStart, aSelectionEnd);
if (NS_SUCCEEDED(rv)) {
rv = textControlFrame->ScrollSelectionIntoView();
}
}
}
return rv;

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

@ -76,6 +76,8 @@ public:
* @throws various and sundry other things
*/
virtual nsresult EnsureEditorInitialized() = 0;
virtual nsresult ScrollSelectionIntoView() = 0;
};
#endif

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

@ -855,18 +855,23 @@ nsTextControlFrame::SetSelectionInternal(nsIDOMNode *aStartNode,
NS_ENSURE_SUCCESS(rv, rv);
rv = selection->AddRange(range); // NOTE: can destroy the world
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
// Fetch it again since it might have been destroyed (bug 626014).
selCon = txtCtrl->GetSelectionController();
if (!selCon) {
return NS_OK; // nothing to scroll, we're done
nsresult
nsTextControlFrame::ScrollSelectionIntoView()
{
nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
NS_ASSERTION(txtCtrl, "Content not a text control element");
nsISelectionController* selCon = txtCtrl->GetSelectionController();
if (selCon) {
// Scroll the selection into view (see bug 231389).
return selCon->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL,
nsISelectionController::SELECTION_FOCUS_REGION,
nsISelectionController::SCROLL_FIRST_ANCESTOR_ONLY);
}
// Scroll the selection into view (see bug 231389).
return selCon->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL,
nsISelectionController::SELECTION_FOCUS_REGION,
nsISelectionController::SCROLL_FIRST_ANCESTOR_ONLY);
return NS_ERROR_FAILURE;
}
nsresult
@ -914,8 +919,11 @@ nsTextControlFrame::SelectAllOrCollapseToEndOfText(PRBool aSelect)
}
}
return SetSelectionInternal(rootNode, aSelect ? 0 : numChildren,
rootNode, numChildren);
rv = SetSelectionInternal(rootNode, aSelect ? 0 : numChildren,
rootNode, numChildren);
NS_ENSURE_SUCCESS(rv, rv);
return ScrollSelectionIntoView();
}
nsresult

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

@ -370,6 +370,8 @@ protected:
nsresult CalcIntrinsicSize(nsIRenderingContext* aRenderingContext,
nsSize& aIntrinsicSize);
nsresult ScrollSelectionIntoView();
private:
//helper methods
nsresult SetSelectionInternal(nsIDOMNode *aStartNode, PRInt32 aStartOffset,