40457: Add implementation for range methods to tell whether

a node or point intersects the range. r=jfrancis, a=beppe.
This commit is contained in:
akkana%netscape.com 2000-06-07 22:57:36 +00:00
Родитель 13f84efc5a
Коммит 4d58187b46
4 изменённых файлов: 268 добавлений и 148 удалений

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

@ -335,6 +335,126 @@ nsresult nsRange::QueryInterface(const nsIID& aIID,
return NS_NOINTERFACE;
}
/********************************************************
* Utilities for comparing points: API from nsIDOMNSRange
********************************************************/
NS_IMETHODIMP
nsRange::IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset, PRBool* aResult)
{
PRInt16 compareResult = 0;
nsresult res;
res = ComparePoint(aParent, aOffset, &compareResult);
if (compareResult)
*aResult = PR_FALSE;
else
*aResult = PR_TRUE;
return res;
}
// returns -1 if point is before range, 0 if point is in range,
// 1 if point is after range.
NS_IMETHODIMP
nsRange::ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset, PRInt16* aResult)
{
// check arguments
if (!aResult)
return NS_ERROR_NULL_POINTER;
// no trivial cases please
if (!aParent)
return NS_ERROR_NULL_POINTER;
// our range is in a good state?
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
// check common case first
if ((aParent == mStartParent.get()) && (aParent == mEndParent.get()))
{
if (aOffset<mStartOffset)
{
*aResult = -1;
return NS_OK;
}
if (aOffset>mEndOffset)
{
*aResult = 1;
return NS_OK;
}
*aResult = 0;
return NS_OK;
}
// more common cases
if ((aParent == mStartParent.get()) && (aOffset == mStartOffset))
{
*aResult = 0;
return NS_OK;
}
if ((aParent == mEndParent.get()) && (aOffset == mEndOffset))
{
*aResult = 0;
return NS_OK;
}
// ok, do it the hard way
if (IsIncreasing(aParent,aOffset,mStartParent,mStartOffset))
*aResult = -1;
else if (IsIncreasing(mEndParent,mEndOffset,aParent,aOffset))
*aResult = 1;
else
*aResult = 0;
return NS_OK;
}
NS_IMETHODIMP
nsRange::IntersectsNode(nsIDOMNode* aNode, PRBool* aReturn)
{
if (!aReturn)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIContent> content (do_QueryInterface(aNode));
if (!content)
{
*aReturn = 0;
return NS_ERROR_UNEXPECTED;
}
*aReturn = IsNodeIntersectsRange(content, this);
return NS_OK;
}
// HOW does the node intersect the range?
NS_IMETHODIMP
nsRange::CompareNode(nsIDOMNode* aNode, PRInt16* aReturn)
{
if (!aReturn)
return NS_ERROR_NULL_POINTER;
*aReturn = 0;
PRBool nodeBefore, nodeAfter;
nsCOMPtr<nsIContent> content (do_QueryInterface(aNode));
if (!content)
return NS_ERROR_UNEXPECTED;
nsresult res = CompareNodeToRange(content, this, &nodeBefore, &nodeAfter);
if (NS_FAILED(res))
return res;
// nodeBefore -> range start after node start, i.e. node starts before range.
// nodeAfter -> range end before node end, i.e. node ends after range.
// But I know that I get nodeBefore && !nodeAfter when the node is
// entirely inside the selection! This doesn't make sense.
if (nodeBefore && !nodeAfter)
*aReturn = nsIDOMNSRange::NODE_BEFORE; // May or may not intersect
else if (!nodeBefore && nodeAfter)
*aReturn = nsIDOMNSRange::NODE_AFTER; // May or may not intersect
else if (nodeBefore && nodeAfter)
*aReturn = nsIDOMNSRange::NODE_BEFORE_AND_AFTER; // definitely intersects
else
*aReturn = nsIDOMNSRange::NODE_INSIDE; // definitely intersects
return NS_OK;
}
/******************************************************
* Private helper routines
******************************************************/
@ -550,73 +670,6 @@ PRBool nsRange::IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOffset,
}
}
nsresult nsRange::IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset, PRBool* aResult)
{
PRInt32 compareResult = 0;
nsresult res;
res = ComparePointToRange(aParent, aOffset, &compareResult);
if (compareResult)
*aResult = PR_FALSE;
else
*aResult = PR_TRUE;
return res;
}
// returns -1 if point is before range, 0 if point is in range, 1 if point is after range
nsresult nsRange::ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult)
{
// check arguments
if (!aResult)
return NS_ERROR_NULL_POINTER;
// no trivial cases please
if (!aParent)
return NS_ERROR_NULL_POINTER;
// our range is in a good state?
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
// check common case first
if ((aParent == mStartParent.get()) && (aParent == mEndParent.get()))
{
if (aOffset<mStartOffset)
{
*aResult = -1;
return NS_OK;
}
if (aOffset>mEndOffset)
{
*aResult = 1;
return NS_OK;
}
*aResult = 0;
return NS_OK;
}
// more common cases
if ((aParent == mStartParent.get()) && (aOffset == mStartOffset))
{
*aResult = 0;
return NS_OK;
}
if ((aParent == mEndParent.get()) && (aOffset == mEndOffset))
{
*aResult = 0;
return NS_OK;
}
// ok, do it the hard way
if (IsIncreasing(aParent,aOffset,mStartParent,mStartOffset))
*aResult = -1;
else if (IsIncreasing(mEndParent,mEndOffset,aParent,aOffset))
*aResult = 1;
else
*aResult = 0;
return NS_OK;
}
PRInt32 nsRange::IndexOf(nsIDOMNode* aChildNode)
{
nsCOMPtr<nsIDOMNode> parentNode;

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

@ -90,10 +90,19 @@ public:
NS_IMETHOD ToString(nsString& aReturn);
// nsIDOMNSRange interface
/*BEGIN nsIDOMNSRange interface implementations*/
NS_IMETHOD CreateContextualFragment(const nsString& aFragment,
nsIDOMDocumentFragment** aReturn);
NS_IMETHOD IsValidFragment(const nsString& aFragment, PRBool* aReturn);
NS_IMETHOD IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset,
PRBool* aResult);
NS_IMETHOD ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset,
PRInt16* aResult);
NS_IMETHOD IntersectsNode(nsIDOMNode* aNode, PRBool* aReturn);
NS_IMETHOD CompareNode(nsIDOMNode* aNode, PRInt16* aReturn);
/*END nsIDOMNSRange interface implementations*/
NS_IMETHOD GetHasGeneratedBefore(PRBool *aBool);
NS_IMETHOD GetHasGeneratedAfter(PRBool *aBool);
NS_IMETHOD SetHasGeneratedBefore(PRBool aBool);
@ -159,8 +168,6 @@ public:
PRBool IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOff,
nsIDOMNode* aEndN, PRInt32 aEndOff);
nsresult IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset, PRBool* aResult);
nsresult ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult);
@ -172,7 +179,7 @@ public:
nsresult RemoveFromListOf(nsIDOMNode* aNode);
nsresult ContentOwnsUs(nsIDOMNode* domNode);
protected:
void* mScriptObject;
PRBool mBeforeGenContent;
@ -207,9 +214,9 @@ PRBool IsNodeIntersectsRange(nsIContent* aNode, nsIDOMRange* aRange);
*
************************************************************************************/
nsresult CompareNodeToRange(nsIContent* aNode,
nsIDOMRange* aRange,
PRBool *outNodeBefore,
PRBool *outNodeAfter);
nsIDOMRange* aRange,
PRBool *outNodeBefore,
PRBool *outNodeAfter);
/*************************************************************************************

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

@ -335,6 +335,126 @@ nsresult nsRange::QueryInterface(const nsIID& aIID,
return NS_NOINTERFACE;
}
/********************************************************
* Utilities for comparing points: API from nsIDOMNSRange
********************************************************/
NS_IMETHODIMP
nsRange::IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset, PRBool* aResult)
{
PRInt16 compareResult = 0;
nsresult res;
res = ComparePoint(aParent, aOffset, &compareResult);
if (compareResult)
*aResult = PR_FALSE;
else
*aResult = PR_TRUE;
return res;
}
// returns -1 if point is before range, 0 if point is in range,
// 1 if point is after range.
NS_IMETHODIMP
nsRange::ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset, PRInt16* aResult)
{
// check arguments
if (!aResult)
return NS_ERROR_NULL_POINTER;
// no trivial cases please
if (!aParent)
return NS_ERROR_NULL_POINTER;
// our range is in a good state?
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
// check common case first
if ((aParent == mStartParent.get()) && (aParent == mEndParent.get()))
{
if (aOffset<mStartOffset)
{
*aResult = -1;
return NS_OK;
}
if (aOffset>mEndOffset)
{
*aResult = 1;
return NS_OK;
}
*aResult = 0;
return NS_OK;
}
// more common cases
if ((aParent == mStartParent.get()) && (aOffset == mStartOffset))
{
*aResult = 0;
return NS_OK;
}
if ((aParent == mEndParent.get()) && (aOffset == mEndOffset))
{
*aResult = 0;
return NS_OK;
}
// ok, do it the hard way
if (IsIncreasing(aParent,aOffset,mStartParent,mStartOffset))
*aResult = -1;
else if (IsIncreasing(mEndParent,mEndOffset,aParent,aOffset))
*aResult = 1;
else
*aResult = 0;
return NS_OK;
}
NS_IMETHODIMP
nsRange::IntersectsNode(nsIDOMNode* aNode, PRBool* aReturn)
{
if (!aReturn)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIContent> content (do_QueryInterface(aNode));
if (!content)
{
*aReturn = 0;
return NS_ERROR_UNEXPECTED;
}
*aReturn = IsNodeIntersectsRange(content, this);
return NS_OK;
}
// HOW does the node intersect the range?
NS_IMETHODIMP
nsRange::CompareNode(nsIDOMNode* aNode, PRInt16* aReturn)
{
if (!aReturn)
return NS_ERROR_NULL_POINTER;
*aReturn = 0;
PRBool nodeBefore, nodeAfter;
nsCOMPtr<nsIContent> content (do_QueryInterface(aNode));
if (!content)
return NS_ERROR_UNEXPECTED;
nsresult res = CompareNodeToRange(content, this, &nodeBefore, &nodeAfter);
if (NS_FAILED(res))
return res;
// nodeBefore -> range start after node start, i.e. node starts before range.
// nodeAfter -> range end before node end, i.e. node ends after range.
// But I know that I get nodeBefore && !nodeAfter when the node is
// entirely inside the selection! This doesn't make sense.
if (nodeBefore && !nodeAfter)
*aReturn = nsIDOMNSRange::NODE_BEFORE; // May or may not intersect
else if (!nodeBefore && nodeAfter)
*aReturn = nsIDOMNSRange::NODE_AFTER; // May or may not intersect
else if (nodeBefore && nodeAfter)
*aReturn = nsIDOMNSRange::NODE_BEFORE_AND_AFTER; // definitely intersects
else
*aReturn = nsIDOMNSRange::NODE_INSIDE; // definitely intersects
return NS_OK;
}
/******************************************************
* Private helper routines
******************************************************/
@ -550,73 +670,6 @@ PRBool nsRange::IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOffset,
}
}
nsresult nsRange::IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset, PRBool* aResult)
{
PRInt32 compareResult = 0;
nsresult res;
res = ComparePointToRange(aParent, aOffset, &compareResult);
if (compareResult)
*aResult = PR_FALSE;
else
*aResult = PR_TRUE;
return res;
}
// returns -1 if point is before range, 0 if point is in range, 1 if point is after range
nsresult nsRange::ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult)
{
// check arguments
if (!aResult)
return NS_ERROR_NULL_POINTER;
// no trivial cases please
if (!aParent)
return NS_ERROR_NULL_POINTER;
// our range is in a good state?
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
// check common case first
if ((aParent == mStartParent.get()) && (aParent == mEndParent.get()))
{
if (aOffset<mStartOffset)
{
*aResult = -1;
return NS_OK;
}
if (aOffset>mEndOffset)
{
*aResult = 1;
return NS_OK;
}
*aResult = 0;
return NS_OK;
}
// more common cases
if ((aParent == mStartParent.get()) && (aOffset == mStartOffset))
{
*aResult = 0;
return NS_OK;
}
if ((aParent == mEndParent.get()) && (aOffset == mEndOffset))
{
*aResult = 0;
return NS_OK;
}
// ok, do it the hard way
if (IsIncreasing(aParent,aOffset,mStartParent,mStartOffset))
*aResult = -1;
else if (IsIncreasing(mEndParent,mEndOffset,aParent,aOffset))
*aResult = 1;
else
*aResult = 0;
return NS_OK;
}
PRInt32 nsRange::IndexOf(nsIDOMNode* aChildNode)
{
nsCOMPtr<nsIDOMNode> parentNode;

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

@ -90,10 +90,19 @@ public:
NS_IMETHOD ToString(nsString& aReturn);
// nsIDOMNSRange interface
/*BEGIN nsIDOMNSRange interface implementations*/
NS_IMETHOD CreateContextualFragment(const nsString& aFragment,
nsIDOMDocumentFragment** aReturn);
NS_IMETHOD IsValidFragment(const nsString& aFragment, PRBool* aReturn);
NS_IMETHOD IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset,
PRBool* aResult);
NS_IMETHOD ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset,
PRInt16* aResult);
NS_IMETHOD IntersectsNode(nsIDOMNode* aNode, PRBool* aReturn);
NS_IMETHOD CompareNode(nsIDOMNode* aNode, PRInt16* aReturn);
/*END nsIDOMNSRange interface implementations*/
NS_IMETHOD GetHasGeneratedBefore(PRBool *aBool);
NS_IMETHOD GetHasGeneratedAfter(PRBool *aBool);
NS_IMETHOD SetHasGeneratedBefore(PRBool aBool);
@ -159,8 +168,6 @@ public:
PRBool IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOff,
nsIDOMNode* aEndN, PRInt32 aEndOff);
nsresult IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset, PRBool* aResult);
nsresult ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult);
@ -172,7 +179,7 @@ public:
nsresult RemoveFromListOf(nsIDOMNode* aNode);
nsresult ContentOwnsUs(nsIDOMNode* domNode);
protected:
void* mScriptObject;
PRBool mBeforeGenContent;
@ -207,9 +214,9 @@ PRBool IsNodeIntersectsRange(nsIContent* aNode, nsIDOMRange* aRange);
*
************************************************************************************/
nsresult CompareNodeToRange(nsIContent* aNode,
nsIDOMRange* aRange,
PRBool *outNodeBefore,
PRBool *outNodeAfter);
nsIDOMRange* aRange,
PRBool *outNodeBefore,
PRBool *outNodeAfter);
/*************************************************************************************