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:
Masayuki Nakano 2017-03-14 22:01:36 +09:00
Родитель 3f530e2fd9
Коммит 566d8c8f39
2 изменённых файлов: 143 добавлений и 116 удалений

Просмотреть файл

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