Bug 1294863 - Part 1: Expose nsCSSRuleProcessor's RefreshRuleCascade as a virtual function (default no-op) on nsIStyleRuleProcessor, up through nsStyleSet and nsPresContext. r?heycam
RefreshRuleCascade is currently called by MediumFeaturesChanged. Refreshing the
rule cascade causes us to check which rule groups we need to apply (if media
feature values have changed). The checks for individual rule groups are
implemented in MediaRule::UseForPresentation. (MediaRule::UseForPresentation).
This patch series will change the behavior of SupportsRule::UseFromPresentation
to support custom property registrations changing, requiring reevaluation of
the @supports condition. When registrations change, we want to refresh the rule
cascade so that SupportsRule::UseFromPresentation is reevaluated.
We could call nsPresContext::MediaFeatureValuesChanged, but that does extra
work, and CSS variable registrations are not really media features.
MozReview-Commit-ID: GUEX7w9hrUK
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1848,16 +1848,29 @@ nsPresContext::MediaFeatureValuesChanged
aChangeHint
};
mDocument->EnumerateSubDocuments(MediaFeatureValuesChangedAllDocumentsCallback,
&hints);
}
void
+nsPresContext::RefreshRuleCascade()
+{
+ if (mShell) {
+ if (mShell->StyleSet()->IsGecko()) {
+ mShell->StyleSet()->AsGecko()->RefreshRuleCascade();
+ } else {
+ NS_WARNING("stylo: ServoStyleSet needs to expose the same functionality. "
+ "See also the warning in MediaFeatureValuesChanged.");
+ }
+ }
+}
+
+void
nsPresContext::MediaFeatureValuesChanged(nsRestyleHint aRestyleHint,
nsChangeHint aChangeHint)
{
mPendingMediaFeatureValuesChanged = false;
// MediumFeaturesChanged updates the applied rules, so it always gets called.
if (mShell) {
// XXXheycam ServoStyleSets don't support responding to medium
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -262,16 +262,22 @@ public:
/**
* Just like RebuildAllStyleData, except (1) asynchronous and (2) it
* doesn't rebuild the user font set.
*/
void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
nsRestyleHint aRestyleHint);
/**
+ * Refresh the rule cascade. This does not rebuild all style data -- call
+ * RebuildAllStyleData that is necessary.
+ */
+ void RefreshRuleCascade();
+
+ /**
* Handle changes in the values of media features (used in media
* queries).
*
* There are three sensible values to use for aRestyleHint:
* * nsRestyleHint(0) to rebuild style data, with rerunning of
* selector matching, only if media features have changed
* * eRestyle_ForceDescendants to force rebuilding of style data (but
* still only rerun selector matching if media query results have
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -3756,17 +3756,17 @@ nsCSSRuleProcessor::GetRuleCascade(nsPre
if (!mRuleCascades || aPresContext != mLastPresContext) {
RefreshRuleCascade(aPresContext);
}
mLastPresContext = aPresContext;
return mRuleCascades;
}
-void
+/* virtual */ void
nsCSSRuleProcessor::RefreshRuleCascade(nsPresContext* aPresContext)
{
// Having RuleCascadeData objects be per-medium (over all variation
// caused by media queries, handled through mCacheKey) works for now
// since nsCSSRuleProcessor objects are per-document. (For a given
// set of stylesheets they can vary based on medium (@media) or
// document (@-moz-document).)
--- a/layout/style/nsCSSRuleProcessor.h
+++ b/layout/style/nsCSSRuleProcessor.h
@@ -229,17 +229,17 @@ public:
protected:
virtual ~nsCSSRuleProcessor();
private:
static bool CascadeSheet(mozilla::CSSStyleSheet* aSheet,
CascadeEnumData* aData);
RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext);
- void RefreshRuleCascade(nsPresContext* aPresContext);
+ virtual void RefreshRuleCascade(nsPresContext* aPresContext) override;
nsRestyleHint HasStateDependentStyle(ElementDependentRuleProcessorData* aData,
mozilla::dom::Element* aStatefulElement,
mozilla::CSSPseudoElementType aPseudoType,
mozilla::EventStates aStateMask);
void ClearSheets();
--- a/layout/style/nsIStyleRuleProcessor.h
+++ b/layout/style/nsIStyleRuleProcessor.h
@@ -115,16 +115,25 @@ public:
* only, and may err on the side of reporting more dependencies than
* really exist.
*/
virtual nsRestyleHint HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
mozilla::RestyleHintData& aRestyleHintDataResult) = 0;
/**
+ * Refresh the rule cascade, if relevant.
+ * Currently only nsCSSRuleProcessor can/should.
+ */
+ virtual void RefreshRuleCascade(nsPresContext* aPresContext)
+ {
+ // No-op unless overridden.
+ };
+
+ /**
* Do any processing that needs to happen as a result of a change in
* the characteristics of the medium, and return whether this rule
* processor's rules have changed (e.g., because of media queries).
*/
virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) = 0;
/**
* Report the size of this style rule processor to about:memory. A
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -2405,16 +2405,35 @@ nsStyleSet::HasAttributeDependentStyle(E
if (!(data.mHint & eRestyle_Subtree)) {
// No point keeping the list of selectors around if we are going to
// restyle the whole subtree unconditionally.
aRestyleHintDataResult = Move(data.mHintData);
}
return data.mHint;
}
+void
+nsStyleSet::RefreshRuleCascade()
+{
+ NS_ASSERTION(mBatching == 0, "rule processors out of date");
+
+ nsPresContext* presContext = PresContext();
+
+ for (nsIStyleRuleProcessor* processor : mRuleProcessors) {
+ if (!processor) {
+ continue;
+ }
+ processor->RefreshRuleCascade(presContext);
+ }
+
+ for (nsIStyleRuleProcessor* processor : mScopedDocSheetRuleProcessors) {
+ processor->RefreshRuleCascade(presContext);
+ }
+}
+
bool
nsStyleSet::MediumFeaturesChanged()
{
NS_ASSERTION(mBatching == 0, "rule processors out of date");
// We can't use WalkRuleProcessors without a content node.
nsPresContext* presContext = PresContext();
bool stylesChanged = false;
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -303,16 +303,21 @@ class nsStyleSet final
nsIAtom* aAttribute,
int32_t aModType,
bool aAttrHasChanged,
const nsAttrValue* aOtherValue,
mozilla::RestyleHintData&
aRestyleHintDataResult);
/*
+ * Refresh the rule cascade in all associated rule processors.
+ */
+ void RefreshRuleCascade();
+
+ /*
* Do any processing that needs to happen as a result of a change in
* the characteristics of the medium, and return whether style rules
* may have changed as a result.
*/
bool MediumFeaturesChanged();
// APIs for registering objects that can supply additional
// rules during processing.