mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 653881 - Push <xbl:children> in ancestor filter. r=bz,dbaron
--HG-- extra : rebase_source : 9aafffadd2451ca7274e99d7e07d0d71ea52ca02
This commit is contained in:
parent
a3a6516091
commit
1f6764a664
@ -3513,6 +3513,19 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
|
||||
const nsStyleDisplay* display = styleContext->StyleDisplay();
|
||||
nsIContent* const content = aItem.mContent;
|
||||
|
||||
// Get the parent of the content and check if it is a XBL children element.
|
||||
// Push the children element as an ancestor here because it does
|
||||
// not have a frame and would not otherwise be pushed as an ancestor. It is
|
||||
// necessary to do so in order to correctly handle style resolution on
|
||||
// descendants.
|
||||
nsIContent* parent = content->GetParent();
|
||||
bool pushInsertionPoint = aState.mTreeMatchContext.mAncestorFilter.HasFilter() &&
|
||||
parent && parent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL);
|
||||
TreeMatchContext::AutoAncestorPusher
|
||||
insertionPointPusher(pushInsertionPoint,
|
||||
aState.mTreeMatchContext,
|
||||
parent && parent->IsElement() ? parent->AsElement() : nullptr);
|
||||
|
||||
// Push the content as a style ancestor now, so we don't have to do
|
||||
// it in our various full-constructor functions. In particular,
|
||||
// since a number of full-constructor functions don't actually call
|
||||
@ -9945,6 +9958,20 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
|
||||
|
||||
FlattenedChildIterator iter(aContent);
|
||||
for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
|
||||
// Get the parent of the content and check if it is a XBL children element
|
||||
// (if the content is a children element then parent != aContent because the
|
||||
// FlattenedChildIterator will transitively iterate through <xbl:children>
|
||||
// for default content). Push the children element as an ancestor here because
|
||||
// it does not have a frame and would not otherwise be pushed as an ancestor.
|
||||
nsIContent* parent = child->GetParent();
|
||||
MOZ_ASSERT(parent, "Parent must be non-null because we are iterating children.");
|
||||
MOZ_ASSERT(parent->IsElement());
|
||||
bool pushInsertionPoint = parent != aContent &&
|
||||
aState.mTreeMatchContext.mAncestorFilter.HasFilter();
|
||||
TreeMatchContext::AutoAncestorPusher
|
||||
ancestorPusher(pushInsertionPoint, aState.mTreeMatchContext,
|
||||
parent->AsElement());
|
||||
|
||||
// Frame construction item construction should not post
|
||||
// restyles, so removing restyle flags here is safe.
|
||||
if (child->IsElement()) {
|
||||
@ -11204,6 +11231,20 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState,
|
||||
|
||||
FlattenedChildIterator iter(parentContent);
|
||||
for (nsIContent* content = iter.GetNextChild(); content; content = iter.GetNextChild()) {
|
||||
// Get the parent of the content and check if it is a XBL children element
|
||||
// (if the content is a children element then contentParent != parentContent because the
|
||||
// FlattenedChildIterator will transitively iterate through <xbl:children>
|
||||
// for default content). Push the children element as an ancestor here because
|
||||
// it does not have a frame and would not otherwise be pushed as an ancestor.
|
||||
nsIContent* contentParent = content->GetParent();
|
||||
MOZ_ASSERT(contentParent, "Parent must be non-null because we are iterating children.");
|
||||
MOZ_ASSERT(contentParent->IsElement());
|
||||
bool pushInsertionPoint = contentParent != parentContent &&
|
||||
aState.mTreeMatchContext.mAncestorFilter.HasFilter();
|
||||
TreeMatchContext::AutoAncestorPusher
|
||||
insertionPointPusher(pushInsertionPoint, aState.mTreeMatchContext,
|
||||
contentParent->AsElement());
|
||||
|
||||
// Manually check for comments/PIs, since we don't have a frame to pass to
|
||||
// AddFrameConstructionItems. We know our parent is a non-replaced inline,
|
||||
// so there is no need to do the NeedFrameFor check.
|
||||
|
@ -1369,6 +1369,18 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
|
||||
NS_ASSERTION(!undisplayed->mStyle->GetPseudo(),
|
||||
"Shouldn't have random pseudo style contexts in the "
|
||||
"undisplayed map");
|
||||
|
||||
// Get the parent of the undisplayed content and check if it is a XBL
|
||||
// children element. Push the children element as an ancestor here because it does
|
||||
// not have a frame and would not otherwise be pushed as an ancestor.
|
||||
nsIContent* parent = undisplayed->mContent->GetParent();
|
||||
bool pushInsertionPoint = parent &&
|
||||
parent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL);
|
||||
TreeMatchContext::AutoAncestorPusher
|
||||
insertionPointPusher(pushInsertionPoint,
|
||||
aTreeMatchContext,
|
||||
parent && parent->IsElement() ? parent->AsElement() : nullptr);
|
||||
|
||||
nsRestyleHint thisChildHint = childRestyleHint;
|
||||
RestyleTracker::RestyleData undisplayedRestyleData;
|
||||
if (aRestyleTracker.GetRestyleData(undisplayed->mContent->AsElement(),
|
||||
@ -1524,6 +1536,19 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
|
||||
for (; !childFrames.AtEnd(); childFrames.Next()) {
|
||||
nsIFrame* child = childFrames.get();
|
||||
if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
|
||||
// Get the parent of the child frame's content and check if it is a XBL
|
||||
// children element. Push the children element as an ancestor here because it does
|
||||
// not have a frame and would not otherwise be pushed as an ancestor.
|
||||
|
||||
// Check if the frame has a content because |child| may be a nsPageFrame that does
|
||||
// not have a content.
|
||||
nsIContent* parent = child->GetContent() ? child->GetContent()->GetParent() : nullptr;
|
||||
bool pushInsertionPoint = parent &&
|
||||
parent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL);
|
||||
TreeMatchContext::AutoAncestorPusher
|
||||
insertionPointPusher(pushInsertionPoint, aTreeMatchContext,
|
||||
parent && parent->IsElement() ? parent->AsElement() : nullptr);
|
||||
|
||||
// only do frames that are in flow
|
||||
if (nsGkAtoms::placeholderFrame == child->GetType()) { // placeholder
|
||||
// get out of flow frame and recur there
|
||||
|
@ -3395,14 +3395,6 @@ TreeMatchContext::InitAncestors(Element *aElement)
|
||||
break;
|
||||
}
|
||||
|
||||
if (parent->AsElement()->NodeInfo()->Equals(nsGkAtoms::children,
|
||||
kNameSpaceID_XBL)) {
|
||||
parent = parent->GetParentNode();
|
||||
if (!parent->IsElement()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cur = parent->AsElement();
|
||||
} while (true);
|
||||
|
||||
@ -3471,17 +3463,6 @@ AncestorFilter::AssertHasAllAncestors(Element *aElement) const
|
||||
{
|
||||
nsINode* cur = aElement->GetParentNode();
|
||||
while (cur && cur->IsElement()) {
|
||||
// We build our ancestor tree from the top-down. However, because
|
||||
// <xbl:children> elements don't have frames and don't directly
|
||||
// participate in the style tree, they never get pushed as ancestors.
|
||||
// Skip them on the way up as we do on the way down (see also
|
||||
// mozilla::dom::ExplicitChildIterator).
|
||||
if (cur->AsElement()->NodeInfo()->Equals(nsGkAtoms::children,
|
||||
kNameSpaceID_XBL)) {
|
||||
cur = cur->GetParentNode();
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mElements.Contains(cur));
|
||||
cur = cur->GetParentNode();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user