summaryrefslogtreecommitdiffstats
path: root/dom/base/FragmentOrElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/FragmentOrElement.cpp')
-rw-r--r--dom/base/FragmentOrElement.cpp41
1 files changed, 40 insertions, 1 deletions
diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp
index ca00a49a5..d7e7a78f4 100644
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -152,7 +152,7 @@ nsIContent::FindFirstNonChromeOnlyAccessContent() const
}
nsINode*
-nsIContent::GetFlattenedTreeParentNodeInternal() const
+nsIContent::GetFlattenedTreeParentNodeInternal(FlattenedParentType aType) const
{
nsINode* parentNode = GetParentNode();
if (!parentNode || !parentNode->IsContent()) {
@@ -161,6 +161,45 @@ nsIContent::GetFlattenedTreeParentNodeInternal() const
}
nsIContent* parent = parentNode->AsContent();
+ if (aType == eForStyle &&
+ IsRootOfNativeAnonymousSubtree() &&
+ OwnerDoc()->GetRootElement() == parent) {
+ // When getting the flattened tree parent for style, we return null
+ // for any "document level" native anonymous content subtree root.
+ // This is NAC generated by an ancestor frame of the document element's
+ // primary frame, and includes scrollbar elements created by the root
+ // scroll frame, and the "custom content container" and accessible caret
+ // generated by the nsCanvasFrame. We distinguish document level NAC
+ // from NAC generated by the root element's primary frame below.
+ nsIFrame* parentFrame = parent->GetPrimaryFrame();
+ if (!parentFrame) {
+ // If the root element has no primary frame, it means it can't have
+ // generated any NAC itself. Thus any NAC we have here must have
+ // been generated by an ancestor frame.
+ //
+ // If we are in here, then either the root element is display:none, or
+ // we are in the middle of constructing the root of the frame tree and
+ // we are trying to eagerly restyle document level NAC in
+ // nsCSSFrameConstructor::GetAnonymousContent before the root
+ // element's frame has been constructed.
+ return nullptr;
+ }
+ nsIAnonymousContentCreator* creator = do_QueryFrame(parentFrame);
+ if (!creator) {
+ // If the root element does have a frame, but does not implement
+ // nsIAnonymousContentCreator, then this must be document level NAC.
+ return nullptr;
+ }
+ AutoTArray<nsIContent*, 8> elements;
+ creator->AppendAnonymousContentTo(elements, 0);
+ if (!elements.Contains(this)) {
+ // If the root element does have a frame, and also does implement
+ // nsIAnonymousContentCreator, but didn't create this node, then
+ // it must be document level NAC.
+ return nullptr;
+ }
+ }
+
if (parent && nsContentUtils::HasDistributedChildren(parent) &&
nsContentUtils::IsInSameAnonymousTree(parent, this)) {
// This node is distributed to insertion points, thus we