Fix ComparePoints() to be faster (helps with things like innerHTML). Bug

262764, r+sr=peterv
This commit is contained in:
bzbarsky%mit.edu 2004-10-09 21:02:16 +00:00
Родитель e278485bd2
Коммит be30301ca0
7 изменённых файлов: 96 добавлений и 84 удалений

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

@ -185,8 +185,9 @@ ContentIsInTraversalRange(nsIContent *aContent, PRBool aIsPreMode,
if (!aIsPreMode)
++indx;
return (ComparePoints(aStartNode, aStartOffset, parentNode, indx) <= 0) &&
(ComparePoints(aEndNode, aEndOffset, parentNode, indx) >= 0);
return (nsRange::ComparePoints(aStartNode, aStartOffset,
parentNode, indx) <= 0) &&
(nsRange::ComparePoints(aEndNode, aEndOffset, parentNode, indx) >= 0);
}

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

@ -351,7 +351,7 @@ nsGeneratedContentIterator::Init(nsIDOMRange* aRange)
// no content. In this case, we want the iterator to
// be empty
if (!IsNodeIntersectsRange(mFirst, aRange))
if (!nsRange::IsNodeIntersectsRange(mFirst, aRange))
{
MakeEmpty();
return NS_OK;

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

@ -121,29 +121,23 @@ class nsAutoRangeLock
// Returns -1 if point1 < point2, 1, if point1 > point2,
// 0 if error or if point1 == point2.
PRInt32 ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2)
/* static */
PRInt32
nsRange::ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2)
{
if (aParent1 == aParent2 && aOffset1 == aOffset2)
return 0;
nsIDOMRange* range;
if (NS_FAILED(NS_NewRange(&range)))
return 0;
nsresult res = range->SetStart(aParent1, aOffset1);
if (NS_FAILED(res))
return 0;
res = range->SetEnd(aParent2, aOffset2);
NS_RELEASE(range);
if (NS_SUCCEEDED(res))
return -1;
else
return 1;
if (aParent1 == aParent2) {
return (aOffset1 < aOffset2) ? -1 :
((aOffset1 > aOffset2) ? 1 : 0);
}
return IsIncreasing(aParent1, aOffset1, aParent2, aOffset2) ? -1 : 1;
}
// Utility routine to detect if a content node intersects a range
PRBool IsNodeIntersectsRange(nsIContent* aNode, nsIDOMRange* aRange)
/* static */
PRBool
nsRange::IsNodeIntersectsRange(nsIContent* aNode, nsIDOMRange* aRange)
{
// create a pair of dom points that expresses location of node:
// NODE(start), NODE(end)
@ -279,19 +273,15 @@ PRBool GetNodeBracketPoints(nsIContent* aNode,
if (!outEndOffset)
return PR_FALSE;
nsCOMPtr<nsIDOMNode> theDOMNode( do_QueryInterface(aNode) );
theDOMNode->GetParentNode(getter_AddRefs(*outParent));
nsIContent* parent = aNode->GetParent();
if (!(*outParent)) // special case for root node
if (!parent) // special case for root node
{
// can't make a parent/offset pair to represent start or
// end of the root node, becasue it has no parent.
// so instead represent it by (node,0) and (node,numChildren)
*outParent = do_QueryInterface(aNode);
nsCOMPtr<nsIContent> cN(do_QueryInterface(*outParent));
if (!cN)
return PR_FALSE;
PRUint32 indx = cN->GetChildCount();
PRUint32 indx = aNode->GetChildCount();
if (!indx)
return PR_FALSE;
*outStartOffset = 0;
@ -299,7 +289,8 @@ PRBool GetNodeBracketPoints(nsIContent* aNode,
}
else
{
*outStartOffset = nsRange::IndexOf(theDOMNode);
*outParent = do_QueryInterface(parent);
*outStartOffset = parent->IndexOf(aNode);
*outEndOffset = *outStartOffset+1;
}
return PR_TRUE;
@ -354,15 +345,15 @@ NS_IMPL_ISUPPORTS1(nsRangeUtils, nsIRangeUtils)
NS_IMETHODIMP_(PRInt32)
nsRangeUtils::ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2)
nsIDOMNode* aParent2, PRInt32 aOffset2)
{
return ::ComparePoints(aParent1, aOffset1, aParent2, aOffset2);
return nsRange::ComparePoints(aParent1, aOffset1, aParent2, aOffset2);
}
NS_IMETHODIMP_(PRBool)
nsRangeUtils::IsNodeIntersectsRange(nsIContent* aNode, nsIDOMRange* aRange)
{
return ::IsNodeIntersectsRange( aNode, aRange);
return nsRange::IsNodeIntersectsRange( aNode, aRange);
}
NS_IMETHODIMP

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

@ -158,6 +158,19 @@ public:
nsIDOMNode** closestAncestor,
nsIDOMNode** farthestAncestor);
/**
* Utility routine to compare two "points", were a point is a node/offset pair
* Returns -1 if point1 < point2, 1, if point1 > point2,
* 0 if error or if point1 == point2.
*/
static PRInt32 ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2);
/**
* Utility routine to detect if a content node intersects a range
*/
static PRBool IsNodeIntersectsRange(nsIContent* aNode, nsIDOMRange* aRange);
/******************************************************************************
* Utility routine to detect if a content node starts before a range and/or
* ends after a range. If neither it is contained inside the range.
@ -182,7 +195,7 @@ protected:
nsresult DoSetRange(nsIDOMNode* aStartN, PRInt32 aStartOffset,
nsIDOMNode* aEndN, PRInt32 aEndOffset);
PRBool IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOff,
static PRBool IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOff,
nsIDOMNode* aEndN, PRInt32 aEndOff);
PRBool IsDetached(){return mIsDetached;}
@ -205,21 +218,6 @@ nsresult NS_NewRange(nsIDOMRange** aInstancePtrResult);
nsresult NS_NewRangeUtils(nsIRangeUtils** aInstancePtrResult);
/*************************************************************************************
* Utility routine to compare two "points", were a point is a node/offset pair
* Returns -1 if point1 < point2, 1, if point1 > point2,
* 0 if error or if point1 == point2.
************************************************************************************/
PRInt32 ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2);
/*************************************************************************************
* Utility routine to detect if a content node intersects a range
************************************************************************************/
PRBool IsNodeIntersectsRange(nsIContent* aNode, nsIDOMRange* aRange);
/*************************************************************************************
* Utility routine to create a pair of dom points to represent
* the start and end locations of a single node. Return false

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

@ -1781,7 +1781,8 @@ nsSelection::SelectLines(nsPresContext *aPresContext,
nsresult result;
// normalize the order before we start to avoid piles of conditions later
relativePosition = ComparePoints(aAnchorNode, aAnchorOffset, aCurrentNode, aCurrentOffset);
relativePosition = nsRange::ComparePoints(aAnchorNode, aAnchorOffset,
aCurrentNode, aCurrentOffset);
if (0 == relativePosition)
return NS_ERROR_FAILURE;
else if (relativePosition < 0)
@ -1829,7 +1830,7 @@ nsSelection::SelectLines(nsPresContext *aPresContext,
startNode = do_QueryInterface(startContent);
// If we have already overshot the endpoint, back out
if (ComparePoints(startNode, startOffset, endNode, endOffset) >= 0)
if (nsRange::ComparePoints(startNode, startOffset, endNode, endOffset) >= 0)
return NS_ERROR_FAILURE;
aPos.mStartOffset = endOffset;
@ -1854,7 +1855,7 @@ nsSelection::SelectLines(nsPresContext *aPresContext,
endContent = aPos.mResultContent;
endNode = do_QueryInterface(endContent);
if (ComparePoints(startNode, startOffset, endNode, endOffset) < 0)
if (nsRange::ComparePoints(startNode, startOffset, endNode, endOffset) < 0)
{
TakeFocus(startContent, startOffset, startOffset, PR_FALSE, PR_TRUE);
return TakeFocus(endContent, endOffset, endOffset, PR_TRUE, PR_TRUE);
@ -2424,7 +2425,8 @@ nsSelection::AdjustForMaintainedSelection(nsIContent *aContent, PRInt32 aOffset)
}
}
PRInt32 relativePosition = ComparePoints(rangenode, rangeOffset, domNode, aOffset);
PRInt32 relativePosition = nsRange::ComparePoints(rangenode, rangeOffset,
domNode, aOffset);
// if == 0 or -1 do nothing if < 0 then we need to swap direction
if (relativePosition > 0
&& (mDomSelections[index]->GetDirection() == eDirNext))
@ -5040,14 +5042,19 @@ nsTypedSelection::LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset,
}
else { //then we MUST be completely selected! unless someone needs us to check to make sure with slowcheck
if (cnt > 1 || aSlowCheck){ //if more than 1 selection or we need to do slow check see if farther than start or less than end.
//we only have to look at start offset because anything else would have been in the range
PRInt32 resultnum = ComparePoints(startNode, startOffset
,passedInNode, aContentOffset);
if (cnt > 1 || aSlowCheck){ //if more than 1 selection or we need to do
//slow check see if farther than start or
//less than end.
//we only have to look at start offset because anything else would
//have been in the range
PRInt32 resultnum = nsRange::ComparePoints(startNode,
startOffset,
passedInNode,
aContentOffset);
if (resultnum > 0)
continue;
resultnum = ComparePoints(endNode, endOffset,
passedInNode, aContentOffset );
resultnum = nsRange::ComparePoints(endNode, endOffset,
passedInNode, aContentOffset);
if (resultnum <0)
continue;
}
@ -6229,14 +6236,18 @@ nsTypedSelection::Extend(nsIDOMNode* aParentNode, PRInt32 aOffset)
if (NS_FAILED(res))
return res;
PRInt32 result1 = ComparePoints(FetchAnchorNode(), FetchAnchorOffset()
,FetchFocusNode(), FetchFocusOffset());
PRInt32 result1 = nsRange::ComparePoints(FetchAnchorNode(),
FetchAnchorOffset(),
FetchFocusNode(),
FetchFocusOffset());
//compare old cursor to new cursor
PRInt32 result2 = ComparePoints(FetchFocusNode(), FetchFocusOffset(),
aParentNode, aOffset );
PRInt32 result2 = nsRange::ComparePoints(FetchFocusNode(),
FetchFocusOffset(),
aParentNode, aOffset);
//compare anchor to new cursor
PRInt32 result3 = ComparePoints(FetchAnchorNode(), FetchAnchorOffset(),
aParentNode , aOffset );
PRInt32 result3 = nsRange::ComparePoints(FetchAnchorNode(),
FetchAnchorOffset(),
aParentNode, aOffset);
if (result2 == 0) //not selecting anywhere
return NS_OK;
@ -6570,7 +6581,7 @@ nsTypedSelection::ContainsNode(nsIDOMNode* aNode, PRBool aRecursive, PRBool* aYe
nsCOMPtr<nsIContent> content (do_QueryInterface(aNode));
if (content)
{
if (IsNodeIntersectsRange(content, range))
if (nsRange::IsNodeIntersectsRange(content, range))
{
// If recursive, then we're done -- IsNodeIntersectsRange does the right thing
if (aRecursive)

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

@ -1070,7 +1070,7 @@ nsHTMLFormElement::CompareNodes(nsIDOMNode* a, nsIDOMNode* b, PRInt32* retval)
indexB = parentB->IndexOf(bContent);
}
*retval = ComparePoints(parentANode, indexA, parentBNode, indexB);
*retval = nsRange::ComparePoints(parentANode, indexA, parentBNode, indexB);
return NS_OK;
}

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

@ -1781,7 +1781,8 @@ nsSelection::SelectLines(nsPresContext *aPresContext,
nsresult result;
// normalize the order before we start to avoid piles of conditions later
relativePosition = ComparePoints(aAnchorNode, aAnchorOffset, aCurrentNode, aCurrentOffset);
relativePosition = nsRange::ComparePoints(aAnchorNode, aAnchorOffset,
aCurrentNode, aCurrentOffset);
if (0 == relativePosition)
return NS_ERROR_FAILURE;
else if (relativePosition < 0)
@ -1829,7 +1830,7 @@ nsSelection::SelectLines(nsPresContext *aPresContext,
startNode = do_QueryInterface(startContent);
// If we have already overshot the endpoint, back out
if (ComparePoints(startNode, startOffset, endNode, endOffset) >= 0)
if (nsRange::ComparePoints(startNode, startOffset, endNode, endOffset) >= 0)
return NS_ERROR_FAILURE;
aPos.mStartOffset = endOffset;
@ -1854,7 +1855,7 @@ nsSelection::SelectLines(nsPresContext *aPresContext,
endContent = aPos.mResultContent;
endNode = do_QueryInterface(endContent);
if (ComparePoints(startNode, startOffset, endNode, endOffset) < 0)
if (nsRange::ComparePoints(startNode, startOffset, endNode, endOffset) < 0)
{
TakeFocus(startContent, startOffset, startOffset, PR_FALSE, PR_TRUE);
return TakeFocus(endContent, endOffset, endOffset, PR_TRUE, PR_TRUE);
@ -2424,7 +2425,8 @@ nsSelection::AdjustForMaintainedSelection(nsIContent *aContent, PRInt32 aOffset)
}
}
PRInt32 relativePosition = ComparePoints(rangenode, rangeOffset, domNode, aOffset);
PRInt32 relativePosition = nsRange::ComparePoints(rangenode, rangeOffset,
domNode, aOffset);
// if == 0 or -1 do nothing if < 0 then we need to swap direction
if (relativePosition > 0
&& (mDomSelections[index]->GetDirection() == eDirNext))
@ -5040,14 +5042,19 @@ nsTypedSelection::LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset,
}
else { //then we MUST be completely selected! unless someone needs us to check to make sure with slowcheck
if (cnt > 1 || aSlowCheck){ //if more than 1 selection or we need to do slow check see if farther than start or less than end.
//we only have to look at start offset because anything else would have been in the range
PRInt32 resultnum = ComparePoints(startNode, startOffset
,passedInNode, aContentOffset);
if (cnt > 1 || aSlowCheck){ //if more than 1 selection or we need to do
//slow check see if farther than start or
//less than end.
//we only have to look at start offset because anything else would
//have been in the range
PRInt32 resultnum = nsRange::ComparePoints(startNode,
startOffset,
passedInNode,
aContentOffset);
if (resultnum > 0)
continue;
resultnum = ComparePoints(endNode, endOffset,
passedInNode, aContentOffset );
resultnum = nsRange::ComparePoints(endNode, endOffset,
passedInNode, aContentOffset);
if (resultnum <0)
continue;
}
@ -6229,14 +6236,18 @@ nsTypedSelection::Extend(nsIDOMNode* aParentNode, PRInt32 aOffset)
if (NS_FAILED(res))
return res;
PRInt32 result1 = ComparePoints(FetchAnchorNode(), FetchAnchorOffset()
,FetchFocusNode(), FetchFocusOffset());
PRInt32 result1 = nsRange::ComparePoints(FetchAnchorNode(),
FetchAnchorOffset(),
FetchFocusNode(),
FetchFocusOffset());
//compare old cursor to new cursor
PRInt32 result2 = ComparePoints(FetchFocusNode(), FetchFocusOffset(),
aParentNode, aOffset );
PRInt32 result2 = nsRange::ComparePoints(FetchFocusNode(),
FetchFocusOffset(),
aParentNode, aOffset);
//compare anchor to new cursor
PRInt32 result3 = ComparePoints(FetchAnchorNode(), FetchAnchorOffset(),
aParentNode , aOffset );
PRInt32 result3 = nsRange::ComparePoints(FetchAnchorNode(),
FetchAnchorOffset(),
aParentNode, aOffset);
if (result2 == 0) //not selecting anywhere
return NS_OK;
@ -6570,7 +6581,7 @@ nsTypedSelection::ContainsNode(nsIDOMNode* aNode, PRBool aRecursive, PRBool* aYe
nsCOMPtr<nsIContent> content (do_QueryInterface(aNode));
if (content)
{
if (IsNodeIntersectsRange(content, range))
if (nsRange::IsNodeIntersectsRange(content, range))
{
// If recursive, then we're done -- IsNodeIntersectsRange does the right thing
if (aRecursive)