зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1347092 part.2 Make EditorBase::CreateTxnForDeleteInsertionPoint() return already_AddRefed<EditTransactionBase> r=m_kato
EditorBase::CreateTxnForDeleteInsertionPoint() appends DeleteTextTransaction or DeleteNodeTransaction to the given EditAggregateTransaction. For consistency with other CreateTxnFor*() methods, this should just create a transaction and return it. Then, the caller should append the transaction to EditAggregateTransaction. MozReview-Commit-ID: 6sqEijicFHE --HG-- extra : rebase_source : 1443b3d9c8e90044994ad87965a26d76926e2c72
This commit is contained in:
Родитель
3f530e2fd9
Коммит
566d8c8f39
|
@ -4375,10 +4375,17 @@ EditorBase::CreateTxnForDeleteSelection(EDirection aAction,
|
|||
} else if (aAction != eNone) {
|
||||
// we have an insertion point. delete the thing in front of it or
|
||||
// behind it, depending on aAction
|
||||
nsresult rv = CreateTxnForDeleteInsertionPoint(range, aAction,
|
||||
aggregateTransaction,
|
||||
aNode, aOffset, aLength);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// XXX Odd, when there are two or more ranges, this returns the last
|
||||
// range information with aNode, aOffset and aLength.
|
||||
RefPtr<EditTransactionBase> deleteRangeTransaction =
|
||||
CreateTxnForDeleteRange(range, aAction, aNode, aOffset, aLength);
|
||||
// XXX When there are two or more ranges and at least one of them is
|
||||
// not editable, deleteRangeTransaction may be nullptr.
|
||||
// In such case, should we stop removing other ranges too?
|
||||
if (NS_WARN_IF(!deleteRangeTransaction)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aggregateTransaction->AppendChild(deleteRangeTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4423,22 +4430,22 @@ EditorBase::CreateTxnForDeleteCharacter(nsGenericDOMDataNode& aData,
|
|||
|
||||
//XXX: currently, this doesn't handle edge conditions because GetNext/GetPrior
|
||||
//are not implemented
|
||||
nsresult
|
||||
EditorBase::CreateTxnForDeleteInsertionPoint(
|
||||
nsRange* aRange,
|
||||
EDirection aAction,
|
||||
EditAggregateTransaction* aTransaction,
|
||||
nsINode** aNode,
|
||||
int32_t* aOffset,
|
||||
int32_t* aLength)
|
||||
already_AddRefed<EditTransactionBase>
|
||||
EditorBase::CreateTxnForDeleteRange(nsRange* aRangeToDelete,
|
||||
EDirection aAction,
|
||||
nsINode** aRemovingNode,
|
||||
int32_t* aOffset,
|
||||
int32_t* aLength)
|
||||
{
|
||||
MOZ_ASSERT(aAction != eNone);
|
||||
|
||||
// get the node and offset of the insertion point
|
||||
nsCOMPtr<nsINode> node = aRange->GetStartParent();
|
||||
NS_ENSURE_STATE(node);
|
||||
nsCOMPtr<nsINode> node = aRangeToDelete->GetStartParent();
|
||||
if (NS_WARN_IF(!node)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t offset = aRange->StartOffset();
|
||||
int32_t offset = aRangeToDelete->StartOffset();
|
||||
|
||||
// determine if the insertion point is at the beginning, middle, or end of
|
||||
// the node
|
||||
|
@ -4457,7 +4464,9 @@ EditorBase::CreateTxnForDeleteInsertionPoint(
|
|||
// we're backspacing from the beginning of the node. Delete the first
|
||||
// thing to our left
|
||||
nsCOMPtr<nsIContent> priorNode = GetPriorNode(node, true);
|
||||
NS_ENSURE_STATE(priorNode);
|
||||
if (NS_WARN_IF(!priorNode)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// there is a priorNode, so delete its last child (if chardata, delete the
|
||||
// last char). if it has no children, delete it
|
||||
|
@ -4466,34 +4475,37 @@ EditorBase::CreateTxnForDeleteInsertionPoint(
|
|||
static_cast<nsGenericDOMDataNode*>(priorNode.get());
|
||||
uint32_t length = priorNode->Length();
|
||||
// Bail out for empty chardata XXX: Do we want to do something else?
|
||||
NS_ENSURE_STATE(length);
|
||||
RefPtr<DeleteTextTransaction> transaction =
|
||||
CreateTxnForDeleteCharacter(*priorNodeAsCharData, length, ePrevious);
|
||||
NS_ENSURE_STATE(transaction);
|
||||
|
||||
*aOffset = transaction->GetOffset();
|
||||
*aLength = transaction->GetNumCharsToDelete();
|
||||
aTransaction->AppendChild(transaction);
|
||||
} else {
|
||||
// priorNode is not chardata, so tell its parent to delete it
|
||||
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
|
||||
CreateTxnForDeleteNode(priorNode);
|
||||
if (NS_WARN_IF(!deleteNodeTransaction)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (NS_WARN_IF(!length)) {
|
||||
return nullptr;
|
||||
}
|
||||
aTransaction->AppendChild(deleteNodeTransaction);
|
||||
RefPtr<DeleteTextTransaction> deleteTextTransaction =
|
||||
CreateTxnForDeleteCharacter(*priorNodeAsCharData, length, ePrevious);
|
||||
if (NS_WARN_IF(!deleteTextTransaction)) {
|
||||
return nullptr;
|
||||
}
|
||||
*aOffset = deleteTextTransaction->GetOffset();
|
||||
*aLength = deleteTextTransaction->GetNumCharsToDelete();
|
||||
priorNode.forget(aRemovingNode);
|
||||
return deleteTextTransaction.forget();
|
||||
}
|
||||
|
||||
NS_ADDREF(*aNode = priorNode);
|
||||
|
||||
return NS_OK;
|
||||
// priorNode is not chardata, so tell its parent to delete it
|
||||
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
|
||||
CreateTxnForDeleteNode(priorNode);
|
||||
if (NS_WARN_IF(!deleteNodeTransaction)) {
|
||||
return nullptr;
|
||||
}
|
||||
priorNode.forget(aRemovingNode);
|
||||
return deleteNodeTransaction.forget();
|
||||
}
|
||||
|
||||
if (aAction == eNext && isLast) {
|
||||
// we're deleting from the end of the node. Delete the first thing to our
|
||||
// right
|
||||
nsCOMPtr<nsIContent> nextNode = GetNextNode(node, true);
|
||||
NS_ENSURE_STATE(nextNode);
|
||||
if (NS_WARN_IF(!nextNode)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// there is a nextNode, so delete its first child (if chardata, delete the
|
||||
// first char). if it has no children, delete it
|
||||
|
@ -4502,92 +4514,96 @@ EditorBase::CreateTxnForDeleteInsertionPoint(
|
|||
static_cast<nsGenericDOMDataNode*>(nextNode.get());
|
||||
uint32_t length = nextNode->Length();
|
||||
// Bail out for empty chardata XXX: Do we want to do something else?
|
||||
NS_ENSURE_STATE(length);
|
||||
RefPtr<DeleteTextTransaction> transaction =
|
||||
CreateTxnForDeleteCharacter(*nextNodeAsCharData, 0, eNext);
|
||||
NS_ENSURE_STATE(transaction);
|
||||
|
||||
*aOffset = transaction->GetOffset();
|
||||
*aLength = transaction->GetNumCharsToDelete();
|
||||
aTransaction->AppendChild(transaction);
|
||||
} else {
|
||||
// nextNode is not chardata, so tell its parent to delete it
|
||||
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
|
||||
CreateTxnForDeleteNode(nextNode);
|
||||
if (NS_WARN_IF(!deleteNodeTransaction)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (NS_WARN_IF(!length)) {
|
||||
return nullptr;
|
||||
}
|
||||
aTransaction->AppendChild(deleteNodeTransaction);
|
||||
RefPtr<DeleteTextTransaction> deleteTextTransaction =
|
||||
CreateTxnForDeleteCharacter(*nextNodeAsCharData, 0, eNext);
|
||||
if (NS_WARN_IF(!deleteTextTransaction)) {
|
||||
return nullptr;
|
||||
}
|
||||
*aOffset = deleteTextTransaction->GetOffset();
|
||||
*aLength = deleteTextTransaction->GetNumCharsToDelete();
|
||||
nextNode.forget(aRemovingNode);
|
||||
return deleteTextTransaction.forget();
|
||||
}
|
||||
|
||||
NS_ADDREF(*aNode = nextNode);
|
||||
|
||||
return NS_OK;
|
||||
// nextNode is not chardata, so tell its parent to delete it
|
||||
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
|
||||
CreateTxnForDeleteNode(nextNode);
|
||||
if (NS_WARN_IF(!deleteNodeTransaction)) {
|
||||
return nullptr;
|
||||
}
|
||||
nextNode.forget(aRemovingNode);
|
||||
return deleteNodeTransaction.forget();
|
||||
}
|
||||
|
||||
if (node->IsNodeOfType(nsINode::eDATA_NODE)) {
|
||||
RefPtr<nsGenericDOMDataNode> nodeAsCharData =
|
||||
static_cast<nsGenericDOMDataNode*>(node.get());
|
||||
// we have chardata, so delete a char at the proper offset
|
||||
RefPtr<DeleteTextTransaction> transaction =
|
||||
RefPtr<DeleteTextTransaction> deleteTextTransaction =
|
||||
CreateTxnForDeleteCharacter(*nodeAsCharData, offset, aAction);
|
||||
NS_ENSURE_STATE(transaction);
|
||||
|
||||
aTransaction->AppendChild(transaction);
|
||||
NS_ADDREF(*aNode = node);
|
||||
*aOffset = transaction->GetOffset();
|
||||
*aLength = transaction->GetNumCharsToDelete();
|
||||
} else {
|
||||
// we're either deleting a node or chardata, need to dig into the next/prev
|
||||
// node to find out
|
||||
nsCOMPtr<nsINode> selectedNode;
|
||||
if (aAction == ePrevious) {
|
||||
selectedNode = GetPriorNode(node, offset, true);
|
||||
} else if (aAction == eNext) {
|
||||
selectedNode = GetNextNode(node, offset, true);
|
||||
if (NS_WARN_IF(!deleteTextTransaction)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
while (selectedNode &&
|
||||
selectedNode->IsNodeOfType(nsINode::eDATA_NODE) &&
|
||||
!selectedNode->Length()) {
|
||||
// Can't delete an empty chardata node (bug 762183)
|
||||
if (aAction == ePrevious) {
|
||||
selectedNode = GetPriorNode(selectedNode, true);
|
||||
} else if (aAction == eNext) {
|
||||
selectedNode = GetNextNode(selectedNode, true);
|
||||
}
|
||||
}
|
||||
NS_ENSURE_STATE(selectedNode);
|
||||
|
||||
if (selectedNode->IsNodeOfType(nsINode::eDATA_NODE)) {
|
||||
RefPtr<nsGenericDOMDataNode> selectedNodeAsCharData =
|
||||
static_cast<nsGenericDOMDataNode*>(selectedNode.get());
|
||||
// we are deleting from a chardata node, so do a character deletion
|
||||
uint32_t position = 0;
|
||||
if (aAction == ePrevious) {
|
||||
position = selectedNode->Length();
|
||||
}
|
||||
RefPtr<DeleteTextTransaction> deleteTextTransaction =
|
||||
CreateTxnForDeleteCharacter(*selectedNodeAsCharData, position,
|
||||
aAction);
|
||||
NS_ENSURE_TRUE(deleteTextTransaction, NS_ERROR_NULL_POINTER);
|
||||
|
||||
aTransaction->AppendChild(deleteTextTransaction);
|
||||
*aOffset = deleteTextTransaction->GetOffset();
|
||||
*aLength = deleteTextTransaction->GetNumCharsToDelete();
|
||||
} else {
|
||||
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
|
||||
CreateTxnForDeleteNode(selectedNode);
|
||||
if (NS_WARN_IF(!deleteNodeTransaction)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aTransaction->AppendChild(deleteNodeTransaction);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aNode = selectedNode);
|
||||
*aOffset = deleteTextTransaction->GetOffset();
|
||||
*aLength = deleteTextTransaction->GetNumCharsToDelete();
|
||||
node.forget(aRemovingNode);
|
||||
return deleteTextTransaction.forget();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
// we're either deleting a node or chardata, need to dig into the next/prev
|
||||
// node to find out
|
||||
nsCOMPtr<nsINode> selectedNode;
|
||||
if (aAction == ePrevious) {
|
||||
selectedNode = GetPriorNode(node, offset, true);
|
||||
} else if (aAction == eNext) {
|
||||
selectedNode = GetNextNode(node, offset, true);
|
||||
}
|
||||
|
||||
while (selectedNode &&
|
||||
selectedNode->IsNodeOfType(nsINode::eDATA_NODE) &&
|
||||
!selectedNode->Length()) {
|
||||
// Can't delete an empty chardata node (bug 762183)
|
||||
if (aAction == ePrevious) {
|
||||
selectedNode = GetPriorNode(selectedNode, true);
|
||||
} else if (aAction == eNext) {
|
||||
selectedNode = GetNextNode(selectedNode, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!selectedNode)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (selectedNode->IsNodeOfType(nsINode::eDATA_NODE)) {
|
||||
RefPtr<nsGenericDOMDataNode> selectedNodeAsCharData =
|
||||
static_cast<nsGenericDOMDataNode*>(selectedNode.get());
|
||||
// we are deleting from a chardata node, so do a character deletion
|
||||
uint32_t position = 0;
|
||||
if (aAction == ePrevious) {
|
||||
position = selectedNode->Length();
|
||||
}
|
||||
RefPtr<DeleteTextTransaction> deleteTextTransaction =
|
||||
CreateTxnForDeleteCharacter(*selectedNodeAsCharData, position,
|
||||
aAction);
|
||||
if (NS_WARN_IF(!deleteTextTransaction)) {
|
||||
return nullptr;
|
||||
}
|
||||
*aOffset = deleteTextTransaction->GetOffset();
|
||||
*aLength = deleteTextTransaction->GetNumCharsToDelete();
|
||||
selectedNode.forget(aRemovingNode);
|
||||
return deleteTextTransaction.forget();
|
||||
}
|
||||
|
||||
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
|
||||
CreateTxnForDeleteNode(selectedNode);
|
||||
if (NS_WARN_IF(!deleteNodeTransaction)) {
|
||||
return nullptr;
|
||||
}
|
||||
selectedNode.forget(aRemovingNode);
|
||||
return deleteNodeTransaction.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -112,6 +112,7 @@ class CreateElementTransaction;
|
|||
class DeleteNodeTransaction;
|
||||
class DeleteTextTransaction;
|
||||
class EditAggregateTransaction;
|
||||
class EditTransactionBase;
|
||||
class ErrorResult;
|
||||
class HTMLEditor;
|
||||
class InsertNodeTransaction;
|
||||
|
@ -323,14 +324,24 @@ protected:
|
|||
int32_t* aOffset,
|
||||
int32_t* aLength);
|
||||
|
||||
nsresult CreateTxnForDeleteInsertionPoint(
|
||||
nsRange* aRange,
|
||||
EDirection aAction,
|
||||
EditAggregateTransaction* aTransaction,
|
||||
nsINode** aNode,
|
||||
int32_t* aOffset,
|
||||
int32_t* aLength);
|
||||
|
||||
/**
|
||||
* Create a transaction for removing the nodes and/or text in aRange.
|
||||
*
|
||||
* @param aRangeToDelete The range to be removed.
|
||||
* @param aAction The action caused removing the range.
|
||||
* @param aRemovingNode The node to be removed.
|
||||
* @param aOffset The start offset of the range in aRemovingNode.
|
||||
* @param aLength The length of the range in aRemovingNode.
|
||||
* @return The transaction to remove the range. Its type
|
||||
* is DeleteNodeTransaction or
|
||||
* DeleteTextTransaction.
|
||||
*/
|
||||
already_AddRefed<EditTransactionBase>
|
||||
CreateTxnForDeleteRange(nsRange* aRangeToDelete,
|
||||
EDirection aAction,
|
||||
nsINode** aRemovingNode,
|
||||
int32_t* aOffset,
|
||||
int32_t* aLength);
|
||||
|
||||
/**
|
||||
* Create a transaction for inserting aStringToInsert into aTextNode. Never
|
||||
|
|
Загрузка…
Ссылка в новой задаче