Bug 1418560: Properly return null from GetFlattenedTreeParent if the node is XBL fallback content and the binding is active. r=heycam

Otherwise we may inappropriately style it or what not. This asserts with the
patches of bug 1414999 plus the cleanup of bug 1418456, since we no longer do
StyleNewChildren (which walks over the flattened tree children).

Too bad that GetXBLBinding is a virtual call in Gecko, probably can do just
MAY_BE_IN_BINDING_MGR...

MozReview-Commit-ID: CNU0YdKeaR0
This commit is contained in:
Emilio Cobos Álvarez 2017-11-18 07:04:23 +01:00
parent be362f7fee
commit 02c0028d6e
3 changed files with 40 additions and 12 deletions

View File

@ -236,8 +236,11 @@ nsIContent::GetFlattenedTreeParentNodeInternal(FlattenedParentType aType) const
}
}
if (nsContentUtils::HasDistributedChildren(parent) &&
nsContentUtils::IsInSameAnonymousTree(parent, this)) {
if (IsRootOfAnonymousSubtree()) {
return parent;
}
if (nsContentUtils::HasDistributedChildren(parent)) {
// This node is distributed to insertion points, thus we
// need to consult the destination insertion points list to
// figure out where this node was inserted in the flattened tree.
@ -245,20 +248,25 @@ nsIContent::GetFlattenedTreeParentNodeInternal(FlattenedParentType aType) const
// but the child does not match any insertion points, thus
// the flattened tree parent is nullptr.
nsTArray<nsIContent*>* destInsertionPoints = GetExistingDestInsertionPoints();
parent = destInsertionPoints && !destInsertionPoints->IsEmpty() ?
destInsertionPoints->LastElement()->GetParent() : nullptr;
if (!destInsertionPoints || destInsertionPoints->IsEmpty()) {
return nullptr;
}
parent = destInsertionPoints->LastElement()->GetParent();
MOZ_ASSERT(parent);
} else if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
if (nsIContent* insertionPoint = GetXBLInsertionPoint()) {
parent = insertionPoint->GetParent();
MOZ_ASSERT(parent);
}
} else if (parent->OwnerDoc()->BindingManager()->GetBindingWithContent(parent)) {
// This is fallback content not assigned to any insertion point.
return nullptr;
}
// Shadow roots never shows up in the flattened tree. Return the host
// instead.
if (parent && parent->IsInShadowTree()) {
ShadowRoot* parentShadowRoot = ShadowRoot::FromNode(parent);
if (parentShadowRoot) {
if (parent->IsInShadowTree()) {
if (ShadowRoot* parentShadowRoot = ShadowRoot::FromNode(parent)) {
return parentShadowRoot->GetHost();
}
}

View File

@ -75,17 +75,21 @@ static inline bool FlattenedTreeParentIsParent(const nsINode* aNode)
}
// Check if we want the flattened parent for style, and the node is the root
// of a native anonymous content subtree parented to the document's root element.
if (Type == nsIContent::eForStyle && aNode->HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) &&
// of a native anonymous content subtree parented to the document's root
// element.
if (Type == nsIContent::eForStyle &&
aNode->HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) &&
aNode->OwnerDoc()->GetRootElement() == aNode->GetParentNode())
{
return false;
}
// Check if the node is an explicit child of an element with a shadow root,
// re-bound to an insertion point.
// Check if the node is an explicit child of an element with a shadow root or
// an element with an XBL binding, which may be re-bound to an insertion
// point, or not be bound to any, and thus won't appear on the flattened tree
// at all.
nsIContent* parent = aNode->GetParent();
if (parent && parent->GetShadowRoot()) {
if (parent && (parent->GetShadowRoot() || parent->GetXBLBinding())) {
return false;
}

View File

@ -7491,6 +7491,20 @@ nsCSSFrameConstructor::LazilyStyleNewChildRange(nsIContent* aStartChild,
}
}
static bool
IsFlattenedTreeChild(nsIContent* aParent, nsIContent* aChild)
{
FlattenedChildIterator iter(aParent);
for (nsIContent* node = iter.GetNextChild();
node;
node = iter.GetNextChild()) {
if (node == aChild) {
return true;
}
}
return false;
}
void
nsCSSFrameConstructor::StyleNewChildRange(nsIContent* aStartChild,
nsIContent* aEndChild)
@ -7504,6 +7518,8 @@ nsCSSFrameConstructor::StyleNewChildRange(nsIContent* aStartChild,
// NB: Parent may be null if the content is appended to a shadow root, and
// isn't assigned to any insertion point.
if (MOZ_LIKELY(parent) && parent->HasServoData()) {
MOZ_ASSERT(IsFlattenedTreeChild(parent, child),
"GetFlattenedTreeParent and ChildIterator don't agree, fix this!");
styleSet->StyleNewSubtree(child->AsElement());
}
}