Bug 597331 - Reframing a textarea sets the caret position to the end of its contents; r=bzbarsky a=blocking-final+

This commit is contained in:
Ehsan Akhgari 2010-10-13 01:34:05 -04:00
Родитель 4832c503b9
Коммит 8c42ff3cb3
4 изменённых файлов: 92 добавлений и 0 удалений

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

@ -73,6 +73,11 @@ static NS_DEFINE_CID(kFrameSelectionCID, NS_FRAMESELECTION_CID);
static nsINativeKeyBindings *sNativeInputBindings = nsnull;
static nsINativeKeyBindings *sNativeTextAreaBindings = nsnull;
struct SelectionState {
PRInt32 mStart;
PRInt32 mEnd;
};
/*static*/
PRBool
nsITextControlElement::GetWrapPropertyEnum(nsIContent* aContent,
@ -1321,6 +1326,12 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
if (mTextListener)
newEditor->AddEditorObserver(mTextListener);
// Restore our selection after being bound to a new frame
if (mSelState) {
mBoundFrame->SetSelectionRange(mSelState->mStart, mSelState->mEnd);
mSelState = nsnull;
}
return rv;
}
@ -1351,6 +1362,20 @@ nsTextEditorState::UnbindFromFrame(nsTextControlFrame* aFrame)
nsAutoString value;
GetValue(value, PR_TRUE);
// Save our selection state if needed.
// Note that nsTextControlFrame::GetSelectionRange attempts to initialize the
// editor before grabbing the range, and because this is not an acceptable
// side effect for unbinding from a text control frame, we need to call
// GetSelectionRange before calling DestroyEditor, and only if
// mEditorInitialized indicates that we actually have an editor available.
if (mEditorInitialized) {
mSelState = new SelectionState();
nsresult rv = mBoundFrame->GetSelectionRange(&mSelState->mStart, &mSelState->mEnd);
if (NS_FAILED(rv)) {
mSelState = nsnull;
}
}
// Destroy our editor
DestroyEditor();

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

@ -51,6 +51,7 @@ class nsISelectionController;
class nsFrameSelection;
class nsIEditor;
class nsITextControlElement;
struct SelectionState;
/**
* nsTextEditorState is a class which is responsible for managing the state of
@ -250,6 +251,7 @@ private:
nsITextControlElement* const mTextCtrlElement;
nsRefPtr<nsTextInputSelectionImpl> mSelCon;
nsAutoPtr<SelectionState> mSelState;
nsCOMPtr<nsIEditor> mEditor;
nsCOMPtr<nsIContent> mRootNode;
nsCOMPtr<nsIContent> mPlaceholderDiv;

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

@ -51,6 +51,7 @@ _TEST_FILES = \
test_bug596001.html \
test_bug596333.html \
test_bug596506.html \
test_bug597331.html \
test_bug600570.html \
$(NULL)

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

@ -0,0 +1,64 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=597331
-->
<head>
<title>Test for Bug 597331</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=597331">Mozilla Bug 597331</a>
<p id="display"></p>
<div id="content">
<textarea>line1
line2
line3
</textarea>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 597331 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var t = document.querySelector("textarea");
t.focus();
t.selectionStart = 4;
t.selectionEnd = 4;
SimpleTest.executeSoon(function() {
var before = snapshotWindow(window, true);
t.selectionStart = 5;
t.selectionEnd = 5;
t.addEventListener("keydown", function() {
t.removeEventListener("keydown", arguments.callee, false);
SimpleTest.executeSoon(function() {
t.style.display = 'block';
document.body.offsetWidth;
t.style.display = '';
document.body.offsetWidth;
is(t.selectionStart, 4, "Cursor should be moved correctly");
is(t.selectionEnd, 4, "Cursor should be moved correctly");
var after = snapshotWindow(window, true);
var result = compareSnapshots(before, after, true);
ok(result[0], "The caret should be displayed correctly after reframing");
SimpleTest.finish();
});
}, false);
synthesizeKey("VK_LEFT", {});
});
});
</script>
</pre>
</body>
</html>