diff --git a/editor/base/nsHTMLEditRules.cpp b/editor/base/nsHTMLEditRules.cpp
index 767f8e61e35a..a5cc4456b884 100644
--- a/editor/base/nsHTMLEditRules.cpp
+++ b/editor/base/nsHTMLEditRules.cpp
@@ -1261,8 +1261,21 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
// block parents the same?
if (mHTMLEditor->HasSameBlockNodeParent(startNode, priorNode))
{
+ // is prior node a text node?
+ if ( mHTMLEditor->IsTextNode(priorNode) )
+ {
+ // delete last character
+ PRUint32 offset;
+ nsCOMPtrnodeAsText;
+ nodeAsText = do_QueryInterface(priorNode);
+ nodeAsText->GetLength((PRUint32*)&offset);
+ res = aSelection->Collapse(priorNode,offset);
+ // just return without setting handled to true.
+ // default code will take care of actual deletion
+ return res;
+ }
// is prior node not a container? (ie, a br, hr, image...)
- if (!mHTMLEditor->IsContainer(priorNode)) // MOOSE: anchors not handled
+ else if (!mHTMLEditor->IsContainer(priorNode)) // MOOSE: anchors not handled
{
// delete the break, and join like nodes if appropriate
res = mHTMLEditor->DeleteNode(priorNode);
@@ -1289,19 +1302,6 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
}
return res;
}
- // is prior node a text node?
- else if ( mHTMLEditor->IsTextNode(priorNode) )
- {
- // delete last character
- PRUint32 offset;
- nsCOMPtrnodeAsText;
- nodeAsText = do_QueryInterface(priorNode);
- nodeAsText->GetLength((PRUint32*)&offset);
- res = aSelection->Collapse(priorNode,offset);
- // just return without setting handled to true.
- // default code will take care of actual deletion
- return res;
- }
else if ( mHTMLEditor->IsInlineNode(priorNode) )
{
// remember where we are
@@ -1374,8 +1374,19 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
// block parents the same?
if (mHTMLEditor->HasSameBlockNodeParent(startNode, nextNode))
{
+ // is next node a text node?
+ if ( mHTMLEditor->IsTextNode(nextNode) )
+ {
+ // delete first character
+ nsCOMPtrnodeAsText;
+ nodeAsText = do_QueryInterface(nextNode);
+ res = aSelection->Collapse(nextNode,0);
+ // just return without setting handled to true.
+ // default code will take care of actual deletion
+ return res;
+ }
// is next node not a container? (ie, a br, hr, image...)
- if (!mHTMLEditor->IsContainer(nextNode)) // MOOSE: anchors not handled
+ else if (!mHTMLEditor->IsContainer(nextNode)) // MOOSE: anchors not handled
{
// delete the break, and join like nodes if appropriate
res = mHTMLEditor->DeleteNode(nextNode);
@@ -1402,17 +1413,6 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
}
return res;
}
- // is next node a text node?
- else if ( mHTMLEditor->IsTextNode(nextNode) )
- {
- // delete first character
- nsCOMPtrnodeAsText;
- nodeAsText = do_QueryInterface(nextNode);
- res = aSelection->Collapse(nextNode,0);
- // just return without setting handled to true.
- // default code will take care of actual deletion
- return res;
- }
else if ( mHTMLEditor->IsInlineNode(nextNode) )
{
PRInt32 offset;
@@ -2590,7 +2590,7 @@ nsHTMLEditRules::CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocume
if (!mHTMLEditor->mTypeInState) return NS_ERROR_NULL_POINTER;
PRBool weDidSometing = PR_FALSE;
- nsCOMPtr node;
+ nsCOMPtr node, tmp;
PRInt32 offset;
nsresult res = mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(node), &offset);
if (NS_FAILED(res)) return res;
@@ -2600,13 +2600,30 @@ nsHTMLEditRules::CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocume
mHTMLEditor->mTypeInState->TakeClearProperty(&item);
while (item)
{
- nsCOMPtr leftNode, rightNode, secondSplitParent, newSelParent;
+ nsCOMPtr leftNode, rightNode, secondSplitParent, newSelParent, savedBR;
res = mHTMLEditor->SplitStyleAbovePoint(address_of(node), &offset, item->tag, &item->attr, address_of(leftNode), address_of(rightNode));
if (NS_FAILED(res)) return res;
+ PRBool bIsEmptyNode;
+ mHTMLEditor->IsEmptyNode(leftNode, &bIsEmptyNode, PR_FALSE, PR_TRUE);
+ if (bIsEmptyNode)
+ {
+ // delete leftNode if it became empty
+ res = mEditor->DeleteNode(leftNode);
+ if (NS_FAILED(res)) return res;
+ }
+
if (rightNode)
{
res = mHTMLEditor->GetLeftmostChild(rightNode, getter_AddRefs(secondSplitParent));
if (NS_FAILED(res)) return res;
+ // don't try to split br's...
+ // note: probably should only split containers, but being more conservative in changes for now.
+ if (nsHTMLEditUtils::IsBreak(secondSplitParent))
+ {
+ savedBR = secondSplitParent;
+ savedBR->GetParentNode(getter_AddRefs(tmp));
+ secondSplitParent = tmp;
+ }
offset = 0;
res = mHTMLEditor->SplitStyleAbovePoint(address_of(secondSplitParent), &offset, item->tag, &(item->attr), address_of(leftNode), address_of(rightNode));
if (NS_FAILED(res)) return res;
@@ -2614,6 +2631,20 @@ nsHTMLEditRules::CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocume
if (!leftNode) return NS_ERROR_FAILURE;
res = mHTMLEditor->GetLeftmostChild(leftNode, getter_AddRefs(newSelParent));
if (NS_FAILED(res)) return res;
+ // if rightNode starts with a br, suck it out of right node and into leftNode.
+ // This is so we you don't revert back to the previous style if you happen to click at the end of a line.
+ if (savedBR)
+ {
+ res = mEditor->MoveNode(savedBR, newSelParent, 0);
+ if (NS_FAILED(res)) return res;
+ }
+ mHTMLEditor->IsEmptyNode(rightNode, &bIsEmptyNode, PR_FALSE, PR_TRUE);
+ if (bIsEmptyNode)
+ {
+ // delete rightNode if it became empty
+ res = mEditor->DeleteNode(rightNode);
+ if (NS_FAILED(res)) return res;
+ }
// register a rangeStore item that points at the new heirarchy.
// This is so we can know where to put the selection after we call
// RemoveStyleInside(). RemoveStyleInside() could remove any and all of those nodes,
@@ -2655,7 +2686,6 @@ nsHTMLEditRules::CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocume
// if we are in a text node, split it
res = mHTMLEditor->SplitNodeDeep(node, node, offset, &offset);
if (NS_FAILED(res)) return res;
- nsCOMPtr tmp;
node->GetParentNode(getter_AddRefs(tmp));
node = tmp;
}
diff --git a/editor/libeditor/html/nsHTMLEditRules.cpp b/editor/libeditor/html/nsHTMLEditRules.cpp
index 767f8e61e35a..a5cc4456b884 100644
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -1261,8 +1261,21 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
// block parents the same?
if (mHTMLEditor->HasSameBlockNodeParent(startNode, priorNode))
{
+ // is prior node a text node?
+ if ( mHTMLEditor->IsTextNode(priorNode) )
+ {
+ // delete last character
+ PRUint32 offset;
+ nsCOMPtrnodeAsText;
+ nodeAsText = do_QueryInterface(priorNode);
+ nodeAsText->GetLength((PRUint32*)&offset);
+ res = aSelection->Collapse(priorNode,offset);
+ // just return without setting handled to true.
+ // default code will take care of actual deletion
+ return res;
+ }
// is prior node not a container? (ie, a br, hr, image...)
- if (!mHTMLEditor->IsContainer(priorNode)) // MOOSE: anchors not handled
+ else if (!mHTMLEditor->IsContainer(priorNode)) // MOOSE: anchors not handled
{
// delete the break, and join like nodes if appropriate
res = mHTMLEditor->DeleteNode(priorNode);
@@ -1289,19 +1302,6 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
}
return res;
}
- // is prior node a text node?
- else if ( mHTMLEditor->IsTextNode(priorNode) )
- {
- // delete last character
- PRUint32 offset;
- nsCOMPtrnodeAsText;
- nodeAsText = do_QueryInterface(priorNode);
- nodeAsText->GetLength((PRUint32*)&offset);
- res = aSelection->Collapse(priorNode,offset);
- // just return without setting handled to true.
- // default code will take care of actual deletion
- return res;
- }
else if ( mHTMLEditor->IsInlineNode(priorNode) )
{
// remember where we are
@@ -1374,8 +1374,19 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
// block parents the same?
if (mHTMLEditor->HasSameBlockNodeParent(startNode, nextNode))
{
+ // is next node a text node?
+ if ( mHTMLEditor->IsTextNode(nextNode) )
+ {
+ // delete first character
+ nsCOMPtrnodeAsText;
+ nodeAsText = do_QueryInterface(nextNode);
+ res = aSelection->Collapse(nextNode,0);
+ // just return without setting handled to true.
+ // default code will take care of actual deletion
+ return res;
+ }
// is next node not a container? (ie, a br, hr, image...)
- if (!mHTMLEditor->IsContainer(nextNode)) // MOOSE: anchors not handled
+ else if (!mHTMLEditor->IsContainer(nextNode)) // MOOSE: anchors not handled
{
// delete the break, and join like nodes if appropriate
res = mHTMLEditor->DeleteNode(nextNode);
@@ -1402,17 +1413,6 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
}
return res;
}
- // is next node a text node?
- else if ( mHTMLEditor->IsTextNode(nextNode) )
- {
- // delete first character
- nsCOMPtrnodeAsText;
- nodeAsText = do_QueryInterface(nextNode);
- res = aSelection->Collapse(nextNode,0);
- // just return without setting handled to true.
- // default code will take care of actual deletion
- return res;
- }
else if ( mHTMLEditor->IsInlineNode(nextNode) )
{
PRInt32 offset;
@@ -2590,7 +2590,7 @@ nsHTMLEditRules::CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocume
if (!mHTMLEditor->mTypeInState) return NS_ERROR_NULL_POINTER;
PRBool weDidSometing = PR_FALSE;
- nsCOMPtr node;
+ nsCOMPtr node, tmp;
PRInt32 offset;
nsresult res = mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(node), &offset);
if (NS_FAILED(res)) return res;
@@ -2600,13 +2600,30 @@ nsHTMLEditRules::CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocume
mHTMLEditor->mTypeInState->TakeClearProperty(&item);
while (item)
{
- nsCOMPtr leftNode, rightNode, secondSplitParent, newSelParent;
+ nsCOMPtr leftNode, rightNode, secondSplitParent, newSelParent, savedBR;
res = mHTMLEditor->SplitStyleAbovePoint(address_of(node), &offset, item->tag, &item->attr, address_of(leftNode), address_of(rightNode));
if (NS_FAILED(res)) return res;
+ PRBool bIsEmptyNode;
+ mHTMLEditor->IsEmptyNode(leftNode, &bIsEmptyNode, PR_FALSE, PR_TRUE);
+ if (bIsEmptyNode)
+ {
+ // delete leftNode if it became empty
+ res = mEditor->DeleteNode(leftNode);
+ if (NS_FAILED(res)) return res;
+ }
+
if (rightNode)
{
res = mHTMLEditor->GetLeftmostChild(rightNode, getter_AddRefs(secondSplitParent));
if (NS_FAILED(res)) return res;
+ // don't try to split br's...
+ // note: probably should only split containers, but being more conservative in changes for now.
+ if (nsHTMLEditUtils::IsBreak(secondSplitParent))
+ {
+ savedBR = secondSplitParent;
+ savedBR->GetParentNode(getter_AddRefs(tmp));
+ secondSplitParent = tmp;
+ }
offset = 0;
res = mHTMLEditor->SplitStyleAbovePoint(address_of(secondSplitParent), &offset, item->tag, &(item->attr), address_of(leftNode), address_of(rightNode));
if (NS_FAILED(res)) return res;
@@ -2614,6 +2631,20 @@ nsHTMLEditRules::CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocume
if (!leftNode) return NS_ERROR_FAILURE;
res = mHTMLEditor->GetLeftmostChild(leftNode, getter_AddRefs(newSelParent));
if (NS_FAILED(res)) return res;
+ // if rightNode starts with a br, suck it out of right node and into leftNode.
+ // This is so we you don't revert back to the previous style if you happen to click at the end of a line.
+ if (savedBR)
+ {
+ res = mEditor->MoveNode(savedBR, newSelParent, 0);
+ if (NS_FAILED(res)) return res;
+ }
+ mHTMLEditor->IsEmptyNode(rightNode, &bIsEmptyNode, PR_FALSE, PR_TRUE);
+ if (bIsEmptyNode)
+ {
+ // delete rightNode if it became empty
+ res = mEditor->DeleteNode(rightNode);
+ if (NS_FAILED(res)) return res;
+ }
// register a rangeStore item that points at the new heirarchy.
// This is so we can know where to put the selection after we call
// RemoveStyleInside(). RemoveStyleInside() could remove any and all of those nodes,
@@ -2655,7 +2686,6 @@ nsHTMLEditRules::CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocume
// if we are in a text node, split it
res = mHTMLEditor->SplitNodeDeep(node, node, offset, &offset);
if (NS_FAILED(res)) return res;
- nsCOMPtr tmp;
node->GetParentNode(getter_AddRefs(tmp));
node = tmp;
}