diff --git a/editor/libeditor/base/Makefile.in b/editor/libeditor/base/Makefile.in index 81c5bdc964bb..acedb86f4994 100644 --- a/editor/libeditor/base/Makefile.in +++ b/editor/libeditor/base/Makefile.in @@ -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 \ diff --git a/editor/libeditor/base/nsEditor.cpp b/editor/libeditor/base/nsEditor.cpp index fa6e76892fa7..0d158e9661db 100644 --- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -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 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 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 children; + res = (*aInOutNode)->GetChildNodes(getter_AddRefs(children)); + if (NS_SUCCEEDED(res)) { + nsCOMPtr possibleMozBRNode; + res = children->Item(*aInOutOffset, getter_AddRefs(possibleMozBRNode)); + if (NS_SUCCEEDED(res) && nsTextEditUtils::IsMozBR(possibleMozBRNode)) { + nsCOMPtr 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)