From 7fbc5086d699155b781bb65e98769bfc31beffa0 Mon Sep 17 00:00:00 2001 From: zhaowenkai <799480165@qq.com> Date: Wed, 29 May 2024 09:18:51 +0800 Subject: [PATCH 1/2] support cascade @layer --- src/Compiler/Enum.cs | 2 +- src/Compiler/Parser.cs | 4 +- src/Compiler/Serializer.cs | 1 + test/CssInCSharp.Tests/ParserTests.cs | 65 +++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Enum.cs b/src/Compiler/Enum.cs index 61cc3d8..ca9acbf 100644 --- a/src/Compiler/Enum.cs +++ b/src/Compiler/Enum.cs @@ -20,6 +20,6 @@ internal static class Enum public const string FONT_FACE = "@font-face"; public const string COUNTER_STYLE = "@counter-style"; public const string FONT_FEATURE_VALUES = "@font-feature-values"; - + public const string LAYER = "@layer"; } } diff --git a/src/Compiler/Parser.cs b/src/Compiler/Parser.cs index 96db851..8416673 100644 --- a/src/Compiler/Parser.cs +++ b/src/Compiler/Parser.cs @@ -95,8 +95,8 @@ public static List Parse(Tokenizer tokenizer, string value, Element roo else switch (atrule == 99 && CharAt(characters, 3) == 110 ? 100 : atrule) { - // d m s - case 100 or 109 or 115: + // d l m s + case 100 or 108 or 109 or 115: var p = new List(); if (rule != null) { diff --git a/src/Compiler/Serializer.cs b/src/Compiler/Serializer.cs index 4a30f63..1610d5a 100644 --- a/src/Compiler/Serializer.cs +++ b/src/Compiler/Serializer.cs @@ -25,6 +25,7 @@ public static string Stringify(Element element, SerializeCallback callback) { switch (element.Type) { + case LAYER: if(element.Children.Count != 0) break; goto case IMPORT; case IMPORT: case DECLARATION: return element.Return = !string.IsNullOrEmpty(element.Return) ? element.Return : element.Value; case COMMENT: return ""; case KEYFRAMES: return element.Return = element.Value + "{" + Serialize(element.Children, callback) + "}"; diff --git a/test/CssInCSharp.Tests/ParserTests.cs b/test/CssInCSharp.Tests/ParserTests.cs index f1e1b82..17e5e5f 100644 --- a/test/CssInCSharp.Tests/ParserTests.cs +++ b/test/CssInCSharp.Tests/ParserTests.cs @@ -1000,5 +1000,70 @@ public void Nested() ".user.foo.bar{color:orange;}", ".user.foo.bar.barbar{color:orange;}")); } + + [Fact] + public void Cascade_Layer() + { + stylis(@" + @layer base { + border-left:1px solid hotpink; + } + ").ShouldBe("@layer base{.user{border-left:1px solid hotpink;}}"); + + stylis(@" + @layer base { + @layer layout { + border-left:1px solid hotpink; + } + } + ").ShouldBe("@layer base{@layer layout{.user{border-left:1px solid hotpink;}}}"); + + stylis(@" + @layer framework.layout { + border-left:1px solid hotpink; + } + ").ShouldBe("@layer framework.layout{.user{border-left:1px solid hotpink;}}"); + + stylis(@" + @import ""theme.css"" layer(utilties); + ").ShouldBe("@import \"theme.css\" layer(utilties);"); + + stylis(@" + @import ""foo""; + ").ShouldBe("@import \"foo\";"); + + stylis(@" + @layer utilities; + ").ShouldBe("@layer utilities;"); + + stylis(@" + @layer theme, layout, utilities; + ").ShouldBe("@layer theme,layout,utilities;"); + + stylis(@" + @media (min-width: 30em) { + @layer layout { + .title { font-size: x-large; } + } + } + + @layer theme { + @media (prefers-color-scheme: dark) { + .title { color: white; } + } + } + ").ShouldBe(string.Join("", + "@media (min-width: 30em){@layer layout{.user .title{font-size:x-large;}}}", + "@layer theme{@media (prefers-color-scheme: dark){.user .title{color:white;}}}")); + + stylis(@" + @layer framework { + @keyframes slide-left { + from { margin-left: 0; } + to { margin-left: -100%; } + } + } + ").ShouldBe("@layer framework{@keyframes slide-left{from{margin-left:0;}to{margin-left:-100%;}}}"); + } } } \ No newline at end of file From 0cd2484e1f00a90d73fc7fbb238048e7bb5e3270 Mon Sep 17 00:00:00 2001 From: zhaowenkai <799480165@qq.com> Date: Wed, 29 May 2024 09:36:19 +0800 Subject: [PATCH 2/2] Fixed `&` search after consuming parenthesis --- src/Compiler/Parser.cs | 2 +- src/Compiler/Utility.cs | 4 ++-- test/CssInCSharp.Tests/ParserTests.cs | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Parser.cs b/src/Compiler/Parser.cs index 8416673..0c732df 100644 --- a/src/Compiler/Parser.cs +++ b/src/Compiler/Parser.cs @@ -42,7 +42,7 @@ public static List Parse(Tokenizer tokenizer, string value, Element roo case 40: if (previous != 108 && CharAt(characters, length - 1) == 58) { - if (IndexOf(characters += Replace(tokenizer.Delimit(character), "&", "&\f"), "&\f") != -1) + if (IndexOf(characters += Replace(tokenizer.Delimit(character), "&", "&\f"), "&\f", Abs(index != 0 ? points[index - 1] : 0)) != -1) ampersand = -1; break; } diff --git a/src/Compiler/Utility.cs b/src/Compiler/Utility.cs index 4a69f69..17c8db0 100644 --- a/src/Compiler/Utility.cs +++ b/src/Compiler/Utility.cs @@ -11,9 +11,9 @@ public static int CharAt(string value, int index) return (int) value[index]; } - public static int IndexOf(string value, string search) + public static int IndexOf(string value, string search, int position) { - return value.IndexOf(search); + return value.IndexOf(search, position); } public static string Replace(string value, string pattern, string replacement, bool all = false) diff --git a/test/CssInCSharp.Tests/ParserTests.cs b/test/CssInCSharp.Tests/ParserTests.cs index 17e5e5f..1f82d98 100644 --- a/test/CssInCSharp.Tests/ParserTests.cs +++ b/test/CssInCSharp.Tests/ParserTests.cs @@ -142,6 +142,21 @@ public void Ampersand_In_String() ).ShouldBe(".user [href=\"https://css-tricks.com?a=1&b=2\"]{color:red;}"); } + [Fact] + public void Ampersand_In_First_Selector_Within_A_CommaSeparated_List() + { + stylis(@" + div { + display: flex; + + &.foo, + p:not(:last-child) { + background: red; + } + } + ").ShouldBe(".user div{display:flex;}.user div.foo,.user div p:not(:last-child){background:red;}"); + } + [Fact] public void Escaped_Chars_In_Selector_Identifiers() { @@ -769,6 +784,10 @@ public void Context_Character() .ShouldBe(string.Join("", ".user{background:url[img}.png];}", ".user .a{background:url[img}.png];}")); + stylis("background: url(i&m&g.png);.a {background: url(i&m&g.png);}") + .ShouldBe(string.Join("", + ".user{background:url(i&m&g.png);}", + ".user .a{background:url(i&m&g.png);}")); } [Fact]