Skip to content

Commit 6d52e79

Browse files
committed
Updated media parsing #133
1 parent 78740fe commit 6d52e79

19 files changed

+369
-167
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Released on tbd.
44

55
- Updated to use AngleSharp 1.0
6+
- Updated media parsing to media L4 spec (#133)
67
- Fixed issue when updating shorthands with invalid values (#129)
78
- Fixed issue with appended EOF character in `CssText` (#123)
89
- Fixed missing semicolon in `@page` rule (#135)

src/AngleSharp.Css.Tests/CssConstructionFunctions.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ namespace AngleSharp.Css.Tests
22
{
33
using AngleSharp.Css.Dom;
44
using AngleSharp.Css.Parser;
5+
using AngleSharp.Css.Values;
56
using AngleSharp.Html.Dom;
67
using AngleSharp.Html.Parser;
78
using System;
@@ -70,7 +71,6 @@ internal static CssProperty ParseDeclaration(String source, CssParserOptions opt
7071
internal static CssStyleDeclaration ParseDeclarations(String declarations)
7172
{
7273
var context = BrowsingContext.New(Configuration.Default.WithCss());
73-
var parser = context.GetService<ICssParser>();
7474
var style = new CssStyleDeclaration(context);
7575
style.Update(declarations);
7676
return style;
@@ -93,7 +93,7 @@ internal static CssImportRule ParseImportRule(String source)
9393
internal static Predicate<IRenderDevice> CreateValidator(String name, String value)
9494
{
9595
var validator = CreateMediaFeatureValidator(name);
96-
var feature = new MediaFeature(name, value);
96+
var feature = new MediaFeature(name, new CssAnyValue(value));
9797
return device => validator.Validate(feature, device);
9898
}
9999

src/AngleSharp.Css.Tests/Rules/CssMediaList.cs

+18-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public void FeatureMinWidthMediaList()
132132
}
133133

134134
[Test]
135-
public void OnlyFeatureWidthMediaList()
135+
public void OnlyFeatureWidthMediaListInvalid()
136136
{
137137
var source = @"@media only (width: 640px) {
138138
h1 { color: green }
@@ -141,7 +141,23 @@ public void OnlyFeatureWidthMediaList()
141141
Assert.AreEqual(1, sheet.Rules.Length);
142142
Assert.IsInstanceOf<CssMediaRule>(sheet.Rules[0]);
143143
var media = (CssMediaRule)sheet.Rules[0];
144-
Assert.AreEqual("only (width: 640px)", media.Media.MediaText);
144+
Assert.AreEqual("not all", media.Media.MediaText);
145+
var list = media.Media;
146+
Assert.AreEqual(1, list.Length);
147+
Assert.AreEqual(1, media.Rules.Length);
148+
}
149+
150+
[Test]
151+
public void OnlyFeatureWidthScreenAndMediaList()
152+
{
153+
var source = @"@media only screen and (width: 640px) {
154+
h1 { color: green }
155+
}";
156+
var sheet = ParseStyleSheet(source);
157+
Assert.AreEqual(1, sheet.Rules.Length);
158+
Assert.IsInstanceOf<CssMediaRule>(sheet.Rules[0]);
159+
var media = (CssMediaRule)sheet.Rules[0];
160+
Assert.AreEqual("only screen and (width: 640px)", media.Media.MediaText);
145161
var list = media.Media;
146162
Assert.AreEqual(1, list.Length);
147163
Assert.AreEqual(1, media.Rules.Length);

src/AngleSharp.Css/Dom/Internal/MediaFeature.cs

+26-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
namespace AngleSharp.Css.Dom
1+
namespace AngleSharp.Css.Dom
22
{
3+
using AngleSharp.Css.Values;
34
using AngleSharp.Text;
45
using System;
56
using System.IO;
@@ -13,8 +14,9 @@ sealed class MediaFeature : IMediaFeature
1314

1415
private readonly Boolean _min;
1516
private readonly Boolean _max;
16-
private readonly String _name;
17+
private readonly ICssValue _name;
1718
private readonly ICssValue _value;
19+
private readonly String _op;
1820

1921
#endregion
2022

@@ -26,17 +28,28 @@ internal MediaFeature(String name)
2628

2729
internal MediaFeature(String name, ICssValue value)
2830
{
29-
_name = name;
31+
_name = new CssAnyValue(name);
3032
_value = value;
3133
_min = name.StartsWith("min-");
3234
_max = name.StartsWith("max-");
3335
}
3436

37+
internal MediaFeature(String name, ICssValue value, String op)
38+
: this(new CssAnyValue(name), value, op)
39+
{}
40+
41+
internal MediaFeature(ICssValue name, ICssValue value, String op)
42+
{
43+
_name = name;
44+
_value = value;
45+
_op = op;
46+
}
47+
3548
#endregion
3649

3750
#region Properties
3851

39-
public String Name => _name;
52+
public String Name => _name?.CssText ?? String.Empty;
4053

4154
public Boolean IsMinimum => _min;
4255

@@ -53,9 +66,16 @@ internal MediaFeature(String name, ICssValue value)
5366
public void ToCss(TextWriter writer, IStyleFormatter formatter)
5467
{
5568
writer.Write(Symbols.RoundBracketOpen);
56-
writer.Write(_name);
69+
writer.Write(Name);
5770

58-
if (_value != null)
71+
if (_op is not null)
72+
{
73+
writer.Write(" ");
74+
writer.Write(_op);
75+
writer.Write(" ");
76+
writer.Write(Value);
77+
}
78+
else if (_value is not null)
5979
{
6080
writer.Write(": ");
6181
writer.Write(Value);

src/AngleSharp.Css/Extensions/CssValueExtensions.cs

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ public static Double AsDouble(this ICssValue value)
2424
{
2525
return fr.Value;
2626
}
27+
else if (value is Ratio ratio)
28+
{
29+
return ratio.Value;
30+
}
2731
else if (value is ICssMultipleValue multiple && multiple.Count == 1)
2832
{
2933
return multiple[0].AsDouble();

src/AngleSharp.Css/FeatureValidators/AspectRatioFeatureValidator.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public Boolean Validate(IMediaFeature feature, IRenderDevice renderDevice)
1111
{
1212
var ratio = RatioConverter.Convert(feature.Value);
1313

14-
if (ratio != null)
14+
if (ratio is not null)
1515
{
1616
var desired = ratio.AsDouble();
1717
var available = renderDevice.ViewPortWidth / (Double)renderDevice.ViewPortHeight;

src/AngleSharp.Css/FeatureValidators/DeviceAspectRatioFeatureValidator.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public Boolean Validate(IMediaFeature feature, IRenderDevice renderDevice)
1111
{
1212
var ratio = RatioConverter.Convert(feature.Value);
1313

14-
if (ratio != null)
14+
if (ratio is not null)
1515
{
1616
var desired = ratio.AsDouble();
1717
var available = renderDevice.DeviceWidth / (Double)renderDevice.DeviceHeight;

src/AngleSharp.Css/Parser/Micro/CalcParser.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,11 @@ private static ICssValue ParseBracketExpression(this StringSource source)
141141

142142
return source.ParseAtomicExpression();
143143
}
144-
145-
private static ICssValue ParseAtomicExpression(this StringSource source)
144+
145+
/// <summary>
146+
/// Parses a unit value into a ICssValue.
147+
/// </summary>
148+
public static ICssValue ParseAtomicExpression(this StringSource source)
146149
{
147150
var unit = source.ParseUnit();
148151

src/AngleSharp.Css/Parser/Micro/IdentParser.cs

+15
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ public static String ParseIdent(this StringSource source)
4848
return Start(source, current, buffer);
4949
}
5050

51+
/// <summary>
52+
/// Parses a CSS identifier value.
53+
/// </summary>
54+
public static ICssValue ParseIdentAsValue(this StringSource source)
55+
{
56+
var value = source.ParseIdent();
57+
58+
if (value is not null)
59+
{
60+
return new Identifier(value);
61+
}
62+
63+
return null;
64+
}
65+
5166
/// <summary>
5267
/// Parses a CSS constant value from a given dictionary.
5368
/// </summary>

src/AngleSharp.Css/Parser/Micro/MediaParser.cs

+16-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ namespace AngleSharp.Css.Parser
44
using AngleSharp.Text;
55
using System;
66
using System.Collections.Generic;
7+
using System.Diagnostics.Tracing;
8+
using System.Linq;
79

810
/// <summary>
911
/// Represents extensions to for media values.
@@ -31,7 +33,20 @@ public static IEnumerable<CssMedium> ParseMedia(this StringSource source, IFeatu
3133
{
3234
if (current != Symbols.Comma)
3335
{
34-
return null;
36+
media[media.Count - 1] = null;
37+
38+
while (!source.IsDone && current != Symbols.Comma)
39+
{
40+
if (current == Symbols.RoundBracketOpen)
41+
{
42+
source.Next();
43+
source.TakeUntilClosed();
44+
}
45+
46+
current = source.Next();
47+
}
48+
49+
continue;
3550
}
3651

3752
source.SkipCurrentAndSpaces();

0 commit comments

Comments
 (0)