зеркало из https://github.com/mozilla/gecko-dev.git
Bug 996796 patch 18 - Fix RestyleTracker to handle restyle hints exactly rather than pessimistically when restyling continuations with varying styles (e.g., spans inside ::first-line or ::first-letter). r=heycam
This will be necessary when we use the restyle tracker for the animation-only style flush, because animation-only style flushes need to update *only* the animation style data and no other style data. Thus using the RestyleTracker for animation-only style flushes requires that we do this.
This commit is contained in:
Родитель
242b2eae80
Коммит
d2fe2e8c79
|
@ -1943,7 +1943,8 @@ GetPrevContinuationWithSameStyle(nsIFrame* aFrame)
|
|||
*/
|
||||
static nsIFrame*
|
||||
GetNextContinuationWithSameStyle(nsIFrame* aFrame,
|
||||
nsStyleContext* aOldStyleContext)
|
||||
nsStyleContext* aOldStyleContext,
|
||||
bool* aHaveMoreContinuations = nullptr)
|
||||
{
|
||||
// See GetPrevContinuationWithSameStyle about {ib} splits.
|
||||
|
||||
|
@ -1973,6 +1974,9 @@ GetNextContinuationWithSameStyle(nsIFrame* aFrame,
|
|||
aOldStyleContext->GetParent() != nextStyle->GetParent(),
|
||||
"continuations should have the same style context");
|
||||
nextContinuation = nullptr;
|
||||
if (aHaveMoreContinuations) {
|
||||
*aHaveMoreContinuations = true;
|
||||
}
|
||||
}
|
||||
return nextContinuation;
|
||||
}
|
||||
|
@ -2335,6 +2339,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
|
|||
MOZ_ASSERT(!(aRestyleHint & eRestyle_LaterSiblings),
|
||||
"eRestyle_LaterSiblings must not be part of aRestyleHint");
|
||||
|
||||
nsRestyleHint hintToRestore = nsRestyleHint(0);
|
||||
if (mContent && mContent->IsElement()) {
|
||||
mContent->OwnerDoc()->FlushPendingLinkUpdates();
|
||||
RestyleTracker::RestyleData restyleData;
|
||||
|
@ -2342,6 +2347,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
|
|||
if (NS_UpdateHint(mHintsHandled, restyleData.mChangeHint)) {
|
||||
mChangeList->AppendChange(mFrame, mContent, restyleData.mChangeHint);
|
||||
}
|
||||
hintToRestore = restyleData.mRestyleHint;
|
||||
aRestyleHint = nsRestyleHint(aRestyleHint | restyleData.mRestyleHint);
|
||||
}
|
||||
}
|
||||
|
@ -2354,10 +2360,20 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
|
|||
// TEMPORARY (until bug 918064): Call RestyleSelf for each
|
||||
// continuation or block-in-inline sibling.
|
||||
|
||||
bool haveMoreContinuations = false;
|
||||
for (nsIFrame* f = mFrame; f;
|
||||
f = GetNextContinuationWithSameStyle(f, oldContext)) {
|
||||
f = GetNextContinuationWithSameStyle(f, oldContext,
|
||||
&haveMoreContinuations)) {
|
||||
RestyleSelf(f, aRestyleHint);
|
||||
}
|
||||
|
||||
if (haveMoreContinuations && hintToRestore) {
|
||||
// If we have more continuations with different style (e.g., because
|
||||
// we're inside a ::first-letter or ::first-line), put the restyle
|
||||
// hint back.
|
||||
mRestyleTracker.AddPendingRestyleToTable(mContent->AsElement(),
|
||||
hintToRestore, nsChangeHint(0));
|
||||
}
|
||||
}
|
||||
|
||||
RestyleChildren(childRestyleHint);
|
||||
|
@ -2455,17 +2471,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint)
|
|||
"non pseudo-element frame without content node");
|
||||
newContext = styleSet->ResolveStyleForNonElement(parentContext);
|
||||
}
|
||||
else if (!(aRestyleHint & (eRestyle_Self | eRestyle_Subtree)) &&
|
||||
!prevContinuation) {
|
||||
// Unfortunately, if prevContinuation is non-null then we may have
|
||||
// already stolen the restyle tracker entry for this element while
|
||||
// processing prevContinuation. So we don't know whether aRestyleHint
|
||||
// should really be 0 here or whether it should be eRestyle_Self. Be
|
||||
// pessimistic and force an actual reresolve in that situation. The good
|
||||
// news is that in the common case when prevContinuation is non-null we
|
||||
// just used prevContinuationContext anyway and aren't reaching this code
|
||||
// to start with.
|
||||
|
||||
else if (!(aRestyleHint & (eRestyle_Self | eRestyle_Subtree))) {
|
||||
Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType);
|
||||
if (aRestyleHint == nsRestyleHint(0)) {
|
||||
newContext =
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
namespace mozilla {
|
||||
|
||||
class RestyleManager;
|
||||
class ElementRestyler;
|
||||
|
||||
/**
|
||||
* Helper class that collects a list of frames that need
|
||||
|
@ -230,6 +231,8 @@ class RestyleTracker {
|
|||
public:
|
||||
typedef mozilla::dom::Element Element;
|
||||
|
||||
friend class ElementRestyler; // for AddPendingRestyleToTable
|
||||
|
||||
RestyleTracker(Element::FlagsType aRestyleBits) :
|
||||
mRestyleBits(aRestyleBits),
|
||||
mHaveLaterSiblingRestyles(false)
|
||||
|
@ -261,7 +264,7 @@ public:
|
|||
* if the element already had eRestyle_LaterSiblings set on it.
|
||||
*/
|
||||
bool AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint,
|
||||
nsChangeHint aMinChangeHint);
|
||||
nsChangeHint aMinChangeHint);
|
||||
|
||||
/**
|
||||
* Process the restyles we've been tracking.
|
||||
|
@ -312,6 +315,9 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
bool AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint,
|
||||
nsChangeHint aMinChangeHint);
|
||||
|
||||
/**
|
||||
* Handle a single mPendingRestyles entry. aRestyleHint must not
|
||||
* include eRestyle_LaterSiblings; that needs to be dealt with
|
||||
|
@ -352,9 +358,10 @@ private:
|
|||
bool mHaveLaterSiblingRestyles;
|
||||
};
|
||||
|
||||
inline bool RestyleTracker::AddPendingRestyle(Element* aElement,
|
||||
nsRestyleHint aRestyleHint,
|
||||
nsChangeHint aMinChangeHint)
|
||||
inline bool
|
||||
RestyleTracker::AddPendingRestyleToTable(Element* aElement,
|
||||
nsRestyleHint aRestyleHint,
|
||||
nsChangeHint aMinChangeHint)
|
||||
{
|
||||
RestyleData existingData;
|
||||
existingData.mRestyleHint = nsRestyleHint(0);
|
||||
|
@ -377,6 +384,17 @@ inline bool RestyleTracker::AddPendingRestyle(Element* aElement,
|
|||
|
||||
mPendingRestyles.Put(aElement, existingData);
|
||||
|
||||
return hadRestyleLaterSiblings;
|
||||
}
|
||||
|
||||
inline bool
|
||||
RestyleTracker::AddPendingRestyle(Element* aElement,
|
||||
nsRestyleHint aRestyleHint,
|
||||
nsChangeHint aMinChangeHint)
|
||||
{
|
||||
bool hadRestyleLaterSiblings =
|
||||
AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint);
|
||||
|
||||
// We can only treat this element as a restyle root if we would
|
||||
// actually restyle its descendants (so either call
|
||||
// ReResolveStyleContext on it or just reframe it).
|
||||
|
|
Загрузка…
Ссылка в новой задаче