Backed out 5 changesets (bug 1302470) for causing bug 1323200 a=backout
authorWes Kocher <wkocher@mozilla.com>
Fri, 16 Dec 2016 16:45:09 -0800
changeset 450591 34a1ab064cb5b868fa75cb74d052e978eb34d6c1
parent 450590 119f24606f99d82c6539763a778bb24f9df28037
child 450592 7d6aed808a90eeb8b4b97aa2246cc215261bb924
child 450595 906cf3bedd84b84d7708a148f6ac0bd3b5336e05
child 450602 4b9e6bb1f5a676473b389209fb40a0980e7d8ab7
child 450607 8eb7672df5bbca621616f9093b2127ae13c4b2e7
child 450614 e6930cdb718d947b915227f213b77e3c845fc328
child 450622 25b7de5035b21ecc788d9e53ab85bbb23065582d
child 450624 2cf9cd43c36bc301f75c705692a951df10bc3027
child 450657 ea640163f898cdc3dfe3dea222c2a01897c0889e
child 450666 e05f7cbd765c45414e8cb77a2ea49c07a4ebfa33
child 450668 d3e310464a83d1769b4e58abf68f7c473b8b42c9
child 450693 da15ea8d6fa5433e275cffe3ec820a74d413c938
child 450764 38e6552bbf0f202980cb7a37f2939813593fd4ef
child 450834 95b5e90d6d4142c88bb78ea43f20a68402842c27
child 450859 a06f99a62cb3c3ddce5db0a58bbd33274e10c389
child 450981 07c49bb0c565497dfdbd24b4cea7210bc49badf1
child 451016 8ff6721bba0d0a1c4f55b4b61a0bdf41547cfff5
child 451210 09c4ffd37156e7919c1aeeedde643f892287644b
child 451211 be8b5dca84f0bda6126ecbe5891ac984c3629ec9
child 451327 98c821c59547eac41ae7eea3686546561035bb77
child 451521 9051ed0bff30d3fb34f59d505fac0b7f33331e37
child 451532 5d35595a652aa588d32020518e19a20cbca33995
child 452624 8aec41c2b9a7af98bcdbc2334eaec26ebf7042fc
child 458108 be1bd1851c6cd96c3990d683bdd6df26b545ed29
push id38911
push userbmo:cku@mozilla.com
push dateSat, 17 Dec 2016 03:26:49 +0000
reviewersbackout
bugs1302470, 1323200
milestone53.0a1
backs out005adbf78cd24afd81a24902ad8802d1b1d0c5aa
113f7b13475cc8de15f8d253cee720e3a9df8ce1
3d2569996ebc5b4625f9a221c78c00cb982a8735
b92b78271941789fc06c7b9ec7cd9c566b7fc20a
5b92678afff8770634c1125fd48d63f6a0c3ba23
Backed out 5 changesets (bug 1302470) for causing bug 1323200 a=backout Backed out changeset 005adbf78cd2 (bug 1302470) Backed out changeset 113f7b13475c (bug 1302470) Backed out changeset 3d2569996ebc (bug 1302470) Backed out changeset b92b78271941 (bug 1302470) Backed out changeset 5b92678afff8 (bug 1302470) MozReview-Commit-ID: FgeA5OQV8WP
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/forms/nsHTMLButtonControlFrame.cpp
toolkit/components/typeaheadfind/nsITypeAheadFind.idl
toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
toolkit/components/typeaheadfind/nsTypeAheadFind.h
toolkit/modules/FinderHighlighter.jsm
toolkit/modules/FinderIterator.jsm
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3168,33 +3168,32 @@ nsLayoutUtils::GetFramesForArea(nsIFrame
     if (rootScrollFrame) {
       builder.SetIgnoreScrollFrame(rootScrollFrame);
     }
   }
   if (aFlags & IGNORE_CROSS_DOC) {
     builder.SetDescendIntoSubdocuments(false);
   }
 
-  builder.SetHitTestShouldStopAtFirstOpaque(aFlags & ONLY_VISIBLE);
-
   builder.EnterPresShell(aFrame);
   aFrame->BuildDisplayListForStackingContext(&builder, aRect, &list);
   builder.LeavePresShell(aFrame, nullptr);
 
 #ifdef MOZ_DUMP_PAINTING
   if (gDumpEventList) {
     fprintf_stderr(stderr, "Event handling --- (%d,%d):\n", aRect.x, aRect.y);
 
     std::stringstream ss;
     nsFrame::PrintDisplayList(&builder, list, ss);
     print_stderr(ss);
   }
 #endif
 
   nsDisplayItem::HitTestState hitTestState;
+  builder.SetHitTestShouldStopAtFirstOpaque(aFlags & ONLY_VISIBLE);
   list.HitTest(&builder, aRect, &hitTestState, &aOutFrames);
   list.DeleteAll();
   return NS_OK;
 }
 
 // aScrollFrameAsScrollable must be non-nullptr and queryable to an nsIFrame
 FrameMetrics
 nsLayoutUtils::CalculateBasicFrameMetrics(nsIScrollableFrame* aScrollFrame) {
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -820,17 +820,17 @@ public:
   static nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt,
                                     uint32_t aFlags = 0);
 
   /**
    * Given aFrame, the root frame of a stacking context, find all descendant
    * frames under the area of a rectangle that receives a mouse event,
    * or nullptr if there is no such frame.
    * @param aRect the rect, relative to the frame origin
-   * @param aOutFrames an array to append all the frames found
+   * @param aOutFrames an array to add all the frames found
    * @param aFlags some combination of FrameForPointFlags
    */
   static nsresult GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
                                    nsTArray<nsIFrame*> &aOutFrames,
                                    uint32_t aFlags = 0);
 
   /**
    * Transform aRect relative to aFrame up to the coordinate system of
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -114,17 +114,17 @@ nsHTMLButtonControlFrame::BuildDisplayLi
   nsDisplayList onTop;
   if (IsVisibleForPainting(aBuilder)) {
     mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop);
   }
 
   nsDisplayListCollection set;
 
   // Do not allow the child subtree to receive events.
-  if (!isForEventDelivery || aBuilder->HitTestShouldStopAtFirstOpaque()) {
+  if (!isForEventDelivery) {
     DisplayListClipState::AutoSaveRestore clipState(aBuilder);
 
     if (ShouldClipPaintingToBorderBox()) {
       nsMargin border = StyleBorder()->GetComputedBorder();
       nsRect rect(aBuilder->ToReferenceFrame(this), GetSize());
       rect.Deflate(border);
       nscoord radii[8];
       bool hasRadii = GetPaddingBoxBorderRadii(radii);
--- a/toolkit/components/typeaheadfind/nsITypeAheadFind.idl
+++ b/toolkit/components/typeaheadfind/nsITypeAheadFind.idl
@@ -13,17 +13,17 @@
 /******************************** Declarations *******************************/
 
 interface mozIDOMWindow;
 interface nsIDocShell;
 
 
 /****************************** nsTypeAheadFind ******************************/
 
-[scriptable, uuid(3cfe7906-f189-45a0-8abe-8e4437a23cae)]
+[scriptable, uuid(ae501e28-c57f-4692-ac74-410e1bed98b7)]
 interface nsITypeAheadFind : nsISupports
 {
   /****************************** Initializer ******************************/
 
   /* Necessary initialization that can't happen in the constructor, either
    * because function calls here may fail, or because the docShell is
    * required. */
   void init(in nsIDocShell aDocShell);
@@ -53,17 +53,17 @@ interface nsITypeAheadFind : nsISupports
   void setSelectionModeAndRepaint(in short toggle);
 
   /* Collapse the "found match" selection to its start.  Because not all
    * matches are owned by the same selection controller, this doesn't
    * necessarily happen automatically. */
   void collapseSelection();
 
   /* Check if a range is visible */
-  boolean isRangeVisible(in nsIDOMRange aRange, in boolean aFlushLayout);
+  boolean isRangeVisible(in nsIDOMRange aRange, in boolean aMustBeInViewPort);
 
   /******************************* Attributes ******************************/
 
   readonly attribute AString searchString;
                                         // Most recent search string
   attribute boolean caseSensitive;      // Searches are case sensitive
   attribute boolean entireWord;         // Search for whole words only
   readonly attribute nsIDOMElement foundLink;
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -47,17 +47,16 @@
 #include "nsNameSpaceManager.h"
 #include "nsIWindowWatcher.h"
 #include "nsIObserverService.h"
 #include "nsFocusManager.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Link.h"
 #include "nsRange.h"
 #include "nsXBLBinding.h"
-#include "nsLayoutUtils.h"
 
 #include "nsTypeAheadFind.h"
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTypeAheadFind)
   NS_INTERFACE_MAP_ENTRY(nsITypeAheadFind)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsITypeAheadFind)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
@@ -66,16 +65,18 @@ NS_INTERFACE_MAP_END
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTypeAheadFind)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTypeAheadFind)
 
 NS_IMPL_CYCLE_COLLECTION(nsTypeAheadFind, mFoundLink, mFoundEditable,
                          mCurrentWindow, mStartFindRange, mSearchRange,
                          mStartPointRange, mEndPointRange, mSoundInterface,
                          mFind, mFoundRange)
 
+static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
+
 #define NS_FIND_CONTRACTID "@mozilla.org/embedcomp/rangefind;1"
 
 nsTypeAheadFind::nsTypeAheadFind():
   mStartLinksOnlyPref(false),
   mCaretBrowsingOn(false),
   mDidAddObservers(false),
   mLastFindLength(0),
   mIsSoundInitialized(false),
@@ -416,31 +417,32 @@ nsTypeAheadFind::FindItNow(nsIPresShell 
     return NS_ERROR_FAILURE;
 
   mFind->SetFindBackwards(aFindPrev);
 
   while (true) {    // ----- Outer while loop: go through all docs -----
     while (true) {  // === Inner while loop: go through a single doc ===
       mFind->Find(mTypeAheadBuffer.get(), mSearchRange, mStartPointRange,
                   mEndPointRange, getter_AddRefs(returnRange));
-
+      
       if (!returnRange)
         break;  // Nothing found in this doc, go to outer loop (try next doc)
 
       // ------- Test resulting found range for success conditions ------
       bool isInsideLink = false, isStartingLink = false;
 
       if (aIsLinksOnly) {
         // Don't check if inside link when searching all text
         RangeStartsInsideLink(returnRange, presShell, &isInsideLink,
                               &isStartingLink);
       }
 
       bool usesIndependentSelection;
-      if (!IsRangeVisible(presShell, presContext, returnRange, true,
+      if (!IsRangeVisible(presShell, presContext, returnRange,
+                          aIsFirstVisiblePreferred, false,
                           getter_AddRefs(mStartPointRange), 
                           &usesIndependentSelection) ||
           (aIsLinksOnly && !isInsideLink) ||
           (mStartLinksOnlyPref && aIsLinksOnly && !isStartingLink)) {
         // ------ Failure ------
         // At this point mStartPointRange got updated to the first
         // visible range in the viewport.  We _may_ be able to just
         // start there, if it's not taking us in the wrong direction.
@@ -810,17 +812,18 @@ nsTypeAheadFind::GetSearchContainers(nsI
     if (selection)
       selection->GetRangeAt(0, getter_AddRefs(currentSelectionRange));
   }
 
   if (!currentSelectionRange) {
     // Ensure visible range, move forward if necessary
     // This uses ignores the return value, but usese the side effect of
     // IsRangeVisible. It returns the first visible range after searchRange
-    IsRangeVisible(presShell, presContext, mSearchRange, true,
+    IsRangeVisible(presShell, presContext, mSearchRange, 
+                   aIsFirstVisiblePreferred, true, 
                    getter_AddRefs(mStartPointRange), nullptr);
   }
   else {
     int32_t startOffset;
     nsCOMPtr<nsIDOMNode> startNode;
     if (aFindPrev) {
       currentSelectionRange->GetStartContainer(getter_AddRefs(startNode));
       currentSelectionRange->GetStartOffset(&startOffset);
@@ -1000,28 +1003,28 @@ nsTypeAheadFind::Find(const nsAString& a
     // is typed
     mStartFindRange = nullptr;
     mSelectionController = nullptr;
 
     *aResult = FIND_FOUND;
     return NS_OK;
   }
 
-  bool atEnd = false;
+  bool atEnd = false;    
   if (mTypeAheadBuffer.Length()) {
     const nsAString& oldStr = Substring(mTypeAheadBuffer, 0, mTypeAheadBuffer.Length());
     const nsAString& newStr = Substring(aSearchString, 0, mTypeAheadBuffer.Length());
     if (oldStr.Equals(newStr))
       atEnd = true;
-
+  
     const nsAString& newStr2 = Substring(aSearchString, 0, aSearchString.Length());
     const nsAString& oldStr2 = Substring(mTypeAheadBuffer, 0, aSearchString.Length());
     if (oldStr2.Equals(newStr2))
       atEnd = true;
-
+    
     if (!atEnd)
       mStartFindRange = nullptr;
   }
 
   if (!mIsSoundInitialized && !mNotFoundSoundURL.IsEmpty()) {
     // This makes sure system sound library is loaded so that
     // there's no lag before the first sound is played
     // by waiting for the first keystroke, we still get the startup time benefits.
@@ -1153,122 +1156,160 @@ nsTypeAheadFind::GetFoundRange(nsIDOMRan
   }
 
   mFoundRange->CloneRange(aFoundRange);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTypeAheadFind::IsRangeVisible(nsIDOMRange *aRange,
-                                bool aFlushLayout,
+                                bool aMustBeInViewPort,
                                 bool *aResult)
 {
   // Jump through hoops to extract the docShell from the range.
   nsCOMPtr<nsIDOMNode> node;
   aRange->GetStartContainer(getter_AddRefs(node));
   nsCOMPtr<nsIDOMDocument> document;
   node->GetOwnerDocument(getter_AddRefs(document));
   nsCOMPtr<mozIDOMWindowProxy> window;
   document->GetDefaultView(getter_AddRefs(window));
   nsCOMPtr<nsIWebNavigation> navNav (do_GetInterface(window));
   nsCOMPtr<nsIDocShell> docShell (do_GetInterface(navNav));
 
   // Set up the arguments needed to check if a range is visible.
   nsCOMPtr<nsIPresShell> presShell (docShell->GetPresShell());
   RefPtr<nsPresContext> presContext = presShell->GetPresContext();
   nsCOMPtr<nsIDOMRange> startPointRange = new nsRange(presShell->GetDocument());
-  *aResult = IsRangeVisible(presShell, presContext, aRange, aFlushLayout,
+  *aResult = IsRangeVisible(presShell, presContext, aRange,
+                            aMustBeInViewPort, false,
                             getter_AddRefs(startPointRange),
                             nullptr);
   return NS_OK;
 }
 
 bool
 nsTypeAheadFind::IsRangeVisible(nsIPresShell *aPresShell,
                                 nsPresContext *aPresContext,
-                                nsIDOMRange *aRange,
-                                bool aFlushLayout,
+                                nsIDOMRange *aRange, bool aMustBeInViewPort,
+                                bool aGetTopVisibleLeaf,
                                 nsIDOMRange **aFirstVisibleRange,
                                 bool *aUsesIndependentSelection)
 {
   NS_ASSERTION(aPresShell && aPresContext && aRange && aFirstVisibleRange, 
                "params are invalid");
 
-  // We need to know if the range start and end are both visible.
-  // In all cases, return the first visible range in aFirstVisibleRange.
-  aRange->CloneRange(aFirstVisibleRange);
+  // We need to know if the range start is visible.
+  // Otherwise, return the first visible range start 
+  // in aFirstVisibleRange
 
-  if (aFlushLayout) {
-    aPresShell->FlushPendingNotifications(Flush_Layout);
-  }
-
+  aRange->CloneRange(aFirstVisibleRange);
   nsCOMPtr<nsIDOMNode> node;
-  aRange->GetCommonAncestorContainer(getter_AddRefs(node));
+  aRange->GetStartContainer(getter_AddRefs(node));
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(node));
-  if (!content) {
+  if (!content)
     return false;
-  }
 
   nsIFrame *frame = content->GetPrimaryFrame();
-  if (!frame) {
+  if (!frame)    
     return false;  // No frame! Not visible then.
-  }
-
-  // Having a primary frame doesn't mean that the range is visible inside the
-  // viewport. Do a hit-test to determine that quickly and properly.
-  bool foundContent = false;
-  AutoTArray<nsIFrame*,8> frames;
-  nsIFrame *rootFrame = aPresShell->GetRootFrame();
-  RefPtr<nsRange> range = static_cast<nsRange*>(aRange);
-  RefPtr<mozilla::dom::DOMRectList> rects = range->GetClientRects(true, false);
-  for (uint32_t i = 0; i < rects->Length(); ++i) {
-    RefPtr<mozilla::dom::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()));
-    // Append visible frames to frames array.
-    nsLayoutUtils::GetFramesForArea(rootFrame, r, frames,
-      nsLayoutUtils::IGNORE_PAINT_SUPPRESSION |
-      nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME |
-      nsLayoutUtils::ONLY_VISIBLE);
 
-    // See if any of the frames contain the content. If they do, then the range
-    // is visible. We search for the content rather than the original frame,
-    // because nsTextContinuation frames might be returned instead of the
-    // original frame.
-    for (const auto &f: frames) {
-      if (f->GetContent() == content) {
-        foundContent = true;
-        break;
-      }
-    }
-
-    if (foundContent) {
-      break;
-    }
-
-    frames.ClearAndRetainStorage();
-  }
-
-  // Test that content appears in the list of framesForArea. If it does, then
-  // that means that content is at least partly visible.
-  if (!foundContent) {
+  if (!frame->StyleVisibility()->IsVisible())
     return false;
-  }
 
   // Detect if we are _inside_ a text control, or something else with its own
   // selection controller.
   if (aUsesIndependentSelection) {
     *aUsesIndependentSelection = 
       (frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION);
   }
 
-  return true;
+  // ---- We have a frame ----
+  if (!aMustBeInViewPort)   
+    return true; //  Don't need it to be on screen, just in rendering tree
+
+  // Get the next in flow frame that contains the range start
+  int32_t startRangeOffset, startFrameOffset, endFrameOffset;
+  aRange->GetStartOffset(&startRangeOffset);
+  while (true) {
+    frame->GetOffsets(startFrameOffset, endFrameOffset);
+    if (startRangeOffset < endFrameOffset)
+      break;
+
+    nsIFrame *nextContinuationFrame = frame->GetNextContinuation();
+    if (nextContinuationFrame)
+      frame = nextContinuationFrame;
+    else
+      break;
+  }
+
+  // Set up the variables we need, return true if we can't get at them all
+  const uint16_t kMinPixels  = 12;
+  nscoord minDistance = nsPresContext::CSSPixelsToAppUnits(kMinPixels);
+
+  // Get the bounds of the current frame, relative to the current view.
+  // 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()),
+                                    minDistance);
+
+    if (rectVisibility != nsRectVisibility_kAboveViewport) {
+      return true;
+    }
+  }
+
+  // We know that the target range isn't usable because it's not in the
+  // view port. Move range forward to first visible point,
+  // this speeds us up a lot in long documents
+  nsCOMPtr<nsIFrameEnumerator> frameTraversal;
+  nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID));
+  if (trav)
+    trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
+                            aPresContext, frame,
+                            eLeaf,
+                            false, // aVisual
+                            false, // aLockInScrollView
+                            false, // aFollowOOFs
+                            false  // aSkipPopupChecks
+                            );
+
+  if (!frameTraversal)
+    return false;
+
+  while (rectVisibility == nsRectVisibility_kAboveViewport) {
+    frameTraversal->Next();
+    frame = frameTraversal->CurrentItem();
+    if (!frame)
+      return false;
+
+    if (!frame->GetRect().IsEmpty()) {
+      rectVisibility =
+        aPresShell->GetRectVisibility(frame,
+                                      nsRect(nsPoint(0,0), frame->GetSize()),
+                                      minDistance);
+    }
+  }
+
+  if (frame) {
+    nsCOMPtr<nsIDOMNode> firstVisibleNode = do_QueryInterface(frame->GetContent());
+
+    if (firstVisibleNode) {
+      frame->GetOffsets(startFrameOffset, endFrameOffset);
+      (*aFirstVisibleRange)->SetStart(firstVisibleNode, startFrameOffset);
+      (*aFirstVisibleRange)->SetEnd(firstVisibleNode, endFrameOffset);
+    }
+  }
+
+  return false;
 }
 
 already_AddRefed<nsIPresShell>
 nsTypeAheadFind::GetPresShell()
 {
   if (!mPresShell)
     return nullptr;
 
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.h
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.h
@@ -51,18 +51,18 @@ protected:
   void RangeStartsInsideLink(nsIDOMRange *aRange, nsIPresShell *aPresShell, 
                              bool *aIsInsideLink, bool *aIsStartingLink);
 
   void GetSelection(nsIPresShell *aPresShell, nsISelectionController **aSelCon, 
                     nsISelection **aDomSel);
   // *aNewRange may not be collapsed.  If you want to collapse it in a
   // particular way, you need to do it yourself.
   bool IsRangeVisible(nsIPresShell *aPresShell, nsPresContext *aPresContext,
-                        nsIDOMRange *aRange, bool aFlushLayout,
-                        nsIDOMRange **aNewRange,
+                        nsIDOMRange *aRange, bool aMustBeVisible, 
+                        bool aGetTopVisibleLeaf, nsIDOMRange **aNewRange,
                         bool *aUsesIndependentSelection);
   nsresult FindItNow(nsIPresShell *aPresShell, bool aIsLinksOnly,
                      bool aIsFirstVisiblePreferred, bool aFindPrev,
                      uint16_t* aResult);
   nsresult GetSearchContainers(nsISupports *aContainer,
                                nsISelectionController *aSelectionController,
                                bool aIsFirstVisiblePreferred,
                                bool aFindPrev, nsIPresShell **aPresShell,
@@ -90,17 +90,17 @@ protected:
   // mLastFindLength is the character length of the last find string.  It is used for
   // disabling the "not found" sound when using backspace or delete
   uint32_t mLastFindLength;
 
   // Sound is played asynchronously on some platforms.
   // If we destroy mSoundInterface before sound has played, it won't play
   nsCOMPtr<nsISound> mSoundInterface;
   bool mIsSoundInitialized;
-
+  
   // where selection was when user started the find
   nsCOMPtr<nsIDOMRange> mStartFindRange;
   nsCOMPtr<nsIDOMRange> mSearchRange;
   nsCOMPtr<nsIDOMRange> mStartPointRange;
   nsCOMPtr<nsIDOMRange> mEndPointRange;
 
   // Cached useful interfaces
   nsCOMPtr<nsIFind> mFind;
--- a/toolkit/modules/FinderHighlighter.jsm
+++ b/toolkit/modules/FinderHighlighter.jsm
@@ -1132,19 +1132,16 @@ FinderHighlighter.prototype = {
     this._updateRangeOutline(dict);
 
     let allRects = [];
     if (paintContent || dict.modalHighlightAllMask) {
       this._updateDynamicRangesRects(dict);
 
       let DOMRect = window.DOMRect;
       for (let [range, rectsAndTexts] of dict.modalHighlightRectsMap) {
-        if (!this.finder._fastFind.isRangeVisible(range, false))
-          continue;
-
         if (dict.updateAllRanges)
           rectsAndTexts = this._updateRangeRects(range);
 
         // If a geometry change was detected, we bail out right away here, because
         // the current set of ranges has been invalidated.
         if (dict.detectedGeometryChange)
           return;
 
--- a/toolkit/modules/FinderIterator.jsm
+++ b/toolkit/modules/FinderIterator.jsm
@@ -562,17 +562,23 @@ this.FinderIterator = {
       return frames;
 
     // Casting `window.frames` to an Iterator doesn't work, so we're stuck with
     // a plain, old for-loop.
     for (let i = 0, l = window.frames.length; i < l; ++i) {
       let frame = window.frames[i];
       // Don't count matches in hidden frames.
       let frameEl = frame && frame.frameElement;
-      if (!frameEl || !frameEl.getClientRects().length)
+      if (!frameEl)
+        continue;
+      // Construct a range around the frame element to check its visiblity.
+      let range = window.document.createRange();
+      range.setStart(frameEl, 0);
+      range.setEnd(frameEl, 0);
+      if (!finder._fastFind.isRangeVisible(range, this._getDocShell(range), true))
         continue;
       // All conditions pass, so push the current frame and its children on the
       // stack.
       frames.push(frame, ...this._collectFrames(frame, finder));
     }
 
     return frames;
   },