From b5cf192b43bc91e0a18cf1399fd5f64d152e969c Mon Sep 17 00:00:00 2001 From: Patrick Angle Date: Fri, 6 Jan 2023 12:29:07 -0800 Subject: [PATCH] Web Inspector: Show parent style rules for nested style rules in Styles sidebar https://bugs.webkit.org/show_bug.cgi?id=250088 rdar://100522930 Reviewed by Antti Koivisto. Add basic support for viewing and editing parent style rule selectors for nested style rules. This uses the same mechanism we already use for showing parent `@rule`s, including support for editing. * LayoutTests/inspector/css/getMatchesStylesForNodeNestingStyleGrouping-expected.txt: Added. * LayoutTests/inspector/css/getMatchesStylesForNodeNestingStyleGrouping.html: Added. * LayoutTests/inspector/css/setGroupingHeaderText-expected.txt: * LayoutTests/inspector/css/setGroupingHeaderText.html: - Add test cases for modifying a parent Style rule's selector via a Grouping on a child nested rule. * Source/JavaScriptCore/inspector/protocol/CSS.json: - Add new "StyleRule" grouping type to represent parent style rules. * Source/WebCore/WebCore.xcodeproj/project.pbxproj: * Source/WebCore/css/CSSStyleRule.cpp: (WebCore::CSSStyleRule::CSSStyleRule): (WebCore::CSSStyleRule::length const): (WebCore::CSSStyleRule::item const): (WebCore::CSSStyleRule::cssRules const): * Source/WebCore/css/CSSStyleRule.h: - Add support for getting the nested rules inside a CSSStyleRule. * Source/WebCore/css/StyleRule.cpp: (WebCore::StyleRuleBase::createCSSOMWrapper const): * Source/WebCore/css/StyleRule.h: - Support creating a wrapper with a CSSStyleRule as a parent. * Source/WebCore/css/parser/CSSParser.cpp: (WebCore::CSSParser::parseSelector): * Source/WebCore/css/parser/CSSParser.h: - Allow callers to enable nesting syntax for parsing a selector, which is done to verify a selector is valid by Web Inspector when editing a nested rule's selector. * Source/WebCore/inspector/InspectorStyleSheet.cpp: (WebCore::flatteningStrategyForStyleRuleType): - Style rules can now contain rules, so get rid of the `Commit` strategy and use the existing `CommitSelfThenChildren` for style rules instead. (WebCore::isValidRuleHeaderText): - Pass through the nesting mode for parsing selectors. (WebCore::protocolGroupingTypeForStyleRuleType): (WebCore::flattenSourceData): - Get rid of `Commit` strategy. (WebCore::StyleSheetHandler::startRuleHeader): - It is no longer invalid to encounter the start of a style rule before encountering the end of the previous style rule. (WebCore::asCSSRuleList): (WebCore::InspectorStyleSheet::buildArrayForGroupings): - Start with the parent of the passed CSSRule, otherwise every style rule will include itself as a grouping. (WebCore::isNestedContext): (WebCore::InspectorStyleSheet::setRuleHeaderText): - Nested rules should allow relevant syntax for selectors. (WebCore::InspectorStyleSheet::collectFlatRules): * Source/WebCore/style/InspectorCSSOMWrappers.cpp: (WebCore::Style::InspectorCSSOMWrappers::collect): - Eagerly create CSSOM wrappers for nested rules. * Source/WebInspectorUI/UserInterface/Models/CSSGrouping.js: (WI.CSSGrouping.prototype.get isStyle): (WI.CSSGrouping.prototype.get prefix): (WI.CSSGrouping): - Nested rules don't have a prefix like `@rule`s do, so provide a null prefix. * Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js: (WI.SpreadsheetCSSStyleDeclarationSection.prototype._renderGroupings): - Support groupings without a prefix by not prepending the prefix. Canonical link: https://commits.webkit.org/258555@main --- ...esForNodeNestingStyleGrouping-expected.txt | 33 +++++ ...chedStylesForNodeNestingStyleGrouping.html | 133 ++++++++++++++++++ .../css/setGroupingHeaderText-expected.txt | 20 +++ .../inspector/css/setGroupingHeaderText.html | 32 ++++- .../inspector/protocol/CSS.json | 4 +- Source/WebCore/Headers.cmake | 2 + .../WebCore/WebCore.xcodeproj/project.pbxproj | 2 +- Source/WebCore/css/CSSStyleRule.cpp | 29 ++++ Source/WebCore/css/CSSStyleRule.h | 8 ++ Source/WebCore/css/StyleRule.cpp | 7 +- Source/WebCore/css/StyleRule.h | 4 +- Source/WebCore/css/parser/CSSParser.cpp | 4 +- Source/WebCore/css/parser/CSSParser.h | 3 +- .../WebCore/inspector/InspectorStyleSheet.cpp | 88 +++++++----- .../inspector/agents/InspectorCSSAgent.cpp | 2 +- .../WebCore/style/InspectorCSSOMWrappers.cpp | 3 + .../UserInterface/Models/CSSGrouping.js | 9 ++ .../Models/CSSStyleDeclaration.js | 5 +- .../SpreadsheetCSSStyleDeclarationSection.js | 5 +- 19 files changed, 342 insertions(+), 51 deletions(-) create mode 100644 LayoutTests/inspector/css/getMatchedStylesForNodeNestingStyleGrouping-expected.txt create mode 100644 LayoutTests/inspector/css/getMatchedStylesForNodeNestingStyleGrouping.html diff --git a/LayoutTests/inspector/css/getMatchedStylesForNodeNestingStyleGrouping-expected.txt b/LayoutTests/inspector/css/getMatchedStylesForNodeNestingStyleGrouping-expected.txt new file mode 100644 index 000000000000..2df786e9f03c --- /dev/null +++ b/LayoutTests/inspector/css/getMatchedStylesForNodeNestingStyleGrouping-expected.txt @@ -0,0 +1,33 @@ +Tests for the CSS.getMatchedStyleForNode command and container rule groups. + + +== Running test suite: CSS.getMatchedStyleForNode.NestingStyleGrouping +-- Running test case: CSS.getMatchedStyleForNode.NestingStyleGrouping.NormalProperty +PASS: Should have 1 authored rules. +- Testing rule #0 +PASS: Selector text should be "#outerA". +PASS: "color" property value should be "red". +PASS: Rule should have no groupings. + +-- Running test case: CSS.getMatchedStyleForNode.NestingStyleGrouping.NestedRulePropertyWithImplicitAmpersand +PASS: Should have 2 authored rules. +- Testing rule #0 +PASS: Selector text should be ".innerA". +PASS: "color" property value should be "green". +PASS: Rule should have 1 grouping(s). +PASS: Grouping 0 should have a type of "style-rule". +PASS: Grouping 0 should have a text of "#outerA". +- Testing rule #1 +PASS: Selector text should be "#outerA". +PASS: "color" property value should be "red". +PASS: Rule should have no groupings. + +-- Running test case: CSS.getMatchedStyleForNode.NestingStyleGrouping.NestedRulePropertyWithImplicitAmpersand +PASS: Should have 1 authored rules. +- Testing rule #0 +PASS: Selector text should be ".outer:not(&)". +PASS: "color" property value should be "blue". +PASS: Rule should have 1 grouping(s). +PASS: Grouping 0 should have a type of "style-rule". +PASS: Grouping 0 should have a text of "#outerA". + diff --git a/LayoutTests/inspector/css/getMatchedStylesForNodeNestingStyleGrouping.html b/LayoutTests/inspector/css/getMatchedStylesForNodeNestingStyleGrouping.html new file mode 100644 index 000000000000..b8659aba45eb --- /dev/null +++ b/LayoutTests/inspector/css/getMatchedStylesForNodeNestingStyleGrouping.html @@ -0,0 +1,133 @@ + + + + + + + + +

Tests for the CSS.getMatchedStyleForNode command and container rule groups.

+
+
+
+
+
+ + diff --git a/LayoutTests/inspector/css/setGroupingHeaderText-expected.txt b/LayoutTests/inspector/css/setGroupingHeaderText-expected.txt index 4f25da3e2faf..f4d6da286b6b 100644 --- a/LayoutTests/inspector/css/setGroupingHeaderText-expected.txt +++ b/LayoutTests/inspector/css/setGroupingHeaderText-expected.txt @@ -186,3 +186,23 @@ PASS: Setting text should succeed. PASS: Text should change. PASS: Text should change on the same grouping attached to a different rule. +-- Running test case: CSS.setGroupingHeaderText.StyleRule +PASS: Should have 2 authored rule. +PASS: Should find grouping of type 'style-rule'. +Setting text to '#test, #test2'. +PASS: Setting text should succeed. +PASS: Text should change. +PASS: Text should change on the same grouping attached to a different rule. +Setting text to '#test {} #test'. +PASS: Setting text should fail. +PASS: Text should not change. +PASS: Text should not change on the same grouping attached to a different rule. +Setting text to ''. +PASS: Setting text should fail. +PASS: Text should not change. +PASS: Text should not change on the same grouping attached to a different rule. +Setting text to '#test'. +PASS: Setting text should succeed. +PASS: Text should change. +PASS: Text should change on the same grouping attached to a different rule. + diff --git a/LayoutTests/inspector/css/setGroupingHeaderText.html b/LayoutTests/inspector/css/setGroupingHeaderText.html index 4e3329cc8a8f..3181f8e45c5b 100644 --- a/LayoutTests/inspector/css/setGroupingHeaderText.html +++ b/LayoutTests/inspector/css/setGroupingHeaderText.html @@ -7,14 +7,14 @@ { let suite = InspectorTest.createAsyncSuite("CSS.setGroupingHeaderText"); - function addTestCase({name, description, groupingType, subtestCases}) + function addTestCase({name, description, selector, groupingType, subtestCases}) { suite.addTestCase({ name, description, async test() { let documentNode = await WI.domManager.requestDocument(); - let nodeId = await documentNode.querySelector("#test"); + let nodeId = await documentNode.querySelector(selector); let domNode = WI.domManager.nodeForId(nodeId); InspectorTest.assert(domNode, `Should find DOM Node for selector '#test'.`); @@ -60,6 +60,7 @@ addTestCase({ name: "CSS.setGroupingHeaderText.MediaRule", description: "@media rules should be mutable and should only accept syntactically correct text.", + selector: "#test", groupingType: WI.CSSGrouping.Type.MediaRule, subtestCases: [ { text: "not print" }, @@ -78,6 +79,7 @@ addTestCase({ name: "CSS.setGroupingHeaderText.SupportsRule", description: "@supports rules should be mutable and should only accept syntactically correct text.", + selector: "#test", groupingType: WI.CSSGrouping.Type.SupportsRule, subtestCases: [ { text: "(color: purple)" }, @@ -98,6 +100,7 @@ addTestCase({ name: "CSS.setGroupingHeaderText.LayerRule", description: "@layer rules should be mutable and should only accept syntactically correct text.", + selector: "#test", groupingType: WI.CSSGrouping.Type.LayerRule, subtestCases: [ { text: "howdy" }, @@ -112,6 +115,7 @@ addTestCase({ name: "CSS.setGroupingHeaderText.ContainerRule", description: "@container rules should be mutable and should only accept syntactically correct text.", + selector: "#test", groupingType: WI.CSSGrouping.Type.ContainerRule, subtestCases: [ { text: "name (min-width: 42px)" }, @@ -127,6 +131,18 @@ ], }); + addTestCase({ + name: "CSS.setGroupingHeaderText.StyleRule", + description: "Parent style rules for a nested style rule should be mutable and should only accept syntactically correct text.", + selector: "#nested", + groupingType: WI.CSSGrouping.Type.StyleRule, + subtestCases: [ + { text: "#test, #test2" }, + { text: "#test {} #test", expectsFailure: true }, + { text: "", expectsFailure: true }, + ], + }); + suite.runTestCasesAndFinish(); } @@ -141,6 +157,14 @@ @container (min-width: 1px) { #test { color: lawngreen; + + #nested { + color: rebeccapurple; + } + + .nested { + color: seagreen; + } } .test { @@ -154,6 +178,8 @@

Tests for the CSS.setGroupingHeaderText command.

-
+
+
+
diff --git a/Source/JavaScriptCore/inspector/protocol/CSS.json b/Source/JavaScriptCore/inspector/protocol/CSS.json index e887c3529e06..4d1ce3ee03ab 100644 --- a/Source/JavaScriptCore/inspector/protocol/CSS.json +++ b/Source/JavaScriptCore/inspector/protocol/CSS.json @@ -242,8 +242,8 @@ "type": "object", "description": "CSS @media (as well as other users of media queries, like @import,