From c9c94f0ee1af64ad1a98b39014044c80d512c249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 21 Dec 2018 11:30:28 +0000 Subject: [PATCH] Bug 1513749 - Move NodesFromRectHelper to DocumentOrShadowRoot. r=mats We'll factor the commont bits out in a bit. Differential Revision: https://phabricator.services.mozilla.com/D14356 --HG-- extra : moz-landing-system : lando --- dom/base/DocumentOrShadowRoot.cpp | 71 +++++++++++++++++++++++++++ dom/base/DocumentOrShadowRoot.h | 6 +++ dom/base/nsDocument.cpp | 80 +------------------------------ dom/base/nsIDocument.h | 5 -- 4 files changed, 79 insertions(+), 83 deletions(-) diff --git a/dom/base/DocumentOrShadowRoot.cpp b/dom/base/DocumentOrShadowRoot.cpp index b99a8e4a8fd7..50348b5d6a0d 100644 --- a/dom/base/DocumentOrShadowRoot.cpp +++ b/dom/base/DocumentOrShadowRoot.cpp @@ -328,6 +328,77 @@ Element* DocumentOrShadowRoot::ElementFromPointHelper( return elementArray.SafeElementAt(0); } +nsresult DocumentOrShadowRoot::NodesFromRectHelper( + float aX, float aY, float aTopSize, float aRightSize, float aBottomSize, + float aLeftSize, bool aIgnoreRootScrollFrame, bool aFlushLayout, + nsINodeList** aReturn) { + MOZ_ASSERT(AsNode().IsDocument()); + NS_ENSURE_ARG_POINTER(aReturn); + + nsIDocument* doc = AsNode().AsDocument(); + nsSimpleContentList* elements = new nsSimpleContentList(doc); + NS_ADDREF(elements); + *aReturn = elements; + + // Following the same behavior of elementFromPoint, + // we don't return anything if either coord is negative + if (!aIgnoreRootScrollFrame && (aX < 0 || aY < 0)) return NS_OK; + + nscoord x = nsPresContext::CSSPixelsToAppUnits(aX - aLeftSize); + nscoord y = nsPresContext::CSSPixelsToAppUnits(aY - aTopSize); + nscoord w = nsPresContext::CSSPixelsToAppUnits(aLeftSize + aRightSize) + 1; + nscoord h = nsPresContext::CSSPixelsToAppUnits(aTopSize + aBottomSize) + 1; + + nsRect rect(x, y, w, h); + + // Make sure the layout information we get is up-to-date, and + // ensure we get a root frame (for everything but XUL) + if (aFlushLayout) { + doc->FlushPendingNotifications(FlushType::Layout); + } + + nsIPresShell* ps = doc->GetShell(); + NS_ENSURE_STATE(ps); + nsIFrame* rootFrame = ps->GetRootFrame(); + + // XUL docs, unlike HTML, have no frame tree until everything's done loading + if (!rootFrame) + return NS_OK; // return nothing to premature XUL callers as a reminder to + // wait + + EnumSet options = { + FrameForPointOption::IgnorePaintSuppression, + FrameForPointOption::IgnoreCrossDoc}; + + if (aIgnoreRootScrollFrame) { + options += FrameForPointOption::IgnoreRootScrollFrame; + } + + AutoTArray outFrames; + nsLayoutUtils::GetFramesForArea(rootFrame, rect, outFrames, options); + + // Used to filter out repeated elements in sequence. + nsIContent* lastAdded = nullptr; + + for (uint32_t i = 0; i < outFrames.Length(); i++) { + nsIContent* node = doc->GetContentInThisDocument(outFrames[i]); + + if (node && !node->IsElement() && !node->IsText()) { + // We have a node that isn't an element or a text node, + // use its parent content instead. + // FIXME(emilio): How can this possibly be? We only create frames for + // elements and text! + node = node->GetParent(); + } + if (node && node != lastAdded) { + elements->AppendElement(node); + lastAdded = node; + } + } + + return NS_OK; +} + Element* DocumentOrShadowRoot::AddIDTargetObserver(nsAtom* aID, IDTargetObserver aObserver, void* aData, diff --git a/dom/base/DocumentOrShadowRoot.h b/dom/base/DocumentOrShadowRoot.h index ea8a7ee9b086..ef77dbeb40b5 100644 --- a/dom/base/DocumentOrShadowRoot.h +++ b/dom/base/DocumentOrShadowRoot.h @@ -17,6 +17,7 @@ class nsContentList; class nsCycleCollectionTraversalCallback; class nsIDocument; class nsINode; +class nsINodeList; class nsIRadioVisitor; class nsWindowSizes; @@ -115,6 +116,11 @@ class DocumentOrShadowRoot { bool aIgnoreRootScrollFrame, bool aFlushLayout); + nsresult NodesFromRectHelper(float aX, float aY, float aTopSize, + float aRightSize, float aBottomSize, + float aLeftSize, bool aIgnoreRootScrollFrame, + bool aFlushLayout, nsINodeList** aReturn); + /** * This gets fired when the element that an id refers to changes. * This fires at difficult times. It is generally not safe to do anything diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 14abdb624a9e..42a81d78b2ad 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -3394,84 +3394,6 @@ Element* nsIDocument::GetCurrentScript() { return el; } -namespace { - -using FrameForPointOption = nsLayoutUtils::FrameForPointOption; - -} - -// FIXME(emilio): Unify with DocumentOrShadowRoot stuff. -nsresult nsIDocument::NodesFromRectHelper(float aX, float aY, float aTopSize, - float aRightSize, float aBottomSize, - float aLeftSize, - bool aIgnoreRootScrollFrame, - bool aFlushLayout, - nsINodeList** aReturn) { - NS_ENSURE_ARG_POINTER(aReturn); - - nsSimpleContentList* elements = new nsSimpleContentList(this); - NS_ADDREF(elements); - *aReturn = elements; - - // Following the same behavior of elementFromPoint, - // we don't return anything if either coord is negative - if (!aIgnoreRootScrollFrame && (aX < 0 || aY < 0)) return NS_OK; - - nscoord x = nsPresContext::CSSPixelsToAppUnits(aX - aLeftSize); - nscoord y = nsPresContext::CSSPixelsToAppUnits(aY - aTopSize); - nscoord w = nsPresContext::CSSPixelsToAppUnits(aLeftSize + aRightSize) + 1; - nscoord h = nsPresContext::CSSPixelsToAppUnits(aTopSize + aBottomSize) + 1; - - nsRect rect(x, y, w, h); - - // Make sure the layout information we get is up-to-date, and - // ensure we get a root frame (for everything but XUL) - if (aFlushLayout) { - FlushPendingNotifications(FlushType::Layout); - } - - nsIPresShell* ps = GetShell(); - NS_ENSURE_STATE(ps); - nsIFrame* rootFrame = ps->GetRootFrame(); - - // XUL docs, unlike HTML, have no frame tree until everything's done loading - if (!rootFrame) - return NS_OK; // return nothing to premature XUL callers as a reminder to - // wait - - EnumSet options = { - FrameForPointOption::IgnorePaintSuppression, - FrameForPointOption::IgnoreCrossDoc}; - - if (aIgnoreRootScrollFrame) { - options += FrameForPointOption::IgnoreRootScrollFrame; - } - - AutoTArray outFrames; - nsLayoutUtils::GetFramesForArea(rootFrame, rect, outFrames, options); - - // Used to filter out repeated elements in sequence. - nsIContent* lastAdded = nullptr; - - for (uint32_t i = 0; i < outFrames.Length(); i++) { - nsIContent* node = GetContentInThisDocument(outFrames[i]); - - if (node && !node->IsElement() && !node->IsText()) { - // We have a node that isn't an element or a text node, - // use its parent content instead. - // FIXME(emilio): How can this possibly be? We only create frames for - // elements and text! - node = node->GetParent(); - } - if (node && node != lastAdded) { - elements->AppendElement(node); - lastAdded = node; - } - } - - return NS_OK; -} - void nsIDocument::ReleaseCapture() const { // only release the capture if the caller can access it. This prevents a // page from stopping a scrollbar grab for example. @@ -9265,6 +9187,8 @@ already_AddRefed nsIDocument::CreateTouchList( already_AddRefed nsIDocument::CaretPositionFromPoint( float aX, float aY) { + using FrameForPointOption = nsLayoutUtils::FrameForPointOption; + nscoord x = nsPresContext::CSSPixelsToAppUnits(aX); nscoord y = nsPresContext::CSSPixelsToAppUnits(aY); nsPoint pt(x, y); diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 53a9009e4575..201cbad84f6a 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2183,11 +2183,6 @@ class nsIDocument : public nsINode, nsAtom* aAttrName, const nsAString& aAttrValue) const; - nsresult NodesFromRectHelper(float aX, float aY, float aTopSize, - float aRightSize, float aBottomSize, - float aLeftSize, bool aIgnoreRootScrollFrame, - bool aFlushLayout, nsINodeList** aReturn); - /** * See FlushSkinBindings on nsBindingManager */