mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
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:
parent
fafc8f28c6
commit
4c382bfcd4
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user