diff --git a/accessible/generic/Accessible.h b/accessible/generic/Accessible.h index 2385c776c853..7b49672cdaf6 100644 --- a/accessible/generic/Accessible.h +++ b/accessible/generic/Accessible.h @@ -14,6 +14,7 @@ #include "mozilla/UniquePtr.h" #include "nsIContent.h" +#include "nsIContentInlines.h" #include "nsString.h" #include "nsTArray.h" #include "nsRefPtrHashtable.h" diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 646891d8eea9..7df6a7cdac19 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -151,10 +151,15 @@ nsIContent::FindFirstNonChromeOnlyAccessContent() const return nullptr; } -nsIContent* -nsIContent::GetFlattenedTreeParent() const +nsINode* +nsIContent::GetFlattenedTreeParentNodeInternal() const { - nsIContent* parent = GetParent(); + nsINode* parentNode = GetParentNode(); + if (!parentNode || !parentNode->IsContent()) { + MOZ_ASSERT(!parentNode || parentNode == OwnerDoc()); + return parentNode; + } + nsIContent* parent = parentNode->AsContent(); if (parent && nsContentUtils::HasDistributedChildren(parent) && nsContentUtils::IsInSameAnonymousTree(parent, this)) { diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 4a29532292e4..0878a74bdb7b 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -107,6 +107,7 @@ #include "nsIChromeRegistry.h" #include "nsIConsoleService.h" #include "nsIContent.h" +#include "nsIContentInlines.h" #include "nsIContentSecurityPolicy.h" #include "nsIContentSink.h" #include "nsIContentViewer.h" diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h index 6a03e6f06537..c52396258ec7 100644 --- a/dom/base/nsIContent.h +++ b/dom/base/nsIContent.h @@ -719,13 +719,15 @@ public: virtual void SetXBLInsertionParent(nsIContent* aContent) = 0; /** - * Returns the content node that is the parent of this node in the flattened - * tree. For nodes that are not filtered into an insertion point, this - * simply returns their DOM parent in the original DOM tree. - * - * @return the flattened tree parent + * Same as GetFlattenedTreeParentNode, but returns null if the parent is + * non-nsIContent. */ - nsIContent *GetFlattenedTreeParent() const; + inline nsIContent *GetFlattenedTreeParent() const; + + /** + * Helper method, which we leave public so that it's accessible from nsINode. + */ + nsINode *GetFlattenedTreeParentNodeInternal() const; /** * Gets the custom element data used by web components custom element. diff --git a/dom/base/nsIContentInlines.h b/dom/base/nsIContentInlines.h index a9fd95bfeda8..16fde9e56e26 100644 --- a/dom/base/nsIContentInlines.h +++ b/dom/base/nsIContentInlines.h @@ -33,5 +33,39 @@ inline mozilla::dom::ShadowRoot* nsIContent::GetShadowRoot() const return AsElement()->FastGetShadowRoot(); } +inline nsINode* nsINode::GetFlattenedTreeParentNode() const +{ + nsINode* parent = GetParentNode(); + + // Try to short-circuit past the complicated and not-exactly-fast logic for + // computing the flattened parent. + // + // There are three cases where we need might something other than parentNode: + // (1) The node is an explicit child of an XBL-bound element, re-bound + // to an XBL insertion point. + // (2) The node is a top-level element in a shadow tree, whose flattened + // parent is the host element (as opposed to the actual parent which + // is the shadow root). + // (3) The node is an explicit child of an element with a shadow root, + // re-bound to an insertion point. + bool needSlowCall = HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) || + IsInShadowTree() || + (parent && parent->IsContent() && + parent->AsContent()->GetShadowRoot()); + if (MOZ_UNLIKELY(needSlowCall)) { + MOZ_ASSERT(IsContent()); + return AsContent()->GetFlattenedTreeParentNodeInternal(); + } + + return parent; +} + +inline nsIContent* +nsIContent::GetFlattenedTreeParent() const +{ + nsINode* parent = GetFlattenedTreeParentNode(); + return (parent && parent->IsContent()) ? parent->AsContent() : nullptr; +} + #endif // nsIContentInlines_h diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h index 215dce51d6ee..893f014f7e01 100644 --- a/dom/base/nsINode.h +++ b/dom/base/nsINode.h @@ -928,6 +928,16 @@ public: return mParent; } + /** + * Returns the node that is the parent of this node in the flattened + * tree. This differs from the normal parent if the node is filtered + * into an insertion point, or if the node is a direct child of a + * shadow root. + * + * @return the flattened tree parent + */ + inline nsINode* GetFlattenedTreeParentNode() const; + /** * Get the parent nsINode for this node if it is an Element. * @return the parent node diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index fc0734c9dc2f..f9a5e5075969 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -29,6 +29,7 @@ #include "nsCOMPtr.h" #include "nsFocusManager.h" #include "nsIContent.h" +#include "nsIContentInlines.h" #include "nsIDocument.h" #include "nsIFrame.h" #include "nsIWidget.h" diff --git a/dom/html/HTMLLinkElement.cpp b/dom/html/HTMLLinkElement.cpp index 4743570d088a..1e166b172d67 100644 --- a/dom/html/HTMLLinkElement.cpp +++ b/dom/html/HTMLLinkElement.cpp @@ -17,6 +17,7 @@ #include "nsGenericHTMLElement.h" #include "nsGkAtoms.h" #include "nsDOMTokenList.h" +#include "nsIContentInlines.h" #include "nsIDocument.h" #include "nsIDOMEvent.h" #include "nsIDOMStyleSheet.h" diff --git a/dom/svg/SVGAnimationElement.cpp b/dom/svg/SVGAnimationElement.cpp index c9d1191daf4b..838db997abcc 100644 --- a/dom/svg/SVGAnimationElement.cpp +++ b/dom/svg/SVGAnimationElement.cpp @@ -10,6 +10,7 @@ #include "nsSMILAnimationController.h" #include "nsSMILAnimationFunction.h" #include "nsContentUtils.h" +#include "nsIContentInlines.h" #include "nsIURI.h" #include "prtime.h" diff --git a/dom/svg/SVGSVGElement.h b/dom/svg/SVGSVGElement.h index 56738380fe36..f0a056e69fc1 100644 --- a/dom/svg/SVGSVGElement.h +++ b/dom/svg/SVGSVGElement.h @@ -9,6 +9,7 @@ #include "mozilla/dom/FromParser.h" #include "nsAutoPtr.h" +#include "nsIContentInlines.h" #include "nsISVGPoint.h" #include "nsSVGEnum.h" #include "nsSVGLength2.h" diff --git a/layout/base/RestyleTracker.h b/layout/base/RestyleTracker.h index 5247ed423c46..95ec9064d80f 100644 --- a/layout/base/RestyleTracker.h +++ b/layout/base/RestyleTracker.h @@ -16,6 +16,7 @@ #include "nsAutoPtr.h" #include "nsClassHashtable.h" #include "nsContainerFrame.h" +#include "nsIContentInlines.h" #include "mozilla/SplayTree.h" #include "mozilla/RestyleLogging.h" #include "GeckoProfiler.h" diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 9f80bd953890..98cc84ac7284 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -23,6 +23,7 @@ #include "nsFrameList.h" #include "nsPlaceholderFrame.h" #include "nsIContent.h" +#include "nsIContentInlines.h" #include "nsContentUtils.h" #include "nsCSSPseudoElements.h" #include "nsIAtom.h" diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp index 5c083ba1850b..2b6799f48539 100644 --- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -18,6 +18,7 @@ #include "nsPresContext.h" #include "nsRenderingContext.h" #include "nsIFrameInlines.h" +#include "nsIContentInlines.h" using namespace mozilla; using namespace mozilla::gfx; diff --git a/layout/inspector/inDOMUtils.cpp b/layout/inspector/inDOMUtils.cpp index 8a9fed8a13be..c979cb1ab4c1 100644 --- a/layout/inspector/inDOMUtils.cpp +++ b/layout/inspector/inDOMUtils.cpp @@ -14,6 +14,7 @@ #include "nsISupportsArray.h" #include "nsString.h" #include "nsIStyleSheetLinkingElement.h" +#include "nsIContentInlines.h" #include "nsIDOMElement.h" #include "nsIDocument.h" #include "nsIPresShell.h"