mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1478564 - part 1: Optimize TextEditRules::HandleNewLines() r=m_kato
TextEditRules::HandleNewLines() is expensive since it may scan all of given string twice and more. On the other hand, in most cases, given string does not contain \n, \r nor \r\n. First, for avoid using nsTString::FindCharInSet(), HandleNewLine() should receive string which never contains \r nor \r\n. Then, it always can use nsTSubstring::FindChar() instead. Next, HandleNewLines() should do nothing if given string does not contain \n. Finally, because of unused, this removes unnecessary HandleNewLines() argument which can specify the way to handle new lines. MozReview-Commit-ID: 8WSfxfkuFgN --HG-- extra : rebase_source : 1c05721162a30288929d030c0a15fe83a50fe9d2
This commit is contained in:
parent
58cbd9a01e
commit
a9d57dd8a8
@ -596,37 +596,40 @@ TextEditRules::GetTextNodeAroundSelectionStartContainer()
|
||||
#define ASSERT_PASSWORD_LENGTHS_EQUAL()
|
||||
#endif
|
||||
|
||||
// static
|
||||
void
|
||||
TextEditRules::HandleNewLines(nsString& aString,
|
||||
int32_t aNewlineHandling)
|
||||
TextEditRules::HandleNewLines(nsString& aString)
|
||||
{
|
||||
if (aNewlineHandling < 0) {
|
||||
int32_t caretStyle;
|
||||
TextEditor::GetDefaultEditorPrefs(aNewlineHandling, caretStyle);
|
||||
static const char16_t kLF = static_cast<char16_t>('\n');
|
||||
MOZ_ASSERT(IsEditorDataAvailable());
|
||||
MOZ_ASSERT(aString.FindChar(static_cast<uint16_t>('\r')) == kNotFound);
|
||||
|
||||
// First of all, check if aString contains '\n' since if the string
|
||||
// does not include it, we don't need to do nothing here.
|
||||
int32_t firstLF = aString.FindChar(kLF, 0);
|
||||
if (firstLF == kNotFound) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(aNewlineHandling) {
|
||||
switch(TextEditorRef().mNewlineHandling) {
|
||||
case nsIPlaintextEditor::eNewlinesReplaceWithSpaces:
|
||||
// Default of Firefox:
|
||||
// Strip trailing newlines first so we don't wind up with trailing spaces
|
||||
aString.Trim(CRLF, false, true);
|
||||
aString.ReplaceChar(CRLF, ' ');
|
||||
aString.Trim(LFSTR, false, true);
|
||||
aString.ReplaceChar(kLF, ' ');
|
||||
break;
|
||||
case nsIPlaintextEditor::eNewlinesStrip:
|
||||
aString.StripCRLF();
|
||||
aString.StripChar(kLF);
|
||||
break;
|
||||
case nsIPlaintextEditor::eNewlinesPasteToFirst:
|
||||
default: {
|
||||
int32_t firstCRLF = aString.FindCharInSet(CRLF);
|
||||
|
||||
// we get first *non-empty* line.
|
||||
int32_t offset = 0;
|
||||
while (firstCRLF == offset) {
|
||||
while (firstLF == offset) {
|
||||
offset++;
|
||||
firstCRLF = aString.FindCharInSet(CRLF, offset);
|
||||
firstLF = aString.FindChar(kLF, offset);
|
||||
}
|
||||
if (firstCRLF > 0) {
|
||||
aString.Truncate(firstCRLF);
|
||||
if (firstLF > 0) {
|
||||
aString.Truncate(firstLF);
|
||||
}
|
||||
if (offset > 0) {
|
||||
aString.Cut(0, offset);
|
||||
@ -634,25 +637,27 @@ TextEditRules::HandleNewLines(nsString& aString,
|
||||
break;
|
||||
}
|
||||
case nsIPlaintextEditor::eNewlinesReplaceWithCommas:
|
||||
aString.Trim(CRLF, true, true);
|
||||
aString.ReplaceChar(CRLF, ',');
|
||||
// Default of Thunderbird:
|
||||
aString.Trim(LFSTR, true, true);
|
||||
aString.ReplaceChar(kLF, ',');
|
||||
break;
|
||||
case nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace: {
|
||||
nsAutoString result;
|
||||
uint32_t offset = 0;
|
||||
while (offset < aString.Length()) {
|
||||
int32_t nextCRLF = aString.FindCharInSet(CRLF, offset);
|
||||
if (nextCRLF < 0) {
|
||||
int32_t nextLF =
|
||||
!offset ? firstLF : aString.FindChar(kLF, offset);
|
||||
if (nextLF < 0) {
|
||||
result.Append(nsDependentSubstring(aString, offset));
|
||||
break;
|
||||
}
|
||||
uint32_t wsBegin = nextCRLF;
|
||||
uint32_t wsBegin = nextLF;
|
||||
// look backwards for the first non-whitespace char
|
||||
while (wsBegin > offset && NS_IS_SPACE(aString[wsBegin - 1])) {
|
||||
--wsBegin;
|
||||
}
|
||||
result.Append(nsDependentSubstring(aString, offset, wsBegin - offset));
|
||||
offset = nextCRLF + 1;
|
||||
offset = nextLF + 1;
|
||||
while (offset < aString.Length() && NS_IS_SPACE(aString[offset])) {
|
||||
++offset;
|
||||
}
|
||||
@ -662,7 +667,7 @@ TextEditRules::HandleNewLines(nsString& aString,
|
||||
}
|
||||
case nsIPlaintextEditor::eNewlinesPasteIntact:
|
||||
// even if we're pasting newlines, don't paste leading/trailing ones
|
||||
aString.Trim(CRLF, true, true);
|
||||
aString.Trim(LFSTR, true, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -760,7 +765,15 @@ TextEditRules::WillInsertText(EditSubAction aEditSubAction,
|
||||
// So find out what we're expected to do:
|
||||
if (IsSingleLineEditor()) {
|
||||
nsAutoString tString(*outString);
|
||||
HandleNewLines(tString, TextEditorRef().mNewlineHandling);
|
||||
// XXX Some callers of TextEditor::InsertTextAsAction() already make the
|
||||
// string use only \n as a linebreaker. However, they are not hot
|
||||
// path and nsContentUtils::PlatformToDOMLineBreaks() does nothing
|
||||
// if the string doesn't include \r. So, let's convert linebreakers
|
||||
// here. Note that there are too many callers of
|
||||
// TextEditor::InsertTextAsAction(). So, it's difficult to keep
|
||||
// maintaining all of them won't reach here without \r nor \r\n.
|
||||
nsContentUtils::PlatformToDOMLineBreaks(tString);
|
||||
HandleNewLines(tString);
|
||||
outString->Assign(tString);
|
||||
}
|
||||
|
||||
@ -885,6 +898,7 @@ TextEditRules::WillSetText(bool* aCancel,
|
||||
MOZ_ASSERT(aCancel);
|
||||
MOZ_ASSERT(aHandled);
|
||||
MOZ_ASSERT(aString);
|
||||
MOZ_ASSERT(aString->FindChar(static_cast<char16_t>('\r')) == kNotFound);
|
||||
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
@ -923,7 +937,7 @@ TextEditRules::WillSetText(bool* aCancel,
|
||||
mPasswordText.Assign(tString);
|
||||
FillBufWithPWChars(&tString, tString.Length());
|
||||
} else if (IsSingleLineEditor()) {
|
||||
HandleNewLines(tString, TextEditorRef().mNewlineHandling);
|
||||
HandleNewLines(tString);
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
|
@ -104,28 +104,26 @@ public:
|
||||
void ResetIMETextPWBuf();
|
||||
|
||||
/**
|
||||
* Handles the newline characters either according to aNewLineHandling
|
||||
* or to the default system prefs if aNewLineHandling is negative.
|
||||
* Handles the newline characters according to the default system prefs
|
||||
* (editor.singleLine.pasteNewlines).
|
||||
* Each value means:
|
||||
* nsIPlaintextEditor::eNewlinesReplaceWithSpaces (2, Firefox default):
|
||||
* replace newlines with spaces.
|
||||
* nsIPlaintextEditor::eNewlinesStrip (3):
|
||||
* remove newlines from the string.
|
||||
* nsIPlaintextEditor::eNewlinesReplaceWithCommas (4, Thunderbird default):
|
||||
* replace newlines with commas.
|
||||
* nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace (5):
|
||||
* collapse newlines and surrounding whitespace characters and
|
||||
* remove them from the string.
|
||||
* nsIPlaintextEditor::eNewlinesPasteIntact (0):
|
||||
* only remove the leading and trailing newlines.
|
||||
* nsIPlaintextEditor::eNewlinesPasteToFirst (1) or any other value:
|
||||
* remove the first newline and all characters following it.
|
||||
*
|
||||
* @param aString the string to be modified in place.
|
||||
* @param aNewLineHandling determine the desired type of newline handling:
|
||||
* * negative values:
|
||||
* handle newlines according to platform defaults.
|
||||
* * nsIPlaintextEditor::eNewlinesReplaceWithSpaces:
|
||||
* replace newlines with spaces.
|
||||
* * nsIPlaintextEditor::eNewlinesStrip:
|
||||
* remove newlines from the string.
|
||||
* * nsIPlaintextEditor::eNewlinesReplaceWithCommas:
|
||||
* replace newlines with commas.
|
||||
* * nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace:
|
||||
* collapse newlines and surrounding whitespace characters and
|
||||
* remove them from the string.
|
||||
* * nsIPlaintextEditor::eNewlinesPasteIntact:
|
||||
* only remove the leading and trailing newlines.
|
||||
* * nsIPlaintextEditor::eNewlinesPasteToFirst or any other value:
|
||||
* remove the first newline and all characters following it.
|
||||
*/
|
||||
static void HandleNewLines(nsString& aString, int32_t aNewLineHandling);
|
||||
void HandleNewLines(nsString& aString);
|
||||
|
||||
/**
|
||||
* Prepare a string buffer for being displayed as the contents of a password
|
||||
|
@ -1114,6 +1114,8 @@ TextEditor::InsertParagraphSeparatorAsAction()
|
||||
nsresult
|
||||
TextEditor::SetText(const nsAString& aString)
|
||||
{
|
||||
MOZ_ASSERT(aString.FindChar(static_cast<char16_t>('\r')) == kNotFound);
|
||||
|
||||
if (NS_WARN_IF(!mRules)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user