Bug 240933 - Part 8: Avoid creating multiple textnodes when adding text to textareas; r=roc a=dbaron

--HG--
extra : rebase_source : 9799daa7662dacdf3f4d0f7b8ecdaba2b9005221
This commit is contained in:
Ehsan Akhgari 2010-07-19 16:47:52 -04:00
Родитель 5b02abf39b
Коммит 49b28a59ba
2 изменённых файлов: 45 добавлений и 1 удалений

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

@ -90,6 +90,7 @@ FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
INCLUDES += \
-I$(topsrcdir)/editor/libeditor/text \
-I$(topsrcdir)/content/base/src \
-I$(topsrcdir)/content/events/src \
-I$(topsrcdir)/layout/style \

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

@ -113,6 +113,7 @@
#include "nsITransferable.h"
#include "nsComputedDOMStyle.h"
#include "nsTextEditUtils.h"
#include "mozilla/FunctionTimer.h"
@ -2273,11 +2274,53 @@ NS_IMETHODIMP nsEditor::InsertTextImpl(const nsAString& aStringToInsert,
// class to turn off txn selection updating. Caller also turned on rules sniffing
// if desired.
nsresult res;
NS_ENSURE_TRUE(aInOutNode && *aInOutNode && aInOutOffset && aDoc, NS_ERROR_NULL_POINTER);
if (!mInIMEMode && aStringToInsert.IsEmpty()) return NS_OK;
nsCOMPtr<nsIDOMText> nodeAsText = do_QueryInterface(*aInOutNode);
if (!nodeAsText && IsPlaintextEditor()) {
// In some cases, aInOutNode is the anonymous DIV, and aInOutOffset is 0.
// To avoid injecting unneeded text nodes, we first look to see if we have
// one available. In that case, we'll just adjust aInOutNode and aInOutOffset
// accordingly.
if (*aInOutNode == GetRoot() && *aInOutOffset == 0) {
nsCOMPtr<nsIDOMNode> possibleTextNode;
res = (*aInOutNode)->GetFirstChild(getter_AddRefs(possibleTextNode));
if (NS_SUCCEEDED(res)) {
nodeAsText = do_QueryInterface(possibleTextNode);
if (nodeAsText) {
*aInOutNode = possibleTextNode;
}
}
}
// In some other cases, aInOutNode is the anonymous DIV, and aInOutOffset points
// to the terminating mozBR. In that case, we'll adjust aInOutNode and aInOutOffset
// to the preceding text node, if any.
if (!nodeAsText && *aInOutNode == GetRoot() && *aInOutOffset > 0) {
nsCOMPtr<nsIDOMNodeList> children;
res = (*aInOutNode)->GetChildNodes(getter_AddRefs(children));
if (NS_SUCCEEDED(res)) {
nsCOMPtr<nsIDOMNode> possibleMozBRNode;
res = children->Item(*aInOutOffset, getter_AddRefs(possibleMozBRNode));
if (NS_SUCCEEDED(res) && nsTextEditUtils::IsMozBR(possibleMozBRNode)) {
nsCOMPtr<nsIDOMNode> possibleTextNode;
res = children->Item(*aInOutOffset - 1, getter_AddRefs(possibleTextNode));
if (NS_SUCCEEDED(res)) {
nodeAsText = do_QueryInterface(possibleTextNode);
if (nodeAsText) {
PRUint32 length;
res = nodeAsText->GetLength(&length);
if (NS_SUCCEEDED(res)) {
*aInOutOffset = PRInt32(length);
*aInOutNode = possibleTextNode;
}
}
}
}
}
}
}
PRInt32 offset = *aInOutOffset;
nsresult res;
if (mInIMEMode)
{
if (!nodeAsText)