Bug 221820 - Part 4: Fix the newline handling for text fields without an editor; r=bzbarsky

--HG--
extra : rebase_source : 92d9e491351a6183f0232604cd989c14d10d5fad
This commit is contained in:
Ehsan Akhgari 2010-02-22 16:15:56 -08:00
parent a85b9fbf14
commit 380b7b208c
8 changed files with 59 additions and 35 deletions

View File

@ -1583,6 +1583,18 @@ public:
static nsresult ReparentClonedObjectToScope(JSContext* cx, JSObject* obj,
JSObject* scope);
/**
* Strip all \n, \r and nulls from the given string
* @param aString the string to remove newlines from [in/out]
*/
static void RemoveNewlines(nsString &aString);
/**
* Convert Windows and Mac platform linebreaks to \n.
* @param aString the string to convert the newlines inside [in/out]
*/
static void PlatformToDOMLineBreaks(nsString &aString);
private:
static PRBool InitializeEventTable();

View File

@ -5931,3 +5931,24 @@ mozAutoRemovableBlockerRemover::~mozAutoRemovableBlockerRemover()
}
}
}
void nsContentUtils::RemoveNewlines(nsString &aString)
{
// strip CR/LF and null
static const char badChars[] = {'\r', '\n', 0};
aString.StripChars(badChars);
}
void nsContentUtils::PlatformToDOMLineBreaks(nsString &aString)
{
if (aString.FindChar(PRUnichar('\r')) != -1) {
// Windows linebreaks: Map CRLF to LF:
aString.ReplaceSubstring(NS_LITERAL_STRING("\r\n").get(),
NS_LITERAL_STRING("\n").get());
// Mac linebreaks: Map any remaining CR to LF:
aString.ReplaceSubstring(NS_LITERAL_STRING("\r").get(),
NS_LITERAL_STRING("\n").get());
}
}

View File

@ -130,6 +130,8 @@ INCLUDES += \
-I$(srcdir)/../../../../layout/xul/base/src \
-I$(srcdir)/../../../../layout/generic \
-I$(srcdir)/../../../../dom/base \
-I$(srcdir)/../../../../editor/libeditor/base \
-I$(srcdir)/../../../../editor/libeditor/text \
-I$(srcdir) \
$(NULL)

View File

@ -110,6 +110,8 @@
#include "mozAutoDocUpdate.h"
#include "nsHTMLFormElement.h"
#include "nsTextEditRules.h"
// XXX align=left, hspace, vspace, border? other nav4 attrs
static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
@ -880,6 +882,13 @@ nsHTMLInputElement::GetValue(nsAString& aValue)
} else {
CopyUTF8toUTF16(mValue, aValue);
}
// If the value is not owned by the frame, then we should handle any
// exiting newline characters inside it, instead of relying on the
// editor to do it for us.
nsString value(aValue);
nsTextEditRules::HandleNewLines(value, -1);
aValue.Assign(value);
}
return NS_OK;
@ -1007,7 +1016,9 @@ nsHTMLInputElement::TakeTextFrameValue(const nsAString& aValue)
if (mValue) {
nsMemory::Free(mValue);
}
mValue = ToNewUTF8String(aValue);
nsString value(aValue);
nsContentUtils::PlatformToDOMLineBreaks(value);
mValue = ToNewUTF8String(value);
return NS_OK;
}

View File

@ -435,7 +435,9 @@ nsHTMLTextAreaElement::TakeTextFrameValue(const nsAString& aValue)
if (mValue) {
nsMemory::Free(mValue);
}
mValue = ToNewUTF8String(aValue);
nsString value(aValue);
nsContentUtils::PlatformToDOMLineBreaks(value);
mValue = ToNewUTF8String(value);
return NS_OK;
}

View File

@ -105,8 +105,12 @@ function runTests() {
for (var i = 0; i < textareas.length; ++i) {
runTestsFor(textareas[i], simple_tests, value_append_tests);
}
runTestsFor(document.getElementsByTagName("input")[0],
simple_tests_for_input, value_append_tests_for_input);
var input = document.getElementsByTagName("input")[0];
runTestsFor(input, simple_tests_for_input, value_append_tests_for_input);
// initialize the editor
input.focus();
input.blur();
runTestsFor(input, simple_tests_for_input, value_append_tests_for_input);
SimpleTest.finish();
}

View File

@ -136,18 +136,6 @@ static const PRInt32 DEFAULT_UNDO_CAP = 1000;
static nsINativeKeyBindings *sNativeInputBindings = nsnull;
static nsINativeKeyBindings *sNativeTextAreaBindings = nsnull;
static void
PlatformToDOMLineBreaks(nsString &aString)
{
// Windows linebreaks: Map CRLF to LF:
aString.ReplaceSubstring(NS_LITERAL_STRING("\r\n").get(),
NS_LITERAL_STRING("\n").get());
// Mac linebreaks: Map any remaining CR to LF:
aString.ReplaceSubstring(NS_LITERAL_STRING("\r").get(),
NS_LITERAL_STRING("\n").get());
}
// wrap can be one of these three values.
typedef enum {
eHTMLTextWrap_Off = 1, // "off"
@ -2532,7 +2520,7 @@ nsTextControlFrame::GetText(nsString& aText)
if (IsSingleLineTextControl()) {
// If we're going to remove newlines anyway, ignore the wrap property
GetValue(aText, PR_TRUE);
RemoveNewlines(aText);
nsContentUtils::RemoveNewlines(aText);
} else {
nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea = do_QueryInterface(mContent);
if (textArea) {
@ -2563,14 +2551,6 @@ nsTextControlFrame::GetPhonetic(nsAString& aPhonetic)
///END NSIFRAME OVERLOADS
/////BEGIN PROTECTED METHODS
void nsTextControlFrame::RemoveNewlines(nsString &aString)
{
// strip CR/LF and null
static const char badChars[] = {10, 13, 0};
aString.StripChars(badChars);
}
PRBool
nsTextControlFrame::GetMaxLength(PRInt32* aSize)
{
@ -2742,9 +2722,7 @@ nsTextControlFrame::SetValue(const nsAString& aValue)
// Unfortunately aValue is declared const, so we have to copy
// in order to do this substitution.
nsString newValue(aValue);
if (aValue.FindChar(PRUnichar('\r')) != -1) {
::PlatformToDOMLineBreaks(newValue);
}
nsContentUtils::PlatformToDOMLineBreaks(newValue);
nsCOMPtr<nsIDOMDocument> domDoc;
editor->GetDocument(getter_AddRefs(domDoc));
@ -3110,7 +3088,7 @@ nsTextControlFrame::UpdatePlaceholderText(PRBool aNotify)
nsAutoString placeholderValue;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholderValue);
RemoveNewlines(placeholderValue);
nsContentUtils::RemoveNewlines(placeholderValue);
NS_ASSERTION(mPlaceholderDiv->GetChildAt(0), "placeholder div has no child");
mPlaceholderDiv->GetChildAt(0)->SetText(placeholderValue, aNotify);

View File

@ -286,12 +286,6 @@ protected:
PRBool aBeforeEditorInit = PR_FALSE,
const nsAString *aValue = nsnull);
/**
* Strip all \n, \r and nulls from the given string
* @param aString the string to remove newlines from [in/out]
*/
void RemoveNewlines(nsString &aString);
/**
* Get the maxlength attribute
* @param aMaxLength the value of the max length attr