From 51d3f2d2f3f19e253f31edac92f23c47dde5b878 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Fri, 18 Jun 2021 10:35:19 +0000 Subject: [PATCH] Issue #1783 - Part 1: Move GetNodeDepth to ResizeObserver.cpp GetNodeDepth() is a specialized version for ResizeObserver to get the depth of a node across Shadow DOM. It's better to have this in ResizeObserver.cpp instead of the generic ContentUtils. Also updated the function to bypass the shadow root itself and not count it because ResizeObserver doesn't observe the shadow root and only needs the relative depths among all observed targets. IOW we use the flattened tree here. --- dom/base/ResizeObserver.cpp | 38 ++++++++++++++++++++++++++++++++----- dom/base/nsContentUtils.cpp | 14 -------------- dom/base/nsContentUtils.h | 8 -------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/dom/base/ResizeObserver.cpp b/dom/base/ResizeObserver.cpp index 37d940c2b3..c3302efee3 100644 --- a/dom/base/ResizeObserver.cpp +++ b/dom/base/ResizeObserver.cpp @@ -6,13 +6,43 @@ #include "mozilla/dom/ResizeObserver.h" #include "mozilla/dom/DOMRect.h" -#include "nsContentUtils.h" +#include "nsIContentInlines.h" #include "nsIFrame.h" #include "nsSVGUtils.h" namespace mozilla { namespace dom { +/** + * Returns the length of the parent-traversal path (in terms of the number of + * nodes) to an unparented/root node from aNode. An unparented/root node is + * considered to have a depth of 1, its children have a depth of 2, etc. + * aNode is expected to be non-null. + * Note: The shadow root is not part of the calculation because the caller, + * ResizeObserver, doesn't observe the shadow root, and only needs relative + * depths among all the observed targets. In other words, we calculate the + * depth of the flattened tree. + * + * Note: these is a spec issue about how to handle shadow DOM case. We + * may need to update this function later. + * + * + * https://drafts.csswg.org/resize-observer/#calculate-depth-for-node-h + */ +static uint32_t GetNodeDepth(nsINode* aNode) { + uint32_t depth = 1; + + MOZ_ASSERT(aNode, "Node shouldn't be null"); + + // Use GetFlattenedTreeParentNode to bypass the shadow root and cross the + // shadow boundary to calculate the node depth without the shadow root. + while ((aNode = aNode->GetFlattenedTreeParentNode())) { + ++depth; + } + + return depth; +} + NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObserver) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsISupports) @@ -128,8 +158,7 @@ ResizeObserver::GatherActiveObservations(uint32_t aDepth) for (auto observation : mObservationList) { if (observation->IsActive()) { - uint32_t targetDepth = - nsContentUtils::GetNodeDepth(observation->Target()); + uint32_t targetDepth = GetNodeDepth(observation->Target()); if (targetDepth > aDepth) { mActiveTargets.AppendElement(observation); @@ -176,8 +205,7 @@ ResizeObserver::BroadcastActiveObservations() // will be based on the updated size from last delivered observations. observation->UpdateBroadcastSize(rect); - uint32_t targetDepth = - nsContentUtils::GetNodeDepth(observation->Target()); + uint32_t targetDepth = GetNodeDepth(observation->Target()); if (targetDepth < shallowestTargetDepth) { shallowestTargetDepth = targetDepth; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 95f176ca8f..fdffd95531 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -9781,17 +9781,3 @@ nsContentUtils::GetClosestNonNativeAnonymousAncestor(Element* aElement) } return e; } - -/* static */ uint32_t -nsContentUtils::GetNodeDepth(nsINode* aNode) -{ - uint32_t depth = 1; - - MOZ_ASSERT(aNode, "Node shouldn't be null"); - - while ((aNode = aNode->GetParentNode())) { - ++depth; - } - - return depth; -} \ No newline at end of file diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 83ee417403..b3bc22f286 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -2756,14 +2756,6 @@ public: static bool IsCustomElementsEnabled() { return sIsCustomElementsEnabled; } - /** - * Returns the length of the parent-traversal path (in terms of the number of - * nodes) to an unparented/root node from aNode. An unparented/root node is - * considered to have a depth of 1, its children have a depth of 2, etc. - * aNode is expected to be non-null. - */ - static uint32_t GetNodeDepth(nsINode* aNode); - private: static bool InitializeEventTable();