adding range gravity for dom text nodes

This commit is contained in:
jfrancis%netscape.com 1999-01-03 14:29:54 +00:00
Родитель 99455f5082
Коммит ff9cf6ef75
5 изменённых файлов: 154 добавлений и 1 удалений

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

@ -1311,6 +1311,9 @@ nsresult nsRange::OwnerGone(nsIContent* aDyingNode)
nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset)
{
// sanity check - null nodes shouldn't have enclosed ranges
if (!aParentNode) return NS_ERROR_UNEXPECTED;
// quick return if no range list
nsVoidArray *theRangeList;
aParentNode->GetRangeList(theRangeList);
@ -1353,6 +1356,9 @@ nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset)
nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aRemovedNode)
{
// sanity check - null nodes shouldn't have enclosed ranges
if (!aParentNode) return NS_ERROR_UNEXPECTED;
// quick return if no range list
nsVoidArray *theRangeList;
aParentNode->GetRangeList(theRangeList);
@ -1403,6 +1409,9 @@ nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, ns
nsresult nsRange::OwnerChildReplaced(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aReplacedNode)
{
// sanity check - null nodes shouldn't have enclosed ranges
if (!aParentNode) return NS_ERROR_UNEXPECTED;
// don't need to adjust ranges whose endpoints are in this parent,
// but we do need to pop out any range endpoints inside the subtree
// rooted by aReplacedNode.
@ -1420,3 +1429,65 @@ nsresult nsRange::OwnerChildReplaced(nsIContent* aParentNode, PRInt32 aOffset, n
return res;
}
nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged, PRInt32 aEndChanged, PRInt32 aReplaceLength)
{
// sanity check - null nodes shouldn't have enclosed ranges
if (!aTextNode) return NS_ERROR_UNEXPECTED;
nsVoidArray *theRangeList;
aTextNode->GetRangeList(theRangeList);
// the caller already checked to see if there was a range list
PRInt32 loop = 0;
nsRange *theRange;
nsIDOMNode *domNode;
nsresult res;
res = GetDOMNodeFromContent(aTextNode, &domNode);
if (NS_SUCCEEDED(res)) return res;
if (!domNode) return NS_ERROR_UNEXPECTED;
// any ranges that are in the textNode may need to have offsets updated
while (theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))))
{
// sanity check - do range and content agree over ownership?
res = theRange->ContentOwnsUs(domNode);
NS_PRECONDITION(NS_SUCCEEDED(res), "range and content disagree over range ownership");
if (NS_SUCCEEDED(res))
{
PRBool bStartPointInChangedText = false;
if (theRange->mStartParent == domNode)
{
// if range start is inside changed text, position it after change
if ((aStartChanged <= theRange->mStartOffset) && (aEndChanged >= theRange->mStartOffset))
{
theRange->mStartOffset = aStartChanged+aReplaceLength;
bStartPointInChangedText = true;
}
// else if text changed before start, adjust start offset
else if (aEndChanged <= theRange->mStartOffset)
theRange->mStartOffset += aStartChanged + aReplaceLength - aEndChanged;
}
if (theRange->mEndParent == domNode)
{
// if range end is inside changed text, position it before change
if ((aStartChanged <= theRange->mEndOffset) && (aEndChanged >= theRange->mEndOffset))
{
theRange->mEndOffset = aStartChanged;
// hack: if BOTH range endpoints were inside the change, then they
// both get collapsed to the beginning of the change.
if (bStartPointInChangedText) theRange->mStartOffset = aStartChanged;
}
// else if text changed before end, adjust end offset
else if (aEndChanged <= theRange->mEndOffset)
theRange->mEndOffset += aStartChanged + aReplaceLength - aEndChanged;
}
}
loop++;
}
NS_RELEASE(domNode);
return NS_OK;
}

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

@ -88,6 +88,7 @@ public:
static NS_METHOD OwnerChildReplaced(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aReplacedNode);
static NS_METHOD TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartOffset, PRInt32 aEndOffset, PRInt32 aReplaceLength);
private:
PRBool mIsPositioned;

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

@ -1311,6 +1311,9 @@ nsresult nsRange::OwnerGone(nsIContent* aDyingNode)
nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset)
{
// sanity check - null nodes shouldn't have enclosed ranges
if (!aParentNode) return NS_ERROR_UNEXPECTED;
// quick return if no range list
nsVoidArray *theRangeList;
aParentNode->GetRangeList(theRangeList);
@ -1353,6 +1356,9 @@ nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset)
nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aRemovedNode)
{
// sanity check - null nodes shouldn't have enclosed ranges
if (!aParentNode) return NS_ERROR_UNEXPECTED;
// quick return if no range list
nsVoidArray *theRangeList;
aParentNode->GetRangeList(theRangeList);
@ -1403,6 +1409,9 @@ nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, ns
nsresult nsRange::OwnerChildReplaced(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aReplacedNode)
{
// sanity check - null nodes shouldn't have enclosed ranges
if (!aParentNode) return NS_ERROR_UNEXPECTED;
// don't need to adjust ranges whose endpoints are in this parent,
// but we do need to pop out any range endpoints inside the subtree
// rooted by aReplacedNode.
@ -1420,3 +1429,65 @@ nsresult nsRange::OwnerChildReplaced(nsIContent* aParentNode, PRInt32 aOffset, n
return res;
}
nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged, PRInt32 aEndChanged, PRInt32 aReplaceLength)
{
// sanity check - null nodes shouldn't have enclosed ranges
if (!aTextNode) return NS_ERROR_UNEXPECTED;
nsVoidArray *theRangeList;
aTextNode->GetRangeList(theRangeList);
// the caller already checked to see if there was a range list
PRInt32 loop = 0;
nsRange *theRange;
nsIDOMNode *domNode;
nsresult res;
res = GetDOMNodeFromContent(aTextNode, &domNode);
if (NS_SUCCEEDED(res)) return res;
if (!domNode) return NS_ERROR_UNEXPECTED;
// any ranges that are in the textNode may need to have offsets updated
while (theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))))
{
// sanity check - do range and content agree over ownership?
res = theRange->ContentOwnsUs(domNode);
NS_PRECONDITION(NS_SUCCEEDED(res), "range and content disagree over range ownership");
if (NS_SUCCEEDED(res))
{
PRBool bStartPointInChangedText = false;
if (theRange->mStartParent == domNode)
{
// if range start is inside changed text, position it after change
if ((aStartChanged <= theRange->mStartOffset) && (aEndChanged >= theRange->mStartOffset))
{
theRange->mStartOffset = aStartChanged+aReplaceLength;
bStartPointInChangedText = true;
}
// else if text changed before start, adjust start offset
else if (aEndChanged <= theRange->mStartOffset)
theRange->mStartOffset += aStartChanged + aReplaceLength - aEndChanged;
}
if (theRange->mEndParent == domNode)
{
// if range end is inside changed text, position it before change
if ((aStartChanged <= theRange->mEndOffset) && (aEndChanged >= theRange->mEndOffset))
{
theRange->mEndOffset = aStartChanged;
// hack: if BOTH range endpoints were inside the change, then they
// both get collapsed to the beginning of the change.
if (bStartPointInChangedText) theRange->mStartOffset = aStartChanged;
}
// else if text changed before end, adjust end offset
else if (aEndChanged <= theRange->mEndOffset)
theRange->mEndOffset += aStartChanged + aReplaceLength - aEndChanged;
}
}
loop++;
}
NS_RELEASE(domNode);
return NS_OK;
}

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

@ -88,6 +88,7 @@ public:
static NS_METHOD OwnerChildReplaced(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aReplacedNode);
static NS_METHOD TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartOffset, PRInt32 aEndOffset, PRInt32 aReplaceLength);
private:
PRBool mIsPositioned;

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

@ -23,6 +23,7 @@
#include "nsIDOMRange.h"
#include "nsXIFConverter.h"
#include "nsSelectionRange.h"
#include "nsRange.h"
#include "nsCRT.h"
#include "nsIEventStateManager.h"
#include "nsIPrivateDOMEvent.h"
@ -193,8 +194,13 @@ nsGenericDOMDataNode::GetData(nsString& aData)
nsresult
nsGenericDOMDataNode::SetData(const nsString& aData)
{
mText = aData;
// inform any enclosed ranges of change
// we can lie and say we are deleting all the text, since in a total
// text replacement we should just collapse all the ranges.
if (mRangeList) nsRange::TextOwnerChanged(mContent, 0, mText.GetLength(), 0);
mText = aData;
// Notify the document that the text changed
if (nsnull != mDocument) {
mDocument->ContentChanged(mContent, nsnull);
@ -282,6 +288,9 @@ nsGenericDOMDataNode::ReplaceData(PRUint32 aOffset, PRUint32 aCount,
return NS_ERROR_OUT_OF_MEMORY;
}
// inform any enclosed ranges of change
if (mRangeList) nsRange::TextOwnerChanged(mContent, aOffset, endOffset, dataLength);
// Copy over appropriate data
if (0 != aOffset) {
mText.CopyTo(to, 0, aOffset);