diff --git a/editor/base/nsHTMLEditRules.cpp b/editor/base/nsHTMLEditRules.cpp
index d1d35abed273..9a4e8ec74389 100644
--- a/editor/base/nsHTMLEditRules.cpp
+++ b/editor/base/nsHTMLEditRules.cpp
@@ -98,12 +98,17 @@ nsHTMLEditRules::Init(nsHTMLEditor *aEditor, PRUint32 aFlags)
bodyNode = do_QueryInterface(bodyElem);
if (bodyNode)
{
+ // temporarily turn off rules sniffing
+ nsAutoLockRulesSniffing lockIt((nsTextEditRules*)this);
res = nsComponentManager::CreateInstance(kRangeCID, nsnull, NS_GET_IID(nsIDOMRange),
getter_AddRefs(mDocChangeRange));
if (NS_FAILED(res)) return res;
if (!mDocChangeRange) return NS_ERROR_NULL_POINTER;
mDocChangeRange->SelectNode(bodyNode);
- AdjustSpecialBreaks();
+ res = ReplaceNewlines(mDocChangeRange);
+ if (NS_FAILED(res)) return res;
+ res = AdjustSpecialBreaks();
+ if (NS_FAILED(res)) return res;
}
// turn on undo
mEditor->EnableUndo(PR_TRUE);
@@ -180,6 +185,13 @@ nsHTMLEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection)
res = AdjustWhitespace(selection);
if (NS_FAILED(res)) return res;
}
+ // replace newlines that are preformatted
+ if ((action == nsEditor::kOpInsertText) ||
+ (action == nsEditor::kOpInsertIMEText) ||
+ (action == nsEditor::kOpInsertNode))
+ {
+ res = ReplaceNewlines(mDocChangeRange);
+ }
// clean up any empty nodes in the selection
res = RemoveEmptyNodes();
if (NS_FAILED(res)) return res;
@@ -1577,8 +1589,27 @@ nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection,
PRBool outMakeEmpty;
res = ShouldMakeEmptyBlock(aSelection, alignType, &outMakeEmpty);
if (NS_FAILED(res)) return res;
- if (outMakeEmpty) return NS_OK;
-
+ if (outMakeEmpty)
+ {
+ PRInt32 offset;
+ nsCOMPtr brNode, parent, theDiv;
+ nsAutoString divType("div");
+ res = mEditor->GetStartNodeAndOffset(aSelection, &parent, &offset);
+ if (NS_FAILED(res)) return res;
+ res = mEditor->CreateNode(divType, parent, offset, getter_AddRefs(theDiv));
+ if (NS_FAILED(res)) return res;
+ // set up the alignment on the div
+ nsCOMPtr divElem = do_QueryInterface(theDiv);
+ nsAutoString attr("align");
+ res = mEditor->SetAttribute(divElem, attr, *alignType);
+ if (NS_FAILED(res)) return res;
+ *aHandled = PR_TRUE;
+ // put in a moz-br so that it won't get deleted
+ res = CreateMozBR(theDiv, 0, &brNode);
+ if (NS_FAILED(res)) return res;
+ res = aSelection->Collapse(theDiv, 0);
+ return res;
+ }
// convert the selection ranges into "promoted" selection ranges:
// this basically just expands the range to include the immediate
diff --git a/editor/base/nsHTMLEditor.cpp b/editor/base/nsHTMLEditor.cpp
index 340c7486fd96..82a791e85162 100644
--- a/editor/base/nsHTMLEditor.cpp
+++ b/editor/base/nsHTMLEditor.cpp
@@ -4269,6 +4269,38 @@ nsHTMLEditor::CanContainTag(nsIDOMNode* aParent, const nsString &aTag)
}
+NS_IMETHODIMP
+nsHTMLEditor::SelectEntireDocument(nsIDOMSelection *aSelection)
+{
+ nsresult res;
+ if (!aSelection || !mRules) { return NS_ERROR_NULL_POINTER; }
+
+ // get body node
+ nsCOMPtrbodyElement;
+ res = GetBodyElement(getter_AddRefs(bodyElement));
+ if (NS_FAILED(res)) return res;
+ nsCOMPtrbodyNode = do_QueryInterface(bodyElement);
+ if (!bodyNode) return NS_ERROR_FAILURE;
+
+ // is doc empty?
+ PRBool bDocIsEmpty;
+ res = mRules->DocumentIsEmpty(&bDocIsEmpty);
+ if (NS_FAILED(res)) return res;
+
+ if (bDocIsEmpty)
+ {
+ // if its empty dont select entire doc - that would select the bogus node
+ return aSelection->Collapse(bodyNode, 0);
+ }
+ else
+ {
+ return nsEditor::SelectEntireDocument(aSelection);
+ }
+ return res;
+}
+
+
+
#ifdef XP_MAC
#pragma mark -
#pragma mark --- Random methods ---
diff --git a/editor/base/nsHTMLEditor.h b/editor/base/nsHTMLEditor.h
index da9f8d795227..feeb95bab509 100644
--- a/editor/base/nsHTMLEditor.h
+++ b/editor/base/nsHTMLEditor.h
@@ -241,11 +241,6 @@ public:
NS_IMETHOD DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed);
- /* ------------ nsICSSLoaderObserver -------------- */
- NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet*aSheet, PRBool aNotify);
-
- /* ------------ nsEditor overrides ---------------- */
-
/** All editor operations which alter the doc should be prefaced
* with a call to StartOperation, naming the action and direction */
NS_IMETHOD StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
@@ -257,6 +252,12 @@ public:
/** returns PR_TRUE if aParent can contain a child of type aTag */
PRBool CanContainTag(nsIDOMNode* aParent, const nsString &aTag);
+ /** make the given selection span the entire document */
+ NS_IMETHOD SelectEntireDocument(nsIDOMSelection *aSelection);
+
+ /* ------------ nsICSSLoaderObserver -------------- */
+ NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet*aSheet, PRBool aNotify);
+
/* ------------ Utility Routines, not part of public API -------------- */
NS_IMETHOD GetBodyStyleContext(nsIStyleContext** aStyleContext);
diff --git a/editor/base/nsTextEditRules.cpp b/editor/base/nsTextEditRules.cpp
index 07f281ab1e03..9360d8034f67 100644
--- a/editor/base/nsTextEditRules.cpp
+++ b/editor/base/nsTextEditRules.cpp
@@ -37,8 +37,10 @@
#include "nsLayoutCID.h"
#include "nsIEditProperty.h"
#include "nsEditorUtils.h"
+#include "EditTxn.h"
-static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
+static NS_DEFINE_CID(kContentIteratorCID, NS_CONTENTITERATOR_CID);
+static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
#define CANCEL_OPERATION_IF_READONLY_OR_DISABLED \
@@ -82,6 +84,24 @@ nsTextEditRules::Init(nsHTMLEditor *aEditor, PRUint32 aFlags)
mEditor->GetSelection(getter_AddRefs(selection));
NS_ASSERTION(selection, "editor cannot get selection");
nsresult res = CreateBogusNodeIfNeeded(selection); // this method handles null selection, which should never happen anyway
+
+ // create a range that is the entire body contents
+ if (NS_FAILED(res)) return res;
+ nsCOMPtr bodyElement;
+ res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
+ if (NS_FAILED(res)) return res;
+ if (!bodyElement) return NS_ERROR_NULL_POINTER;
+ nsCOMPtrbodyNode = do_QueryInterface(bodyElement);
+ if (!bodyNode) return NS_ERROR_FAILURE;
+ nsCOMPtr wholeDoc;
+ res = nsComponentManager::CreateInstance(kRangeCID, nsnull, NS_GET_IID(nsIDOMRange),
+ getter_AddRefs(wholeDoc));
+ if (NS_FAILED(res)) return res;
+ res = wholeDoc->SelectNode(bodyNode);
+ if (NS_FAILED(res)) return res;
+
+ // replace newlines in that range with breaks
+ res = ReplaceNewlines(wholeDoc);
return res;
}
@@ -1264,6 +1284,101 @@ nsTextEditRules::DidOutputText(nsIDOMSelection *aSelection, nsresult aResult)
}
+nsresult
+nsTextEditRules::ReplaceNewlines(nsIDOMRange *aRange)
+{
+ if (!aRange) return NS_ERROR_NULL_POINTER;
+
+ // convert any newlines in editable, preformatted text nodes
+ // into normal breaks. this is because layout wont give us a place
+ // to put the cursor on empty lines otherwise.
+
+ nsCOMPtr iter;
+ nsCOMPtr isupports;
+ PRUint32 nodeCount,j;
+ nsCOMPtr arrayOfNodes;
+
+ // make an isupportsArray to hold a list of nodes
+ nsresult res = NS_NewISupportsArray(getter_AddRefs(arrayOfNodes));
+ if (NS_FAILED(res)) return res;
+
+ // need an iterator
+ res = nsComponentManager::CreateInstance(kContentIteratorCID,
+ nsnull,
+ NS_GET_IID(nsIContentIterator),
+ getter_AddRefs(iter));
+ if (NS_FAILED(res)) return res;
+ res = iter->Init(aRange);
+ if (NS_FAILED(res)) return res;
+
+ // gather up a list of editable preformatted text nodes
+ while (NS_ENUMERATOR_FALSE == iter->IsDone())
+ {
+ nsCOMPtr node;
+ nsCOMPtr content;
+ res = iter->CurrentNode(getter_AddRefs(content));
+ if (NS_FAILED(res)) return res;
+ node = do_QueryInterface(content);
+ if (!node) return NS_ERROR_FAILURE;
+
+ if (mEditor->IsTextNode(node) && mEditor->IsEditable(node))
+ {
+ PRBool isPRE;
+ res = mEditor->IsPreformatted(node, &isPRE);
+ if (NS_FAILED(res)) return res;
+ if (isPRE)
+ {
+ isupports = do_QueryInterface(node);
+ arrayOfNodes->AppendElement(isupports);
+ }
+ }
+ res = iter->Next();
+ if (NS_FAILED(res)) return res;
+ }
+
+ // replace newlines with breaks. have to do this left to right,
+ // since inserting the break can split the text node, and the
+ // original node becomes the righthand node.
+ char newlineChar[] = {'\n',0};
+ res = arrayOfNodes->Count(&nodeCount);
+ if (NS_FAILED(res)) return res;
+ for (j = 0; j < nodeCount; j++)
+ {
+ isupports = (dont_AddRef)(arrayOfNodes->ElementAt(0));
+ nsCOMPtr brNode, theNode( do_QueryInterface(isupports) );
+ nsCOMPtr textNode( do_QueryInterface(theNode) );
+ arrayOfNodes->RemoveElementAt(0);
+ // find the newline
+ PRInt32 offset;
+ nsAutoString tempString;
+ do
+ {
+ textNode->GetData(tempString);
+ offset = tempString.FindCharInSet(newlineChar);
+ if (offset == -1) break; // done with this node
+
+ // delete the newline
+ EditTxn *txn;
+ // note 1: we are not telling edit listeners about these because they don't care
+ // note 2: we are not wrapping these in a placeholder because we know they already are,
+ // or, failing that, undo is disabled
+ res = mEditor->CreateTxnForDeleteText(textNode, offset, 1, (DeleteTextTxn**)&txn);
+ if (NS_FAILED(res)) return res;
+ if (!txn) return NS_ERROR_OUT_OF_MEMORY;
+ res = mEditor->Do(txn);
+ if (NS_FAILED(res)) return res;
+ // The transaction system (if any) has taken ownwership of txn
+ NS_IF_RELEASE(txn);
+
+ // insert a break
+ res = mEditor->CreateBR(textNode, offset, &brNode);
+ if (NS_FAILED(res)) return res;
+ } while (1); // break used to exit while loop
+ }
+ return res;
+}
+
+
nsresult
nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection)
{
diff --git a/editor/base/nsTextEditRules.h b/editor/base/nsTextEditRules.h
index db89294a7e2d..55a94df5aab0 100644
--- a/editor/base/nsTextEditRules.h
+++ b/editor/base/nsTextEditRules.h
@@ -182,6 +182,9 @@ protected:
const nsString &aValue,
nsIDOMSelection *aSelection);
+ /** replaces newllines with breaks, if needed. acts on doc portion in aRange */
+ nsresult ReplaceNewlines(nsIDOMRange *aRange);
+
/** creates a bogus text node if the document has no editable content */
nsresult CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection);
diff --git a/editor/libeditor/html/nsHTMLEditRules.cpp b/editor/libeditor/html/nsHTMLEditRules.cpp
index d1d35abed273..9a4e8ec74389 100644
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -98,12 +98,17 @@ nsHTMLEditRules::Init(nsHTMLEditor *aEditor, PRUint32 aFlags)
bodyNode = do_QueryInterface(bodyElem);
if (bodyNode)
{
+ // temporarily turn off rules sniffing
+ nsAutoLockRulesSniffing lockIt((nsTextEditRules*)this);
res = nsComponentManager::CreateInstance(kRangeCID, nsnull, NS_GET_IID(nsIDOMRange),
getter_AddRefs(mDocChangeRange));
if (NS_FAILED(res)) return res;
if (!mDocChangeRange) return NS_ERROR_NULL_POINTER;
mDocChangeRange->SelectNode(bodyNode);
- AdjustSpecialBreaks();
+ res = ReplaceNewlines(mDocChangeRange);
+ if (NS_FAILED(res)) return res;
+ res = AdjustSpecialBreaks();
+ if (NS_FAILED(res)) return res;
}
// turn on undo
mEditor->EnableUndo(PR_TRUE);
@@ -180,6 +185,13 @@ nsHTMLEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection)
res = AdjustWhitespace(selection);
if (NS_FAILED(res)) return res;
}
+ // replace newlines that are preformatted
+ if ((action == nsEditor::kOpInsertText) ||
+ (action == nsEditor::kOpInsertIMEText) ||
+ (action == nsEditor::kOpInsertNode))
+ {
+ res = ReplaceNewlines(mDocChangeRange);
+ }
// clean up any empty nodes in the selection
res = RemoveEmptyNodes();
if (NS_FAILED(res)) return res;
@@ -1577,8 +1589,27 @@ nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection,
PRBool outMakeEmpty;
res = ShouldMakeEmptyBlock(aSelection, alignType, &outMakeEmpty);
if (NS_FAILED(res)) return res;
- if (outMakeEmpty) return NS_OK;
-
+ if (outMakeEmpty)
+ {
+ PRInt32 offset;
+ nsCOMPtr brNode, parent, theDiv;
+ nsAutoString divType("div");
+ res = mEditor->GetStartNodeAndOffset(aSelection, &parent, &offset);
+ if (NS_FAILED(res)) return res;
+ res = mEditor->CreateNode(divType, parent, offset, getter_AddRefs(theDiv));
+ if (NS_FAILED(res)) return res;
+ // set up the alignment on the div
+ nsCOMPtr divElem = do_QueryInterface(theDiv);
+ nsAutoString attr("align");
+ res = mEditor->SetAttribute(divElem, attr, *alignType);
+ if (NS_FAILED(res)) return res;
+ *aHandled = PR_TRUE;
+ // put in a moz-br so that it won't get deleted
+ res = CreateMozBR(theDiv, 0, &brNode);
+ if (NS_FAILED(res)) return res;
+ res = aSelection->Collapse(theDiv, 0);
+ return res;
+ }
// convert the selection ranges into "promoted" selection ranges:
// this basically just expands the range to include the immediate
diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp
index 340c7486fd96..82a791e85162 100644
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -4269,6 +4269,38 @@ nsHTMLEditor::CanContainTag(nsIDOMNode* aParent, const nsString &aTag)
}
+NS_IMETHODIMP
+nsHTMLEditor::SelectEntireDocument(nsIDOMSelection *aSelection)
+{
+ nsresult res;
+ if (!aSelection || !mRules) { return NS_ERROR_NULL_POINTER; }
+
+ // get body node
+ nsCOMPtrbodyElement;
+ res = GetBodyElement(getter_AddRefs(bodyElement));
+ if (NS_FAILED(res)) return res;
+ nsCOMPtrbodyNode = do_QueryInterface(bodyElement);
+ if (!bodyNode) return NS_ERROR_FAILURE;
+
+ // is doc empty?
+ PRBool bDocIsEmpty;
+ res = mRules->DocumentIsEmpty(&bDocIsEmpty);
+ if (NS_FAILED(res)) return res;
+
+ if (bDocIsEmpty)
+ {
+ // if its empty dont select entire doc - that would select the bogus node
+ return aSelection->Collapse(bodyNode, 0);
+ }
+ else
+ {
+ return nsEditor::SelectEntireDocument(aSelection);
+ }
+ return res;
+}
+
+
+
#ifdef XP_MAC
#pragma mark -
#pragma mark --- Random methods ---
diff --git a/editor/libeditor/html/nsHTMLEditor.h b/editor/libeditor/html/nsHTMLEditor.h
index da9f8d795227..feeb95bab509 100644
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -241,11 +241,6 @@ public:
NS_IMETHOD DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed);
- /* ------------ nsICSSLoaderObserver -------------- */
- NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet*aSheet, PRBool aNotify);
-
- /* ------------ nsEditor overrides ---------------- */
-
/** All editor operations which alter the doc should be prefaced
* with a call to StartOperation, naming the action and direction */
NS_IMETHOD StartOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
@@ -257,6 +252,12 @@ public:
/** returns PR_TRUE if aParent can contain a child of type aTag */
PRBool CanContainTag(nsIDOMNode* aParent, const nsString &aTag);
+ /** make the given selection span the entire document */
+ NS_IMETHOD SelectEntireDocument(nsIDOMSelection *aSelection);
+
+ /* ------------ nsICSSLoaderObserver -------------- */
+ NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet*aSheet, PRBool aNotify);
+
/* ------------ Utility Routines, not part of public API -------------- */
NS_IMETHOD GetBodyStyleContext(nsIStyleContext** aStyleContext);
diff --git a/editor/libeditor/text/nsTextEditRules.cpp b/editor/libeditor/text/nsTextEditRules.cpp
index 07f281ab1e03..9360d8034f67 100644
--- a/editor/libeditor/text/nsTextEditRules.cpp
+++ b/editor/libeditor/text/nsTextEditRules.cpp
@@ -37,8 +37,10 @@
#include "nsLayoutCID.h"
#include "nsIEditProperty.h"
#include "nsEditorUtils.h"
+#include "EditTxn.h"
-static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
+static NS_DEFINE_CID(kContentIteratorCID, NS_CONTENTITERATOR_CID);
+static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
#define CANCEL_OPERATION_IF_READONLY_OR_DISABLED \
@@ -82,6 +84,24 @@ nsTextEditRules::Init(nsHTMLEditor *aEditor, PRUint32 aFlags)
mEditor->GetSelection(getter_AddRefs(selection));
NS_ASSERTION(selection, "editor cannot get selection");
nsresult res = CreateBogusNodeIfNeeded(selection); // this method handles null selection, which should never happen anyway
+
+ // create a range that is the entire body contents
+ if (NS_FAILED(res)) return res;
+ nsCOMPtr bodyElement;
+ res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
+ if (NS_FAILED(res)) return res;
+ if (!bodyElement) return NS_ERROR_NULL_POINTER;
+ nsCOMPtrbodyNode = do_QueryInterface(bodyElement);
+ if (!bodyNode) return NS_ERROR_FAILURE;
+ nsCOMPtr wholeDoc;
+ res = nsComponentManager::CreateInstance(kRangeCID, nsnull, NS_GET_IID(nsIDOMRange),
+ getter_AddRefs(wholeDoc));
+ if (NS_FAILED(res)) return res;
+ res = wholeDoc->SelectNode(bodyNode);
+ if (NS_FAILED(res)) return res;
+
+ // replace newlines in that range with breaks
+ res = ReplaceNewlines(wholeDoc);
return res;
}
@@ -1264,6 +1284,101 @@ nsTextEditRules::DidOutputText(nsIDOMSelection *aSelection, nsresult aResult)
}
+nsresult
+nsTextEditRules::ReplaceNewlines(nsIDOMRange *aRange)
+{
+ if (!aRange) return NS_ERROR_NULL_POINTER;
+
+ // convert any newlines in editable, preformatted text nodes
+ // into normal breaks. this is because layout wont give us a place
+ // to put the cursor on empty lines otherwise.
+
+ nsCOMPtr iter;
+ nsCOMPtr isupports;
+ PRUint32 nodeCount,j;
+ nsCOMPtr arrayOfNodes;
+
+ // make an isupportsArray to hold a list of nodes
+ nsresult res = NS_NewISupportsArray(getter_AddRefs(arrayOfNodes));
+ if (NS_FAILED(res)) return res;
+
+ // need an iterator
+ res = nsComponentManager::CreateInstance(kContentIteratorCID,
+ nsnull,
+ NS_GET_IID(nsIContentIterator),
+ getter_AddRefs(iter));
+ if (NS_FAILED(res)) return res;
+ res = iter->Init(aRange);
+ if (NS_FAILED(res)) return res;
+
+ // gather up a list of editable preformatted text nodes
+ while (NS_ENUMERATOR_FALSE == iter->IsDone())
+ {
+ nsCOMPtr node;
+ nsCOMPtr content;
+ res = iter->CurrentNode(getter_AddRefs(content));
+ if (NS_FAILED(res)) return res;
+ node = do_QueryInterface(content);
+ if (!node) return NS_ERROR_FAILURE;
+
+ if (mEditor->IsTextNode(node) && mEditor->IsEditable(node))
+ {
+ PRBool isPRE;
+ res = mEditor->IsPreformatted(node, &isPRE);
+ if (NS_FAILED(res)) return res;
+ if (isPRE)
+ {
+ isupports = do_QueryInterface(node);
+ arrayOfNodes->AppendElement(isupports);
+ }
+ }
+ res = iter->Next();
+ if (NS_FAILED(res)) return res;
+ }
+
+ // replace newlines with breaks. have to do this left to right,
+ // since inserting the break can split the text node, and the
+ // original node becomes the righthand node.
+ char newlineChar[] = {'\n',0};
+ res = arrayOfNodes->Count(&nodeCount);
+ if (NS_FAILED(res)) return res;
+ for (j = 0; j < nodeCount; j++)
+ {
+ isupports = (dont_AddRef)(arrayOfNodes->ElementAt(0));
+ nsCOMPtr brNode, theNode( do_QueryInterface(isupports) );
+ nsCOMPtr textNode( do_QueryInterface(theNode) );
+ arrayOfNodes->RemoveElementAt(0);
+ // find the newline
+ PRInt32 offset;
+ nsAutoString tempString;
+ do
+ {
+ textNode->GetData(tempString);
+ offset = tempString.FindCharInSet(newlineChar);
+ if (offset == -1) break; // done with this node
+
+ // delete the newline
+ EditTxn *txn;
+ // note 1: we are not telling edit listeners about these because they don't care
+ // note 2: we are not wrapping these in a placeholder because we know they already are,
+ // or, failing that, undo is disabled
+ res = mEditor->CreateTxnForDeleteText(textNode, offset, 1, (DeleteTextTxn**)&txn);
+ if (NS_FAILED(res)) return res;
+ if (!txn) return NS_ERROR_OUT_OF_MEMORY;
+ res = mEditor->Do(txn);
+ if (NS_FAILED(res)) return res;
+ // The transaction system (if any) has taken ownwership of txn
+ NS_IF_RELEASE(txn);
+
+ // insert a break
+ res = mEditor->CreateBR(textNode, offset, &brNode);
+ if (NS_FAILED(res)) return res;
+ } while (1); // break used to exit while loop
+ }
+ return res;
+}
+
+
nsresult
nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection)
{
diff --git a/editor/libeditor/text/nsTextEditRules.h b/editor/libeditor/text/nsTextEditRules.h
index db89294a7e2d..55a94df5aab0 100644
--- a/editor/libeditor/text/nsTextEditRules.h
+++ b/editor/libeditor/text/nsTextEditRules.h
@@ -182,6 +182,9 @@ protected:
const nsString &aValue,
nsIDOMSelection *aSelection);
+ /** replaces newllines with breaks, if needed. acts on doc portion in aRange */
+ nsresult ReplaceNewlines(nsIDOMRange *aRange);
+
/** creates a bogus text node if the document has no editable content */
nsresult CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection);