diff --git a/editor/libeditor/html/nsHTMLDataTransfer.cpp b/editor/libeditor/html/nsHTMLDataTransfer.cpp
index 5d1e57f18cd7..11b8433b72e2 100644
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -434,7 +434,10 @@ nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAString & aInputString,
res = GetStartNodeAndOffset(selection, address_of(parentNode), &offsetOfNewNode);
if (!parentNode) res = NS_ERROR_FAILURE;
if (NS_FAILED(res)) return res;
-
+
+ // Adjust position based on the first node we are going to insert.
+ NormalizeEOLInsertPosition(nodeList[0], address_of(parentNode), &offsetOfNewNode);
+
// if there are any invisible br's after our insertion point, remove them.
// this is because if there is a br at end of what we paste, it will make
// the invisible br visible.
diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp
index 054a54365a1a..d12f8bde7d31 100644
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -1952,6 +1952,78 @@ nsHTMLEditor::RebuildDocumentFromSource(const nsAString& aSourceString)
return BeginningOfDocument();
}
+void
+nsHTMLEditor::NormalizeEOLInsertPosition(nsIDOMNode *firstNodeToInsert,
+ nsCOMPtr *insertParentNode,
+ PRInt32 *insertOffset)
+{
+ /*
+ This function will either correct the position passed in,
+ or leave the position unchanged.
+
+ When the (first) item to insert is a block level element,
+ and our insertion position is after the last visible item in a line,
+ i.e. the insertion position is just before a visible line break
,
+ we want to skip to the position just after the line break (see bug 68767)
+
+ However, our logic to detect whether we should skip or not
+ needs to be more clever.
+ We must not skip when the caret appears to be positioned at the beginning
+ of a block, in that case skipping the
would not insert the
+ at the caret position, but after the current empty line.
+
+ So we have several cases to test:
+
+ 1) We only ever want to skip, if the next visible thing after the current position is a break
+
+ 2) We do not want to skip if there is no previous visible thing at all
+ That is detected if the call to PriorVisibleNode gives us an offset of zero.
+ Because PriorVisibleNode always positions after the prior node, we would
+ see an offset > 0, if there were a prior node.
+
+ 3) We do not want to skip, if both the next and the previous visible things are breaks.
+
+ 4) We do not want to skip if the previous visible thing is in a different block
+ than the insertion position.
+ */
+
+ if (!IsBlockNode(firstNodeToInsert))
+ return;
+
+ nsWSRunObject wsObj(this, *insertParentNode, *insertOffset);
+ nsCOMPtr nextVisNode;
+ nsCOMPtr prevVisNode;
+ PRInt32 nextVisOffset=0;
+ PRInt16 nextVisType=0;
+ PRInt32 prevVisOffset=0;
+ PRInt16 prevVisType=0;
+
+ wsObj.NextVisibleNode(*insertParentNode, *insertOffset, address_of(nextVisNode), &nextVisOffset, &nextVisType);
+ if (!nextVisNode)
+ return;
+
+ if (! (nextVisType & nsWSRunObject::eBreak))
+ return;
+
+ wsObj.PriorVisibleNode(*insertParentNode, *insertOffset, address_of(prevVisNode), &prevVisOffset, &prevVisType);
+ if (!prevVisNode)
+ return;
+
+ if (prevVisType & nsWSRunObject::eBreak)
+ return;
+
+ if (prevVisType & nsWSRunObject::eThisBlock)
+ return;
+
+ nsCOMPtr brNode;
+ PRInt32 brOffset=0;
+
+ GetNodeLocation(nextVisNode, address_of(brNode), &brOffset);
+
+ *insertParentNode = brNode;
+ *insertOffset = brOffset + 1;
+}
+
NS_IMETHODIMP
nsHTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, PRBool aDeleteSelection)
{
@@ -2020,6 +2092,9 @@ nsHTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, PRBool aDeleteSe
}
#endif
+ // Adjust position based on the node we are going to insert.
+ NormalizeEOLInsertPosition(node, address_of(parentSelectedNode), &offsetForInsert);
+
res = InsertNodeAtPoint(node, address_of(parentSelectedNode), &offsetForInsert, PR_FALSE);
NS_ENSURE_SUCCESS(res, res);
// Set caret after element, but check for special case
diff --git a/editor/libeditor/html/nsHTMLEditor.h b/editor/libeditor/html/nsHTMLEditor.h
index 8ddc3d9c88df..820b153a00b6 100644
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -730,6 +730,12 @@ protected:
/* small utility routine to test if a break node is visible to user */
PRBool IsVisBreak(nsIDOMNode *aNode);
+ /* utility routine to possibly adjust the insertion position when
+ inserting a block level element */
+ void NormalizeEOLInsertPosition(nsIDOMNode *firstNodeToInsert,
+ nsCOMPtr *insertParentNode,
+ PRInt32 *insertOffset);
+
/* small utility routine to test the eEditorReadonly bit */
PRBool IsModifiable();