author | Brad Werth <bwerth@mozilla.com> |
Wed, 25 Apr 2018 12:28:57 -0700 | |
changeset 416911 | ec1b3f950848608328c18c0102c55305538abe36 |
parent 416910 | b0c260eb196cb1e214f8d5b0810e0ea93ebb7196 |
child 416912 | dc092a92c289664b31977c4f5f1b986ae6a9f931 |
push id | 33943 |
push user | csabou@mozilla.com |
push date | Fri, 04 May 2018 17:19:55 +0000 |
treeherder | mozilla-central@ef1db4e8bf06 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bz |
bugs | 1436431 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
toolkit/components/typeaheadfind/nsTypeAheadFind.cpp | file | annotate | diff | comparison | revisions |
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp +++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp @@ -1263,23 +1263,56 @@ nsTypeAheadFind::IsRangeVisible(nsIPresS // We don't use the more accurate AccGetBounds, because that is // more expensive and the STATE_OFFSCREEN flag that this is used // for only needs to be a rough indicator nsRectVisibility rectVisibility = nsRectVisibility_kAboveViewport; if (!aGetTopVisibleLeaf && !frame->GetRect().IsEmpty()) { rectVisibility = aPresShell->GetRectVisibility(frame, - nsRect(nsPoint(0,0), frame->GetSize()), + frame->GetRectRelativeToSelf(), minDistance); if (rectVisibility == nsRectVisibility_kVisible) { - // This is an early exit case, where we return true if and only if - // the range is actually rendered. - return IsRangeRendered(aPresShell, aPresContext, aRange); + // The primary frame of the range is visible, but we don't yet know if + // any of the rects of the range itself are visible. Check to see if at + // least one of the rects is visible. + bool atLeastOneRangeRectVisible = false; + + nsIFrame* containerFrame = + nsLayoutUtils::GetContainingBlockForClientRect(frame); + RefPtr<DOMRectList> rects = aRange->GetClientRects(true, true); + for (uint32_t i = 0; i < rects->Length(); ++i) { + RefPtr<DOMRect> rect = rects->Item(i); + nsRect r(nsPresContext::CSSPixelsToAppUnits((float)rect->X()), + nsPresContext::CSSPixelsToAppUnits((float)rect->Y()), + nsPresContext::CSSPixelsToAppUnits((float)rect->Width()), + nsPresContext::CSSPixelsToAppUnits((float)rect->Height())); + + // r is relative to containerFrame; transform it back to frame, so we + // can do a proper visibility check that is cropped to all of frame's + // ancestor scroll frames. + nsLayoutUtils::TransformResult res = + nsLayoutUtils::TransformRect(containerFrame, frame, r); + if (res == nsLayoutUtils::TransformResult::TRANSFORM_SUCCEEDED) { + nsRectVisibility rangeRectVisibility = + aPresShell->GetRectVisibility(frame, r, minDistance); + + if (rangeRectVisibility == nsRectVisibility_kVisible) { + atLeastOneRangeRectVisible = true; + break; + } + } + } + + if (atLeastOneRangeRectVisible) { + // This is an early exit case, where we return true if and only if + // the range is actually rendered. + return IsRangeRendered(aPresShell, aPresContext, aRange); + } } } // Below this point, we know the range is not in the viewport. if (!aMustBeInViewPort) { // This is an early exit case because we don't care that that range // is out of viewport, so we return that the range is "visible".