Bug 1180118 - Part 2: Add eRestyle_SomeDescendants restyle hint and pass associated restyle hint data into restyle methods. r=bzbarsky

This commit is contained in:
Cameron McCormack 2015-08-04 17:27:52 +10:00
parent 26cab7b377
commit 535001e4ae
5 changed files with 133 additions and 66 deletions

View File

@ -981,11 +981,12 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
}
void
RestyleManager::RestyleElement(Element* aElement,
nsIFrame* aPrimaryFrame,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint)
RestyleManager::RestyleElement(Element* aElement,
nsIFrame* aPrimaryFrame,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData)
{
MOZ_ASSERT(mReframingStyleContexts, "should have rsc");
NS_ASSERTION(aPrimaryFrame == aElement->GetPrimaryFrame(),
@ -1022,7 +1023,7 @@ RestyleManager::RestyleElement(Element* aElement,
nsCSSFrameConstructor::REMOVE_FOR_RECONSTRUCTION, nullptr);
} else if (aPrimaryFrame) {
ComputeAndProcessStyleChange(aPrimaryFrame, aMinHint, aRestyleTracker,
aRestyleHint);
aRestyleHint, aRestyleHintData);
} else if (aRestyleHint & ~eRestyle_LaterSiblings) {
// We're restyling an element with no frame, so we should try to
// make one if its new style says it should have one. But in order
@ -1038,7 +1039,8 @@ RestyleManager::RestyleElement(Element* aElement,
newContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS) {
// Style change for a display:contents node that did not recreate frames.
ComputeAndProcessStyleChange(newContext, aElement, aMinHint,
aRestyleTracker, aRestyleHint);
aRestyleTracker, aRestyleHint,
aRestyleHintData);
}
}
}
@ -1637,7 +1639,8 @@ RestyleManager::StartRebuildAllStyleData(RestyleTracker& aRestyleTracker)
// frame and not the root node's primary frame? (We could do
// roughly what we do for aRestyleHint above.)
ComputeAndProcessStyleChange(rootFrame,
changeHint, aRestyleTracker, restyleHint);
changeHint, aRestyleTracker, restyleHint,
RestyleHintData());
}
void
@ -1819,7 +1822,8 @@ RestyleManager::UpdateOnlyAnimationStyles()
void
RestyleManager::PostRestyleEvent(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint)
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData)
{
if (MOZ_UNLIKELY(!mPresContext) ||
MOZ_UNLIKELY(mPresContext->PresShell()->IsDestroying())) {
@ -1831,7 +1835,8 @@ RestyleManager::PostRestyleEvent(Element* aElement,
return;
}
mPendingRestyles.AddPendingRestyle(aElement, aRestyleHint, aMinChangeHint);
mPendingRestyles.AddPendingRestyle(aElement, aRestyleHint, aMinChangeHint,
aRestyleHintData);
// Set mHavePendingNonAnimationRestyles for any restyle that could
// possibly contain non-animation styles (i.e., those that require us
@ -2742,6 +2747,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
nsTArray<nsRefPtr<Element>> descendants;
nsRestyleHint hintToRestore = nsRestyleHint(0);
RestyleHintData hintDataToRestore;
if (mContent && mContent->IsElement() &&
// If we're resolving from the root of the frame tree (which
// we do when mDoRebuildAllStyleData), we need to avoid getting the
@ -2764,6 +2770,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
mChangeList->AppendChange(mFrame, mContent, restyleData->mChangeHint);
}
hintToRestore = restyleData->mRestyleHint;
hintDataToRestore = Move(restyleData->mRestyleHintData);
aRestyleHint = nsRestyleHint(aRestyleHint | restyleData->mRestyleHint);
descendants.SwapElements(restyleData->mDescendants);
}
@ -3586,11 +3593,12 @@ ElementRestyler::RestyleChildren(nsRestyleHint aChildRestyleHint)
void
ElementRestyler::RestyleChildrenOfDisplayContentsElement(
nsIFrame* aParentFrame,
nsStyleContext* aNewContext,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint)
nsIFrame* aParentFrame,
nsStyleContext* aNewContext,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData)
{
MOZ_ASSERT(!(mHintsHandled & nsChangeHint_ReconstructFrame), "why call me?");
@ -3619,8 +3627,8 @@ ElementRestyler::RestyleChildrenOfDisplayContentsElement(
!f->GetPrevContinuation()) {
if (!(f->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
ComputeStyleChangeFor(f, mChangeList, aMinHint, aRestyleTracker,
aRestyleHint, mContextsToClear,
mSwappedStructOwners);
aRestyleHint, aRestyleHintData,
mContextsToClear, mSwappedStructOwners);
}
}
}
@ -3637,6 +3645,7 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData,
nsTArray<ContextToClear>&
aContextsToClear,
nsTArray<nsRefPtr<nsStyleContext>>&
@ -4090,10 +4099,11 @@ ClearCachedInheritedStyleDataOnDescendants(
}
void
RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint)
RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData)
{
MOZ_ASSERT(mReframingStyleContexts, "should have rsc");
nsStyleChangeList changeList;
@ -4105,17 +4115,19 @@ RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsTArray<nsRefPtr<nsStyleContext>> swappedStructOwners;
ElementRestyler::ComputeStyleChangeFor(aFrame, &changeList, aMinChange,
aRestyleTracker, aRestyleHint,
aRestyleHintData,
contextsToClear, swappedStructOwners);
ProcessRestyledFrames(changeList);
ClearCachedInheritedStyleDataOnDescendants(contextsToClear);
}
void
RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
Element* aElement,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint)
RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
Element* aElement,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData)
{
MOZ_ASSERT(mReframingStyleContexts, "should have rsc");
MOZ_ASSERT(aNewContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS);
@ -4142,7 +4154,8 @@ RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
visibleKidsOfHiddenElement, contextsToClear,
swappedStructOwners);
r.RestyleChildrenOfDisplayContentsElement(frame, aNewContext, aMinChange,
aRestyleTracker, aRestyleHint);
aRestyleTracker,
aRestyleHint, aRestyleHintData);
ProcessRestyledFrames(changeList);
ClearCachedInheritedStyleDataOnDescendants(contextsToClear);
}
@ -4223,9 +4236,11 @@ RestyleManager::RestyleHintToString(nsRestyleHint aHint)
{
nsCString result;
bool any = false;
const char* names[] = { "Self", "Subtree", "LaterSiblings", "CSSTransitions",
"CSSAnimations", "SVGAttrAnimations", "StyleAttribute",
"StyleAttribute_Animations", "Force", "ForceDescendants" };
const char* names[] = {
"Self", "SomeDescendants", "Subtree", "LaterSiblings", "CSSTransitions",
"CSSAnimations", "SVGAttrAnimations", "StyleAttribute",
"StyleAttribute_Animations", "Force", "ForceDescendants"
};
uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1);
uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1);
for (uint32_t i = 0; i < ArrayLength(names); i++) {

View File

@ -129,16 +129,18 @@ public:
private:
// Used when restyling an element with a frame.
void ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint);
void ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData);
// Used when restyling a display:contents element.
void ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
Element* aElement,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint);
void ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
Element* aElement,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData);
public:
@ -335,10 +337,12 @@ public:
* on them.
* @param aMinChangeHint: A minimum change hint for aContent and its
* descendants.
* @param aRestyleHintData: Additional data to go with aRestyleHint.
*/
void PostRestyleEvent(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint);
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData = nullptr);
void PostRestyleEventForLazyConstruction()
{
@ -423,7 +427,8 @@ private:
nsIFrame* aPrimaryFrame,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint);
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData);
void StartRebuildAllStyleData(RestyleTracker& aRestyleTracker);
void FinishRebuildAllStyleData();
@ -577,7 +582,9 @@ public:
nsStyleContext* aNewContext,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint);
nsRestyleHint aRestyleHint,
const RestyleHintData&
aRestyleHintData);
/**
* Re-resolve the style contexts for a frame tree, building aChangeList
@ -588,6 +595,7 @@ public:
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData,
nsTArray<ContextToClear>& aContextsToClear,
nsTArray<nsRefPtr<nsStyleContext>>&
aSwappedStructOwners);

View File

@ -169,6 +169,9 @@ CollectRestyles(nsISupports* aElement,
currentRestyle->mElement = element;
currentRestyle->mRestyleHint = aData->mRestyleHint;
currentRestyle->mChangeHint = aData->mChangeHint;
// We can move aData since we'll be clearing mPendingRestyles after
// we finish enumerating it.
currentRestyle->mRestyleHintData = Move(aData->mRestyleHintData);
#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
currentRestyle->mBacktrace = Move(aData->mBacktrace);
#endif
@ -186,7 +189,8 @@ CollectRestyles(nsISupports* aElement,
inline void
RestyleTracker::ProcessOneRestyle(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aChangeHint)
nsChangeHint aChangeHint,
const RestyleHintData& aRestyleHintData)
{
NS_PRECONDITION((aRestyleHint & eRestyle_LaterSiblings) == 0,
"Someone should have handled this before calling us");
@ -211,7 +215,7 @@ RestyleTracker::ProcessOneRestyle(Element* aElement,
}
#endif
mRestyleManager->RestyleElement(aElement, primaryFrame, aChangeHint,
*this, aRestyleHint);
*this, aRestyleHint, aRestyleHintData);
} else if (aChangeHint &&
(primaryFrame ||
(aChangeHint & nsChangeHint_ReconstructFrame))) {
@ -367,7 +371,8 @@ RestyleTracker::DoProcessRestyles()
profilerRAII.emplace("Paint", "Styles", Move(data->mBacktrace));
}
#endif
ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint);
ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint,
data->mRestyleHintData);
AddRestyleRootsIfAwaitingRestyle(data->mDescendants);
if (isTimelineRecording) {
@ -427,7 +432,8 @@ RestyleTracker::DoProcessRestyles()
ProcessOneRestyle(currentRestyle->mElement,
currentRestyle->mRestyleHint,
currentRestyle->mChangeHint);
currentRestyle->mChangeHint,
currentRestyle->mRestyleHintData);
if (isTimelineRecording) {
mozilla::UniquePtr<TimelineMarker> marker =

View File

@ -258,7 +258,8 @@ public:
* if the element already had eRestyle_LaterSiblings set on it.
*/
bool AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint);
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData = nullptr);
/**
* Process the restyles we've been tracking.
@ -276,8 +277,9 @@ public:
}
struct Hints {
nsRestyleHint mRestyleHint; // What we want to restyle
nsChangeHint mChangeHint; // The minimal change hint for "self"
nsRestyleHint mRestyleHint; // What we want to restyle
nsChangeHint mChangeHint; // The minimal change hint for "self"
RestyleHintData mRestyleHintData; // Data associated with mRestyleHint
};
struct RestyleData : Hints {
@ -286,9 +288,13 @@ public:
mChangeHint = NS_STYLE_HINT_NONE;
}
RestyleData(nsRestyleHint aRestyleHint, nsChangeHint aChangeHint) {
RestyleData(nsRestyleHint aRestyleHint, nsChangeHint aChangeHint,
const RestyleHintData* aRestyleHintData) {
mRestyleHint = aRestyleHint;
mChangeHint = aChangeHint;
if (aRestyleHintData) {
mRestyleHintData = *aRestyleHintData;
}
}
// Descendant elements we must check that we ended up restyling, ordered
@ -341,7 +347,8 @@ public:
private:
bool AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint);
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData = nullptr);
/**
* Handle a single mPendingRestyles entry. aRestyleHint must not
@ -350,7 +357,8 @@ private:
*/
inline void ProcessOneRestyle(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aChangeHint);
nsChangeHint aChangeHint,
const RestyleHintData& aRestyleHintData);
typedef nsClassHashtable<nsISupportsHashKey, RestyleData> PendingRestyleTable;
typedef nsAutoTArray< nsRefPtr<Element>, 32> RestyleRootArray;
@ -381,7 +389,8 @@ private:
inline bool
RestyleTracker::AddPendingRestyleToTable(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint)
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData)
{
RestyleData* existingData;
@ -396,7 +405,8 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement,
}
if (!existingData) {
RestyleData* rd = new RestyleData(aRestyleHint, aMinChangeHint);
RestyleData* rd =
new RestyleData(aRestyleHint, aMinChangeHint, aRestyleHintData);
#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
if (profiler_feature_active("restyle")) {
rd->mBacktrace.reset(profiler_get_backtrace());
@ -411,6 +421,10 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement,
existingData->mRestyleHint =
nsRestyleHint(existingData->mRestyleHint | aRestyleHint);
NS_UpdateHint(existingData->mChangeHint, aMinChangeHint);
if (aRestyleHintData) {
existingData->mRestyleHintData.mSelectorsForDescendants
.AppendElements(aRestyleHintData->mSelectorsForDescendants);
}
return hadRestyleLaterSiblings;
}
@ -418,10 +432,12 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement,
inline bool
RestyleTracker::AddPendingRestyle(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint)
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData)
{
bool hadRestyleLaterSiblings =
AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint);
AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint,
aRestyleHintData);
// We can only treat this element as a restyle root if we would
// actually restyle its descendants (so either call

View File

@ -8,8 +8,11 @@
#ifndef nsChangeHint_h___
#define nsChangeHint_h___
#include "nsDebug.h"
#include "mozilla/Types.h"
#include "nsDebug.h"
#include "nsTArray.h"
class nsCSSSelector;
// Defines for various style related constants
@ -377,36 +380,40 @@ enum nsRestyleHint {
// work.)
eRestyle_Self = (1<<0),
// Rerun selector matching on descendants of the element that match
// a given selector.
eRestyle_SomeDescendants = (1<<1),
// Rerun selector matching on the element and all of its descendants.
// (Implies eRestyle_ForceDescendants, which ensures that we continue
// the restyling process for all descendants, but doesn't cause
// selector matching.)
eRestyle_Subtree = (1<<1),
eRestyle_Subtree = (1<<2),
// Rerun selector matching on all later siblings of the element and
// all of their descendants.
eRestyle_LaterSiblings = (1<<2),
eRestyle_LaterSiblings = (1<<3),
// Replace the style data coming from CSS transitions without updating
// any other style data. If a new style context results, update style
// contexts on the descendants. (Irrelevant if eRestyle_Self or
// eRestyle_Subtree is also set, since those imply a superset of the
// work.)
eRestyle_CSSTransitions = (1<<3),
eRestyle_CSSTransitions = (1<<4),
// Replace the style data coming from CSS animations without updating
// any other style data. If a new style context results, update style
// contexts on the descendants. (Irrelevant if eRestyle_Self or
// eRestyle_Subtree is also set, since those imply a superset of the
// work.)
eRestyle_CSSAnimations = (1<<4),
eRestyle_CSSAnimations = (1<<5),
// Replace the style data coming from SVG animations (SMIL Animations)
// without updating any other style data. If a new style context
// results, update style contexts on the descendants. (Irrelevant if
// eRestyle_Self or eRestyle_Subtree is also set, since those imply a
// superset of the work.)
eRestyle_SVGAttrAnimations = (1<<5),
eRestyle_SVGAttrAnimations = (1<<6),
// Replace the style data coming from inline style without updating
// any other style data. If a new style context results, update style
@ -417,22 +424,22 @@ enum nsRestyleHint {
// eRestyle_Self.
// If the change is for the advance of a declarative animation, use
// the value below instead.
eRestyle_StyleAttribute = (1<<6),
eRestyle_StyleAttribute = (1<<7),
// Same as eRestyle_StyleAttribute, but for when the change results
// from the advance of a declarative animation.
eRestyle_StyleAttribute_Animations = (1<<7),
eRestyle_StyleAttribute_Animations = (1<<8),
// Continue the restyling process to the current frame's children even
// if this frame's restyling resulted in no style changes.
eRestyle_Force = (1<<8),
eRestyle_Force = (1<<9),
// Continue the restyling process to all of the current frame's
// descendants, even if any frame's restyling resulted in no style
// changes. (Implies eRestyle_Force.) Note that this is weaker than
// eRestyle_Subtree, which makes us rerun selector matching on all
// descendants rather than just continuing the restyling process.
eRestyle_ForceDescendants = (1<<9),
eRestyle_ForceDescendants = (1<<10),
// Useful unions:
eRestyle_AllHintsWithAnimations = eRestyle_CSSTransitions |
@ -483,4 +490,19 @@ inline nsRestyleHint operator^=(nsRestyleHint& aLeft, nsRestyleHint aRight)
return aLeft = aLeft ^ aRight;
}
namespace mozilla {
/**
* Additional data used in conjunction with an nsRestyleHint to control the
* restyle process.
*/
struct RestyleHintData
{
// When eRestyle_SomeDescendants is used, this array contains the selectors
// that identify which descendants will be restyled.
nsTArray<nsCSSSelector*> mSelectorsForDescendants;
};
} // namespace mozilla
#endif /* nsChangeHint_h___ */