Bug 240933 - Part 1: Do not split multiline text into textframes separated by BR elements; r=roc a=dbaron

--HG--
extra : rebase_source : bcaf760ad9d2e939a5d99f21cd8727ef71faea92
This commit is contained in:
Ehsan Akhgari 2010-07-11 16:26:26 -04:00
parent 27aec6b8bd
commit 4085a00c0c
4 changed files with 36 additions and 75 deletions

View File

@ -756,83 +756,20 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
// don't spaz my selection in subtransactions
nsAutoTxnsConserveSelection dontSpazMySelection(mEditor);
nsString tString(*outString);
const PRUnichar *unicodeBuf = tString.get();
nsCOMPtr<nsIDOMNode> unused;
PRInt32 pos = 0;
// for efficiency, break out the pre case separately. This is because
// it's a lot cheaper to search the input string for only newlines than
// it is to search for both tabs and newlines.
if (isPRE)
{
while (unicodeBuf && (pos != -1) && ((PRUint32)pos < tString.Length()))
{
PRInt32 oldPos = pos;
PRInt32 subStrLen;
pos = tString.FindChar(nsCRT::LF, oldPos);
if (pos != -1)
{
subStrLen = pos - oldPos;
// if first char is newline, then use just it
if (subStrLen == 0)
subStrLen = 1;
}
else
{
subStrLen = tString.Length() - oldPos;
pos = tString.Length();
}
nsDependentSubstring subStr(tString, oldPos, subStrLen);
// is it a return?
if (subStr.EqualsLiteral(LFSTR))
{
if (IsSingleLineEditor())
{
NS_ASSERTION((mEditor->mNewlineHandling == nsIPlaintextEditor::eNewlinesPasteIntact),
"Newline improperly getting into single-line edit field!");
res = mEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc);
}
else
{
res = mEditor->CreateBRImpl(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone);
// If the newline is the last character in the string, and the BR we
// just inserted is the last node in the content tree, we need to add
// a mozBR so that a blank line is created.
if (NS_SUCCEEDED(res) && curNode && pos == (PRInt32)(tString.Length() - 1))
{
nsCOMPtr<nsIDOMNode> nextChild = mEditor->GetChildAt(curNode, curOffset);
if (!nextChild)
{
// We must be at the end since there isn't a nextChild.
//
// curNode and curOffset should be set to the position after
// the BR we added above, so just create a mozBR at that position.
//
// Note that we don't update curOffset after we've created/inserted
// the mozBR since we never want the selection to be placed after it.
res = CreateMozBR(curNode, curOffset, address_of(unused));
}
}
}
pos++;
}
else
{
res = mEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc);
}
NS_ENSURE_SUCCESS(res, res);
}
res = mEditor->InsertTextImpl(*outString, address_of(curNode),
&curOffset, doc);
NS_ENSURE_SUCCESS(res, res);
}
else
{
const nsString& tString = PromiseFlatString(*outString);
const PRUnichar *unicodeBuf = tString.get();
nsCOMPtr<nsIDOMNode> unused;
PRInt32 pos = 0;
char specialChars[] = {TAB, nsCRT::LF, 0};
while (unicodeBuf && (pos != -1) && ((PRUint32)pos < tString.Length()))
{
@ -873,18 +810,28 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
}
NS_ENSURE_SUCCESS(res, res);
}
outString->Assign(tString);
}
outString->Assign(tString);
if (curNode)
{
aSelection->Collapse(curNode, curOffset);
// Make the caret attach to the inserted text, unless this text ends with a LF,
// in which case make the caret attach to the next line.
PRBool endsWithLF = !tString.IsEmpty() && tString.get()[tString.Length() - 1] == nsCRT::LF;
PRBool endsWithLF =
!outString->IsEmpty() && outString->Last() == nsCRT::LF;
nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection));
selPrivate->SetInterlinePosition(endsWithLF);
// If the last character is a linefeed character, make sure that we inject
// a BR element for correct caret positioning.
if (endsWithLF) {
nsCOMPtr<nsIDOMNode> mozBR;
res = CreateMozBR(curNode, curOffset, address_of(mozBR));
NS_ENSURE_SUCCESS(res, res);
curNode = mozBR;
curOffset = 0;
}
aSelection->Collapse(curNode, curOffset);
}
}
ASSERT_PASSWORD_LENGTHS_EQUAL()

View File

@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<body onload="document.querySelector('textarea').focus();">
<textarea>foo</textarea>
</body>
</html>

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<body onload="document.querySelector('textarea').focus();">
<textarea>foo
</textarea>
</body>
</html>

View File

@ -18,3 +18,4 @@ include xul/reftest.list
== emptypasswd-2.html emptypasswd-ref.html
== caret_on_positioned.html caret_on_positioned-ref.html
== spellcheck-1.html spellcheck-ref.html
!= caret_on_textarea_lastline.html caret_on_textarea_lastline-ref.html