b=68767 extra blank space added when block level element (hr, table) is inserted at the end of a line, between two lines

r=jfrancis sr=kin
This commit is contained in:
kaie%netscape.com 2003-04-15 20:53:15 +00:00
parent fafc8f28c6
commit 4c382bfcd4
3 changed files with 85 additions and 1 deletions

View File

@ -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.

View File

@ -1952,6 +1952,78 @@ nsHTMLEditor::RebuildDocumentFromSource(const nsAString& aSourceString)
return BeginningOfDocument();
}
void
nsHTMLEditor::NormalizeEOLInsertPosition(nsIDOMNode *firstNodeToInsert,
nsCOMPtr<nsIDOMNode> *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 <br>,
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 <br> would not insert the <br>
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<nsIDOMNode> nextVisNode;
nsCOMPtr<nsIDOMNode> 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<nsIDOMNode> 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

View File

@ -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<nsIDOMNode> *insertParentNode,
PRInt32 *insertOffset);
/* small utility routine to test the eEditorReadonly bit */
PRBool IsModifiable();