Bug 1884072 - [devtools] Make getStyleSheetRuleCountAndAtRules faster. r=layout-reviewers,devtools-reviewers,emilio,ochameau.

We were returning the whole list of rules for a given stylesheet, and then
picking the at-rules we wanted in JS.
This patch make it so that the InspectorUtils method will only return the
at-rules we want directly, so we're building a smaller array of rule in the end.
Since `getStyleSheetRuleCountAndAtRules` also need to return the total number
of rules, this adds a simple `InspectorUtils.getStyleSheetRulesCount` method that
does that.

Differential Revision: https://phabricator.services.mozilla.com/D203878
This commit is contained in:
Nicolas Chevobbe 2024-03-14 10:57:05 +00:00
parent 2f25336530
commit d9bc1a76d3
4 changed files with 66 additions and 19 deletions

View file

@ -640,10 +640,14 @@ class StyleSheetsManager extends EventEmitter {
return win;
};
const styleSheetRules =
InspectorUtils.getAllStyleSheetCSSStyleRules(styleSheet);
const ruleCount = styleSheetRules.length;
// We need to go through nested rules to extract all the rules we're interested in
// This returns the following type of at-rules:
// - CSSMediaRule
// - CSSContainerRule
// - CSSSupportsRule
// - CSSLayerBlockRule
// New types can be added from InpsectorUtils.cpp `CollectAtRules`
const { atRules: styleSheetRules, ruleCount } =
InspectorUtils.getStyleSheetRuleCountAndAtRules(styleSheet);
const atRules = [];
for (const rule of styleSheetRules) {
const className = ChromeUtils.getClassName(rule);
@ -703,7 +707,10 @@ class StyleSheetsManager extends EventEmitter {
});
}
}
return { ruleCount, atRules };
return {
ruleCount,
atRules,
};
}
/**

View file

@ -23,10 +23,10 @@ namespace InspectorUtils {
unsigned long getRelativeRuleLine(CSSRule rule);
sequence<unsigned long> getRuleIndex(CSSRule rule);
boolean hasRulesModifiedByCSSOM(CSSStyleSheet sheet);
// Get a flat list of all rules (including nested ones) of a given stylesheet.
// Useful for DevTools as this is faster than in JS where we'd have a lot of
// proxy access overhead building the same list.
sequence<CSSRule> getAllStyleSheetCSSStyleRules(CSSStyleSheet sheet);
// Get a flat list of specific at-rules (including nested ones) of a given stylesheet.
// Useful for DevTools (StyleEditor at-rules sidebar) as this is faster than in JS
// where we'd have a lot of proxy access overhead building the same list.
InspectorStyleSheetRuleCountAndAtRulesResult getStyleSheetRuleCountAndAtRules(CSSStyleSheet sheet);
boolean isInheritedProperty(Document document, UTF8String property);
sequence<DOMString> getCSSPropertyNames(optional PropertyNamesOptions options = {});
sequence<PropertyPref> getCSSPropertyPrefs();
@ -182,6 +182,11 @@ dictionary InspectorGetRuleBodyTextResult {
required double endOffset;
};
dictionary InspectorStyleSheetRuleCountAndAtRulesResult {
required sequence<CSSRule> atRules;
required unsigned long ruleCount;
};
[Func="nsContentUtils::IsCallerChromeOrFuzzingEnabled",
Exposed=Window]
interface InspectorFontFace {

View file

@ -399,21 +399,56 @@ bool InspectorUtils::HasRulesModifiedByCSSOM(GlobalObject& aGlobal,
return aSheet.HasModifiedRulesForDevtools();
}
static void CollectRules(ServoCSSRuleList& aRuleList,
nsTArray<RefPtr<css::Rule>>& aResult) {
for (uint32_t i = 0, len = aRuleList.Length(); i < len; ++i) {
static uint32_t CollectAtRules(ServoCSSRuleList& aRuleList,
Sequence<OwningNonNull<css::Rule>>& aResult) {
uint32_t len = aRuleList.Length();
uint32_t ruleCount = len;
for (uint32_t i = 0; i < len; ++i) {
css::Rule* rule = aRuleList.GetRule(i);
aResult.AppendElement(rule);
// This collect rules we want to display in Devtools Style Editor toolbar.
// When adding a new StyleCssRuleType, put it in the "default" list, and
// file a new bug with
// https://bugzilla.mozilla.org/enter_bug.cgi?product=DevTools&component=Style%20Editor&short_desc=Consider%20displaying%20new%20XXX%20rule%20type%20in%20at-rules%20sidebar
// so the DevTools team gets notified and can decide if it should be
// displayed.
switch (rule->Type()) {
case StyleCssRuleType::Media:
case StyleCssRuleType::Supports:
case StyleCssRuleType::LayerBlock:
case StyleCssRuleType::Container: {
Unused << aResult.AppendElement(OwningNonNull(*rule), fallible);
break;
}
case StyleCssRuleType::Style:
case StyleCssRuleType::Import:
case StyleCssRuleType::Document:
case StyleCssRuleType::LayerStatement:
case StyleCssRuleType::FontFace:
case StyleCssRuleType::Page:
case StyleCssRuleType::Property:
case StyleCssRuleType::Keyframes:
case StyleCssRuleType::Keyframe:
case StyleCssRuleType::Margin:
case StyleCssRuleType::Namespace:
case StyleCssRuleType::CounterStyle:
case StyleCssRuleType::FontFeatureValues:
case StyleCssRuleType::FontPaletteValues:
break;
}
if (rule->IsGroupRule()) {
CollectRules(*static_cast<css::GroupRule*>(rule)->CssRules(), aResult);
ruleCount += CollectAtRules(
*static_cast<css::GroupRule*>(rule)->CssRules(), aResult);
}
}
return ruleCount;
}
void InspectorUtils::GetAllStyleSheetCSSStyleRules(
void InspectorUtils::GetStyleSheetRuleCountAndAtRules(
GlobalObject& aGlobal, StyleSheet& aSheet,
nsTArray<RefPtr<css::Rule>>& aResult) {
CollectRules(*aSheet.GetCssRulesInternal(), aResult);
InspectorStyleSheetRuleCountAndAtRulesResult& aResult) {
aResult.mRuleCount =
CollectAtRules(*aSheet.GetCssRulesInternal(), aResult.mAtRules);
}
/* static */

View file

@ -78,9 +78,9 @@ class InspectorUtils {
static bool HasRulesModifiedByCSSOM(GlobalObject& aGlobal,
StyleSheet& aSheet);
static void GetAllStyleSheetCSSStyleRules(
static void GetStyleSheetRuleCountAndAtRules(
GlobalObject& aGlobal, StyleSheet& aSheet,
nsTArray<RefPtr<css::Rule>>& aResult);
InspectorStyleSheetRuleCountAndAtRulesResult& aResult);
// Utilities for working with CSS properties
//