Bug 1003808 part 3 - Clean up nsRangeStore; r=ehsan

This commit is contained in:
Aryeh Gregor 2014-04-28 18:34:05 +03:00
parent 22dae1beb5
commit 8d1b356925
3 changed files with 316 additions and 263 deletions

View File

@ -12,6 +12,7 @@
#include "nsEditor.h" // for nsEditor
#include "nsEditorUtils.h" // for nsEditorUtils
#include "nsError.h" // for NS_OK, etc
#include "nsIContent.h" // for nsIContent
#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
#include "nsIDOMNode.h" // for nsIDOMNode
#include "nsIDOMRange.h" // for nsIDOMRange, etc
@ -89,8 +90,7 @@ nsSelectionState::RestoreSelection(nsISelection *aSel)
// set the selection ranges anew
for (i=0; i<arrayCount; i++)
{
nsRefPtr<nsRange> range;
mArray[i]->GetRange(getter_AddRefs(range));
nsRefPtr<nsRange> range = mArray[i]->GetRange();
NS_ENSURE_TRUE(range, NS_ERROR_UNEXPECTED);
res = aSel->AddRange(range);
@ -104,8 +104,7 @@ bool
nsSelectionState::IsCollapsed()
{
if (1 != mArray.Length()) return false;
nsRefPtr<nsRange> range;
mArray[0]->GetRange(getter_AddRefs(range));
nsRefPtr<nsRange> range = mArray[0]->GetRange();
NS_ENSURE_TRUE(range, false);
bool bIsCollapsed = false;
range->GetCollapsed(&bIsCollapsed);
@ -122,9 +121,8 @@ nsSelectionState::IsEqual(nsSelectionState *aSelState)
for (i=0; i<myCount; i++)
{
nsRefPtr<nsRange> myRange, itsRange;
mArray[i]->GetRange(getter_AddRefs(myRange));
aSelState->mArray[i]->GetRange(getter_AddRefs(itsRange));
nsRefPtr<nsRange> myRange = mArray[i]->GetRange();
nsRefPtr<nsRange> itsRange = aSelState->mArray[i]->GetRange();
NS_ENSURE_TRUE(myRange && itsRange, false);
int16_t compResult;
@ -212,30 +210,45 @@ nsRangeUpdater::DropSelectionState(nsSelectionState &aSelState)
// gravity methods:
nsresult
nsRangeUpdater::SelAdjCreateNode(nsIDOMNode *aParent, int32_t aPosition)
nsRangeUpdater::SelAdjCreateNode(nsINode* aParent, int32_t aPosition)
{
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
if (mLock) {
// lock set by Will/DidReplaceParent, etc...
return NS_OK;
}
NS_ENSURE_TRUE(aParent, NS_ERROR_NULL_POINTER);
uint32_t i, count = mArray.Length();
uint32_t count = mArray.Length();
if (!count) {
return NS_OK;
}
nsRangeStore *item;
for (i=0; i<count; i++)
{
item = mArray[i];
for (uint32_t i = 0; i < count; i++) {
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if ((item->startNode.get() == aParent) && (item->startOffset > aPosition))
if (item->startNode == aParent && item->startOffset > aPosition) {
item->startOffset++;
if ((item->endNode.get() == aParent) && (item->endOffset > aPosition))
}
if (item->endNode == aParent && item->endOffset > aPosition) {
item->endOffset++;
}
}
return NS_OK;
}
nsresult
nsRangeUpdater::SelAdjCreateNode(nsIDOMNode* aParent, int32_t aPosition)
{
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
return SelAdjCreateNode(parent, aPosition);
}
nsresult
nsRangeUpdater::SelAdjInsertNode(nsINode* aParent, int32_t aPosition)
{
return SelAdjCreateNode(aParent, aPosition);
}
nsresult
nsRangeUpdater::SelAdjInsertNode(nsIDOMNode *aParent, int32_t aPosition)
{
@ -243,49 +256,46 @@ nsRangeUpdater::SelAdjInsertNode(nsIDOMNode *aParent, int32_t aPosition)
}
void
nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
nsRangeUpdater::SelAdjDeleteNode(nsINode* aNode)
{
if (mLock) {
// lock set by Will/DidReplaceParent, etc...
return;
}
MOZ_ASSERT(aNode);
uint32_t i, count = mArray.Length();
uint32_t count = mArray.Length();
if (!count) {
return;
}
int32_t offset = 0;
nsCOMPtr<nsIDOMNode> parent = nsEditor::GetNodeLocation(aNode, &offset);
nsCOMPtr<nsINode> parent = aNode->GetParentNode();
int32_t offset = parent ? parent->IndexOf(aNode) : -1;
// check for range endpoints that are after aNode and in the same parent
nsRangeStore *item;
for (i=0; i<count; i++)
{
item = mArray[i];
for (uint32_t i = 0; i < count; i++) {
nsRangeStore* item = mArray[i];
MOZ_ASSERT(item);
if ((item->startNode.get() == parent) && (item->startOffset > offset))
if (item->startNode == parent && item->startOffset > offset) {
item->startOffset--;
if ((item->endNode.get() == parent) && (item->endOffset > offset))
}
if (item->endNode == parent && item->endOffset > offset) {
item->endOffset--;
}
// check for range endpoints that are in aNode
if (item->startNode == aNode)
{
if (item->startNode == aNode) {
item->startNode = parent;
item->startOffset = offset;
}
if (item->endNode == aNode)
{
if (item->endNode == aNode) {
item->endNode = parent;
item->endOffset = offset;
}
// check for range endpoints that are in descendants of aNode
nsCOMPtr<nsIDOMNode> oldStart;
if (nsEditorUtils::IsDescendantOf(item->startNode, aNode))
{
nsCOMPtr<nsINode> oldStart;
if (nsEditorUtils::IsDescendantOf(item->startNode, aNode)) {
oldStart = item->startNode; // save for efficiency hack below.
item->startNode = parent;
item->startOffset = offset;
@ -300,51 +310,52 @@ nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
}
}
void
nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
{
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(node, );
return SelAdjDeleteNode(node);
}
nsresult
nsRangeUpdater::SelAdjSplitNode(nsIDOMNode *aOldRightNode, int32_t aOffset, nsIDOMNode *aNewLeftNode)
nsRangeUpdater::SelAdjSplitNode(nsINode* aOldRightNode, int32_t aOffset,
nsINode* aNewLeftNode)
{
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
if (mLock) {
// lock set by Will/DidReplaceParent, etc...
return NS_OK;
}
NS_ENSURE_TRUE(aOldRightNode && aNewLeftNode, NS_ERROR_NULL_POINTER);
uint32_t i, count = mArray.Length();
uint32_t count = mArray.Length();
if (!count) {
return NS_OK;
}
int32_t offset;
nsCOMPtr<nsIDOMNode> parent = nsEditor::GetNodeLocation(aOldRightNode, &offset);
nsCOMPtr<nsINode> parent = aOldRightNode->GetParentNode();
int32_t offset = parent ? parent->IndexOf(aOldRightNode) : -1;
// first part is same as inserting aNewLeftnode
nsresult result = SelAdjInsertNode(parent,offset-1);
nsresult result = SelAdjInsertNode(parent, offset - 1);
NS_ENSURE_SUCCESS(result, result);
// next step is to check for range enpoints inside aOldRightNode
nsRangeStore *item;
for (i=0; i<count; i++)
{
item = mArray[i];
for (uint32_t i = 0; i < count; i++) {
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if (item->startNode.get() == aOldRightNode)
{
if (item->startOffset > aOffset)
{
if (item->startNode == aOldRightNode) {
if (item->startOffset > aOffset) {
item->startOffset -= aOffset;
}
else
{
} else {
item->startNode = aNewLeftNode;
}
}
if (item->endNode.get() == aOldRightNode)
{
if (item->endOffset > aOffset)
{
if (item->endNode == aOldRightNode) {
if (item->endOffset > aOffset) {
item->endOffset -= aOffset;
}
else
{
} else {
item->endNode = aNewLeftNode;
}
}
@ -352,143 +363,171 @@ nsRangeUpdater::SelAdjSplitNode(nsIDOMNode *aOldRightNode, int32_t aOffset, nsID
return NS_OK;
}
nsresult
nsRangeUpdater::SelAdjJoinNodes(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
nsIDOMNode *aParent,
int32_t aOffset,
int32_t aOldLeftNodeLength)
nsRangeUpdater::SelAdjSplitNode(nsIDOMNode* aOldRightNode, int32_t aOffset,
nsIDOMNode* aNewLeftNode)
{
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
NS_ENSURE_TRUE(aLeftNode && aRightNode && aParent, NS_ERROR_NULL_POINTER);
uint32_t i, count = mArray.Length();
if (!count) {
return NS_OK;
}
nsRangeStore *item;
for (i=0; i<count; i++)
{
item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if (item->startNode.get() == aParent)
{
// adjust start point in aParent
if (item->startOffset > aOffset)
{
item->startOffset--;
}
else if (item->startOffset == aOffset)
{
// join keeps right hand node
item->startNode = aRightNode;
item->startOffset = aOldLeftNodeLength;
}
}
else if (item->startNode.get() == aRightNode)
{
// adjust start point in aRightNode
item->startOffset += aOldLeftNodeLength;
}
else if (item->startNode.get() == aLeftNode)
{
// adjust start point in aLeftNode
item->startNode = aRightNode;
}
if (item->endNode.get() == aParent)
{
// adjust end point in aParent
if (item->endOffset > aOffset)
{
item->endOffset--;
}
else if (item->endOffset == aOffset)
{
// join keeps right hand node
item->endNode = aRightNode;
item->endOffset = aOldLeftNodeLength;
}
}
else if (item->endNode.get() == aRightNode)
{
// adjust end point in aRightNode
item->endOffset += aOldLeftNodeLength;
}
else if (item->endNode.get() == aLeftNode)
{
// adjust end point in aLeftNode
item->endNode = aRightNode;
}
}
return NS_OK;
nsCOMPtr<nsINode> oldRightNode = do_QueryInterface(aOldRightNode);
nsCOMPtr<nsINode> newLeftNode = do_QueryInterface(aNewLeftNode);
return SelAdjSplitNode(oldRightNode, aOffset, newLeftNode);
}
nsresult
nsRangeUpdater::SelAdjInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString)
nsRangeUpdater::SelAdjJoinNodes(nsINode* aLeftNode,
nsINode* aRightNode,
nsINode* aParent,
int32_t aOffset,
int32_t aOldLeftNodeLength)
{
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
if (mLock) {
// lock set by Will/DidReplaceParent, etc...
return NS_OK;
}
NS_ENSURE_TRUE(aLeftNode && aRightNode && aParent, NS_ERROR_NULL_POINTER);
uint32_t count = mArray.Length();
if (!count) {
return NS_OK;
}
for (uint32_t i = 0; i < count; i++) {
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if (item->startNode == aParent) {
// adjust start point in aParent
if (item->startOffset > aOffset) {
item->startOffset--;
} else if (item->startOffset == aOffset) {
// join keeps right hand node
item->startNode = aRightNode;
item->startOffset = aOldLeftNodeLength;
}
} else if (item->startNode == aRightNode) {
// adjust start point in aRightNode
item->startOffset += aOldLeftNodeLength;
} else if (item->startNode == aLeftNode) {
// adjust start point in aLeftNode
item->startNode = aRightNode;
}
if (item->endNode == aParent) {
// adjust end point in aParent
if (item->endOffset > aOffset) {
item->endOffset--;
} else if (item->endOffset == aOffset) {
// join keeps right hand node
item->endNode = aRightNode;
item->endOffset = aOldLeftNodeLength;
}
} else if (item->endNode == aRightNode) {
// adjust end point in aRightNode
item->endOffset += aOldLeftNodeLength;
} else if (item->endNode == aLeftNode) {
// adjust end point in aLeftNode
item->endNode = aRightNode;
}
}
return NS_OK;
}
nsresult
nsRangeUpdater::SelAdjJoinNodes(nsIDOMNode* aLeftNode,
nsIDOMNode* aRightNode,
nsIDOMNode* aParent,
int32_t aOffset,
int32_t aOldLeftNodeLength)
{
nsCOMPtr<nsINode> leftNode = do_QueryInterface(aLeftNode);
nsCOMPtr<nsINode> rightNode = do_QueryInterface(aRightNode);
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
return SelAdjJoinNodes(leftNode, rightNode, parent, aOffset, aOldLeftNodeLength);
}
nsresult
nsRangeUpdater::SelAdjInsertText(nsIContent* aTextNode, int32_t aOffset,
const nsAString &aString)
{
if (mLock) {
// lock set by Will/DidReplaceParent, etc...
return NS_OK;
}
uint32_t count = mArray.Length();
if (!count) {
return NS_OK;
}
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aTextNode));
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
uint32_t len=aString.Length(), i;
nsRangeStore *item;
for (i=0; i<count; i++)
{
item = mArray[i];
NS_ENSURE_TRUE(aTextNode, NS_ERROR_NULL_POINTER);
uint32_t len = aString.Length();
for (uint32_t i = 0; i < count; i++) {
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if ((item->startNode.get() == node) && (item->startOffset > aOffset))
if (item->startNode == aTextNode && item->startOffset > aOffset) {
item->startOffset += len;
if ((item->endNode.get() == node) && (item->endOffset > aOffset))
}
if (item->endNode == aTextNode && item->endOffset > aOffset) {
item->endOffset += len;
}
}
return NS_OK;
}
nsresult
nsRangeUpdater::SelAdjInsertText(nsIDOMCharacterData* aTextNode,
int32_t aOffset, const nsAString &aString)
{
nsCOMPtr<nsIContent> textNode = do_QueryInterface(aTextNode);
return SelAdjInsertText(textNode, aOffset, aString);
}
nsresult
nsRangeUpdater::SelAdjDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength)
nsRangeUpdater::SelAdjDeleteText(nsIContent* aTextNode, int32_t aOffset,
int32_t aLength)
{
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
if (mLock) {
// lock set by Will/DidReplaceParent, etc...
return NS_OK;
}
uint32_t i, count = mArray.Length();
uint32_t count = mArray.Length();
if (!count) {
return NS_OK;
}
nsRangeStore *item;
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aTextNode));
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
for (i=0; i<count; i++)
{
item = mArray[i];
NS_ENSURE_TRUE(aTextNode, NS_ERROR_NULL_POINTER);
for (uint32_t i = 0; i < count; i++) {
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if ((item->startNode.get() == node) && (item->startOffset > aOffset))
{
if (item->startNode == aTextNode && item->startOffset > aOffset) {
item->startOffset -= aLength;
if (item->startOffset < 0) item->startOffset = 0;
if (item->startOffset < 0) {
item->startOffset = 0;
}
}
if ((item->endNode.get() == node) && (item->endOffset > aOffset))
{
if (item->endNode == aTextNode && item->endOffset > aOffset) {
item->endOffset -= aLength;
if (item->endOffset < 0) item->endOffset = 0;
if (item->endOffset < 0) {
item->endOffset = 0;
}
}
}
return NS_OK;
}
nsresult
nsRangeUpdater::SelAdjDeleteText(nsIDOMCharacterData* aTextNode,
int32_t aOffset, int32_t aLength)
{
nsCOMPtr<nsIContent> textNode = do_QueryInterface(aTextNode);
return SelAdjDeleteText(textNode, aOffset, aLength);
}
nsresult
nsRangeUpdater::WillReplaceContainer()
@ -500,32 +539,40 @@ nsRangeUpdater::WillReplaceContainer()
nsresult
nsRangeUpdater::DidReplaceContainer(nsIDOMNode *aOriginalNode, nsIDOMNode *aNewNode)
nsRangeUpdater::DidReplaceContainer(nsINode* aOriginalNode, nsINode* aNewNode)
{
NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
mLock = false;
NS_ENSURE_TRUE(aOriginalNode && aNewNode, NS_ERROR_NULL_POINTER);
uint32_t i, count = mArray.Length();
uint32_t count = mArray.Length();
if (!count) {
return NS_OK;
}
nsRangeStore *item;
for (i=0; i<count; i++)
{
item = mArray[i];
for (uint32_t i = 0; i < count; i++) {
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if (item->startNode.get() == aOriginalNode)
if (item->startNode == aOriginalNode) {
item->startNode = aNewNode;
if (item->endNode.get() == aOriginalNode)
}
if (item->endNode == aOriginalNode) {
item->endNode = aNewNode;
}
}
return NS_OK;
}
nsresult
nsRangeUpdater::DidReplaceContainer(nsIDOMNode* aOriginalNode,
nsIDOMNode* aNewNode)
{
nsCOMPtr<nsINode> originalNode = do_QueryInterface(aOriginalNode);
nsCOMPtr<nsINode> newNode = do_QueryInterface(aNewNode);
return DidReplaceContainer(originalNode, newNode);
}
nsresult
nsRangeUpdater::WillRemoveContainer()
@ -537,43 +584,48 @@ nsRangeUpdater::WillRemoveContainer()
nsresult
nsRangeUpdater::DidRemoveContainer(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aOffset, uint32_t aNodeOrigLen)
nsRangeUpdater::DidRemoveContainer(nsINode* aNode, nsINode* aParent,
int32_t aOffset, uint32_t aNodeOrigLen)
{
NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
mLock = false;
NS_ENSURE_TRUE(aNode && aParent, NS_ERROR_NULL_POINTER);
uint32_t i, count = mArray.Length();
uint32_t count = mArray.Length();
if (!count) {
return NS_OK;
}
nsRangeStore *item;
for (i=0; i<count; i++)
{
item = mArray[i];
for (uint32_t i = 0; i < count; i++) {
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if (item->startNode.get() == aNode)
{
if (item->startNode == aNode) {
item->startNode = aParent;
item->startOffset += aOffset;
} else if (item->startNode == aParent && item->startOffset > aOffset) {
item->startOffset += (int32_t)aNodeOrigLen - 1;
}
else if ((item->startNode.get() == aParent) && (item->startOffset > aOffset))
item->startOffset += (int32_t)aNodeOrigLen-1;
if (item->endNode.get() == aNode)
{
if (item->endNode == aNode) {
item->endNode = aParent;
item->endOffset += aOffset;
} else if (item->endNode == aParent && item->endOffset > aOffset) {
item->endOffset += (int32_t)aNodeOrigLen - 1;
}
else if ((item->endNode.get() == aParent) && (item->endOffset > aOffset))
item->endOffset += (int32_t)aNodeOrigLen-1;
}
return NS_OK;
}
nsresult
nsRangeUpdater::DidRemoveContainer(nsIDOMNode* aNode, nsIDOMNode* aParent,
int32_t aOffset, uint32_t aNodeOrigLen)
{
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
return DidRemoveContainer(node, parent, aOffset, aNodeOrigLen);
}
nsresult
nsRangeUpdater::WillInsertContainer()
@ -609,26 +661,23 @@ nsRangeUpdater::DidMoveNode(nsINode* aOldParent, int32_t aOldOffset,
NS_ENSURE_TRUE_VOID(mLock);
mLock = false;
nsIDOMNode* oldParent = aOldParent->AsDOMNode();
nsIDOMNode* newParent = aNewParent->AsDOMNode();
for (uint32_t i = 0, count = mArray.Length(); i < count; ++i) {
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE_VOID(item);
// like a delete in aOldParent
if (item->startNode == oldParent && item->startOffset > aOldOffset) {
if (item->startNode == aOldParent && item->startOffset > aOldOffset) {
item->startOffset--;
}
if (item->endNode == oldParent && item->endOffset > aOldOffset) {
if (item->endNode == aOldParent && item->endOffset > aOldOffset) {
item->endOffset--;
}
// and like an insert in aNewParent
if (item->startNode == newParent && item->startOffset > aNewOffset) {
if (item->startNode == aNewParent && item->startOffset > aNewOffset) {
item->startOffset++;
}
if (item->endNode == newParent && item->endOffset > aNewOffset) {
if (item->endNode == aNewParent && item->endOffset > aNewOffset) {
item->endOffset++;
}
}
@ -640,29 +689,28 @@ nsRangeUpdater::DidMoveNode(nsINode* aOldParent, int32_t aOldOffset,
* helper class for nsSelectionState. nsRangeStore stores range endpoints.
*/
// DEBUG: int32_t nsRangeStore::n = 0;
nsRangeStore::nsRangeStore()
{
// DEBUG: n++; printf("range store alloc count=%d\n", n);
}
nsRangeStore::~nsRangeStore()
{
// DEBUG: n--; printf("range store alloc count=%d\n", n);
}
nsresult nsRangeStore::StoreRange(nsIDOMRange *aRange)
void
nsRangeStore::StoreRange(nsRange* aRange)
{
NS_ENSURE_TRUE(aRange, NS_ERROR_NULL_POINTER);
aRange->GetStartContainer(getter_AddRefs(startNode));
aRange->GetEndContainer(getter_AddRefs(endNode));
aRange->GetStartOffset(&startOffset);
aRange->GetEndOffset(&endOffset);
return NS_OK;
MOZ_ASSERT(aRange);
startNode = aRange->GetStartParent();
startOffset = aRange->StartOffset();
endNode = aRange->GetEndParent();
endOffset = aRange->EndOffset();
}
nsresult nsRangeStore::GetRange(nsRange** outRange)
already_AddRefed<nsRange>
nsRangeStore::GetRange()
{
return nsRange::CreateRange(startNode, startOffset, endNode, endOffset,
outRange);
nsRefPtr<nsRange> range = new nsRange(startNode);
nsresult res = range->Set(startNode, startOffset, endNode, endOffset);
NS_ENSURE_SUCCESS(res, nullptr);
return range.forget();
}

View File

@ -39,16 +39,15 @@ private:
~nsRangeStore();
public:
nsresult StoreRange(nsIDOMRange *aRange);
nsresult GetRange(nsRange** outRange);
void StoreRange(nsRange* aRange);
already_AddRefed<nsRange> GetRange();
NS_INLINE_DECL_REFCOUNTING(nsRangeStore)
nsCOMPtr<nsIDOMNode> startNode;
int32_t startOffset;
nsCOMPtr<nsIDOMNode> endNode;
int32_t endOffset;
// DEBUG: static int32_t n;
nsCOMPtr<nsINode> startNode;
int32_t startOffset;
nsCOMPtr<nsINode> endNode;
int32_t endOffset;
};
class nsSelectionState
@ -90,22 +89,39 @@ class nsRangeUpdater
// if you move a node, that corresponds to deleting it and reinserting it.
// DOM Range gravity will promote the selection out of the node on deletion,
// which is not what you want if you know you are reinserting it.
nsresult SelAdjCreateNode(nsINode* aParent, int32_t aPosition);
nsresult SelAdjCreateNode(nsIDOMNode *aParent, int32_t aPosition);
nsresult SelAdjInsertNode(nsINode* aParent, int32_t aPosition);
nsresult SelAdjInsertNode(nsIDOMNode *aParent, int32_t aPosition);
void SelAdjDeleteNode(nsINode* aNode);
void SelAdjDeleteNode(nsIDOMNode *aNode);
nsresult SelAdjSplitNode(nsINode* aOldRightNode, int32_t aOffset,
nsINode* aNewLeftNode);
nsresult SelAdjSplitNode(nsIDOMNode *aOldRightNode, int32_t aOffset, nsIDOMNode *aNewLeftNode);
nsresult SelAdjJoinNodes(nsINode* aLeftNode,
nsINode* aRightNode,
nsINode* aParent,
int32_t aOffset,
int32_t aOldLeftNodeLength);
nsresult SelAdjJoinNodes(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
nsIDOMNode *aParent,
int32_t aOffset,
int32_t aOldLeftNodeLength);
nsresult SelAdjInsertText(nsIContent* aTextNode, int32_t aOffset,
const nsAString &aString);
nsresult SelAdjInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString);
nsresult SelAdjDeleteText(nsIContent* aTextNode, int32_t aOffset,
int32_t aLength);
nsresult SelAdjDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength);
// the following gravity routines need will/did sandwiches, because the other gravity
// routines will be called inside of these sandwiches, but should be ignored.
nsresult WillReplaceContainer();
nsresult DidReplaceContainer(nsINode* aOriginalNode, nsINode* aNewNode);
nsresult DidReplaceContainer(nsIDOMNode *aOriginalNode, nsIDOMNode *aNewNode);
nsresult WillRemoveContainer();
nsresult DidRemoveContainer(nsINode* aNode, nsINode* aParent,
int32_t aOffset, uint32_t aNodeOrigLen);
nsresult DidRemoveContainer(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aOffset, uint32_t aNodeOrigLen);
nsresult WillInsertContainer();
nsresult DidInsertContainer();
@ -137,8 +153,8 @@ class MOZ_STACK_CLASS nsAutoTrackDOMPoint
,mOffset(aOffset)
{
mRangeItem = new nsRangeStore();
mRangeItem->startNode = *mNode;
mRangeItem->endNode = *mNode;
mRangeItem->startNode = do_QueryInterface(*mNode);
mRangeItem->endNode = do_QueryInterface(*mNode);
mRangeItem->startOffset = *mOffset;
mRangeItem->endOffset = *mOffset;
mRU.RegisterRangeItem(mRangeItem);
@ -147,7 +163,7 @@ class MOZ_STACK_CLASS nsAutoTrackDOMPoint
~nsAutoTrackDOMPoint()
{
mRU.DropRangeItem(mRangeItem);
*mNode = mRangeItem->startNode;
*mNode = GetAsDOMNode(mRangeItem->startNode);
*mOffset = mRangeItem->startOffset;
}
};

View File

@ -304,26 +304,17 @@ nsHTMLEditRules::BeforeEdit(EditAction action,
// remember where our selection was before edit action took place:
// get selection
nsCOMPtr<nsISelection> selection;
NS_ENSURE_STATE(mHTMLEditor);
nsresult res = mHTMLEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
// get the selection start location
nsCOMPtr<nsIDOMNode> selStartNode, selEndNode;
int32_t selOffset;
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->GetStartNodeAndOffset(selection, getter_AddRefs(selStartNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
mRangeItem->startNode = selStartNode;
mRangeItem->startOffset = selOffset;
nsRefPtr<Selection> selection = mHTMLEditor->GetSelection();
// get the selection end location
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->GetEndNodeAndOffset(selection, getter_AddRefs(selEndNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
mRangeItem->endNode = selEndNode;
mRangeItem->endOffset = selOffset;
// get the selection location
NS_ENSURE_STATE(selection->GetRangeCount());
mRangeItem->startNode = selection->GetRangeAt(0)->GetStartParent();
mRangeItem->startOffset = selection->GetRangeAt(0)->StartOffset();
mRangeItem->endNode = selection->GetRangeAt(0)->GetEndParent();
mRangeItem->endOffset = selection->GetRangeAt(0)->EndOffset();
nsCOMPtr<nsIDOMNode> selStartNode = GetAsDOMNode(mRangeItem->startNode);
nsCOMPtr<nsIDOMNode> selEndNode = GetAsDOMNode(mRangeItem->endNode);
// register this range with range updater to track this as we perturb the doc
NS_ENSURE_STATE(mHTMLEditor);
@ -352,7 +343,7 @@ nsHTMLEditRules::BeforeEdit(EditAction action,
nsCOMPtr<nsIDOMNode> selNode = selStartNode;
if (aDirection == nsIEditor::eNext)
selNode = selEndNode;
res = CacheInlineStyles(selNode);
nsresult res = CacheInlineStyles(selNode);
NS_ENSURE_SUCCESS(res, res);
}
@ -490,13 +481,13 @@ nsHTMLEditRules::AfterEditInner(EditAction action,
// also do this for original selection endpoints.
NS_ENSURE_STATE(mHTMLEditor);
nsWSRunObject(mHTMLEditor, mRangeItem->startNode,
nsWSRunObject(mHTMLEditor, GetAsDOMNode(mRangeItem->startNode),
mRangeItem->startOffset).AdjustWhitespace();
// we only need to handle old selection endpoint if it was different from start
if (mRangeItem->startNode != mRangeItem->endNode ||
mRangeItem->startOffset != mRangeItem->endOffset) {
NS_ENSURE_STATE(mHTMLEditor);
nsWSRunObject(mHTMLEditor, mRangeItem->endNode,
nsWSRunObject(mHTMLEditor, GetAsDOMNode(mRangeItem->endNode),
mRangeItem->endOffset).AdjustWhitespace();
}
}
@ -536,7 +527,7 @@ nsHTMLEditRules::AfterEditInner(EditAction action,
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->HandleInlineSpellCheck(action, selection,
mRangeItem->startNode,
GetAsDOMNode(mRangeItem->startNode),
mRangeItem->startOffset,
rangeStartParent, rangeStartOffset,
rangeEndParent, rangeEndOffset);
@ -5942,7 +5933,7 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
{
opRange = inArrayOfRanges[0];
rangeItemArray[i] = new nsRangeStore();
rangeItemArray[i]->StoreRange(opRange);
rangeItemArray[i]->StoreRange(static_cast<nsRange*>(opRange.get()));
NS_ENSURE_STATE(mHTMLEditor);
mHTMLEditor->mRangeUpdater.RegisterRangeItem(rangeItemArray[i]);
inArrayOfRanges.RemoveObjectAt(0);
@ -5959,14 +5950,7 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
nsRangeStore* item = rangeItemArray[i];
NS_ENSURE_STATE(mHTMLEditor);
mHTMLEditor->mRangeUpdater.DropRangeItem(item);
nsRefPtr<nsRange> range;
nsresult res2 = item->GetRange(getter_AddRefs(range));
opRange = range;
if (NS_FAILED(res2) && NS_SUCCEEDED(res)) {
// Remember the failure, but keep going so we make sure to unregister
// all our range items.
res = res2;
}
opRange = item->GetRange();
inArrayOfRanges.AppendObject(opRange);
}
NS_ENSURE_SUCCESS(res, res);
@ -6331,7 +6315,8 @@ nsHTMLEditRules::BustUpInlinesAtRangeEndpoints(nsRangeStore &item)
nsresult res = NS_OK;
bool isCollapsed = ((item.startNode == item.endNode) && (item.startOffset == item.endOffset));
nsCOMPtr<nsIDOMNode> endInline = GetHighestInlineParent(item.endNode);
nsCOMPtr<nsIDOMNode> endInline =
GetHighestInlineParent(GetAsDOMNode(item.endNode));
// if we have inline parents above range endpoints, split them
if (endInline && !isCollapsed)
@ -6340,14 +6325,16 @@ nsHTMLEditRules::BustUpInlinesAtRangeEndpoints(nsRangeStore &item)
int32_t resultEndOffset;
endInline->GetParentNode(getter_AddRefs(resultEndNode));
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->SplitNodeDeep(endInline, item.endNode, item.endOffset,
&resultEndOffset, true);
res = mHTMLEditor->SplitNodeDeep(endInline, GetAsDOMNode(item.endNode),
item.endOffset, &resultEndOffset, true);
NS_ENSURE_SUCCESS(res, res);
// reset range
item.endNode = resultEndNode; item.endOffset = resultEndOffset;
item.endNode = do_QueryInterface(resultEndNode);
item.endOffset = resultEndOffset;
}
nsCOMPtr<nsIDOMNode> startInline = GetHighestInlineParent(item.startNode);
nsCOMPtr<nsIDOMNode> startInline =
GetHighestInlineParent(GetAsDOMNode(item.startNode));
if (startInline)
{
@ -6355,11 +6342,13 @@ nsHTMLEditRules::BustUpInlinesAtRangeEndpoints(nsRangeStore &item)
int32_t resultStartOffset;
startInline->GetParentNode(getter_AddRefs(resultStartNode));
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->SplitNodeDeep(startInline, item.startNode, item.startOffset,
&resultStartOffset, true);
res = mHTMLEditor->SplitNodeDeep(startInline, GetAsDOMNode(item.startNode),
item.startOffset, &resultStartOffset,
true);
NS_ENSURE_SUCCESS(res, res);
// reset range
item.startNode = resultStartNode; item.startOffset = resultStartOffset;
item.startNode = do_QueryInterface(resultStartNode);
item.startOffset = resultStartOffset;
}
return res;