зеркало из https://github.com/mozilla/pjs.git
Fix ComparePoints() to be faster (helps with things like innerHTML). Bug
262764, r+sr=peterv
This commit is contained in:
Родитель
e278485bd2
Коммит
be30301ca0
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче