Skip to content

Commit d6e60e0

Browse files
committed
Web Inspector: Support Cascade Layers in the Styles sidebar
https://bugs.webkit.org/show_bug.cgi?id=233208 Reviewed by Devin Rousso. Source/JavaScriptCore: Add new values to `CSS.Grouping`'s `type` enum for cascade layers and make the `text` optional since an anonymous layer will not have a name or other text. * inspector/protocol/CSS.json: Source/WebCore: Test: inspector/css/getMatchedStylesForNodeLayerGrouping.html Add support for parsing and grouping CSS `@layer` rules in `InspectorStyleSheet` to the existing paths for handling other groupings so that the frontend is made aware of rules wrapped inside a layer or multiple layers. * Headers.cmake: * WebCore.xcodeproj/project.pbxproj: - CompiledSelector.h needs to be exported as a private header to include in WebKitLegacy's build, since it is imported by StyleRule.h, which is now imported by CSSImportRule.h, which is imported in WebKitLegacy. * css/CSSImportRule.cpp: (WebCore::CSSImportRule::cascadeLayerName const): * css/CSSImportRule.h: * css/CSSLayerRule.cpp: (WebCore::CSSLayerRule::cssText const): (WebCore::CSSLayerRule::layerName const): (WebCore::CSSLayerRule::stringFromCascadeLayerName): * css/CSSLayerRule.h: * inspector/InspectorStyleSheet.cpp: (flattenSourceData): (WebCore::asCSSRuleList): (WebCore::buildArrayForGroupings): * style/InspectorCSSOMWrappers.cpp: (WebCore::Style::InspectorCSSOMWrappers::collect): Source/WebInspectorUI: * UserInterface/Models/CSSGrouping.js: (WI.CSSGrouping): (WI.CSSGrouping.prototype.get isLayer): (WI.CSSGrouping.prototype.get prefix): - Update `CSSGrouping` to support `@layer` rules, and make `text` optional for a grouping, since anonymous layers will not have a name. * UserInterface/Models/CSSStyleDeclaration.js: (WI.CSSStyleDeclaration.prototype.generateFormattedText): - Ensure that spacing remains correct and "null" isn't shown for groupings without text. * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js: (WI.SpreadsheetCSSStyleDeclarationSection.prototype.initialLayout): - When merging layer groups, ensure that a "." is used as a separator, and that each group has a name (to prevent having a hanging period or the "null" text appearing). LayoutTests: Add new test cases for `CSS.getMatchesStyleForNode` to make sure that layer groupings are correctly determined, and that rules nested in `@layer` rules and `@import layer()`s are correctly represented and sorted by the order they are applied to an element. * inspector/css/getMatchedStylesForNode-expected.txt: - Re-baseline to account for change in order of CSSGrouping properties in the protocol due to `text` now being optional. * inspector/css/getMatchedStylesForNodeLayerGrouping-expected.txt: Added. * inspector/css/getMatchedStylesForNodeLayerGrouping.html: Added. * inspector/css/resources/external-layers.css: Added. Canonical link: https://commits.webkit.org/244888@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286558 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent cde06de commit d6e60e0

20 files changed

Lines changed: 534 additions & 44 deletions

LayoutTests/ChangeLog

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
2021-12-06 Patrick Angle <pangle@apple.com>
2+
3+
Web Inspector: Support Cascade Layers in the Styles sidebar
4+
https://bugs.webkit.org/show_bug.cgi?id=233208
5+
6+
Reviewed by Devin Rousso.
7+
8+
Add new test cases for `CSS.getMatchesStyleForNode` to make sure that layer groupings are correctly determined,
9+
and that rules nested in `@layer` rules and `@import layer()`s are correctly represented and sorted by the order
10+
they are applied to an element.
11+
12+
* inspector/css/getMatchedStylesForNode-expected.txt:
13+
- Re-baseline to account for change in order of CSSGrouping properties in the protocol due to `text` now being
14+
optional.
15+
* inspector/css/getMatchedStylesForNodeLayerGrouping-expected.txt: Added.
16+
* inspector/css/getMatchedStylesForNodeLayerGrouping.html: Added.
17+
* inspector/css/resources/external-layers.css: Added.
18+
119
2021-12-06 Antoine Quint <graouts@webkit.org>
220

321
[Web Animations] Add a way to run scripted animations

LayoutTests/inspector/css/getMatchedStylesForNode-expected.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -904,8 +904,8 @@ Inherited:
904904
"ruleId": "<filtered>",
905905
"groupings": [
906906
{
907-
"text": "(min-width: 0px)",
908907
"type": "media-import-rule",
908+
"text": "(min-width: 0px)",
909909
"sourceURL": "<filtered>"
910910
}
911911
]
@@ -997,8 +997,8 @@ Inherited:
997997
"ruleId": "<filtered>",
998998
"groupings": [
999999
{
1000-
"text": "(min-width: 1px)",
10011000
"type": "media-rule",
1001+
"text": "(min-width: 1px)",
10021002
"sourceURL": "<filtered>"
10031003
}
10041004
]
@@ -1047,13 +1047,13 @@ Inherited:
10471047
"ruleId": "<filtered>",
10481048
"groupings": [
10491049
{
1050-
"text": "(display: block)",
10511050
"type": "supports-rule",
1051+
"text": "(display: block)",
10521052
"sourceURL": "<filtered>"
10531053
},
10541054
{
1055-
"text": "(min-width: 2px)",
10561055
"type": "media-rule",
1056+
"text": "(min-width: 2px)",
10571057
"sourceURL": "<filtered>"
10581058
}
10591059
]
@@ -1102,8 +1102,8 @@ Inherited:
11021102
"ruleId": "<filtered>",
11031103
"groupings": [
11041104
{
1105-
"text": "(min-width: 3px)",
11061105
"type": "media-style-node",
1106+
"text": "(min-width: 3px)",
11071107
"sourceURL": "<filtered>"
11081108
}
11091109
]
@@ -1152,8 +1152,8 @@ Inherited:
11521152
"ruleId": "<filtered>",
11531153
"groupings": [
11541154
{
1155-
"text": "(min-width: 4px)",
11561155
"type": "media-link-node",
1156+
"text": "(min-width: 4px)",
11571157
"sourceURL": "<filtered>"
11581158
}
11591159
]
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
Tests for the CSS.getMatchedStyleForNode command and style rule groupings.
2+
3+
4+
== Running test suite: CSS.getMatchedStyleForNode.LayerGrouping
5+
-- Running test case: CSS.getMatchedStyleForNode.LayerGrouping.Normal
6+
PASS: Should have 3 authored rules.
7+
- Testing rule #0
8+
PASS: Selector text should be ".item".
9+
PASS: "color" property value should be "red".
10+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
11+
PASS: Rule should have no groupings.
12+
- Testing rule #1
13+
PASS: Selector text should be ".item".
14+
PASS: "color" property value should be "lawngreen".
15+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
16+
PASS: Rule should have 2 grouping(s).
17+
PASS: Grouping 0 should have a type of "layer-rule".
18+
PASS: Grouping 0 should have a text of "special".
19+
PASS: Grouping 1 should have a type of "supports-rule".
20+
PASS: Grouping 1 should have a text of "(color: red)".
21+
- Testing rule #2
22+
PASS: Selector text should be ".item".
23+
PASS: "color" property value should be "peachpuff".
24+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
25+
PASS: Rule should have 1 grouping(s).
26+
PASS: Grouping 0 should have a type of "layer-rule".
27+
PASS: Grouping 0 should have a text of "base".
28+
29+
-- Running test case: CSS.getMatchedStyleForNode.LayerGrouping.Imported
30+
PASS: Should have 5 authored rules.
31+
- Testing rule #0
32+
PASS: Selector text should be ".item".
33+
PASS: "color" property value should be "red".
34+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
35+
PASS: Rule should have no groupings.
36+
- Testing rule #1
37+
PASS: Selector text should be ".item".
38+
PASS: "color" property value should be "lawngreen".
39+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
40+
PASS: Rule should have 2 grouping(s).
41+
PASS: Grouping 0 should have a type of "layer-rule".
42+
PASS: Grouping 0 should have a text of "special".
43+
PASS: Grouping 1 should have a type of "supports-rule".
44+
PASS: Grouping 1 should have a text of "(color: red)".
45+
- Testing rule #2
46+
PASS: Selector text should be ".item".
47+
PASS: "color" property value should be "peachpuff".
48+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
49+
PASS: Rule should have 1 grouping(s).
50+
PASS: Grouping 0 should have a type of "layer-rule".
51+
PASS: Grouping 0 should have a text of "base".
52+
- Testing rule #3
53+
PASS: Selector text should be ".imported".
54+
PASS: "color" property value should be "darkslategray".
55+
PASS: Source code for rule should be in file named "external-layers.css".
56+
PASS: Rule should have 3 grouping(s).
57+
PASS: Grouping 0 should have a type of "layer-rule".
58+
PASS: Grouping 0 should have a text of "special".
59+
PASS: Grouping 1 should have a type of "supports-rule".
60+
PASS: Grouping 1 should have a text of "(color: red)".
61+
PASS: Grouping 2 should have a type of "layer-import-rule".
62+
PASS: Grouping 2 should have a text of "imported".
63+
- Testing rule #4
64+
PASS: Selector text should be ".imported".
65+
PASS: "color" property value should be "mintcream".
66+
PASS: Source code for rule should be in file named "external-layers.css".
67+
PASS: Rule should have 2 grouping(s).
68+
PASS: Grouping 0 should have a type of "layer-rule".
69+
PASS: Grouping 0 should have a text of "base".
70+
PASS: Grouping 1 should have a type of "layer-import-rule".
71+
PASS: Grouping 1 should have a text of "imported".
72+
73+
-- Running test case: CSS.getMatchedStyleForNode.LayerGrouping.Anonymous
74+
PASS: Should have 4 authored rules.
75+
- Testing rule #0
76+
PASS: Selector text should be ".item".
77+
PASS: "color" property value should be "red".
78+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
79+
PASS: Rule should have no groupings.
80+
- Testing rule #1
81+
PASS: Selector text should be ".anonymous".
82+
PASS: "color" property value should be "darkviolet".
83+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
84+
PASS: Rule should have 1 grouping(s).
85+
PASS: Grouping 0 should have a type of "layer-rule".
86+
PASS: Grouping 0 should not have any text.
87+
- Testing rule #2
88+
PASS: Selector text should be ".item".
89+
PASS: "color" property value should be "lawngreen".
90+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
91+
PASS: Rule should have 2 grouping(s).
92+
PASS: Grouping 0 should have a type of "layer-rule".
93+
PASS: Grouping 0 should have a text of "special".
94+
PASS: Grouping 1 should have a type of "supports-rule".
95+
PASS: Grouping 1 should have a text of "(color: red)".
96+
- Testing rule #3
97+
PASS: Selector text should be ".item".
98+
PASS: "color" property value should be "peachpuff".
99+
PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
100+
PASS: Rule should have 1 grouping(s).
101+
PASS: Grouping 0 should have a type of "layer-rule".
102+
PASS: Grouping 0 should have a text of "base".
103+
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
5+
<script>
6+
function test()
7+
{
8+
let suite = InspectorTest.createAsyncSuite("CSS.getMatchedStyleForNode.LayerGrouping");
9+
10+
function expectRuleAtIndex(rules, index, {selectorText, colorPropertyValue, file, lineNumber, groupings})
11+
{
12+
InspectorTest.log(`- Testing rule #${index}`);
13+
14+
let rule = rules[index];
15+
InspectorTest.expectEqual(rule.selectorText, selectorText, `Selector text should be "${selectorText}".`);
16+
InspectorTest.expectEqual(rule.style.propertyForName("color").value, colorPropertyValue, `"color" property value should be "${colorPropertyValue}".`);
17+
InspectorTest.expectEqual(rule.sourceCodeLocation?.sourceCode.urlComponents.lastPathComponent, file, `Source code for rule should be in file named "${file}".`);
18+
19+
if (!groupings) {
20+
InspectorTest.expectEmpty(rule.groupings, "Rule should have no groupings.");
21+
return;
22+
}
23+
24+
InspectorTest.expectEqual(rule.groupings.length, groupings.length, `Rule should have ${groupings.length} grouping(s).`);
25+
26+
for (let i = 0; i < groupings.length; ++i) {
27+
InspectorTest.expectEqual(rule.groupings[i].type, groupings[i].type, `Grouping ${i} should have a type of "${groupings[i].type}".`);
28+
29+
if (groupings[i].text)
30+
InspectorTest.expectEqual(rule.groupings[i].text, groupings[i].text, `Grouping ${i} should have a text of "${groupings[i].text}".`);
31+
else
32+
InspectorTest.expectNull(rule.groupings[i].text, `Grouping ${i} should not have any text.`);
33+
}
34+
}
35+
36+
function addTestCase({name, description, selector, expectedAuthoredRuleCount, authoredRulesHandler})
37+
{
38+
suite.addTestCase({
39+
name,
40+
description,
41+
async test() {
42+
let documentNode = await WI.domManager.requestDocument();
43+
let nodeId = await documentNode.querySelector(selector);
44+
let domNode = WI.domManager.nodeForId(nodeId);
45+
InspectorTest.assert(domNode, `Should find DOM Node for selector '${selector}'.`);
46+
47+
let domNodeStyles = WI.cssManager.stylesForNode(domNode);
48+
InspectorTest.assert(domNodeStyles, `Should find CSS Styles for DOM Node.`);
49+
await domNodeStyles.refreshIfNeeded();
50+
51+
let authoredRules = domNodeStyles.matchedRules.filter((rule) => rule.type === WI.CSSStyleSheet.Type.Author);
52+
InspectorTest.expectEqual(authoredRules.length, expectedAuthoredRuleCount, `Should have ${expectedAuthoredRuleCount} authored rules.`);
53+
authoredRulesHandler(authoredRules);
54+
},
55+
});
56+
}
57+
58+
addTestCase({
59+
name: "CSS.getMatchedStyleForNode.LayerGrouping.Normal",
60+
description: "Layers should be presented in the expected order, with layers applied in the order they are declared.",
61+
selector: "#normal",
62+
expectedAuthoredRuleCount: 3,
63+
authoredRulesHandler(rules) {
64+
expectRuleAtIndex(rules, 0, {
65+
selectorText: ".item",
66+
colorPropertyValue: "red",
67+
file: "getMatchedStylesForNodeLayerGrouping.html",
68+
});
69+
expectRuleAtIndex(rules, 1, {
70+
selectorText: ".item",
71+
colorPropertyValue: "lawngreen",
72+
file: "getMatchedStylesForNodeLayerGrouping.html",
73+
groupings: [
74+
{type: WI.CSSGrouping.Type.LayerRule, text: "special"},
75+
{type: WI.CSSGrouping.Type.SupportsRule, text: "(color: red)"},
76+
],
77+
});
78+
expectRuleAtIndex(rules, 2, {
79+
selectorText: ".item",
80+
colorPropertyValue: "peachpuff",
81+
file: "getMatchedStylesForNodeLayerGrouping.html",
82+
groupings: [
83+
{type: WI.CSSGrouping.Type.LayerRule, text: "base"},
84+
],
85+
});
86+
}
87+
});
88+
89+
addTestCase({
90+
name: "CSS.getMatchedStyleForNode.LayerGrouping.Imported",
91+
description: "Stylesheets imported with @import with a layer parameter should have nested layer groupings.",
92+
selector: "#imported",
93+
expectedAuthoredRuleCount: 5,
94+
authoredRulesHandler(rules) {
95+
expectRuleAtIndex(rules, 0, {
96+
selectorText: ".item",
97+
colorPropertyValue: "red",
98+
file: "getMatchedStylesForNodeLayerGrouping.html",
99+
});
100+
expectRuleAtIndex(rules, 1, {
101+
selectorText: ".item",
102+
colorPropertyValue: "lawngreen",
103+
file: "getMatchedStylesForNodeLayerGrouping.html",
104+
groupings: [
105+
{type: WI.CSSGrouping.Type.LayerRule, text: "special"},
106+
{type: WI.CSSGrouping.Type.SupportsRule, text: "(color: red)"},
107+
],
108+
});
109+
expectRuleAtIndex(rules, 2, {
110+
selectorText: ".item",
111+
colorPropertyValue: "peachpuff",
112+
file: "getMatchedStylesForNodeLayerGrouping.html",
113+
groupings: [
114+
{type: WI.CSSGrouping.Type.LayerRule, text: "base"},
115+
],
116+
});
117+
expectRuleAtIndex(rules, 3, {
118+
selectorText: ".imported",
119+
colorPropertyValue: "darkslategray",
120+
file: "external-layers.css",
121+
groupings: [
122+
{type: WI.CSSGrouping.Type.LayerRule, text: "special"},
123+
{type: WI.CSSGrouping.Type.SupportsRule, text: "(color: red)"},
124+
{type: WI.CSSGrouping.Type.LayerImportRule, text: "imported"},
125+
],
126+
});
127+
expectRuleAtIndex(rules, 4, {
128+
selectorText: ".imported",
129+
colorPropertyValue: "mintcream",
130+
file: "external-layers.css",
131+
groupings: [
132+
{type: WI.CSSGrouping.Type.LayerRule, text: "base"},
133+
{type: WI.CSSGrouping.Type.LayerImportRule, text: "imported"},
134+
],
135+
});
136+
}
137+
});
138+
139+
addTestCase({
140+
name: "CSS.getMatchedStyleForNode.LayerGrouping.Anonymous",
141+
description: "Anonymous layers (layers without a name) should be separate and be applied in the order they are declared relative to other anonymous and named layers.",
142+
selector: "#anonymous",
143+
expectedAuthoredRuleCount: 4,
144+
authoredRulesHandler(rules) {
145+
expectRuleAtIndex(rules, 0, {
146+
selectorText: ".item",
147+
colorPropertyValue: "red",
148+
file: "getMatchedStylesForNodeLayerGrouping.html",
149+
});
150+
expectRuleAtIndex(rules, 1, {
151+
selectorText: ".anonymous",
152+
colorPropertyValue: "darkviolet",
153+
file: "getMatchedStylesForNodeLayerGrouping.html",
154+
groupings: [
155+
{type: WI.CSSGrouping.Type.LayerRule},
156+
],
157+
});
158+
expectRuleAtIndex(rules, 2, {
159+
selectorText: ".item",
160+
colorPropertyValue: "lawngreen",
161+
file: "getMatchedStylesForNodeLayerGrouping.html",
162+
groupings: [
163+
{type: WI.CSSGrouping.Type.LayerRule, text: "special"},
164+
{type: WI.CSSGrouping.Type.SupportsRule, text: "(color: red)"},
165+
],
166+
});
167+
expectRuleAtIndex(rules, 3, {
168+
selectorText: ".item",
169+
colorPropertyValue: "peachpuff",
170+
file: "getMatchedStylesForNodeLayerGrouping.html",
171+
groupings: [
172+
{type: WI.CSSGrouping.Type.LayerRule, text: "base"},
173+
],
174+
});
175+
}
176+
});
177+
178+
suite.runTestCasesAndFinish();
179+
}
180+
</script>
181+
<style>
182+
@layer imported, base, special;
183+
184+
@import url("./resources/external-layers.css") layer(imported);
185+
186+
@supports(color: red) {
187+
@layer special {
188+
.item {
189+
color: lawngreen;
190+
}
191+
}
192+
}
193+
194+
@layer base {
195+
.item {
196+
color: peachpuff;
197+
}
198+
}
199+
200+
@layer {
201+
.anonymous {
202+
color: darkviolet;
203+
}
204+
}
205+
206+
.item {
207+
color: red;
208+
}
209+
</style>
210+
</head>
211+
<body onload="runTest()">
212+
<p>Tests for the CSS.getMatchedStyleForNode command and style rule groupings.</p>
213+
<div id="normal" class="item"></div>
214+
<div id="imported" class="item imported"></div>
215+
<div id="anonymous" class="item anonymous"></div>
216+
</body>
217+
</html>

0 commit comments

Comments
 (0)