Bug 1247751 - [devtools] Add InspectorUtils.getRuleIndex. r=emilio,devtools-reviewers,ochameau.

Differential Revision: https://phabricator.services.mozilla.com/D201383
This commit is contained in:
Nicolas Chevobbe 2024-02-15 14:04:32 +00:00
Родитель fcb8172819
Коммит e5fbaa5d69
6 изменённых файлов: 141 добавлений и 29 удалений

Просмотреть файл

@ -611,35 +611,8 @@ class StyleRuleActor extends Actor {
* nested rules.
*/
_computeRuleIndex() {
let rule = this.rawRule;
const result = [];
while (rule) {
let cssRules = [];
if (rule.parentRule) {
cssRules = rule.parentRule.cssRules;
} else if (rule.parentStyleSheet) {
cssRules = rule.parentStyleSheet.cssRules;
}
let found = false;
for (let i = 0; i < cssRules.length; i++) {
if (rule === cssRules.item(i)) {
found = true;
result.unshift(i);
break;
}
}
if (!found) {
this._ruleIndex = null;
return;
}
rule = rule.parentRule;
}
this._ruleIndex = result;
const index = InspectorUtils.getRuleIndex(this.rawRule);
this._ruleIndex = index.length ? index : null;
}
/**

Просмотреть файл

@ -21,6 +21,7 @@ namespace InspectorUtils {
unsigned long getRuleLine(CSSRule rule);
unsigned long getRuleColumn(CSSRule rule);
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

Просмотреть файл

@ -32,6 +32,7 @@
#include "mozilla/dom/CSSBinding.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/CSSStyleRule.h"
#include "mozilla/dom/CSSKeyframesRule.h"
#include "mozilla/dom/Highlight.h"
#include "mozilla/dom/HighlightRegistry.h"
#include "mozilla/dom/InspectorUtilsBinding.h"
@ -350,6 +351,50 @@ uint32_t InspectorUtils::GetRelativeRuleLine(GlobalObject& aGlobal,
return aRule.GetLineNumber() + 1;
}
void InspectorUtils::GetRuleIndex(GlobalObject& aGlobal,
css::Rule& aRule,
nsTArray<uint32_t>& aResult) {
css::Rule* currentRule = &aRule;
do {
css::Rule* parentRule = currentRule->GetParentRule();
dom::CSSRuleList* ruleList = nullptr;
if (parentRule) {
if (parentRule->IsGroupRule()) {
ruleList = static_cast<css::GroupRule*>(parentRule)->CssRules();
} else if (parentRule->Type() == StyleCssRuleType::Keyframes) {
ruleList = static_cast<CSSKeyframesRule*>(parentRule)->CssRules();
} else {
MOZ_ASSERT_UNREACHABLE("Unknown parent rule type?");
}
} else if (StyleSheet* sheet = currentRule->GetStyleSheet()) {
ruleList = sheet->GetCssRulesInternal();
}
if (!ruleList) {
return;
}
bool found = false;
for (uint32_t i = 0, len = ruleList->Length(); i < len; ++i) {
css::Rule* rule = ruleList->Item(i);
if (currentRule == rule) {
found = true;
aResult.InsertElementAt(0, i);
break;
}
}
if (!found) {
return;
}
currentRule = parentRule;
} while (currentRule);
}
/* static */
bool InspectorUtils::HasRulesModifiedByCSSOM(GlobalObject& aGlobal,
StyleSheet& aSheet) {

Просмотреть файл

@ -72,6 +72,9 @@ class InspectorUtils {
*/
static uint32_t GetRelativeRuleLine(GlobalObject& aGlobal, css::Rule& aRule);
static void GetRuleIndex(GlobalObject& aGlobal, css::Rule& aRule,
nsTArray<uint32_t>& aResult);
static bool HasRulesModifiedByCSSOM(GlobalObject& aGlobal,
StyleSheet& aSheet);

Просмотреть файл

@ -58,6 +58,8 @@ support-files = [
["test_getRelativeRuleLine.html"]
["test_getRuleIndex.html"]
["test_get_all_style_sheets.html"]
["test_is_element_themed.html"]

Просмотреть файл

@ -0,0 +1,88 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test InspectorUtils.getRuleIndex</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
@property --color {
syntax: "*";
inherits: false;
}
html {
background: gold;
&:hover {
background: yellow;
}
& body {
color: tomato;
&:focus-visible {
outline: 1px solid cyan;
}
}
}
@keyframes anim {
0% {
color: blue;
}
100% {
color: green;
}
}
</style>
</head>
<body>
<code>InspectorUtils.getRuleIndex</code>
<script>
"use strict";
/** Test for InspectorUtils.getCSSRegisteredProperties **/
const { Assert } = SpecialPowers.ChromeUtils.importESModule(
"resource://testing-common/Assert.sys.mjs"
);
const InspectorUtils = SpecialPowers.InspectorUtils;
const stylesheet = document.styleSheets[1];
const stylesheetRules = stylesheet.cssRules;
let rule = stylesheetRules[0];
is(rule.name, "--color", "Expected @property rule");
Assert.deepEqual(InspectorUtils.getRuleIndex(rule), [0]);
rule = stylesheetRules[1];
is(rule.selectorText, "html", "Expected htlm rule");
Assert.deepEqual(InspectorUtils.getRuleIndex(rule), [1]);
rule = stylesheetRules[1].cssRules[0];
is(rule.selectorText, "&:hover", "Expected nested &:hover rule");
Assert.deepEqual(InspectorUtils.getRuleIndex(rule), [1, 0]);
rule = stylesheetRules[1].cssRules[1];
is(rule.selectorText, "& body", "Expected nested & body rule");
Assert.deepEqual(InspectorUtils.getRuleIndex(rule), [1, 1]);
rule = stylesheetRules[1].cssRules[1].cssRules[0];
is(rule.selectorText, "&:focus-visible", "Expected nested &:focus-visible rule");
Assert.deepEqual(InspectorUtils.getRuleIndex(rule), [1, 1, 0]);
rule = stylesheetRules[2];
is(rule.name, "anim", "Expected @keyframes rule");
Assert.deepEqual(InspectorUtils.getRuleIndex(rule), [2]);
rule = stylesheetRules[2].cssRules[0];
is(rule.keyText, "0%", "Expected 0% keyframe rule");
Assert.deepEqual(InspectorUtils.getRuleIndex(rule), [2, 0]);
rule = stylesheetRules[2].cssRules[1];
is(rule.keyText, "100%", "Expected 100% keyframe rule");
Assert.deepEqual(InspectorUtils.getRuleIndex(rule), [2, 1]);
</script>
</pre>
</body>
</html>