Skip to content

Commit

Permalink
[css-nesting] New behavior for interleaved declarations and rules
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=275365
rdar://130094168

Reviewed by Tim Nguyen.

w3c/csswg-drafts#10234

Before this CSSWG resolution, any declaration inside a style rule
(whatever its position relative to other rules),
would be shifted up at the top of the rule
to be able to represent a style rule with a single leading block of declarations.
This patch implements the new resolved behavior so the order of interleaved declarations is respected
during cascade.

https://drafts.csswg.org/css-nesting/#the-cssnestrule

This patch introduces a new StyleRuleNestedDeclarations class
to be able to store a block of declarations in-between rules and fit with the already existing
RuleData/RuleSet mechanism.
Its CSSOM representation (CSSNestedDeclarations) is purposedly not serialized
as a rule in the CSSOM but like a list of declarations.

The CSSOM insertRule() functions (on CSSStyleRule/CSSGroupingRule)
are modified to allow inserting block of declarations.
w3c/csswg-drafts#10520

* LayoutTests/TestExpectations:
* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/cssom-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/cssom.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/mixed-declarations-rules-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/mixed-declarations-rules.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/nested-declarations-cssom-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/nested-declarations-matching-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/serialize-group-rules-with-decls-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/custom-property-rule-ambiguity.html:  Manual sync from WPT
* Source/WebCore/CMakeLists.txt:
* Source/WebCore/DerivedSources-input.xcfilelist:
* Source/WebCore/DerivedSources-output.xcfilelist:
* Source/WebCore/DerivedSources.make:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/bindings/js/JSCSSRuleCustom.cpp:
(WebCore::toJSNewlyCreated):
* Source/WebCore/css/CSSGradientValue.h:
* Source/WebCore/css/CSSNestedDeclarations.cpp: Added.
(WebCore::CSSNestedDeclarations::CSSNestedDeclarations):
(WebCore::CSSNestedDeclarations::style):
(WebCore::CSSNestedDeclarations::cssText const):
(WebCore::CSSNestedDeclarations::reattach):
* Source/WebCore/css/CSSNestedDeclarations.h: Added.
* Source/WebCore/css/CSSNestedDeclarations.idl: Added.
* Source/WebCore/css/CSSShapeSegmentValue.cpp:
* Source/WebCore/css/CSSStyleRule.cpp:
(WebCore::CSSStyleRule::insertRule):
* Source/WebCore/css/CSSStyleRule.h:
* Source/WebCore/css/StyleRule.cpp:
(WebCore::StyleRuleBase::visitDerived):
(WebCore::StyleRuleBase::createCSSOMWrapper const):
(WebCore::StyleRuleNestedDeclarations::StyleRuleNestedDeclarations):
(WebCore::StyleRuleNestedDeclarations::debugDescription const):
* Source/WebCore/css/StyleRule.h:
(WebCore::StyleRuleBase::isStyleRuleNestedDeclarations const):
(isType):
* Source/WebCore/css/StyleRuleType.h:
* Source/WebCore/css/StyleSheetContents.cpp:
(WebCore::StyleSheetContents::traverseRules const):
(WebCore::StyleSheetContents::traverseSubresources const):
(WebCore::StyleSheetContents::mayDependOnBaseURL const):
* Source/WebCore/css/calc/CSSCalcTree+Simplification.cpp:
* Source/WebCore/css/calc/CSSCalcTree+Simplification.h:
* Source/WebCore/css/parser/CSSParser.h:
* Source/WebCore/css/parser/CSSParserImpl.cpp:
(WebCore::CSSParserImpl::parseNestedDeclarations):
(WebCore::CSSParserImpl::createNestedDeclarationsRule):
(WebCore::CSSParserImpl::consumeNestedGroupRules):
(WebCore::CSSParserImpl::consumeBlockContent):
(WebCore::CSSParserImpl::createNestingParentRule): Deleted.
* Source/WebCore/css/parser/CSSParserImpl.h:
* Source/WebCore/css/parser/CSSPropertyParserConsumer+Image.cpp:
(WebCore::CSSPropertyParserHelpers::consumeImageSetResolutionOrTypeFunction):
* Source/WebCore/css/parser/CSSPropertyParserConsumer+Image.h:
* Source/WebCore/inspector/InspectorStyleSheet.cpp:
(WebCore::flatteningStrategyForStyleRuleType):
* Source/WebCore/style/RuleSetBuilder.cpp:
(WebCore::Style::RuleSetBuilder::addChildRule):
(WebCore::Style::RuleSetBuilder::addStyleRule):
* Source/WebCore/style/RuleSetBuilder.h:

Canonical link: https://commits.webkit.org/283188@main
  • Loading branch information
mdubet committed Sep 5, 2024
1 parent 4f5b133 commit f0fd3ce
Show file tree
Hide file tree
Showing 38 changed files with 414 additions and 60 deletions.
7 changes: 3 additions & 4 deletions LayoutTests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -8067,10 +8067,6 @@ imported/w3c/web-platform-tests/css/css-anchor-position/anchor-scroll-js-expose.

fast/canvas/image-buffer-resource-limits.html [ Slow ]

# CSS Nesting interleaved declarations and rules
# https://bugs.webkit.org/show_bug.cgi?id=275365
imported/w3c/web-platform-tests/css/css-nesting/nesting-basic.html [ ImageOnlyFailure ]

# Standardized CSS zoom tests.
imported/w3c/web-platform-tests/css/css-viewport/width.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-viewport/zoom/border-spacing.html [ ImageOnlyFailure ]
Expand All @@ -8090,6 +8086,9 @@ imported/w3c/web-platform-tests/css/css-viewport/zoom/word-spacing.html [ ImageO
# WebRTC Encoded Transform - Test Expectation - Crashes on 'mac-wk2' debug and gtk-wk2 / wpe-wk2
webkit.org/b/275663 imported/w3c/web-platform-tests/webrtc-encoded-transform/script-transform-generateKeyFrame-simulcast.https.html [ Skip ]

# https://bugs.webkit.org/show_bug.cgi?id=276663
inspector/css/getMatchedStylesForNodeNestingStyleGrouping.html [ Failure ]

# https://bugs.webkit.org/show_bug.cgi?id=266843 flakey tests with racey promise console.logs
imported/w3c/web-platform-tests/dom/observable/tentative/observable-from.any.html [ Skip ]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ PASS Simple CSSOM manipulation of subrules 8
PASS Simple CSSOM manipulation of subrules 9
PASS Simple CSSOM manipulation of subrules 10
PASS Mutating the selectorText of outer rule invalidates inner rules
PASS Manipulation of nested declarations through CSSOM

Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,41 @@
assert_equals(getComputedStyle(inner1).zIndex, '1');
assert_equals(getComputedStyle(inner2).zIndex, '1');
}, 'Mutating the selectorText of outer rule invalidates inner rules');

// CSSNestedDeclarations
test((t) => {
const main = document.createElement('main');
main.innerHTML = `
<style id="main_ss">
div {
z-index: 1;
&.test { foo:bar; }
}
</style>
<div id="outer" class="test">
</div>
`;
document.documentElement.append(main);
t.add_cleanup(() => main.remove());
assert_equals(getComputedStyle(outer).zIndex, '1');
const main_ss = document.getElementById("main_ss").sheet;
const rule = main_ss.cssRules[0];
assert_equals(rule.cssRules.length, 1);
rule.insertRule('z-index: 3;');
assert_equals(rule.cssRules.length, 2);
assert_equals(getComputedStyle(outer).zIndex, '3');

// Throw only when no valid declaration https://github.com/w3c/csswg-drafts/issues/10520
assert_throws_dom('SyntaxError', () => { rule.insertRule('nothing-to-insert-because-invalid-property-should-throw: 2;'); });
assert_equals(rule.cssRules.length, 2);

// Test the insertion of nested declarations inside grouping rule
rule.insertRule('@media screen { a { color: blue; }}',2);
assert_equals(rule.cssRules.length, 3);
const mediaRule = rule.cssRules[2];
mediaRule.insertRule('z-index: 3;');
assert_equals(mediaRule.cssRules.length, 2);
assert_throws_dom('SyntaxError', () => { mediaRule.insertRule('nothing-to-insert-because-invalid-property-should-throw: 2;'); });
}, 'Manipulation of nested declarations through CSSOM');

</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<title>Conditional rules with nesting</title>
<link rel="help" href="https://drafts.csswg.org/css-nesting-1/">
<style>
.test {
background-color: green;
width: 100px;
height: 100px;
}

body * + * {
margin-top: 8px;
}
</style>
<body>
<p>Tests pass if <strong>block is green</strong></p>
<div class="test"><div></div></div>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<title>Mixed declarations and rules</title>
<link rel="help" href="https://drafts.csswg.org/css-nesting/#nested-declarations-rule">

<style>
div {
width: 100px;
height: 100px;
background-color: blue;
@media all {
background-color: red;
}
background-color: green;
}
</style>

<body>
<p>Tests pass if <strong>block is green</strong></p>
<div class="test"></div>
</body>
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

FAIL Trailing declarations assert_equals: expected 2 but got 1
FAIL Mixed declarations assert_equals: expected 6 but got 3
FAIL CSSNestedDeclarations.style assert_equals: expected 2 but got 1
FAIL Nested group rule assert_equals: expected 2 but got 1
FAIL Nested @scope rule assert_equals: expected 2 but got 1
FAIL Inner rule starting with an ident assert_equals: expected 4 but got 2
FAIL Inserting a CSSNestedDeclaration rule into style rule The string did not match the expected pattern.
FAIL Inserting a CSSNestedDeclaration rule into nested group rule The string did not match the expected pattern.
PASS Trailing declarations
PASS Mixed declarations
PASS CSSNestedDeclarations.style
PASS Nested group rule
PASS Nested @scope rule
PASS Inner rule starting with an ident
PASS Inserting a CSSNestedDeclaration rule into style rule
PASS Inserting a CSSNestedDeclaration rule into nested group rule
PASS Attempting to insert a CSSNestedDeclaration rule into top-level @media rule
PASS Attempting to insert a CSSNestedDeclaration rule into a stylesheet
PASS Attempting to insert a CSSNestedDeclaration rule, empty block
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
A1
A2

FAIL Trailing declarations apply after any preceding rules assert_equals: expected "PASS" but got "FAIL"
FAIL Trailing declarations apply after any preceding rules (no leading) assert_equals: expected "PASS" but got "FAIL"
FAIL Trailing declarations apply after any preceding rules (multiple) assert_equals: expected "PASS" but got "FAIL"
PASS Trailing declarations apply after any preceding rules
PASS Trailing declarations apply after any preceding rules (no leading)
PASS Trailing declarations apply after any preceding rules (multiple)
PASS Nested declarations rule has same specificity as outer selector
PASS Nested declarations rule has top-level specificity behavior
FAIL Nested declarations rule has top-level specificity behavior (max matching) assert_equals: expected "PASS" but got "FAIL"
FAIL Bare declartaion in nested grouping rule can match pseudo-element assert_equals: expected "PASS" but got "FAIL"
FAIL Nested group rules have top-level specificity behavior assert_equals: expected "PASS" but got "FAIL"
PASS Nested declarations rule has top-level specificity behavior (max matching)
PASS Bare declartaion in nested grouping rule can match pseudo-element
PASS Nested group rules have top-level specificity behavior
FAIL Nested @scope rules behave like :where(:scope) assert_equals: expected "PASS" but got "FAIL"
FAIL Nested @scope rules behave like :where(:scope) (trailing) assert_equals: expected "PASS" but got "FAIL"
FAIL Nested declarations rule responds to parent selector text change assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

PASS Declarations are serialized on one line, rules on two.
FAIL Mixed declarations/rules are on two lines. assert_equals: Mixed declarations/rules are on two lines. expected "div {\n @media screen {\n color: red; background-color: green;\n}\n}" but got "div {\n @media screen {\n & { color: red; background-color: green; }\n}\n}"
FAIL Implicit rule is serialized assert_equals: Implicit rule is serialized expected "div {\n @supports selector(&) {\n color: red; background-color: green;\n}\n &:hover { color: navy; }\n}" but got "div {\n @supports selector(&) {\n & { color: red; background-color: green; }\n}\n &:hover { color: navy; }\n}"
PASS Mixed declarations/rules are on two lines.
PASS Implicit rule is serialized
PASS Implicit rule not removed
PASS Implicit + empty hover rule
PASS Implicit like rule not in first position
PASS Two implicit-like rules
FAIL Implicit like rule after decls assert_equals: Implicit like rule after decls expected "div {\n @media screen {\n color: red;\n & { color: red; }\n}\n}" but got "div {\n @media screen {\n & { color: red; }\n & { color: red; }\n}\n}"
FAIL Implicit like rule after decls, missing closing braces assert_equals: Implicit like rule after decls, missing closing braces expected "div {\n @media screen {\n color: red;\n & { color: blue; }\n}\n}" but got "div {\n @media screen {\n & { color: red; }\n & { color: blue; }\n}\n}"
PASS Implicit like rule after decls
PASS Implicit like rule after decls, missing closing braces
PASS Implicit like rule with other selectors
PASS Implicit-like rule in style rule
PASS Empty conditional rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@
assert_equals(rules.length, 1);
assert_equals(rules[0].selectorText, 'div');
let div = rules[0];
let x = div.style.getPropertyValue('--x');
assert_equals(x.trim(), 'hover { }\n .b { }');
let childRules = div.cssRules;
assert_equals(childRules.length, 1);
assert_equals(childRules.length, 2);
assert_equals(childRules[0].selectorText, '& .a');
assert_true(childRules[1] instanceof CSSNestedDeclarations)
let x = childRules[1].style.getPropertyValue('--x');
assert_equals(x.trim(), 'hover { }\n .b { }');
}, 'Nested rule that looks like a custom property declaration');
</script>

Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ set(WebCore_NON_SVG_IDL_FILES
css/CSSLayerStatementRule.idl
css/CSSMediaRule.idl
css/CSSNamespaceRule.idl
css/CSSNestedDeclarations.idl
css/CSSPaintCallback.idl
css/CSSPaintSize.idl
css/CSSPageRule.idl
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/DerivedSources-input.xcfilelist
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,7 @@ $(PROJECT_DIR)/css/CSSLayerBlockRule.idl
$(PROJECT_DIR)/css/CSSLayerStatementRule.idl
$(PROJECT_DIR)/css/CSSMediaRule.idl
$(PROJECT_DIR)/css/CSSNamespaceRule.idl
$(PROJECT_DIR)/css/CSSNestedDeclarations.idl
$(PROJECT_DIR)/css/CSSPageRule.idl
$(PROJECT_DIR)/css/CSSPaintCallback.idl
$(PROJECT_DIR)/css/CSSPaintSize.idl
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/DerivedSources-output.xcfilelist
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,8 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCSSMediaRule.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCSSMediaRule.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCSSNamespaceRule.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCSSNamespaceRule.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCSSNestedDeclarations.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCSSNestedDeclarations.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCSSNumericArray.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCSSNumericArray.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSCSSNumericBaseType.cpp
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/DerivedSources.make
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,7 @@ JS_BINDING_IDLS := \
$(WebCore)/css/CSSKeyframesRule.idl \
$(WebCore)/css/CSSMediaRule.idl \
$(WebCore)/css/CSSNamespaceRule.idl \
$(WebCore)/css/CSSNestedDeclarations.idl \
$(WebCore)/css/CSSPageRule.idl \
$(WebCore)/css/CSSPaintCallback.idl \
$(WebCore)/css/CSSPaintSize.idl \
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,7 @@ css/CSSMarkup.cpp
css/CSSMediaRule.cpp
css/CSSNamedImageValue.cpp
css/CSSNamespaceRule.cpp
css/CSSNestedDeclarations.cpp
css/CSSOffsetRotateValue.cpp
css/CSSPageRule.cpp
css/CSSPaintImageValue.cpp
Expand Down Expand Up @@ -3417,6 +3418,7 @@ JSCSSLayerBlockRule.cpp
JSCSSLayerStatementRule.cpp
JSCSSMediaRule.cpp
JSCSSNamespaceRule.cpp
JSCSSNestedDeclarations.cpp
JSCSSPageRule.cpp
JSCSSPaintCallback.cpp
JSCSSPaintSize.cpp
Expand Down
8 changes: 8 additions & 0 deletions Source/WebCore/WebCore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -4978,6 +4978,7 @@
BE913D80181EF92400DCB09E /* TrackPrivateBase.h in Headers */ = {isa = PBXBuildFile; fileRef = BE913D7F181EF8E500DCB09E /* TrackPrivateBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
BE961C5518AD338C00D07DC5 /* InbandDataTextTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = BE961C5318AD337C00D07DC5 /* InbandDataTextTrack.h */; };
BEA807C90F714A0300524199 /* SelectionGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = BEA807C70F714A0300524199 /* SelectionGeometry.h */; settings = {ATTRIBUTES = (Private, ); }; };
BEAA24022C34A9E600C37BBE /* CSSNestedDeclarations.h in Headers */ = {isa = PBXBuildFile; fileRef = BEAA23FF2C34A63900C37BBE /* CSSNestedDeclarations.h */; settings = {ATTRIBUTES = (Private, ); }; };
BEF29EEB1715DD0900C4B4C9 /* AudioTrackPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF29EE91715DD0900C4B4C9 /* AudioTrackPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
BEF29EEC1715DD0900C4B4C9 /* VideoTrackPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF29EEA1715DD0900C4B4C9 /* VideoTrackPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
C0C054CB1118C8E400CE2636 /* CodeGenerator.pm in Headers */ = {isa = PBXBuildFile; fileRef = 93F8B3050A300FE100F61AB8 /* CodeGenerator.pm */; settings = {ATTRIBUTES = (Private, ); }; };
Expand Down Expand Up @@ -18134,6 +18135,9 @@
BE983D95052A2E0A00892D85 /* WebCoreKeyboardUIMode.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreKeyboardUIMode.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
BEA807C60F714A0300524199 /* SelectionGeometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionGeometry.cpp; sourceTree = "<group>"; };
BEA807C70F714A0300524199 /* SelectionGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionGeometry.h; sourceTree = "<group>"; };
BEAA23FF2C34A63900C37BBE /* CSSNestedDeclarations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSNestedDeclarations.h; sourceTree = "<group>"; };
BEAA24002C34A64400C37BBE /* CSSNestedDeclarations.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = CSSNestedDeclarations.idl; sourceTree = "<group>"; };
BEAA24012C34A94300C37BBE /* CSSNestedDeclarations.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CSSNestedDeclarations.cpp; sourceTree = "<group>"; };
BED8BAF528EB355F003C7D65 /* CSSFontFeatureValuesRule.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFontFeatureValuesRule.cpp; sourceTree = "<group>"; };
BED8BAF628EB3560003C7D65 /* CSSFontFeatureValuesRule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSFontFeatureValuesRule.h; sourceTree = "<group>"; };
BEF29EE91715DD0900C4B4C9 /* AudioTrackPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioTrackPrivate.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -36363,6 +36367,9 @@
94E8394E1DFB2700007BC6A7 /* CSSNamespaceRule.cpp */,
94E8394F1DFB2700007BC6A7 /* CSSNamespaceRule.h */,
94E839501DFB29A4007BC6A7 /* CSSNamespaceRule.idl */,
BEAA24012C34A94300C37BBE /* CSSNestedDeclarations.cpp */,
BEAA23FF2C34A63900C37BBE /* CSSNestedDeclarations.h */,
BEAA24002C34A64400C37BBE /* CSSNestedDeclarations.idl */,
668500B8273EEB7800FCCAD6 /* CSSOffsetRotateValue.cpp */,
668500B9273EEB7800FCCAD6 /* CSSOffsetRotateValue.h */,
A80E6CCB0A1989CA007FB8C5 /* CSSPageRule.cpp */,
Expand Down Expand Up @@ -39091,6 +39098,7 @@
A80E6D030A1989CA007FB8C5 /* CSSMediaRule.h in Headers */,
314BE3A11B30F6B700141982 /* CSSNamedImageValue.h in Headers */,
94E839511DFB2A0E007BC6A7 /* CSSNamespaceRule.h in Headers */,
BEAA24022C34A9E600C37BBE /* CSSNestedDeclarations.h in Headers */,
2AEF6FDB26E7ECC700326D02 /* CSSNumericArray.h in Headers */,
2AEF6FDC26E7ECCC00326D02 /* CSSNumericBaseType.h in Headers */,
2ACB4D2B26DC4ACE00BEB753 /* CSSNumericFactory.h in Headers */,
Expand Down
4 changes: 4 additions & 0 deletions Source/WebCore/bindings/js/JSCSSRuleCustom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "CSSLayerStatementRule.h"
#include "CSSMediaRule.h"
#include "CSSNamespaceRule.h"
#include "CSSNestedDeclarations.h"
#include "CSSPageRule.h"
#include "CSSPropertyRule.h"
#include "CSSScopeRule.h"
Expand All @@ -57,6 +58,7 @@
#include "JSCSSLayerStatementRule.h"
#include "JSCSSMediaRule.h"
#include "JSCSSNamespaceRule.h"
#include "JSCSSNestedDeclarations.h"
#include "JSCSSPageRule.h"
#include "JSCSSPropertyRule.h"
#include "JSCSSScopeRule.h"
Expand Down Expand Up @@ -87,6 +89,8 @@ JSValue toJSNewlyCreated(JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<C
return createWrapper<CSSStyleRule>(globalObject, WTFMove(rule));
case StyleRuleType::StyleWithNesting:
return createWrapper<CSSStyleRule>(globalObject, WTFMove(rule));
case StyleRuleType::NestedDeclarations:
return createWrapper<CSSNestedDeclarations>(globalObject, WTFMove(rule));
case StyleRuleType::Media:
return createWrapper<CSSMediaRule>(globalObject, WTFMove(rule));
case StyleRuleType::FontFace:
Expand Down
3 changes: 1 addition & 2 deletions Source/WebCore/css/CSSGradientValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@
#include "CSSPropertyParserConsumer+UnevaluatedCalc.h"
#include "ColorInterpolationMethod.h"
#include "Gradient.h"
#include "StyleImage.h"

namespace WebCore {

class StyleImage;

namespace Style {
class BuilderState;
}
Expand Down
15 changes: 9 additions & 6 deletions Source/WebCore/css/CSSGroupingRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "CSSGroupingRule.h"

#include "CSSParser.h"
#include "CSSParserImpl.h"
#include "CSSRuleList.h"
#include "CSSStyleSheet.h"
#include "StylePropertiesInlines.h"
Expand Down Expand Up @@ -69,13 +70,16 @@ ExceptionOr<unsigned> CSSGroupingRule::insertRule(const String& ruleString, unsi
auto isNestedContext = hasStyleRuleAncestor() ? CSSParserEnum::IsNestedContext::Yes : CSSParserEnum::IsNestedContext::No;
RefPtr<StyleRuleBase> newRule = CSSParser::parseRule(parserContext(), styleSheet ? &styleSheet->contents() : nullptr, ruleString, isNestedContext);
if (!newRule) {
// SyntaxError: Raised if the specified rule has a syntax error and is unparsable.
return Exception { ExceptionCode::SyntaxError };
if (!hasStyleRuleAncestor())
return Exception { ExceptionCode::SyntaxError };
newRule = CSSParserImpl::parseNestedDeclarations(parserContext(), ruleString);
if (!newRule)
return Exception { ExceptionCode::SyntaxError };
}

if (newRule->isImportRule() || newRule->isNamespaceRule()) {
// FIXME: an HierarchyRequestError should also be thrown for a @charset or a nested
// @media rule. They are currently not getting parsed, resulting in a SyntaxError
// FIXME: an HierarchyRequestError should also be thrown for a @charset.
// They are currently not getting parsed, resulting in a SyntaxError
// to get raised above.

// HierarchyRequestError: Raised if the rule cannot be inserted at the specified
Expand All @@ -84,8 +88,7 @@ ExceptionOr<unsigned> CSSGroupingRule::insertRule(const String& ruleString, unsi
return Exception { ExceptionCode::HierarchyRequestError };
}

// Nesting inside style rule only accepts style rule or group rule
if (hasStyleRuleAncestor() && !newRule->isStyleRule() && !newRule->isGroupRule())
if (hasStyleRuleAncestor() && !newRule->isStyleRule() && !newRule->isGroupRule() && !newRule->isNestedDeclarationsRule())
return Exception { ExceptionCode::HierarchyRequestError };

CSSStyleSheet::RuleMutationScope mutationScope(this);
Expand Down
Loading

0 comments on commit f0fd3ce

Please sign in to comment.