diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index d11b0b8d83c..a6b14218603 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -3780,10 +3780,34 @@ Selection::GetIndicesForInterval(nsINode* aBeginNode, PRInt32 aBeginOffset, bool intervalIsCollapsed = aBeginNode == aEndNode && aBeginOffset == aEndOffset; + bool doSearches = true; + // Ranges that end before the given interval and begin after the given // interval can be discarded PRInt32 endsBeforeIndex; - if (NS_FAILED(FindInsertionPoint(&mRanges, aEndNode, aEndOffset, + PRInt32 beginsAfterIndex; + + // Optimization: Check that we're not at/after the end first + PRInt32 cmp; + if (NS_FAILED(CompareToRangeEnd(aBeginNode, aBeginOffset, + mRanges[mRanges.Length() - 1].mRange, + &cmp))) { + return; + } else if (cmp == 1) { + *aEndIndex = mRanges.Length(); + return; + } else if (cmp == 0) { + beginsAfterIndex = mRanges.Length() - 1; + if (!intervalIsCollapsed) { + endsBeforeIndex = beginsAfterIndex + 1; + } else { + endsBeforeIndex = beginsAfterIndex; + } + doSearches = false; + } + + if (doSearches && + NS_FAILED(FindInsertionPoint(&mRanges, aEndNode, aEndOffset, &CompareToRangeStart, &endsBeforeIndex))) { return; @@ -3807,14 +3831,12 @@ Selection::GetIndicesForInterval(nsINode* aBeginNode, PRInt32 aBeginOffset, } *aEndIndex = endsBeforeIndex; - PRInt32 beginsAfterIndex; - if (NS_FAILED(FindInsertionPoint(&mRanges, aBeginNode, aBeginOffset, + if (doSearches && + NS_FAILED(FindInsertionPoint(&mRanges, aBeginNode, aBeginOffset, &CompareToRangeEnd, &beginsAfterIndex))) { return; } - if (beginsAfterIndex == (PRInt32) mRanges.Length()) - return; // optimization: all ranges are strictly before us if (aAllowAdjacent) { // At this point, one of the following holds: