Skip to content

Commit 964aea2

Browse files
committed
Added Support for @container rules and comparison operators defined in media queries level 4
1 parent d0a5763 commit 964aea2

28 files changed

+403
-29
lines changed

src/ExCSS.Tests/Container.cs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
namespace ExCSS.Tests
2+
{
3+
using ExCSS;
4+
using Xunit;
5+
using System.Linq;
6+
7+
public class CssContainerTests : CssConstructionFunctions
8+
{
9+
[Fact]
10+
public void SimpleContainer()
11+
{
12+
const string source = "@container tall (min-width: 500px) and (min-height: 300px) {h2 { line-height: 1.6; } }";
13+
var result = ParseStyleSheet(source);
14+
Assert.Equal(source, result.StylesheetText.Text);
15+
var rule = result.Rules[0] as ContainerRule;
16+
Assert.NotNull(rule);
17+
Assert.Equal("@container tall (min-width: 500px) and (min-height: 300px) { h2 { line-height: 1.6 } }", rule.Text);
18+
Assert.Equal("tall", rule.Name);
19+
Assert.Equal("(min-width: 500px) and (min-height: 300px)", rule.ConditionText);
20+
var childRule = rule.Children.OfType<StyleRule>().First();
21+
Assert.Equal("h2 { line-height: 1.6 }", childRule.ToCss());
22+
}
23+
24+
[Fact]
25+
public void ContainerWithoutName()
26+
{
27+
const string source = "@container (min-width: 500px) and (min-height: 300px) {h2 { line-height: 1.6; } }";
28+
var result = ParseStyleSheet(source);
29+
Assert.Equal(source, result.StylesheetText.Text);
30+
var rule = result.Rules[0] as ContainerRule;
31+
Assert.NotNull(rule);
32+
Assert.Equal("@container (min-width: 500px) and (min-height: 300px) { h2 { line-height: 1.6 } }", rule.Text);
33+
Assert.Equal(string.Empty, rule.Name);
34+
Assert.Equal("(min-width: 500px) and (min-height: 300px)", rule.ConditionText);
35+
var childRule = rule.Children.OfType<StyleRule>().First();
36+
Assert.Equal("h2 { line-height: 1.6 }", childRule.ToCss());
37+
}
38+
39+
[Fact]
40+
public void ContainerWithoutCondition()
41+
{
42+
const string source = "@container tall {h2 { line-height: 1.6; } }";
43+
var result = ParseStyleSheet(source);
44+
Assert.Equal(source, result.StylesheetText.Text);
45+
var rule = result.Rules[0] as ContainerRule;
46+
Assert.NotNull(rule);
47+
Assert.Equal("@container tall { h2 { line-height: 1.6 } }", rule.Text);
48+
Assert.Equal("tall", rule.Name);
49+
Assert.Equal(string.Empty, rule.ConditionText);
50+
var childRule = rule.Children.OfType<StyleRule>().First();
51+
Assert.Equal("h2 { line-height: 1.6 }", childRule.ToCss());
52+
}
53+
54+
[Fact]
55+
public void ContainerWithComparisonOperators()
56+
{
57+
const string source = "@container tall (width < 500px) and (height >= 300px) {h2 { line-height: 1.6; } }";
58+
var result = ParseStyleSheet(source);
59+
Assert.Equal(source, result.StylesheetText.Text);
60+
var rule = result.Rules[0] as ContainerRule;
61+
Assert.NotNull(rule);
62+
Assert.Equal("@container tall (width < 500px) and (height >= 300px) { h2 { line-height: 1.6 } }", rule.Text);
63+
Assert.Equal("tall", rule.Name);
64+
Assert.Equal("(width < 500px) and (height >= 300px)", rule.ConditionText);
65+
var childRule = rule.Children.OfType<StyleRule>().First();
66+
Assert.Equal("h2 { line-height: 1.6 }", childRule.ToCss());
67+
}
68+
69+
[Fact]
70+
public void CSSWithTwoContainers()
71+
{
72+
const string source = @"li {
73+
container-type: inline-size;
74+
}
75+
76+
@container (min-width: 45ch) {
77+
li span {
78+
color: rgb(255, 0, 0);
79+
font-size: 2rem !important;
80+
}
81+
}
82+
83+
@container (min-width: 70ch) {
84+
li span {
85+
color: rgb(0, 0, 255);
86+
font-size: 3rem !important;
87+
}
88+
}";
89+
var result = ParseStyleSheet(source);
90+
Assert.Equal(source, result.StylesheetText.Text);
91+
Assert.Equal(3, result.Rules.Length);
92+
var rule1 = result.Rules[0] as StyleRule;
93+
var rule2 = result.Rules[1] as ContainerRule;
94+
var rule3 = result.Rules[2] as ContainerRule;
95+
Assert.NotNull(rule1);
96+
Assert.NotNull(rule2);
97+
Assert.NotNull(rule3);
98+
Assert.Equal("li { container-type: inline-size }", rule1.ToCss());
99+
Assert.Equal("@container (min-width: 45ch) { li span { color: rgb(255, 0, 0); font-size: 2rem !important } }", rule2.ToCss());
100+
Assert.Equal("@container (min-width: 70ch) { li span { color: rgb(0, 0, 255); font-size: 3rem !important } }", rule3.ToCss());
101+
}
102+
}
103+
}

src/ExCSS.Tests/MediaList.cs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using ExCSS;
44
using Xunit;
55
using System;
6-
6+
77
public class CssMediaListTests : CssConstructionFunctions
88
{
99
[Fact]
@@ -375,21 +375,48 @@ public void ImplicitAllFeatureMinResolutionAndMaxResolutionMediaList()
375375
[Fact]
376376
public void CssMediaListApiWithAppendDeleteAndTextShouldWork()
377377
{
378-
var media = new [] { "handheld", "screen", "only screen and (max-device-width: 480px)" };
378+
var media = new[] { "handheld", "screen", "only screen and (max-device-width: 480px)" };
379379
var p = new StylesheetParser();
380-
var m = new MediaList(p);
380+
var m = new MediaList(p);
381381
Assert.Equal(0, m.Length);
382382

383-
m.Add(media[0]);
384-
m.Add(media[1]);
385-
m.Add(media[2]);
383+
m.Add(media[0]);
384+
m.Add(media[1]);
385+
m.Add(media[2]);
386386

387-
m.Remove(media[1]);
387+
m.Remove(media[1]);
388388

389389
Assert.Equal(2, m.Length);
390390
Assert.Equal(media[0], m[0]);
391391
Assert.Equal(media[2], m[1]);
392392
Assert.Equal(String.Concat(media[0], ", ", media[2]), m.MediaText);
393393
}
394+
395+
[Fact]
396+
public void CombinedConditionMediaQueriesLevel4()
397+
{
398+
const string source = @"/* Traditionelle Syntax */
399+
@media (min-height: 500px) and (max-height: 800px) {
400+
/* Styles */
401+
h1 { color: rgb(255, 0, 0); }
402+
}
403+
404+
/* Mit Vergleichsoperatoren */
405+
@media (height >= 500px) and (height <= 800px) {
406+
/* Gleiche Styles */
407+
h1 { color: rgb(255, 0, 0); }
408+
}";
409+
var result = ParseStyleSheet(source);
410+
Assert.Equal(source, result.StylesheetText.Text);
411+
Assert.Equal(2, result.Rules.Length);
412+
var rule1 = result.Rules[0] as MediaRule;
413+
var rule2 = result.Rules[1] as MediaRule;
414+
Assert.NotNull(rule1);
415+
Assert.NotNull(rule2);
416+
Assert.Equal("(min-height: 500px) and (max-height: 800px)", rule1.ConditionText);
417+
Assert.Equal("(height >= 500px) and (height <= 800px)", rule2.ConditionText);
418+
Assert.Equal("@media (min-height: 500px) and (max-height: 800px) { h1 { color: rgb(255, 0, 0) } }", rule1.ToCss());
419+
Assert.Equal("@media (height >= 500px) and (height <= 800px) { h1 { color: rgb(255, 0, 0) } }", rule2.ToCss());
420+
}
394421
}
395422
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace ExCSS
2+
{
3+
public enum ContainerType : byte
4+
{
5+
Normal,
6+
Size,
7+
InlineSize
8+
}
9+
}

src/ExCSS/Enumerations/FeatureNames.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,7 @@ public static class FeatureNames
4242
public static readonly string Scripting = "scripting";
4343
public static readonly string Pointer = "pointer";
4444
public static readonly string Hover = "hover";
45+
public static readonly string BlockSize = "block-size";
46+
public static readonly string InlineSize = "inline-size";
4547
}
4648
}

src/ExCSS/Enumerations/Keywords.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,5 +310,7 @@ internal static class Keywords
310310
public static readonly string Last = "last";
311311
public static readonly string SelfStart = "self-start";
312312
public static readonly string SelfEnd = "self-end";
313+
public static readonly string Size = "size";
314+
public static readonly string InlineSize = "inline-size";
313315
}
314316
}

src/ExCSS/Enumerations/PropertyNames.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ public static class PropertyNames
9191
public static readonly string ClipRule = "clip-rule";
9292
public static readonly string Color = "color";
9393
public static readonly string ColorInterpolationFilters = "color-interpolation-filters";
94+
public static readonly string ContainerName= "container-name";
95+
public static readonly string ContainerType = "container-type";
9496
public static readonly string Content = "content";
9597
public static readonly string CounterIncrement = "counter-increment";
9698
public static readonly string CounterReset = "counter-reset";

src/ExCSS/Enumerations/RuleNames.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ public static class RuleNames
1212
public static readonly string Media = "media";
1313
public static readonly string Namespace = "namespace";
1414
public static readonly string Page = "page";
15+
public static readonly string Container = "container";
1516
}
1617
}

src/ExCSS/Enumerations/RuleType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public enum RuleType : byte
1818
Document,
1919
FontFeatureValues,
2020
Viewport,
21-
RegionStyle
21+
RegionStyle,
22+
Container
2223
}
2324
}

src/ExCSS/Enumerations/TokenType.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ internal enum TokenType : byte
2929
Comma,
3030
Semicolon,
3131
Whitespace,
32-
EndOfFile
32+
EndOfFile,
33+
GreaterThan,
34+
GreaterThanOrEqual,
35+
LessThan,
36+
LessThanOrEqual,
37+
Equal
3338
}
3439
}

src/ExCSS/Factories/MediaFeatureFactory.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ internal sealed class MediaFeatureFactory
6060
{FeatureNames.UpdateFrequency, () => new UpdateFrequencyMediaFeature()},
6161
{FeatureNames.Scripting, () => new ScriptingMediaFeature()},
6262
{FeatureNames.Pointer, () => new PointerMediaFeature()},
63-
{FeatureNames.Hover, () => new HoverMediaFeature()}
63+
{FeatureNames.Hover, () => new HoverMediaFeature()},
64+
{FeatureNames.InlineSize, () => new SizeMediaFeature(FeatureNames.InlineSize)},
65+
{FeatureNames.BlockSize, () => new SizeMediaFeature(FeatureNames.BlockSize)},
6466
};
6567

6668
#endregion

0 commit comments

Comments
 (0)