author | Phil Ringnalda <philringnalda@gmail.com> |
Thu, 31 Aug 2017 20:04:24 -0700 | |
changeset 378154 | 628a46720153fefa077044bff627d2f8f5b5cc17 |
parent 378153 | 85e0bc442b6188e1f706f7681c7a586919053294 |
child 378155 | 14960c3fbf80f4f366b7224792c65089e6192a69 |
push id | 94412 |
push user | archaeopteryx@coole-files.de |
push date | Fri, 01 Sep 2017 08:46:09 +0000 |
treeherder | mozilla-inbound@d56571d7f1be [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1302470 |
milestone | 57.0a1 |
backs out | 3aab8b1494efb366fe048ef9eadb97d0f81ccb85 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
|
--- 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; },