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