mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1632765 - Bypass a restyling assertion in a replicated fixed-pos subtree. r=TYLin
The pref flip in this bug causes an assertion to fail in layout/generic/crashtests/1137723-1.html. Our behavior in that crashtest is so messed up that I can't even begin to describe it. That test-case has three-pages, and a link inside a fixed-pos subtree, which has a ::after pseudo-element. Via the magic of nsCSSFrameConstructor::ReplicateFixedFrames, we end up constructing multiple frames, one per page, for the fixed subtree. We end up with a link with three different ::after pseudo-elements (one on each page), of which the link only knows about the latest one. This means that when restyling the link (which was already broken, it just didn't happen before the prefs), we'd visit the pseudo-element in some other place of the frame tree we can get a hand on. Restyling these frames is generally not supported and will do ~nothing, given the current setup. There's no way to get a hand from the DOM node to all its replicated frames. But that's not something I plan to fix for this bug, and this assertion is blocking me. Differential Revision: https://phabricator.services.mozilla.com/D72755
This commit is contained in:
parent
64c748af66
commit
f7004f36cc
@ -1989,6 +1989,25 @@ static const nsIFrame* ExpectedOwnerForChild(const nsIFrame* aFrame) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
// FIXME(emilio, bug 1633685): We should ideally figure out how to properly
|
||||
// restyle replicated fixed pos frames... We seem to assume everywhere that they
|
||||
// can't get restyled at the moment...
|
||||
static bool IsInReplicatedFixedPosTree(const nsIFrame* aFrame) {
|
||||
if (!aFrame->PresContext()->IsPaginated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; aFrame; aFrame = aFrame->GetParent()) {
|
||||
if (aFrame->StyleDisplay()->mPosition == StylePositionProperty::Fixed &&
|
||||
!aFrame->FirstContinuation()->IsPrimaryFrame() &&
|
||||
nsLayoutUtils::IsReallyFixedPos(aFrame)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServoRestyleState::AssertOwner(const ServoRestyleState& aParent) const {
|
||||
MOZ_ASSERT(mOwner);
|
||||
MOZ_ASSERT(!mOwner->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW));
|
||||
@ -1999,7 +2018,7 @@ void ServoRestyleState::AssertOwner(const ServoRestyleState& aParent) const {
|
||||
// chains of ServoRestyleStates in some cases where it's just not worth it.
|
||||
if (aParent.mOwner) {
|
||||
const nsIFrame* owner = ExpectedOwnerForChild(mOwner);
|
||||
if (owner != aParent.mOwner) {
|
||||
if (owner != aParent.mOwner && !IsInReplicatedFixedPosTree(mOwner)) {
|
||||
MOZ_ASSERT(IsAnonBox(owner),
|
||||
"Should only have expected owner weirdness when anon boxes "
|
||||
"are involved");
|
||||
@ -2022,7 +2041,8 @@ nsChangeHint ServoRestyleState::ChangesHandledFor(
|
||||
return mChangesHandled;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mOwner == ExpectedOwnerForChild(aFrame),
|
||||
MOZ_ASSERT(mOwner == ExpectedOwnerForChild(aFrame) ||
|
||||
IsInReplicatedFixedPosTree(aFrame),
|
||||
"Missed some frame in the hierarchy?");
|
||||
return mChangesHandled;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user