mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1180118 - Part 9: Clear nsCSSSelector pointers in the pending restyle tracker if they might be stale. r=bzbarsky
This commit is contained in:
parent
e55a3ea42c
commit
77856721a3
@ -127,6 +127,10 @@ public:
|
||||
*/
|
||||
nsresult ReparentStyleContext(nsIFrame* aFrame);
|
||||
|
||||
void ClearSelectors() {
|
||||
mPendingRestyles.ClearSelectors();
|
||||
}
|
||||
|
||||
private:
|
||||
// Used when restyling an element with a frame.
|
||||
void ComputeAndProcessStyleChange(nsIFrame* aFrame,
|
||||
|
@ -447,6 +447,9 @@ RestyleTracker::DoProcessRestyles()
|
||||
}
|
||||
}
|
||||
|
||||
// mPendingRestyles is now empty.
|
||||
mHaveSelectors = false;
|
||||
|
||||
mRestyleManager->EndProcessingRestyles();
|
||||
}
|
||||
|
||||
@ -512,4 +515,23 @@ RestyleTracker::AddRestyleRootsIfAwaitingRestyle(
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RestyleTracker::ClearSelectors()
|
||||
{
|
||||
if (!mHaveSelectors) {
|
||||
return;
|
||||
}
|
||||
for (auto it = mPendingRestyles.Iter(); !it.Done(); it.Next()) {
|
||||
RestyleData* data = it.Data();
|
||||
if (data->mRestyleHint & eRestyle_SomeDescendants) {
|
||||
data->mRestyleHint =
|
||||
(data->mRestyleHint & ~eRestyle_SomeDescendants) | eRestyle_Subtree;
|
||||
data->mRestyleHintData.mSelectorsForDescendants.Clear();
|
||||
} else {
|
||||
MOZ_ASSERT(data->mRestyleHintData.mSelectorsForDescendants.IsEmpty());
|
||||
}
|
||||
}
|
||||
mHaveSelectors = false;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -231,6 +231,7 @@ public:
|
||||
explicit RestyleTracker(Element::FlagsType aRestyleBits)
|
||||
: mRestyleBits(aRestyleBits)
|
||||
, mHaveLaterSiblingRestyles(false)
|
||||
, mHaveSelectors(false)
|
||||
{
|
||||
NS_PRECONDITION((mRestyleBits & ~ELEMENT_ALL_RESTYLE_FLAGS) == 0,
|
||||
"Why do we have these bits set?");
|
||||
@ -352,6 +353,14 @@ public:
|
||||
void AddRestyleRootsIfAwaitingRestyle(
|
||||
const nsTArray<nsRefPtr<Element>>& aElements);
|
||||
|
||||
/**
|
||||
* Converts any eRestyle_SomeDescendants restyle hints in the pending restyle
|
||||
* table into eRestyle_Subtree hints and clears out the associated arrays of
|
||||
* nsCSSSelector pointers. This is called in response to a style sheet change
|
||||
* that might have cause an nsCSSSelector to be destroyed.
|
||||
*/
|
||||
void ClearSelectors();
|
||||
|
||||
/**
|
||||
* The document we're associated with.
|
||||
*/
|
||||
@ -402,6 +411,9 @@ private:
|
||||
// flag. We need this to avoid enumerating the hashtable looking
|
||||
// for such entries when we can't possibly have any.
|
||||
bool mHaveLaterSiblingRestyles;
|
||||
// True if we have some entries with selectors in the restyle hint data.
|
||||
// We use this to skip iterating over mPendingRestyles in ClearSelectors.
|
||||
bool mHaveSelectors;
|
||||
};
|
||||
|
||||
inline bool
|
||||
@ -412,6 +424,11 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement,
|
||||
{
|
||||
RestyleData* existingData;
|
||||
|
||||
if (aRestyleHintData &&
|
||||
!aRestyleHintData->mSelectorsForDescendants.IsEmpty()) {
|
||||
mHaveSelectors = true;
|
||||
}
|
||||
|
||||
// Check the RestyleBit() flag before doing the hashtable Get, since
|
||||
// it's possible that the data in the hashtable isn't actually
|
||||
// relevant anymore (if the flag is not set).
|
||||
|
@ -1709,6 +1709,15 @@ CSSStyleSheet::List(FILE* out, int32_t aIndent) const
|
||||
void
|
||||
CSSStyleSheet::ClearRuleCascades()
|
||||
{
|
||||
// We might be in ClearRuleCascades because we had a modification
|
||||
// to the sheet that resulted in an nsCSSSelector being destroyed.
|
||||
// Tell the RestyleManager for each document we're used in
|
||||
// so that they can drop any nsCSSSelector pointers (used for
|
||||
// eRestyle_SomeDescendants) in their mPendingRestyles.
|
||||
for (nsStyleSet* styleSet : mStyleSets) {
|
||||
styleSet->ClearSelectors();
|
||||
}
|
||||
|
||||
bool removedSheetFromRuleProcessorCache = false;
|
||||
if (mRuleProcessors) {
|
||||
nsCSSRuleProcessor **iter = mRuleProcessors->Elements(),
|
||||
|
@ -385,6 +385,14 @@ SortStyleSheetsByScope(nsTArray<CSSStyleSheet*>& aSheets)
|
||||
nsresult
|
||||
nsStyleSet::GatherRuleProcessors(sheetType aType)
|
||||
{
|
||||
// We might be in GatherRuleProcessors because we are dropping a sheet,
|
||||
// resulting in an nsCSSSelector being destroyed. Tell the
|
||||
// RestyleManager for each document we're used in so that they can
|
||||
// drop any nsCSSSelector pointers (used for eRestyle_SomeDescendants)
|
||||
// in their mPendingRestyles.
|
||||
if (IsCSSSheetType(aType)) {
|
||||
ClearSelectors();
|
||||
}
|
||||
nsCOMPtr<nsIStyleRuleProcessor> oldRuleProcessor(mRuleProcessors[aType]);
|
||||
nsTArray<nsCOMPtr<nsIStyleRuleProcessor>> oldScopedDocRuleProcessors;
|
||||
if (aType == eAgentSheet || aType == eUserSheet) {
|
||||
@ -2498,3 +2506,13 @@ nsStyleSet::HasRuleProcessorUsedByMultipleStyleSets(sheetType aSheetType)
|
||||
static_cast<nsCSSRuleProcessor*>(mRuleProcessors[aSheetType].get());
|
||||
return rp->IsUsedByMultipleStyleSets();
|
||||
}
|
||||
|
||||
void
|
||||
nsStyleSet::ClearSelectors()
|
||||
{
|
||||
// We might be called before we've done our first rule tree construction.
|
||||
if (!mRuleTree) {
|
||||
return;
|
||||
}
|
||||
PresContext()->RestyleManager()->ClearSelectors();
|
||||
}
|
||||
|
@ -399,6 +399,10 @@ class nsStyleSet final
|
||||
|
||||
bool HasRuleProcessorUsedByMultipleStyleSets(sheetType aSheetType);
|
||||
|
||||
// Tells the RestyleManager for the document using this style set
|
||||
// to drop any nsCSSSelector pointers it has.
|
||||
void ClearSelectors();
|
||||
|
||||
private:
|
||||
nsStyleSet(const nsStyleSet& aCopy) = delete;
|
||||
nsStyleSet& operator=(const nsStyleSet& aCopy) = delete;
|
||||
|
Loading…
Reference in New Issue
Block a user