mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 896283 - Part c: Use nsINode in nsEditor::JoinNodesImpl; r=ehsan
This commit is contained in:
parent
7ecb7f9c85
commit
971cd2e7d5
@ -67,18 +67,12 @@ NS_IMETHODIMP JoinElementTxn::DoTransaction(void)
|
||||
NS_PRECONDITION((mEditor && mLeftNode && mRightNode), "null arg");
|
||||
if (!mEditor || !mLeftNode || !mRightNode) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsINode> leftNode = do_QueryInterface(mLeftNode);
|
||||
NS_ENSURE_STATE(leftNode);
|
||||
|
||||
nsCOMPtr<nsINode> rightNode = do_QueryInterface(mRightNode);
|
||||
NS_ENSURE_STATE(rightNode);
|
||||
|
||||
// get the parent node
|
||||
nsCOMPtr<nsINode> leftParent = leftNode->GetParentNode();
|
||||
nsCOMPtr<nsINode> leftParent = mLeftNode->GetParentNode();
|
||||
NS_ENSURE_TRUE(leftParent, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// verify that mLeftNode and mRightNode have the same parent
|
||||
nsCOMPtr<nsINode> rightParent = rightNode->GetParentNode();
|
||||
nsCOMPtr<nsINode> rightParent = mRightNode->GetParentNode();
|
||||
NS_ENSURE_TRUE(rightParent, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (leftParent != rightParent) {
|
||||
@ -89,11 +83,9 @@ NS_IMETHODIMP JoinElementTxn::DoTransaction(void)
|
||||
// set this instance mParent.
|
||||
// Other methods will see a non-null mParent and know all is well
|
||||
mParent = leftParent;
|
||||
mOffset = leftNode->Length();
|
||||
mOffset = mLeftNode->Length();
|
||||
|
||||
nsresult rv = mEditor->JoinNodesImpl(mRightNode->AsDOMNode(),
|
||||
mLeftNode->AsDOMNode(),
|
||||
mParent->AsDOMNode());
|
||||
nsresult rv = mEditor->JoinNodesImpl(mRightNode, mLeftNode, mParent);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (NS_SUCCEEDED(rv) && gNoisy) {
|
||||
|
@ -129,9 +129,8 @@ NS_IMETHODIMP SplitElementTxn::UndoTransaction(void)
|
||||
}
|
||||
|
||||
// this assumes Do inserted the new node in front of the prior existing node
|
||||
nsresult result = mEditor->JoinNodesImpl(mExistingRightNode->AsDOMNode(),
|
||||
mNewLeftNode->AsDOMNode(),
|
||||
mParent->AsDOMNode());
|
||||
nsresult rv = mEditor->JoinNodesImpl(mExistingRightNode, mNewLeftNode,
|
||||
mParent);
|
||||
#ifdef DEBUG
|
||||
if (gNoisy)
|
||||
{
|
||||
@ -140,7 +139,7 @@ NS_IMETHODIMP SplitElementTxn::UndoTransaction(void)
|
||||
static_cast<void*>(mExistingRightNode.get()));
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (gNoisy)
|
||||
{
|
||||
@ -150,7 +149,7 @@ NS_IMETHODIMP SplitElementTxn::UndoTransaction(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* redo cannot simply resplit the right node, because subsequent transactions
|
||||
|
@ -2839,153 +2839,127 @@ nsEditor::SplitNodeImpl(nsIDOMNode * aExistingRightNode,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
|
||||
nsIDOMNode * aNodeToJoin,
|
||||
nsIDOMNode * aParent)
|
||||
nsEditor::JoinNodesImpl(nsINode* aNodeToKeep,
|
||||
nsINode* aNodeToJoin,
|
||||
nsINode* aParent)
|
||||
{
|
||||
MOZ_ASSERT(aNodeToKeep);
|
||||
MOZ_ASSERT(aNodeToJoin);
|
||||
MOZ_ASSERT(aParent);
|
||||
|
||||
// get selection
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
GetSelection(getter_AddRefs(selection));
|
||||
nsRefPtr<Selection> selection = GetSelection();
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// remember some selection points
|
||||
nsCOMPtr<nsIDOMNode> selStartNode, selEndNode;
|
||||
int32_t selStartOffset, selEndOffset, joinOffset, keepOffset;
|
||||
nsCOMPtr<nsINode> selStartNode;
|
||||
int32_t selStartOffset;
|
||||
nsresult result = GetStartNodeAndOffset(selection, getter_AddRefs(selStartNode), &selStartOffset);
|
||||
if (NS_FAILED(result)) selStartNode = nullptr;
|
||||
if (NS_FAILED(result)) {
|
||||
selStartNode = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> selEndNode;
|
||||
int32_t selEndOffset;
|
||||
result = GetEndNodeAndOffset(selection, getter_AddRefs(selEndNode), &selEndOffset);
|
||||
// Joe or Kin should comment here on why the following line is not a copy/paste error
|
||||
if (NS_FAILED(result)) selStartNode = nullptr;
|
||||
if (NS_FAILED(result)) {
|
||||
selStartNode = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> leftNode = aNodeToJoin;
|
||||
uint32_t firstNodeLength = aNodeToJoin->Length();
|
||||
|
||||
uint32_t firstNodeLength;
|
||||
result = GetLengthOfDOMNode(leftNode, firstNodeLength);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
nsCOMPtr<nsIDOMNode> parent = GetNodeLocation(aNodeToJoin, &joinOffset);
|
||||
parent = GetNodeLocation(aNodeToKeep, &keepOffset);
|
||||
int32_t joinOffset;
|
||||
GetNodeLocation(aNodeToJoin, &joinOffset);
|
||||
int32_t keepOffset;
|
||||
nsINode* parent = GetNodeLocation(aNodeToKeep, &keepOffset);
|
||||
|
||||
// if selection endpoint is between the nodes, remember it as being
|
||||
// in the one that is going away instead. This simplifies later selection
|
||||
// adjustment logic at end of this method.
|
||||
if (selStartNode)
|
||||
{
|
||||
if (selStartNode == parent)
|
||||
{
|
||||
if ((selStartOffset > joinOffset) && (selStartOffset <= keepOffset))
|
||||
{
|
||||
selStartNode = aNodeToJoin;
|
||||
selStartOffset = firstNodeLength;
|
||||
}
|
||||
if (selStartNode) {
|
||||
if (selStartNode == parent &&
|
||||
joinOffset < selStartOffset && selStartOffset <= keepOffset) {
|
||||
selStartNode = aNodeToJoin;
|
||||
selStartOffset = firstNodeLength;
|
||||
}
|
||||
if (selEndNode == parent)
|
||||
{
|
||||
if ((selEndOffset > joinOffset) && (selEndOffset <= keepOffset))
|
||||
{
|
||||
selEndNode = aNodeToJoin;
|
||||
selEndOffset = firstNodeLength;
|
||||
}
|
||||
if (selEndNode == parent &&
|
||||
joinOffset < selEndOffset && selEndOffset <= keepOffset) {
|
||||
selEndNode = aNodeToJoin;
|
||||
selEndOffset = firstNodeLength;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, ready to do join now.
|
||||
// if it's a text node, just shuffle around some text
|
||||
nsCOMPtr<nsIDOMCharacterData> keepNodeAsText( do_QueryInterface(aNodeToKeep) );
|
||||
nsCOMPtr<nsIDOMCharacterData> joinNodeAsText( do_QueryInterface(aNodeToJoin) );
|
||||
if (keepNodeAsText && joinNodeAsText)
|
||||
{
|
||||
if (keepNodeAsText && joinNodeAsText) {
|
||||
nsAutoString rightText;
|
||||
nsAutoString leftText;
|
||||
keepNodeAsText->GetData(rightText);
|
||||
joinNodeAsText->GetData(leftText);
|
||||
leftText += rightText;
|
||||
keepNodeAsText->SetData(leftText);
|
||||
}
|
||||
else
|
||||
{ // otherwise it's an interior node, so shuffle around the children
|
||||
nsCOMPtr<nsIDOMNodeList> childNodes;
|
||||
result = aNodeToJoin->GetChildNodes(getter_AddRefs(childNodes));
|
||||
NS_ENSURE_TRUE(childNodes, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
} else {
|
||||
// otherwise it's an interior node, so shuffle around the children
|
||||
nsCOMPtr<nsINodeList> childNodes = aNodeToJoin->ChildNodes();
|
||||
MOZ_ASSERT(childNodes);
|
||||
|
||||
int32_t i; // must be signed int!
|
||||
uint32_t childCount=0;
|
||||
nsCOMPtr<nsIDOMNode> firstNode;
|
||||
childNodes->GetLength(&childCount);
|
||||
// remember the first child in aNodeToKeep, we'll insert all the children of aNodeToJoin in front of it
|
||||
result = aNodeToKeep->GetFirstChild(getter_AddRefs(firstNode));
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
// GetFirstChild returns nullptr firstNode if aNodeToKeep has no children, that's ok.
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
// have to go through the list backwards to keep deletes from interfering with iteration
|
||||
nsCOMPtr<nsIDOMNode> previousChild;
|
||||
for (i = childCount - 1; i >= 0; i--)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
result = childNodes->Item(i, getter_AddRefs(childNode));
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
nsCOMPtr<nsIContent> firstNode = aNodeToKeep->GetFirstChild();
|
||||
|
||||
// have to go through the list backwards to keep deletes from interfering with iteration
|
||||
for (uint32_t i = childNodes->Length(); i > 0; --i) {
|
||||
nsCOMPtr<nsIContent> childNode = childNodes->Item(i - 1);
|
||||
if (childNode) {
|
||||
// prepend children of aNodeToJoin
|
||||
result = aNodeToKeep->InsertBefore(childNode, firstNode, getter_AddRefs(resultNode));
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
firstNode = do_QueryInterface(childNode);
|
||||
ErrorResult err;
|
||||
aNodeToKeep->InsertBefore(*childNode, firstNode, err);
|
||||
NS_ENSURE_SUCCESS(err.ErrorCode(), err.ErrorCode());
|
||||
firstNode = childNode.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete the extra node
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
result = aParent->RemoveChild(aNodeToJoin, getter_AddRefs(resultNode));
|
||||
ErrorResult err;
|
||||
aParent->RemoveChild(*aNodeToJoin, err);
|
||||
|
||||
if (GetShouldTxnSetSelection())
|
||||
{
|
||||
if (GetShouldTxnSetSelection()) {
|
||||
// editor wants us to set selection at join point
|
||||
selection->Collapse(aNodeToKeep, firstNodeLength);
|
||||
}
|
||||
else if (selStartNode)
|
||||
{
|
||||
selection->Collapse(aNodeToKeep, SafeCast<int32_t>(firstNodeLength));
|
||||
} else if (selStartNode) {
|
||||
// and adjust the selection if needed
|
||||
// HACK: this is overly simplified - multi-range selections need more work than this
|
||||
bool bNeedToAdjust = false;
|
||||
|
||||
// check to see if we joined nodes where selection starts
|
||||
if (selStartNode.get() == aNodeToJoin)
|
||||
{
|
||||
if (selStartNode == aNodeToJoin) {
|
||||
bNeedToAdjust = true;
|
||||
selStartNode = aNodeToKeep;
|
||||
}
|
||||
else if (selStartNode.get() == aNodeToKeep)
|
||||
{
|
||||
} else if (selStartNode == aNodeToKeep) {
|
||||
bNeedToAdjust = true;
|
||||
selStartOffset += firstNodeLength;
|
||||
}
|
||||
|
||||
// check to see if we joined nodes where selection ends
|
||||
if (selEndNode.get() == aNodeToJoin)
|
||||
{
|
||||
if (selEndNode == aNodeToJoin) {
|
||||
bNeedToAdjust = true;
|
||||
selEndNode = aNodeToKeep;
|
||||
}
|
||||
else if (selEndNode.get() == aNodeToKeep)
|
||||
{
|
||||
} else if (selEndNode == aNodeToKeep) {
|
||||
bNeedToAdjust = true;
|
||||
selEndOffset += firstNodeLength;
|
||||
}
|
||||
|
||||
// adjust selection if needed
|
||||
if (bNeedToAdjust)
|
||||
{
|
||||
selection->Collapse(selStartNode,selStartOffset);
|
||||
selection->Extend(selEndNode,selEndOffset);
|
||||
if (bNeedToAdjust) {
|
||||
selection->Collapse(selStartNode, selStartOffset);
|
||||
selection->Extend(selEndNode, selEndOffset);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return err.ErrorCode();
|
||||
}
|
||||
|
||||
|
||||
@ -3802,21 +3776,40 @@ nsEditor::GetStartNodeAndOffset(nsISelection *aSelection,
|
||||
{
|
||||
NS_ENSURE_TRUE(outStartNode && outStartOffset && aSelection, NS_ERROR_NULL_POINTER);
|
||||
|
||||
*outStartNode = nullptr;
|
||||
*outStartOffset = 0;
|
||||
nsCOMPtr<nsINode> startNode;
|
||||
nsresult rv = GetStartNodeAndOffset(static_cast<Selection*>(aSelection),
|
||||
getter_AddRefs(startNode),
|
||||
outStartOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Selection* selection = static_cast<Selection*>(aSelection);
|
||||
NS_ENSURE_TRUE(selection->GetRangeCount(), NS_ERROR_FAILURE);
|
||||
if (startNode) {
|
||||
NS_ADDREF(*outStartNode = startNode->AsDOMNode());
|
||||
} else {
|
||||
*outStartNode = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRange* range = selection->GetRangeAt(0);
|
||||
nsresult
|
||||
nsEditor::GetStartNodeAndOffset(Selection* aSelection, nsINode** aStartNode,
|
||||
int32_t* aStartOffset)
|
||||
{
|
||||
MOZ_ASSERT(aSelection);
|
||||
MOZ_ASSERT(aStartNode);
|
||||
MOZ_ASSERT(aStartOffset);
|
||||
|
||||
*aStartNode = nullptr;
|
||||
*aStartOffset = 0;
|
||||
|
||||
NS_ENSURE_TRUE(aSelection->GetRangeCount(), NS_ERROR_FAILURE);
|
||||
|
||||
const nsRange* range = aSelection->GetRangeAt(0);
|
||||
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult result = range->GetStartContainer(outStartNode);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = range->GetStartOffset(outStartOffset);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
NS_ENSURE_TRUE(range->IsPositioned(), NS_ERROR_FAILURE);
|
||||
|
||||
NS_IF_ADDREF(*aStartNode = range->GetStartParent());
|
||||
*aStartOffset = range->StartOffset();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3829,23 +3822,42 @@ nsEditor::GetEndNodeAndOffset(nsISelection *aSelection,
|
||||
nsIDOMNode **outEndNode,
|
||||
int32_t *outEndOffset)
|
||||
{
|
||||
NS_ENSURE_TRUE(outEndNode && outEndOffset, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(outEndNode && outEndOffset && aSelection, NS_ERROR_NULL_POINTER);
|
||||
|
||||
*outEndNode = nullptr;
|
||||
|
||||
Selection* selection = static_cast<Selection*>(aSelection);
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(selection->GetRangeCount(), NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsINode> endNode;
|
||||
nsresult rv = GetEndNodeAndOffset(static_cast<Selection*>(aSelection),
|
||||
getter_AddRefs(endNode),
|
||||
outEndOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRange* range = selection->GetRangeAt(0);
|
||||
if (endNode) {
|
||||
NS_ADDREF(*outEndNode = endNode->AsDOMNode());
|
||||
} else {
|
||||
*outEndNode = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::GetEndNodeAndOffset(Selection* aSelection, nsINode** aEndNode,
|
||||
int32_t* aEndOffset)
|
||||
{
|
||||
MOZ_ASSERT(aSelection);
|
||||
MOZ_ASSERT(aEndNode);
|
||||
MOZ_ASSERT(aEndOffset);
|
||||
|
||||
*aEndNode = nullptr;
|
||||
*aEndOffset = 0;
|
||||
|
||||
NS_ENSURE_TRUE(aSelection->GetRangeCount(), NS_ERROR_FAILURE);
|
||||
|
||||
const nsRange* range = aSelection->GetRangeAt(0);
|
||||
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
|
||||
|
||||
if (NS_FAILED(range->GetEndContainer(outEndNode)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (NS_FAILED(range->GetEndOffset(outEndOffset)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
NS_ENSURE_TRUE(range->IsPositioned(), NS_ERROR_FAILURE);
|
||||
|
||||
NS_IF_ADDREF(*aEndNode = range->GetEndParent());
|
||||
*aEndOffset = range->EndOffset();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -451,9 +451,9 @@ public:
|
||||
* There is no requirement that the two nodes be of the same type.
|
||||
* @param aParent The parent of aNodeToKeep
|
||||
*/
|
||||
nsresult JoinNodesImpl(nsIDOMNode *aNodeToKeep,
|
||||
nsIDOMNode *aNodeToJoin,
|
||||
nsIDOMNode *aParent);
|
||||
nsresult JoinNodesImpl(nsINode* aNodeToKeep,
|
||||
nsINode* aNodeToJoin,
|
||||
nsINode* aParent);
|
||||
|
||||
/**
|
||||
* Return the offset of aChild in aParent. Asserts fatally if parent or
|
||||
@ -611,7 +611,13 @@ public:
|
||||
static nsCOMPtr<nsIDOMNode> GetNodeAtRangeOffsetPoint(nsIDOMNode* aParentOrNode, int32_t aOffset);
|
||||
|
||||
static nsresult GetStartNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outStartNode, int32_t *outStartOffset);
|
||||
static nsresult GetStartNodeAndOffset(mozilla::Selection* aSelection,
|
||||
nsINode** aStartNode,
|
||||
int32_t* aStartOffset);
|
||||
static nsresult GetEndNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outEndNode, int32_t *outEndOffset);
|
||||
static nsresult GetEndNodeAndOffset(mozilla::Selection* aSelection,
|
||||
nsINode** aEndNode,
|
||||
int32_t* aEndOffset);
|
||||
#if DEBUG_JOE
|
||||
static void DumpNode(nsIDOMNode *aNode, int32_t indent=0);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user