Diff
Modified: trunk/LayoutTests/ChangeLog (286557 => 286558)
--- trunk/LayoutTests/ChangeLog 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/LayoutTests/ChangeLog 2021-12-06 19:45:45 UTC (rev 286558)
@@ -1,3 +1,21 @@
+2021-12-06 Patrick Angle <[email protected]>
+
+ Web Inspector: Support Cascade Layers in the Styles sidebar
+ https://bugs.webkit.org/show_bug.cgi?id=233208
+
+ Reviewed by Devin Rousso.
+
+ 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.
+
2021-12-06 Antoine Quint <[email protected]>
[Web Animations] Add a way to run scripted animations
Modified: trunk/LayoutTests/inspector/css/getMatchedStylesForNode-expected.txt (286557 => 286558)
--- trunk/LayoutTests/inspector/css/getMatchedStylesForNode-expected.txt 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/LayoutTests/inspector/css/getMatchedStylesForNode-expected.txt 2021-12-06 19:45:45 UTC (rev 286558)
@@ -904,8 +904,8 @@
"ruleId": "<filtered>",
"groupings": [
{
+ "type": "media-import-rule",
"text": "(min-width: 0px)",
- "type": "media-import-rule",
"sourceURL": "<filtered>"
}
]
@@ -997,8 +997,8 @@
"ruleId": "<filtered>",
"groupings": [
{
+ "type": "media-rule",
"text": "(min-width: 1px)",
- "type": "media-rule",
"sourceURL": "<filtered>"
}
]
@@ -1047,13 +1047,13 @@
"ruleId": "<filtered>",
"groupings": [
{
+ "type": "supports-rule",
"text": "(display: block)",
- "type": "supports-rule",
"sourceURL": "<filtered>"
},
{
+ "type": "media-rule",
"text": "(min-width: 2px)",
- "type": "media-rule",
"sourceURL": "<filtered>"
}
]
@@ -1102,8 +1102,8 @@
"ruleId": "<filtered>",
"groupings": [
{
+ "type": "media-style-node",
"text": "(min-width: 3px)",
- "type": "media-style-node",
"sourceURL": "<filtered>"
}
]
@@ -1152,8 +1152,8 @@
"ruleId": "<filtered>",
"groupings": [
{
+ "type": "media-link-node",
"text": "(min-width: 4px)",
- "type": "media-link-node",
"sourceURL": "<filtered>"
}
]
Added: trunk/LayoutTests/inspector/css/getMatchedStylesForNodeLayerGrouping-expected.txt (0 => 286558)
--- trunk/LayoutTests/inspector/css/getMatchedStylesForNodeLayerGrouping-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/css/getMatchedStylesForNodeLayerGrouping-expected.txt 2021-12-06 19:45:45 UTC (rev 286558)
@@ -0,0 +1,103 @@
+Tests for the CSS.getMatchedStyleForNode command and style rule groupings.
+
+
+== Running test suite: CSS.getMatchedStyleForNode.LayerGrouping
+-- Running test case: CSS.getMatchedStyleForNode.LayerGrouping.Normal
+PASS: Should have 3 authored rules.
+- Testing rule #0
+PASS: Selector text should be ".item".
+PASS: "color" property value should be "red".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have no groupings.
+- Testing rule #1
+PASS: Selector text should be ".item".
+PASS: "color" property value should be "lawngreen".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have 2 grouping(s).
+PASS: Grouping 0 should have a type of "layer-rule".
+PASS: Grouping 0 should have a text of "special".
+PASS: Grouping 1 should have a type of "supports-rule".
+PASS: Grouping 1 should have a text of "(color: red)".
+- Testing rule #2
+PASS: Selector text should be ".item".
+PASS: "color" property value should be "peachpuff".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have 1 grouping(s).
+PASS: Grouping 0 should have a type of "layer-rule".
+PASS: Grouping 0 should have a text of "base".
+
+-- Running test case: CSS.getMatchedStyleForNode.LayerGrouping.Imported
+PASS: Should have 5 authored rules.
+- Testing rule #0
+PASS: Selector text should be ".item".
+PASS: "color" property value should be "red".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have no groupings.
+- Testing rule #1
+PASS: Selector text should be ".item".
+PASS: "color" property value should be "lawngreen".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have 2 grouping(s).
+PASS: Grouping 0 should have a type of "layer-rule".
+PASS: Grouping 0 should have a text of "special".
+PASS: Grouping 1 should have a type of "supports-rule".
+PASS: Grouping 1 should have a text of "(color: red)".
+- Testing rule #2
+PASS: Selector text should be ".item".
+PASS: "color" property value should be "peachpuff".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have 1 grouping(s).
+PASS: Grouping 0 should have a type of "layer-rule".
+PASS: Grouping 0 should have a text of "base".
+- Testing rule #3
+PASS: Selector text should be ".imported".
+PASS: "color" property value should be "darkslategray".
+PASS: Source code for rule should be in file named "external-layers.css".
+PASS: Rule should have 3 grouping(s).
+PASS: Grouping 0 should have a type of "layer-rule".
+PASS: Grouping 0 should have a text of "special".
+PASS: Grouping 1 should have a type of "supports-rule".
+PASS: Grouping 1 should have a text of "(color: red)".
+PASS: Grouping 2 should have a type of "layer-import-rule".
+PASS: Grouping 2 should have a text of "imported".
+- Testing rule #4
+PASS: Selector text should be ".imported".
+PASS: "color" property value should be "mintcream".
+PASS: Source code for rule should be in file named "external-layers.css".
+PASS: Rule should have 2 grouping(s).
+PASS: Grouping 0 should have a type of "layer-rule".
+PASS: Grouping 0 should have a text of "base".
+PASS: Grouping 1 should have a type of "layer-import-rule".
+PASS: Grouping 1 should have a text of "imported".
+
+-- Running test case: CSS.getMatchedStyleForNode.LayerGrouping.Anonymous
+PASS: Should have 4 authored rules.
+- Testing rule #0
+PASS: Selector text should be ".item".
+PASS: "color" property value should be "red".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have no groupings.
+- Testing rule #1
+PASS: Selector text should be ".anonymous".
+PASS: "color" property value should be "darkviolet".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have 1 grouping(s).
+PASS: Grouping 0 should have a type of "layer-rule".
+PASS: Grouping 0 should not have any text.
+- Testing rule #2
+PASS: Selector text should be ".item".
+PASS: "color" property value should be "lawngreen".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have 2 grouping(s).
+PASS: Grouping 0 should have a type of "layer-rule".
+PASS: Grouping 0 should have a text of "special".
+PASS: Grouping 1 should have a type of "supports-rule".
+PASS: Grouping 1 should have a text of "(color: red)".
+- Testing rule #3
+PASS: Selector text should be ".item".
+PASS: "color" property value should be "peachpuff".
+PASS: Source code for rule should be in file named "getMatchedStylesForNodeLayerGrouping.html".
+PASS: Rule should have 1 grouping(s).
+PASS: Grouping 0 should have a type of "layer-rule".
+PASS: Grouping 0 should have a text of "base".
+
Added: trunk/LayoutTests/inspector/css/getMatchedStylesForNodeLayerGrouping.html (0 => 286558)
--- trunk/LayoutTests/inspector/css/getMatchedStylesForNodeLayerGrouping.html (rev 0)
+++ trunk/LayoutTests/inspector/css/getMatchedStylesForNodeLayerGrouping.html 2021-12-06 19:45:45 UTC (rev 286558)
@@ -0,0 +1,217 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("CSS.getMatchedStyleForNode.LayerGrouping");
+
+ function expectRuleAtIndex(rules, index, {selectorText, colorPropertyValue, file, lineNumber, groupings})
+ {
+ InspectorTest.log(`- Testing rule #${index}`);
+
+ let rule = rules[index];
+ InspectorTest.expectEqual(rule.selectorText, selectorText, `Selector text should be "${selectorText}".`);
+ InspectorTest.expectEqual(rule.style.propertyForName("color").value, colorPropertyValue, `"color" property value should be "${colorPropertyValue}".`);
+ InspectorTest.expectEqual(rule.sourceCodeLocation?.sourceCode.urlComponents.lastPathComponent, file, `Source code for rule should be in file named "${file}".`);
+
+ if (!groupings) {
+ InspectorTest.expectEmpty(rule.groupings, "Rule should have no groupings.");
+ return;
+ }
+
+ InspectorTest.expectEqual(rule.groupings.length, groupings.length, `Rule should have ${groupings.length} grouping(s).`);
+
+ for (let i = 0; i < groupings.length; ++i) {
+ InspectorTest.expectEqual(rule.groupings[i].type, groupings[i].type, `Grouping ${i} should have a type of "${groupings[i].type}".`);
+
+ if (groupings[i].text)
+ InspectorTest.expectEqual(rule.groupings[i].text, groupings[i].text, `Grouping ${i} should have a text of "${groupings[i].text}".`);
+ else
+ InspectorTest.expectNull(rule.groupings[i].text, `Grouping ${i} should not have any text.`);
+ }
+ }
+
+ function addTestCase({name, description, selector, expectedAuthoredRuleCount, authoredRulesHandler})
+ {
+ suite.addTestCase({
+ name,
+ description,
+ async test() {
+ let documentNode = await WI.domManager.requestDocument();
+ let nodeId = await documentNode.querySelector(selector);
+ let domNode = WI.domManager.nodeForId(nodeId);
+ InspectorTest.assert(domNode, `Should find DOM Node for selector '${selector}'.`);
+
+ let domNodeStyles = WI.cssManager.stylesForNode(domNode);
+ InspectorTest.assert(domNodeStyles, `Should find CSS Styles for DOM Node.`);
+ await domNodeStyles.refreshIfNeeded();
+
+ let authoredRules = domNodeStyles.matchedRules.filter((rule) => rule.type === WI.CSSStyleSheet.Type.Author);
+ InspectorTest.expectEqual(authoredRules.length, expectedAuthoredRuleCount, `Should have ${expectedAuthoredRuleCount} authored rules.`);
+ authoredRulesHandler(authoredRules);
+ },
+ });
+ }
+
+ addTestCase({
+ name: "CSS.getMatchedStyleForNode.LayerGrouping.Normal",
+ description: "Layers should be presented in the expected order, with layers applied in the order they are declared.",
+ selector: "#normal",
+ expectedAuthoredRuleCount: 3,
+ authoredRulesHandler(rules) {
+ expectRuleAtIndex(rules, 0, {
+ selectorText: ".item",
+ colorPropertyValue: "red",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ });
+ expectRuleAtIndex(rules, 1, {
+ selectorText: ".item",
+ colorPropertyValue: "lawngreen",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ groupings: [
+ {type: WI.CSSGrouping.Type.LayerRule, text: "special"},
+ {type: WI.CSSGrouping.Type.SupportsRule, text: "(color: red)"},
+ ],
+ });
+ expectRuleAtIndex(rules, 2, {
+ selectorText: ".item",
+ colorPropertyValue: "peachpuff",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ groupings: [
+ {type: WI.CSSGrouping.Type.LayerRule, text: "base"},
+ ],
+ });
+ }
+ });
+
+ addTestCase({
+ name: "CSS.getMatchedStyleForNode.LayerGrouping.Imported",
+ description: "Stylesheets imported with @import with a layer parameter should have nested layer groupings.",
+ selector: "#imported",
+ expectedAuthoredRuleCount: 5,
+ authoredRulesHandler(rules) {
+ expectRuleAtIndex(rules, 0, {
+ selectorText: ".item",
+ colorPropertyValue: "red",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ });
+ expectRuleAtIndex(rules, 1, {
+ selectorText: ".item",
+ colorPropertyValue: "lawngreen",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ groupings: [
+ {type: WI.CSSGrouping.Type.LayerRule, text: "special"},
+ {type: WI.CSSGrouping.Type.SupportsRule, text: "(color: red)"},
+ ],
+ });
+ expectRuleAtIndex(rules, 2, {
+ selectorText: ".item",
+ colorPropertyValue: "peachpuff",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ groupings: [
+ {type: WI.CSSGrouping.Type.LayerRule, text: "base"},
+ ],
+ });
+ expectRuleAtIndex(rules, 3, {
+ selectorText: ".imported",
+ colorPropertyValue: "darkslategray",
+ file: "external-layers.css",
+ groupings: [
+ {type: WI.CSSGrouping.Type.LayerRule, text: "special"},
+ {type: WI.CSSGrouping.Type.SupportsRule, text: "(color: red)"},
+ {type: WI.CSSGrouping.Type.LayerImportRule, text: "imported"},
+ ],
+ });
+ expectRuleAtIndex(rules, 4, {
+ selectorText: ".imported",
+ colorPropertyValue: "mintcream",
+ file: "external-layers.css",
+ groupings: [
+ {type: WI.CSSGrouping.Type.LayerRule, text: "base"},
+ {type: WI.CSSGrouping.Type.LayerImportRule, text: "imported"},
+ ],
+ });
+ }
+ });
+
+ addTestCase({
+ name: "CSS.getMatchedStyleForNode.LayerGrouping.Anonymous",
+ 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.",
+ selector: "#anonymous",
+ expectedAuthoredRuleCount: 4,
+ authoredRulesHandler(rules) {
+ expectRuleAtIndex(rules, 0, {
+ selectorText: ".item",
+ colorPropertyValue: "red",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ });
+ expectRuleAtIndex(rules, 1, {
+ selectorText: ".anonymous",
+ colorPropertyValue: "darkviolet",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ groupings: [
+ {type: WI.CSSGrouping.Type.LayerRule},
+ ],
+ });
+ expectRuleAtIndex(rules, 2, {
+ selectorText: ".item",
+ colorPropertyValue: "lawngreen",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ groupings: [
+ {type: WI.CSSGrouping.Type.LayerRule, text: "special"},
+ {type: WI.CSSGrouping.Type.SupportsRule, text: "(color: red)"},
+ ],
+ });
+ expectRuleAtIndex(rules, 3, {
+ selectorText: ".item",
+ colorPropertyValue: "peachpuff",
+ file: "getMatchedStylesForNodeLayerGrouping.html",
+ groupings: [
+ {type: WI.CSSGrouping.Type.LayerRule, text: "base"},
+ ],
+ });
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+<style>
+ @layer imported, base, special;
+
+ @import url("./resources/external-layers.css") layer(imported);
+
+ @supports(color: red) {
+ @layer special {
+ .item {
+ color: lawngreen;
+ }
+ }
+ }
+
+ @layer base {
+ .item {
+ color: peachpuff;
+ }
+ }
+
+ @layer {
+ .anonymous {
+ color: darkviolet;
+ }
+ }
+
+ .item {
+ color: red;
+ }
+</style>
+</head>
+<body _onload_="runTest()">
+ <p>Tests for the CSS.getMatchedStyleForNode command and style rule groupings.</p>
+ <div id="normal" class="item"></div>
+ <div id="imported" class="item imported"></div>
+ <div id="anonymous" class="item anonymous"></div>
+</body>
+</html>
Added: trunk/LayoutTests/inspector/css/resources/external-layers.css (0 => 286558)
--- trunk/LayoutTests/inspector/css/resources/external-layers.css (rev 0)
+++ trunk/LayoutTests/inspector/css/resources/external-layers.css 2021-12-06 19:45:45 UTC (rev 286558)
@@ -0,0 +1,15 @@
+@layer base, special;
+
+@supports(color: red) {
+ @layer special {
+ .imported {
+ color: darkslategray;
+ }
+ }
+}
+
+@layer base {
+ .imported {
+ color: mintcream;
+ }
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (286557 => 286558)
--- trunk/Source/_javascript_Core/ChangeLog 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-12-06 19:45:45 UTC (rev 286558)
@@ -1,3 +1,15 @@
+2021-12-06 Patrick Angle <[email protected]>
+
+ Web Inspector: Support Cascade Layers in the Styles sidebar
+ https://bugs.webkit.org/show_bug.cgi?id=233208
+
+ Reviewed by Devin Rousso.
+
+ 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:
+
2021-12-03 Keith Miller <[email protected]>
Remove StructureIDBlob
Modified: trunk/Source/_javascript_Core/inspector/protocol/CSS.json (286557 => 286558)
--- trunk/Source/_javascript_Core/inspector/protocol/CSS.json 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/_javascript_Core/inspector/protocol/CSS.json 2021-12-06 19:45:45 UTC (rev 286558)
@@ -226,10 +226,10 @@
{
"id": "Grouping",
"type": "object",
- "description": "CSS @media (as well as other users of media queries, like @import, <style>, <link>, etc.) and @supports descriptor.",
+ "description": "CSS @media (as well as other users of media queries, like @import, <style>, <link>, etc.), @supports, and @layer descriptor.",
"properties": [
- { "name": "text", "type": "string", "description": "Media query text." },
- { "name": "type", "type": "string", "enum": ["media-rule", "media-import-rule", "media-link-node", "media-style-node", "supports-rule"], "description": "Source of the media query: \"media-rule\" if specified by a @media rule, \"media-import-rule\" if specified by an @import rule, \"media-link-node\" if specified by a \"media\" attribute in a linked style sheet's LINK tag, \"media-style-node\" if specified by a \"media\" attribute in an inline style sheet's STYLE tag, \"supports-rule\" if specified by an @supports rule, ." },
+ { "name": "type", "type": "string", "enum": ["media-rule", "media-import-rule", "media-link-node", "media-style-node", "supports-rule", "layer-rule", "layer-import-rule"], "description": "Source of the media query: \"media-rule\" if specified by a @media rule, \"media-import-rule\" if specified by an @import rule, \"media-link-node\" if specified by a \"media\" attribute in a linked style sheet's LINK tag, \"media-style-node\" if specified by a \"media\" attribute in an inline style sheet's STYLE tag, \"supports-rule\" if specified by an @supports rule, \"layer-rule\" if specified by an @layer rule." },
+ { "name": "text", "type": "string", "optional": true, "description": "Query text if specified by a @media or @supports rule. Layer name (or not present for anonymous layers) for @layer rules." },
{ "name": "sourceURL", "type": "string", "optional": true, "description": "URL of the document containing the CSS grouping." }
]
},
Modified: trunk/Source/WebCore/ChangeLog (286557 => 286558)
--- trunk/Source/WebCore/ChangeLog 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebCore/ChangeLog 2021-12-06 19:45:45 UTC (rev 286558)
@@ -1,3 +1,35 @@
+2021-12-06 Patrick Angle <[email protected]>
+
+ Web Inspector: Support Cascade Layers in the Styles sidebar
+ https://bugs.webkit.org/show_bug.cgi?id=233208
+
+ Reviewed by Devin Rousso.
+
+ 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):
+
2021-12-06 Wenson Hsieh <[email protected]>
Unreviewed, add some missing #includes in WebCore
Modified: trunk/Source/WebCore/Headers.cmake (286557 => 286558)
--- trunk/Source/WebCore/Headers.cmake 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebCore/Headers.cmake 2021-12-06 19:45:45 UTC (rev 286558)
@@ -525,6 +525,8 @@
css/CSSRegisteredCustomProperty.h
css/CSSRule.h
css/CSSRuleList.h
+ css/CSSSelector.h
+ css/CSSSelectorList.h
css/CSSStyleDeclaration.h
css/CSSStyleRule.h
css/CSSStyleSheet.h
@@ -551,6 +553,7 @@
css/Rect.h
css/StyleColor.h
css/StyleProperties.h
+ css/StyleRule.h
css/StyleRuleType.h
css/StyleSheet.h
css/StyleSheetContents.h
@@ -564,6 +567,8 @@
css/parser/CSSParserToken.h
css/parser/CSSParserTokenRange.h
+ cssjit/CompiledSelector.h
+
display/DisplayTree.h
display/DisplayTreeBuilder.h
display/DisplayView.h
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (286557 => 286558)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-06 19:45:45 UTC (rev 286558)
@@ -892,6 +892,7 @@
2DFA488F1DB541D000362B99 /* BufferSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DFA488E1DB541C200362B99 /* BufferSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
2E0888D51148848A00AF4265 /* JSDOMFormData.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E0888D31148848A00AF4265 /* JSDOMFormData.h */; };
2E2D99CE10E2BBDA00496337 /* JSBlob.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E2D99CC10E2BBDA00496337 /* JSBlob.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 2E301BE82745947200C0564F /* CompiledSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = E4451077202C7E0100657D33 /* CompiledSelector.h */; settings = {ATTRIBUTES = (Private, ); }; };
2E37DFDB12DBAFB800A6B233 /* DOMURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E37DFD812DBAFB800A6B233 /* DOMURL.h */; };
2E37E00612DBC5A400A6B233 /* JSDOMURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E37E00412DBC5A400A6B233 /* JSDOMURL.h */; };
2E4346460F546A8200B0F1BA /* Worker.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4346340F546A8200B0F1BA /* Worker.h */; };
@@ -33527,6 +33528,7 @@
E1FE137518402A6700892F13 /* CommonCryptoUtilities.h in Headers */,
0F60F32B1DFBB10700416D6C /* CommonVM.h in Headers */,
7C93F34A1AA6BA5E00A98BAB /* CompiledContentExtension.h in Headers */,
+ 2E301BE82745947200C0564F /* CompiledSelector.h in Headers */,
C2F4E78C1E45C3EF006D7105 /* ComplexTextController.h in Headers */,
E4BA50901BCFBD9500E34EF7 /* ComposedTreeAncestorIterator.h in Headers */,
E44FA1851BCA6B5A0091B6EF /* ComposedTreeIterator.h in Headers */,
Modified: trunk/Source/WebCore/css/CSSImportRule.cpp (286557 => 286558)
--- trunk/Source/WebCore/css/CSSImportRule.cpp 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebCore/css/CSSImportRule.cpp 2021-12-06 19:45:45 UTC (rev 286558)
@@ -56,6 +56,11 @@
return *m_mediaCSSOMWrapper;
}
+const std::optional<CascadeLayerName>& CSSImportRule::cascadeLayerName() const
+{
+ return m_importRule.get().cascadeLayerName();
+}
+
String CSSImportRule::cssText() const
{
if (auto queries = m_importRule.get().mediaQueries()) {
Modified: trunk/Source/WebCore/css/CSSImportRule.h (286557 => 286558)
--- trunk/Source/WebCore/css/CSSImportRule.h 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebCore/css/CSSImportRule.h 2021-12-06 19:45:45 UTC (rev 286558)
@@ -22,6 +22,7 @@
#pragma once
#include "CSSRule.h"
+#include "StyleRule.h"
namespace WebCore {
@@ -37,6 +38,7 @@
WEBCORE_EXPORT String href() const;
WEBCORE_EXPORT MediaList& media() const;
WEBCORE_EXPORT CSSStyleSheet* styleSheet() const;
+ WEBCORE_EXPORT const std::optional<CascadeLayerName>& cascadeLayerName() const;
private:
CSSImportRule(StyleRuleImport&, CSSStyleSheet*);
Modified: trunk/Source/WebCore/css/CSSLayerRule.cpp (286557 => 286558)
--- trunk/Source/WebCore/css/CSSLayerRule.cpp 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebCore/css/CSSLayerRule.cpp 2021-12-06 19:45:45 UTC (rev 286558)
@@ -52,18 +52,10 @@
StringBuilder result;
- auto appendLayerName = [&](auto& name) {
- for (auto& segment : name) {
- result.append(segment);
- if (&segment != &name.last())
- result.append('.');
- }
- };
-
if (layer.isStatement()) {
result.append("@layer ");
for (auto& name : layer.nameList()) {
- appendLayerName(name);
+ result.append(stringFromCascadeLayerName(name));
if (&name != &layer.nameList().last())
result.append(", ");
}
@@ -72,10 +64,8 @@
}
result.append("@layer ");
- if (!layer.name().isEmpty()) {
- appendLayerName(layer.name());
- result.append(' ');
- }
+ if (auto name = layerName())
+ result.append(*name, " ");
result.append("{\n");
appendCSSTextForItems(result);
result.append('}');
@@ -82,5 +72,26 @@
return result.toString();
}
+std::optional<String> CSSLayerRule::layerName() const
+{
+ auto& layer = downcast<StyleRuleLayer>(groupRule());
+
+ if (!layer.isStatement() && !layer.name().isEmpty())
+ return stringFromCascadeLayerName(layer.name());
+
+ return std::nullopt;
+}
+
+String CSSLayerRule::stringFromCascadeLayerName(const CascadeLayerName& name)
+{
+ StringBuilder result;
+ for (auto& segment : name) {
+ result.append(segment);
+ if (&segment != &name.last())
+ result.append('.');
+ }
+ return result.toString();
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/css/CSSLayerRule.h (286557 => 286558)
--- trunk/Source/WebCore/css/CSSLayerRule.h 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebCore/css/CSSLayerRule.h 2021-12-06 19:45:45 UTC (rev 286558)
@@ -30,6 +30,7 @@
#pragma once
#include "CSSGroupingRule.h"
+#include "StyleRule.h"
namespace WebCore {
@@ -40,7 +41,10 @@
static Ref<CSSLayerRule> create(StyleRuleLayer&, CSSStyleSheet* parent);
String cssText() const final;
+ std::optional<String> layerName() const;
+ static String stringFromCascadeLayerName(const CascadeLayerName&);
+
private:
CSSLayerRule(StyleRuleLayer&, CSSStyleSheet*);
CSSRule::Type type() const final { return LAYER_RULE; }
Modified: trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp (286557 => 286558)
--- trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp 2021-12-06 19:45:45 UTC (rev 286558)
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010, Google Inc. All rights reserved.
+ * Copyright (C) 2021, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +28,7 @@
#include "CSSImportRule.h"
#include "CSSKeyframesRule.h"
+#include "CSSLayerRule.h"
#include "CSSMediaRule.h"
#include "CSSParser.h"
#include "CSSParserObserver.h"
@@ -105,10 +107,8 @@
for (auto& data : dataList) {
if (data->type == WebCore::StyleRuleType::Style)
target.append(data.copyRef());
- else if (data->type == WebCore::StyleRuleType::Media)
+ else if (data->type == WebCore::StyleRuleType::Media || data->type == WebCore::StyleRuleType::Supports || data->type == WebCore::StyleRuleType::Layer)
flattenSourceData(data->childRules, target);
- else if (data->type == WebCore::StyleRuleType::Supports)
- flattenSourceData(data->childRules, target);
}
}
@@ -426,6 +426,9 @@
if (is<CSSSupportsRule>(*rule))
return &downcast<CSSSupportsRule>(*rule).cssRules();
+ if (is<CSSLayerRule>(*rule))
+ return &downcast<CSSLayerRule>(*rule).cssRules();
+
return nullptr;
}
@@ -435,32 +438,50 @@
auto* parentRule = &rule;
while (parentRule) {
- RefPtr<Protocol::CSS::Grouping> ruleGroupingPayload;
+ Vector<Ref<Protocol::CSS::Grouping>> ruleGroupingPayloads;
if (is<CSSMediaRule>(parentRule)) {
auto* media = downcast<CSSMediaRule>(parentRule)->media();
if (media && media->length() && media->mediaText() != "all") {
- ruleGroupingPayload = Protocol::CSS::Grouping::create()
- .setText(media->mediaText())
+ auto mediaRulePayload = Protocol::CSS::Grouping::create()
.setType(Protocol::CSS::Grouping::Type::MediaRule)
.release();
+ mediaRulePayload->setText(media->mediaText());
+ ruleGroupingPayloads.append(WTFMove(mediaRulePayload));
}
} else if (is<CSSImportRule>(parentRule)) {
+ if (auto& layerName = downcast<CSSImportRule>(parentRule)->cascadeLayerName()) {
+ auto layerRulePayload = Protocol::CSS::Grouping::create()
+ .setType(Protocol::CSS::Grouping::Type::LayerImportRule)
+ .release();
+ layerRulePayload->setText(CSSLayerRule::stringFromCascadeLayerName(*layerName));
+ ruleGroupingPayloads.append(WTFMove(layerRulePayload));
+ }
+
auto& media = downcast<CSSImportRule>(parentRule)->media();
if (media.length() && media.mediaText() != "all") {
- ruleGroupingPayload = Protocol::CSS::Grouping::create()
- .setText(media.mediaText())
+ auto mediaRulePayload = Protocol::CSS::Grouping::create()
.setType(Protocol::CSS::Grouping::Type::MediaImportRule)
.release();
+ mediaRulePayload->setText(media.mediaText());
+ ruleGroupingPayloads.append(WTFMove(mediaRulePayload));
}
} else if (is<CSSSupportsRule>(parentRule)) {
- ruleGroupingPayload = Protocol::CSS::Grouping::create()
- .setText(downcast<CSSSupportsRule>(parentRule)->conditionText())
+ auto supportsRulePayload = Protocol::CSS::Grouping::create()
.setType(Protocol::CSS::Grouping::Type::SupportsRule)
.release();
+ supportsRulePayload->setText(downcast<CSSSupportsRule>(parentRule)->conditionText());
+ ruleGroupingPayloads.append(WTFMove(supportsRulePayload));
+ } else if (is<CSSLayerRule>(parentRule)) {
+ auto layerRulePayload = Protocol::CSS::Grouping::create()
+ .setType(Protocol::CSS::Grouping::Type::LayerRule)
+ .release();
+ if (auto layerName = downcast<CSSLayerRule>(parentRule)->layerName())
+ layerRulePayload->setText(*layerName);
+ ruleGroupingPayloads.append(WTFMove(layerRulePayload));
}
- if (ruleGroupingPayload) {
+ for (auto&& ruleGroupingPayload : WTFMove(ruleGroupingPayloads)) {
if (auto* parentStyleSheet = parentRule->parentStyleSheet()) {
String sourceURL = parentStyleSheet->contents().baseURL().string();
if (sourceURL.isEmpty()) {
@@ -471,7 +492,7 @@
ruleGroupingPayload->setSourceURL(sourceURL);
}
- groupingsPayload->addItem(ruleGroupingPayload.releaseNonNull());
+ groupingsPayload->addItem(WTFMove(ruleGroupingPayload));
}
if (parentRule->parentRule()) {
@@ -484,9 +505,9 @@
auto* media = styleSheet->media();
if (media && media->length() && media->mediaText() != "all") {
auto sheetGroupingPayload = Protocol::CSS::Grouping::create()
- .setText(media->mediaText())
.setType(is<HTMLStyleElement>(styleSheet->ownerNode()) ? Protocol::CSS::Grouping::Type::MediaStyleNode: Protocol::CSS::Grouping::Type::MediaLinkNode)
.release();
+ sheetGroupingPayload->setText(media->mediaText());
String sourceURL;
if (auto* ownerDocument = styleSheet->ownerDocument())
Modified: trunk/Source/WebCore/style/InspectorCSSOMWrappers.cpp (286557 => 286558)
--- trunk/Source/WebCore/style/InspectorCSSOMWrappers.cpp 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebCore/style/InspectorCSSOMWrappers.cpp 2021-12-06 19:45:45 UTC (rev 286558)
@@ -30,6 +30,7 @@
#include "InspectorCSSOMWrappers.h"
#include "CSSImportRule.h"
+#include "CSSLayerRule.h"
#include "CSSMediaRule.h"
#include "CSSRule.h"
#include "CSSStyleRule.h"
@@ -61,6 +62,9 @@
case CSSRule::IMPORT_RULE:
collect(downcast<CSSImportRule>(*cssRule).styleSheet());
break;
+ case CSSRule::LAYER_RULE:
+ collect(downcast<CSSLayerRule>(cssRule));
+ break;
case CSSRule::MEDIA_RULE:
collect(downcast<CSSMediaRule>(cssRule));
break;
Modified: trunk/Source/WebInspectorUI/ChangeLog (286557 => 286558)
--- trunk/Source/WebInspectorUI/ChangeLog 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebInspectorUI/ChangeLog 2021-12-06 19:45:45 UTC (rev 286558)
@@ -1,3 +1,26 @@
+2021-12-06 Patrick Angle <[email protected]>
+
+ Web Inspector: Support Cascade Layers in the Styles sidebar
+ https://bugs.webkit.org/show_bug.cgi?id=233208
+
+ Reviewed by Devin Rousso.
+
+ * 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).
+
2021-12-02 Devin Rousso <[email protected]>
[css-values-4] Support `*vi` (inline) and `*vb` (block) viewport units
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSGrouping.js (286557 => 286558)
--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSGrouping.js 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSGrouping.js 2021-12-06 19:45:45 UTC (rev 286558)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2019, 2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,11 +28,11 @@
constructor(type, text, sourceCodeLocation)
{
console.assert(Object.values(CSSGrouping.Type).includes(type));
- console.assert(typeof text === "string" && text.length);
+ console.assert(!text || (typeof text === "string" && text.length));
console.assert(!sourceCodeLocation || sourceCodeLocation instanceof WI.SourceCodeLocation);
this._type = type;
- this._text = text;
+ this._text = text || null;
this._sourceCodeLocation = sourceCodeLocation || null;
}
@@ -55,11 +55,20 @@
return this._type === WI.CSSGrouping.Type.SupportsRule;
}
+ get isLayer()
+ {
+ return this._type === WI.CSSGrouping.Type.LayerRule
+ || this._type === WI.CSSGrouping.Type.LayerImportRule;
+ }
+
get prefix()
{
if (this.isSupports)
return "@supports";
+ if (this.isLayer)
+ return "@layer";
+
console.assert(this.isMedia);
return "@media";
}
@@ -71,4 +80,6 @@
MediaLinkNode: "media-link-node",
MediaStyleNode: "media-style-node",
SupportsRule: "supports-rule",
+ LayerRule: "layer-rule",
+ LayerImportRule: "layer-import-rule",
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js (286557 => 286558)
--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js 2021-12-06 19:45:45 UTC (rev 286558)
@@ -470,7 +470,7 @@
{
let indentString = WI.indentString();
let styleText = "";
- let groupings = this.groupings.filter((grouping) => grouping.text !== "all");
+ let groupings = this.groupings.filter((grouping) => !grouping.isMedia || grouping.text !== "all");
let groupingsCount = groupings.length;
if (options.includeGroupingsAndSelectors) {
@@ -478,7 +478,10 @@
if (options.multiline)
styleText += indentString.repeat(groupingsCount - i - 1);
- styleText += groupings[i].prefix + " " + groupings[i].text + " {";
+ styleText += groupings[i].prefix;
+ if (groupings[i].text)
+ styleText += " " + groupings[i].text;
+ styleText += " {";
if (options.multiline)
styleText += "\n";
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js (286557 => 286558)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js 2021-12-06 19:45:31 UTC (rev 286557)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js 2021-12-06 19:45:45 UTC (rev 286558)
@@ -102,24 +102,26 @@
console.assert(iconClassName);
this._element.classList.add("has-icon", iconClassName);
- let groupings = this._style.groupings.filter((grouping) => grouping.text !== "all");
+ let groupings = this._style.groupings.filter((grouping) => !grouping.isMedia || grouping.text !== "all").reverse();
if (groupings.length) {
let groupingsElement = this.element.appendChild(document.createElement("div"));
groupingsElement.classList.add("header-groupings");
let currentGroupingType = null;
+ let currentGroupingHadText = false;
let groupingTypeElement = null;
this._groupingElements = groupings.map((grouping) => {
- if (grouping.type !== currentGroupingType) {
+ if (grouping.type !== currentGroupingType || !grouping.text || !currentGroupingHadText) {
groupingTypeElement = groupingsElement.appendChild(document.createElement("div"));
groupingTypeElement.classList.add("grouping");
groupingTypeElement.textContent = grouping.prefix + " ";
currentGroupingType = grouping.type;
} else
- groupingTypeElement.append(", ");
+ groupingTypeElement.append(grouping.isLayer && grouping.text ? "." : ", ");
+ currentGroupingHadText = !!grouping.text;
let span = groupingTypeElement.appendChild(document.createElement("span"));
- span.textContent = grouping.text;
+ span.textContent = grouping.text ?? "";
return span;
});
}