checkpointing some deletion work

This commit is contained in:
jfrancis%netscape.com 1999-08-31 13:55:18 +00:00
parent 6d8c1b766a
commit 743156ab31
6 changed files with 426 additions and 64 deletions

View File

@ -2417,6 +2417,85 @@ nsEditor::IntermediateNodesAreInline(nsIDOMRange *aRange,
}
nsresult
nsEditor::GetPriorNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
PRBool aEditableNode,
nsIDOMNode **aResultNode)
{
// just another version of GetPriorNode that takes a {parent, offset}
// instead of a node
nsresult result = NS_OK;
if (!aParentNode || !aResultNode) { return NS_ERROR_NULL_POINTER; }
// if we are at beginning of node than just look before it
if (!aOffset)
{
return GetPriorNode(aParentNode, aEditableNode, aResultNode);
}
else
{
// else look before the child at 'aOffset'
nsCOMPtr<nsIDOMNode> child = GetChildAt(aParentNode, aOffset);
if (child)
return GetPriorNode(child, aEditableNode, aResultNode);
// unless there isn't one, in which case we are at the end of the node
// and want the deep-right child.
else
{
result = GetRightmostChild(*aResultNode, aResultNode);
if (NS_FAILED(result)) return result;
if (!aEditableNode) return result;
if (IsEditable(*aResultNode)) return result;
else
{
// restart the search from the non-editable node we just found
nsCOMPtr<nsIDOMNode> notEditableNode = do_QueryInterface(*aResultNode);
return GetPriorNode(notEditableNode, aEditableNode, aResultNode);
}
}
}
}
nsresult
nsEditor::GetNextNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
PRBool aEditableNode,
nsIDOMNode **aResultNode)
{
// just another version of GetNextNode that takes a {parent, offset}
// instead of a node
nsresult result = NS_OK;
if (!aParentNode || !aResultNode) { return NS_ERROR_NULL_POINTER; }
// look at the child at 'aOffset'
nsCOMPtr<nsIDOMNode> child = GetChildAt(aParentNode, aOffset);
if (child)
{
result = GetLeftmostChild(*aResultNode, aResultNode);
if (NS_FAILED(result)) return result;
if (!aEditableNode) return result;
if (IsEditable(*aResultNode)) return result;
else
{
// restart the search from the non-editable node we just found
nsCOMPtr<nsIDOMNode> notEditableNode = do_QueryInterface(*aResultNode);
return GetNextNode(notEditableNode, aEditableNode, aResultNode);
}
}
// unless there isn't one, in which case we are at the end of the node
// and want the next one.
else
{
return GetNextNode(aParentNode, aEditableNode, aResultNode);
}
}
nsresult
nsEditor::GetPriorNode(nsIDOMNode *aCurrentNode,
PRBool aEditableNode,
@ -3525,7 +3604,7 @@ nsEditor::SplitNodeDeep(nsIDOMNode *aNode,
while (nodeToSplit)
{
// need to insert rules code call here to do thingsa like
// need to insert rules code call here to do things like
// not split a list if you are after the last <li> or before the first, etc.
// for now we just have some smarts about unneccessarily splitting
// textnodes, which should be universal enough to put straight in
@ -3577,18 +3656,18 @@ nsEditor::SplitNodeDeep(nsIDOMNode *aNode,
nsresult
nsEditor::JoinNodeDeep(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
nsIDOMSelection *aSelection)
nsCOMPtr<nsIDOMNode> *aOutJoinNode,
PRInt32 *outOffset)
{
if (!aLeftNode || !aRightNode) return NS_ERROR_NULL_POINTER;
if (!aLeftNode || !aRightNode || !aOutJoinNode || !outOffset) return NS_ERROR_NULL_POINTER;
// while the rightmost children and their descendants of the left node
// match the leftmost children and their descendants of the right node
// join them up. Can you say that three times fast?
nsCOMPtr<nsIDOMNode> leftNodeToJoin = do_QueryInterface(aLeftNode);
nsCOMPtr<nsIDOMNode> rightNodeToJoin = do_QueryInterface(aRightNode);
nsCOMPtr<nsIDOMNode> parentNode;
PRInt32 offset;
nsCOMPtr<nsIDOMNode> parentNode,tmp;
nsresult res = NS_OK;
rightNodeToJoin->GetParentNode(getter_AddRefs(parentNode));
@ -3596,23 +3675,51 @@ nsEditor::JoinNodeDeep(nsIDOMNode *aLeftNode,
while (leftNodeToJoin && rightNodeToJoin && parentNode &&
NodesSameType(leftNodeToJoin, rightNodeToJoin))
{
res = JoinNodes(leftNodeToJoin,rightNodeToJoin,parentNode);
// adjust out params
PRUint32 length;
if (IsTextNode(leftNodeToJoin))
{
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
nodeAsText = do_QueryInterface(leftNodeToJoin);
nodeAsText->GetLength(&length);
}
else
{
res = GetLengthOfDOMNode(leftNodeToJoin, length);
if (NS_FAILED(res)) return res;
}
*aOutJoinNode = rightNodeToJoin;
*outOffset = length;
// do the join
res = JoinNodes(leftNodeToJoin, rightNodeToJoin, parentNode);
if (NS_FAILED(res)) return res;
res = GetStartNodeAndOffset(aSelection, &parentNode, &offset);
if (NS_FAILED(res)) return res;
if (offset == 0) // no new left node; we're done joining
return NS_OK;
if (IsTextNode(parentNode)) // we've joined all the way down to text nodes, we're done!
return NS_OK;
else
{
// get new left and right nodes, and begin anew
leftNodeToJoin = GetChildAt(parentNode, offset-1);
rightNodeToJoin = GetChildAt(parentNode, offset);
parentNode = rightNodeToJoin;
leftNodeToJoin = GetChildAt(parentNode, length-1);
rightNodeToJoin = GetChildAt(parentNode, length);
// skip over non-editable nodes
while (leftNodeToJoin && !IsEditable(leftNodeToJoin))
{
leftNodeToJoin->GetPreviousSibling(getter_AddRefs(tmp));
leftNodeToJoin = tmp;
}
if (!leftNodeToJoin) break;
while (rightNodeToJoin && !IsEditable(rightNodeToJoin))
{
rightNodeToJoin->GetNextSibling(getter_AddRefs(tmp));
rightNodeToJoin = tmp;
}
if (!rightNodeToJoin) break;
}
}
@ -4021,7 +4128,6 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
// determine if the insertion point is at the beginning, middle, or end of the node
nsCOMPtr<nsIDOMCharacterData> nodeAsText;
nsCOMPtr<nsIDOMNode> selectedNode;
nodeAsText = do_QueryInterface(node);
if (nodeAsText)
@ -4040,7 +4146,6 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
if ((NS_SUCCEEDED(result)) && childList)
{
childList->GetLength(&count);
childList->Item(offset, getter_AddRefs(selectedNode));
}
isFirst = PRBool(0==offset);
isLast = PRBool((count-1)==(PRUint32)offset);
@ -4140,9 +4245,22 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
else
{ // we're deleting a node
DeleteElementTxn *txn;
result = CreateTxnForDeleteElement(selectedNode, &txn);
if (NS_SUCCEEDED(result)) {
aTxn->AppendChild(txn);
nsCOMPtr<nsIDOMNode> selectedNode;
if (eDeletePrevious==aAction)
{
result = GetPriorNode(node, offset, PR_TRUE, getter_AddRefs(selectedNode));
}
else if (eDeleteNext==aAction)
{
result = GetNextNode(node, offset, PR_TRUE, getter_AddRefs(selectedNode));
}
if (NS_SUCCEEDED(result) && selectedNode)
{
result = CreateTxnForDeleteElement(selectedNode, &txn);
if (NS_SUCCEEDED(result))
{
aTxn->AppendChild(txn);
}
}
}
}

View File

@ -482,6 +482,12 @@ public:
PRBool aEditableNode,
nsIDOMNode **aResultNode);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetPriorNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
PRBool aEditableNode,
nsIDOMNode **aResultNode);
/** get the node immediately after to aCurrentNode
* @param aCurrentNode the node from which we start the search
* @param aEditableNode if PR_TRUE, only return an editable node
@ -493,6 +499,12 @@ public:
PRBool aEditableNode,
nsIDOMNode **aResultNode);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetNextNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
PRBool aEditableNode,
nsIDOMNode **aResultNode);
/** Get the rightmost child of aCurrentNode, and return it in aResultNode
* aResultNode is set to nsnull if aCurrentNode has no children.
*/
@ -565,7 +577,9 @@ public:
nsresult IsPrevCharWhitespace(nsIDOMNode *aParentNode, PRInt32 aOffset, PRBool *aResult);
nsresult SplitNodeDeep(nsIDOMNode *aNode, nsIDOMNode *aSplitPointParent, PRInt32 aSplitPointOffset, PRInt32 *outOffset);
nsresult JoinNodeDeep(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMSelection *aSelection);
nsresult JoinNodeDeep(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsCOMPtr<nsIDOMNode> *aOutJoinNode, PRInt32 *outOffset);
nsresult GetString(const nsString& name, nsString& value);
nsresult BeginUpdateViewBatch(void);
nsresult EndUpdateViewBatch(void);

View File

@ -306,8 +306,8 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
res = aSelection->GetIsCollapsed(&bCollapsed);
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMNode> node;
PRInt32 offset;
nsCOMPtr<nsIDOMNode> node, selNode;
PRInt32 offset, selOffset;
res = mEditor->GetStartNodeAndOffset(aSelection, &node, &offset);
if (NS_FAILED(res)) return res;
@ -356,7 +356,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
{
// join para's, insert break
*aCancel = PR_TRUE;
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
if (NS_FAILED(res)) return res;
res = mEditor->InsertBreak();
return res;
@ -365,7 +368,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
{
// join blocks
*aCancel = PR_TRUE;
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
return res;
}
}
@ -409,7 +415,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
{
// join para's, insert break
*aCancel = PR_TRUE;
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
if (NS_FAILED(res)) return res;
res = mEditor->InsertBreak();
return res;
@ -418,7 +427,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
{
// join blocks
*aCancel = PR_TRUE;
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
return res;
}
}
@ -428,7 +440,41 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
}
}
// else do default
// else not in text node; we need to find right place to act on
else
{
// XXX add (aAction == nsIEditor::eDeleteNext) case!!
nsCOMPtr<nsIDOMNode> nodeToBackspace;
res = mEditor->GetPriorNode(node, offset, PR_TRUE, getter_AddRefs(nodeToBackspace));
if (NS_FAILED(res)) return res;
if (!nodeToBackspace) return NS_ERROR_NULL_POINTER;
// if this node is text node, adjust selection
if (nsEditor::IsTextNode(nodeToBackspace))
{
PRUint32 len;
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
nodeAsText = do_QueryInterface(nodeToBackspace);
nodeAsText->GetLength(&len);
res = aSelection->Collapse(nodeToBackspace,len);
return res;
}
else
{
// editable leaf node is not text; delete it.
// that's the default behavior
res = nsEditor::GetNodeLocation(nodeToBackspace, &node, &offset);
if (NS_FAILED(res)) return res;
// adjust selection to be right after it, for benefit of
// deletion code
res = aSelection->Collapse(node, offset+1);
return res;
}
}
return NS_OK;
}
@ -491,10 +537,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
res = mEditor->DeleteSelectionImpl(aAction);
if (NS_FAILED(res)) return res;
// then join para's, insert break
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
//res = mEditor->InsertBreak();
// uhh, no, we don't want to have the <br> on a deleted selction across para's
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
return res;
}
if (IsListItem(leftParent) || IsHeader(leftParent))
@ -504,7 +550,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
res = mEditor->DeleteSelectionImpl(aAction);
if (NS_FAILED(res)) return res;
// join blocks
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
return res;
}
}

View File

@ -2417,6 +2417,85 @@ nsEditor::IntermediateNodesAreInline(nsIDOMRange *aRange,
}
nsresult
nsEditor::GetPriorNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
PRBool aEditableNode,
nsIDOMNode **aResultNode)
{
// just another version of GetPriorNode that takes a {parent, offset}
// instead of a node
nsresult result = NS_OK;
if (!aParentNode || !aResultNode) { return NS_ERROR_NULL_POINTER; }
// if we are at beginning of node than just look before it
if (!aOffset)
{
return GetPriorNode(aParentNode, aEditableNode, aResultNode);
}
else
{
// else look before the child at 'aOffset'
nsCOMPtr<nsIDOMNode> child = GetChildAt(aParentNode, aOffset);
if (child)
return GetPriorNode(child, aEditableNode, aResultNode);
// unless there isn't one, in which case we are at the end of the node
// and want the deep-right child.
else
{
result = GetRightmostChild(*aResultNode, aResultNode);
if (NS_FAILED(result)) return result;
if (!aEditableNode) return result;
if (IsEditable(*aResultNode)) return result;
else
{
// restart the search from the non-editable node we just found
nsCOMPtr<nsIDOMNode> notEditableNode = do_QueryInterface(*aResultNode);
return GetPriorNode(notEditableNode, aEditableNode, aResultNode);
}
}
}
}
nsresult
nsEditor::GetNextNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
PRBool aEditableNode,
nsIDOMNode **aResultNode)
{
// just another version of GetNextNode that takes a {parent, offset}
// instead of a node
nsresult result = NS_OK;
if (!aParentNode || !aResultNode) { return NS_ERROR_NULL_POINTER; }
// look at the child at 'aOffset'
nsCOMPtr<nsIDOMNode> child = GetChildAt(aParentNode, aOffset);
if (child)
{
result = GetLeftmostChild(*aResultNode, aResultNode);
if (NS_FAILED(result)) return result;
if (!aEditableNode) return result;
if (IsEditable(*aResultNode)) return result;
else
{
// restart the search from the non-editable node we just found
nsCOMPtr<nsIDOMNode> notEditableNode = do_QueryInterface(*aResultNode);
return GetNextNode(notEditableNode, aEditableNode, aResultNode);
}
}
// unless there isn't one, in which case we are at the end of the node
// and want the next one.
else
{
return GetNextNode(aParentNode, aEditableNode, aResultNode);
}
}
nsresult
nsEditor::GetPriorNode(nsIDOMNode *aCurrentNode,
PRBool aEditableNode,
@ -3525,7 +3604,7 @@ nsEditor::SplitNodeDeep(nsIDOMNode *aNode,
while (nodeToSplit)
{
// need to insert rules code call here to do thingsa like
// need to insert rules code call here to do things like
// not split a list if you are after the last <li> or before the first, etc.
// for now we just have some smarts about unneccessarily splitting
// textnodes, which should be universal enough to put straight in
@ -3577,18 +3656,18 @@ nsEditor::SplitNodeDeep(nsIDOMNode *aNode,
nsresult
nsEditor::JoinNodeDeep(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
nsIDOMSelection *aSelection)
nsCOMPtr<nsIDOMNode> *aOutJoinNode,
PRInt32 *outOffset)
{
if (!aLeftNode || !aRightNode) return NS_ERROR_NULL_POINTER;
if (!aLeftNode || !aRightNode || !aOutJoinNode || !outOffset) return NS_ERROR_NULL_POINTER;
// while the rightmost children and their descendants of the left node
// match the leftmost children and their descendants of the right node
// join them up. Can you say that three times fast?
nsCOMPtr<nsIDOMNode> leftNodeToJoin = do_QueryInterface(aLeftNode);
nsCOMPtr<nsIDOMNode> rightNodeToJoin = do_QueryInterface(aRightNode);
nsCOMPtr<nsIDOMNode> parentNode;
PRInt32 offset;
nsCOMPtr<nsIDOMNode> parentNode,tmp;
nsresult res = NS_OK;
rightNodeToJoin->GetParentNode(getter_AddRefs(parentNode));
@ -3596,23 +3675,51 @@ nsEditor::JoinNodeDeep(nsIDOMNode *aLeftNode,
while (leftNodeToJoin && rightNodeToJoin && parentNode &&
NodesSameType(leftNodeToJoin, rightNodeToJoin))
{
res = JoinNodes(leftNodeToJoin,rightNodeToJoin,parentNode);
// adjust out params
PRUint32 length;
if (IsTextNode(leftNodeToJoin))
{
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
nodeAsText = do_QueryInterface(leftNodeToJoin);
nodeAsText->GetLength(&length);
}
else
{
res = GetLengthOfDOMNode(leftNodeToJoin, length);
if (NS_FAILED(res)) return res;
}
*aOutJoinNode = rightNodeToJoin;
*outOffset = length;
// do the join
res = JoinNodes(leftNodeToJoin, rightNodeToJoin, parentNode);
if (NS_FAILED(res)) return res;
res = GetStartNodeAndOffset(aSelection, &parentNode, &offset);
if (NS_FAILED(res)) return res;
if (offset == 0) // no new left node; we're done joining
return NS_OK;
if (IsTextNode(parentNode)) // we've joined all the way down to text nodes, we're done!
return NS_OK;
else
{
// get new left and right nodes, and begin anew
leftNodeToJoin = GetChildAt(parentNode, offset-1);
rightNodeToJoin = GetChildAt(parentNode, offset);
parentNode = rightNodeToJoin;
leftNodeToJoin = GetChildAt(parentNode, length-1);
rightNodeToJoin = GetChildAt(parentNode, length);
// skip over non-editable nodes
while (leftNodeToJoin && !IsEditable(leftNodeToJoin))
{
leftNodeToJoin->GetPreviousSibling(getter_AddRefs(tmp));
leftNodeToJoin = tmp;
}
if (!leftNodeToJoin) break;
while (rightNodeToJoin && !IsEditable(rightNodeToJoin))
{
rightNodeToJoin->GetNextSibling(getter_AddRefs(tmp));
rightNodeToJoin = tmp;
}
if (!rightNodeToJoin) break;
}
}
@ -4021,7 +4128,6 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
// determine if the insertion point is at the beginning, middle, or end of the node
nsCOMPtr<nsIDOMCharacterData> nodeAsText;
nsCOMPtr<nsIDOMNode> selectedNode;
nodeAsText = do_QueryInterface(node);
if (nodeAsText)
@ -4040,7 +4146,6 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
if ((NS_SUCCEEDED(result)) && childList)
{
childList->GetLength(&count);
childList->Item(offset, getter_AddRefs(selectedNode));
}
isFirst = PRBool(0==offset);
isLast = PRBool((count-1)==(PRUint32)offset);
@ -4140,9 +4245,22 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
else
{ // we're deleting a node
DeleteElementTxn *txn;
result = CreateTxnForDeleteElement(selectedNode, &txn);
if (NS_SUCCEEDED(result)) {
aTxn->AppendChild(txn);
nsCOMPtr<nsIDOMNode> selectedNode;
if (eDeletePrevious==aAction)
{
result = GetPriorNode(node, offset, PR_TRUE, getter_AddRefs(selectedNode));
}
else if (eDeleteNext==aAction)
{
result = GetNextNode(node, offset, PR_TRUE, getter_AddRefs(selectedNode));
}
if (NS_SUCCEEDED(result) && selectedNode)
{
result = CreateTxnForDeleteElement(selectedNode, &txn);
if (NS_SUCCEEDED(result))
{
aTxn->AppendChild(txn);
}
}
}
}

View File

@ -482,6 +482,12 @@ public:
PRBool aEditableNode,
nsIDOMNode **aResultNode);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetPriorNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
PRBool aEditableNode,
nsIDOMNode **aResultNode);
/** get the node immediately after to aCurrentNode
* @param aCurrentNode the node from which we start the search
* @param aEditableNode if PR_TRUE, only return an editable node
@ -493,6 +499,12 @@ public:
PRBool aEditableNode,
nsIDOMNode **aResultNode);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetNextNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
PRBool aEditableNode,
nsIDOMNode **aResultNode);
/** Get the rightmost child of aCurrentNode, and return it in aResultNode
* aResultNode is set to nsnull if aCurrentNode has no children.
*/
@ -565,7 +577,9 @@ public:
nsresult IsPrevCharWhitespace(nsIDOMNode *aParentNode, PRInt32 aOffset, PRBool *aResult);
nsresult SplitNodeDeep(nsIDOMNode *aNode, nsIDOMNode *aSplitPointParent, PRInt32 aSplitPointOffset, PRInt32 *outOffset);
nsresult JoinNodeDeep(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMSelection *aSelection);
nsresult JoinNodeDeep(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsCOMPtr<nsIDOMNode> *aOutJoinNode, PRInt32 *outOffset);
nsresult GetString(const nsString& name, nsString& value);
nsresult BeginUpdateViewBatch(void);
nsresult EndUpdateViewBatch(void);

View File

@ -306,8 +306,8 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
res = aSelection->GetIsCollapsed(&bCollapsed);
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMNode> node;
PRInt32 offset;
nsCOMPtr<nsIDOMNode> node, selNode;
PRInt32 offset, selOffset;
res = mEditor->GetStartNodeAndOffset(aSelection, &node, &offset);
if (NS_FAILED(res)) return res;
@ -356,7 +356,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
{
// join para's, insert break
*aCancel = PR_TRUE;
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
if (NS_FAILED(res)) return res;
res = mEditor->InsertBreak();
return res;
@ -365,7 +368,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
{
// join blocks
*aCancel = PR_TRUE;
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
return res;
}
}
@ -409,7 +415,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
{
// join para's, insert break
*aCancel = PR_TRUE;
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
if (NS_FAILED(res)) return res;
res = mEditor->InsertBreak();
return res;
@ -418,7 +427,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
{
// join blocks
*aCancel = PR_TRUE;
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
return res;
}
}
@ -428,7 +440,41 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
}
}
// else do default
// else not in text node; we need to find right place to act on
else
{
// XXX add (aAction == nsIEditor::eDeleteNext) case!!
nsCOMPtr<nsIDOMNode> nodeToBackspace;
res = mEditor->GetPriorNode(node, offset, PR_TRUE, getter_AddRefs(nodeToBackspace));
if (NS_FAILED(res)) return res;
if (!nodeToBackspace) return NS_ERROR_NULL_POINTER;
// if this node is text node, adjust selection
if (nsEditor::IsTextNode(nodeToBackspace))
{
PRUint32 len;
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
nodeAsText = do_QueryInterface(nodeToBackspace);
nodeAsText->GetLength(&len);
res = aSelection->Collapse(nodeToBackspace,len);
return res;
}
else
{
// editable leaf node is not text; delete it.
// that's the default behavior
res = nsEditor::GetNodeLocation(nodeToBackspace, &node, &offset);
if (NS_FAILED(res)) return res;
// adjust selection to be right after it, for benefit of
// deletion code
res = aSelection->Collapse(node, offset+1);
return res;
}
}
return NS_OK;
}
@ -491,10 +537,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
res = mEditor->DeleteSelectionImpl(aAction);
if (NS_FAILED(res)) return res;
// then join para's, insert break
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
//res = mEditor->InsertBreak();
// uhh, no, we don't want to have the <br> on a deleted selction across para's
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
return res;
}
if (IsListItem(leftParent) || IsHeader(leftParent))
@ -504,7 +550,10 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
res = mEditor->DeleteSelectionImpl(aAction);
if (NS_FAILED(res)) return res;
// join blocks
res = mEditor->JoinNodeDeep(leftParent,rightParent,aSelection);
res = mEditor->JoinNodeDeep(leftParent,rightParent,&selNode,&selOffset);
if (NS_FAILED(res)) return res;
// fix up selection
res = aSelection->Collapse(selNode,selOffset);
return res;
}
}