Backed out 6 changesets (bug 1302470) for mochitest-chrome failures
authorPhil Ringnalda <philringnalda@gmail.com>
Thu, 31 Aug 2017 20:04:24 -0700
changeset 378154 628a46720153fefa077044bff627d2f8f5b5cc17
parent 378153 85e0bc442b6188e1f706f7681c7a586919053294
child 378155 14960c3fbf80f4f366b7224792c65089e6192a69
push id94412
push userarchaeopteryx@coole-files.de
push dateFri, 01 Sep 2017 08:46:09 +0000
treeherdermozilla-inbound@d56571d7f1be [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1302470
milestone57.0a1
backs out3aab8b1494efb366fe048ef9eadb97d0f81ccb85
fdd40abac61157fc28e7182a03011fbb6bb6573a
a67bc2f1b62483d36ea19977718e60cb309678e6
160522290018ae5af657629dc7c2dd8b89800999
6b948c53394446f77cf68340671b0ba828057850
399011313b3cbe01ba2c4202e524badc694c40c3
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
Backed out 6 changesets (bug 1302470) for mochitest-chrome failures CLOSED TREE Backed out changeset 3aab8b1494ef (bug 1302470) Backed out changeset fdd40abac611 (bug 1302470) Backed out changeset a67bc2f1b624 (bug 1302470) Backed out changeset 160522290018 (bug 1302470) Backed out changeset 6b948c533944 (bug 1302470) Backed out changeset 399011313b3c (bug 1302470) MozReview-Commit-ID: 2B3uMAkzNGv
layout/base/nsLayoutUtils.cpp
layout/forms/nsHTMLButtonControlFrame.cpp
layout/painting/nsDisplayList.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
@@ -3273,34 +3273,33 @@ nsLayoutUtils::GetFramesForArea(nsIFrame
     if (rootScrollFrame) {
       builder.SetIgnoreScrollFrame(rootScrollFrame);
     }
   }
   if (aFlags & IGNORE_CROSS_DOC) {
     builder.SetDescendIntoSubdocuments(false);
   }
 
-  builder.SetHitTestShouldStopAtFirstOpaque(aFlags & ONLY_VISIBLE);
-
   builder.EnterPresShell(aFrame);
   builder.SetDirtyRect(aRect);
   aFrame->BuildDisplayListForStackingContext(&builder, &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(&builder);
   return NS_OK;
 }
 
 // aScrollFrameAsScrollable must be non-nullptr and queryable to an nsIFrame
 FrameMetrics
 nsLayoutUtils::CalculateBasicFrameMetrics(nsIScrollableFrame* aScrollFrame) {
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -108,17 +108,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/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -5688,30 +5688,22 @@ nsDisplayWrapList::ComputeVisibility(nsD
   aBuilder->SubtractFromVisibleRegion(aVisibleRegion, removed);
 
   return retval;
 }
 
 nsRegion
 nsDisplayWrapList::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                    bool* aSnap) {
+  *aSnap = false;
   nsRegion result;
   if (mList.IsOpaque()) {
     // Everything within GetBounds that's visible is opaque.
     result = GetBounds(aBuilder, aSnap);
-  } else if (aBuilder->HitTestShouldStopAtFirstOpaque()) {
-    // If we care about an accurate opaque region, iterate the display list
-    // and build up a region of opaque bounds.
-    nsDisplayItem* item = mList.GetBottom();
-    while (item) {
-      result.OrWith(item->GetOpaqueRegion(aBuilder, aSnap));
-      item = item->GetAbove();
-    }
-  }
-  *aSnap = false;
+  }
   return result;
 }
 
 Maybe<nscolor>
 nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder) {
   // We could try to do something but let's conservatively just return Nothing.
   return Nothing();
 }
--- a/toolkit/components/typeaheadfind/nsITypeAheadFind.idl
+++ b/toolkit/components/typeaheadfind/nsITypeAheadFind.idl
@@ -52,22 +52,19 @@ interface nsITypeAheadFind : nsISupports
    * the selection. */
   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 using heuristics */
+  /* Check if a range is visible */
   boolean isRangeVisible(in nsIDOMRange aRange, in boolean aMustBeInViewPort);
 
-  /* Check if a range is actually rendered (out of viewport always false) */
-  boolean isRangeRendered(in nsIDOMRange aRange);
-
   /******************************* 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;
                                         // Most recent elem found, if a link
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -1213,32 +1213,32 @@ nsTypeAheadFind::IsRangeVisible(nsIPresS
   nsCOMPtr<nsIDOMNode> node;
   aRange->GetStartContainer(getter_AddRefs(node));
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(node));
   if (!content)
     return false;
 
   nsIFrame *frame = content->GetPrimaryFrame();
-  if (!frame) {
+  if (!frame)
     return false;  // No frame! Not visible then.
-  }
 
-  if (!frame->StyleVisibility()->IsVisible()) {
+  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);
   }
 
   // ---- 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 startFrameOffset, endFrameOffset;
   uint32_t startRangeOffset;
   aRange->GetStartOffset(&startRangeOffset);
   while (true) {
     frame->GetOffsets(startFrameOffset, endFrameOffset);
     if (static_cast<int32_t>(startRangeOffset) < endFrameOffset) {
@@ -1264,48 +1264,37 @@ nsTypeAheadFind::IsRangeVisible(nsIPresS
 
   if (!aGetTopVisibleLeaf && !frame->GetRect().IsEmpty()) {
     rectVisibility =
       aPresShell->GetRectVisibility(frame,
                                     nsRect(nsPoint(0,0), frame->GetSize()),
                                     minDistance);
 
     if (rectVisibility != nsRectVisibility_kAboveViewport) {
-      // This is an early exit case, where we return true iff the range
-      // is actually rendered.
-      return IsRangeRendered(aPresShell, aPresContext, aRange);
+      return true;
     }
   }
 
-  // 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".
-    return true;
-  }
-
-  // The range isn't in the viewport, but we could scroll it into view.
-  // Move range forward to first visible point,
+  // 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) {
+  if (!frameTraversal)
     return false;
-  }
 
   while (rectVisibility == nsRectVisibility_kAboveViewport) {
     frameTraversal->Next();
     frame = frameTraversal->CurrentItem();
     if (!frame)
       return false;
 
     if (!frame->GetRect().IsEmpty()) {
@@ -1324,96 +1313,16 @@ nsTypeAheadFind::IsRangeVisible(nsIPresS
       (*aFirstVisibleRange)->SetStart(firstVisibleNode, startFrameOffset);
       (*aFirstVisibleRange)->SetEnd(firstVisibleNode, endFrameOffset);
     }
   }
 
   return false;
 }
 
-NS_IMETHODIMP
-nsTypeAheadFind::IsRangeRendered(nsIDOMRange *aRange,
-                                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();
-  *aResult = IsRangeRendered(presShell, presContext, aRange);
-  return NS_OK;
-}
-
-bool
-nsTypeAheadFind::IsRangeRendered(nsIPresShell *aPresShell,
-                                 nsPresContext *aPresContext,
-                                 nsIDOMRange *aRange)
-{
-  NS_ASSERTION(aPresShell && aPresContext && aRange,
-               "params are invalid");
-
-  nsCOMPtr<nsIDOMNode> node;
-  aRange->GetCommonAncestorContainer(getter_AddRefs(node));
-
-  nsCOMPtr<nsIContent> content(do_QueryInterface(node));
-  if (!content) {
-    return false;
-  }
-
-  nsIFrame *frame = content->GetPrimaryFrame();
-  if (!frame) {
-    return false;  // No frame! Not visible then.
-  }
-
-  if (!frame->StyleVisibility()->IsVisible()) {
-    return false;
-  }
-
-  // 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.
-  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) {
-        return true;
-      }
-    }
-
-    frames.ClearAndRetainStorage();
-  }
-
-  return false;
-}
-
 already_AddRefed<nsIPresShell>
 nsTypeAheadFind::GetPresShell()
 {
   if (!mPresShell)
     return nullptr;
 
   nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShell);
   if (shell) {
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.h
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.h
@@ -55,18 +55,16 @@ protected:
   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 aMustBeVisible,
                         bool aGetTopVisibleLeaf, nsIDOMRange **aNewRange,
                         bool *aUsesIndependentSelection);
-  bool IsRangeRendered(nsIPresShell *aPresShell, nsPresContext *aPresContext,
-                          nsIDOMRange *aRange);
   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,
                                nsPresContext **aPresContext);
--- a/toolkit/modules/FinderHighlighter.jsm
+++ b/toolkit/modules/FinderHighlighter.jsm
@@ -1124,19 +1124,16 @@ FinderHighlighter.prototype = {
     if (paintContent || dict.modalHighlightAllMask) {
       // No need to update dynamic ranges separately when we already about to
       // update all of them anyway.
       if (!dict.updateAllRanges)
         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
@@ -8,17 +8,16 @@ this.EXPORTED_SYMBOLS = ["FinderIterator
 
 const { interfaces: Ci, classes: Cc, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NLP", "resource://gre/modules/NLP.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Rect", "resource://gre/modules/Geometry.jsm");
 
 const kDebug = false;
 const kIterationSizeMax = 100;
 const kTimeoutPref = "findbar.iteratorTimeout";
 
 /**
  * FinderIterator singleton. See the documentation for the `start()` method to
  * learn more.
@@ -575,23 +574,27 @@ this.FinderIterator = {
    */
   _collectFrames(window, finder) {
     let frames = [];
     if (!("frames" in window) || !window.frames.length)
       return frames;
 
     // Casting `window.frames` to an Iterator doesn't work, so we're stuck with
     // a plain, old for-loop.
-    let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
     for (let i = 0, l = window.frames.length; i < l; ++i) {
       let frame = window.frames[i];
-      // Don't count matches in hidden frames; get the frame element rect and
-      // check if it's empty. We shan't flush!
+      // Don't count matches in hidden frames.
       let frameEl = frame && frame.frameElement;
-      if (!frameEl || Rect.fromRect(dwu.getBoundsWithoutFlushing(frameEl)).isEmpty())
+      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;
   },