This commit is contained in:
Florian Rappl 2024-01-19 00:53:22 +01:00
Родитель 64df5cfe94
Коммит e8dab2666e
93 изменённых файлов: 1547 добавлений и 560 удалений

Просмотреть файл

@ -4,6 +4,7 @@ Released on tbd.
- Updated to use AngleSharp 1.0 (#150)
- Updated media parsing to media L4 spec (#133)
- Updated naming of CSS values (e.g., `Color` to `CssColorValue`)
- Fixed issue when updating shorthands with invalid values (#129)
- Fixed issue with appended EOF character in `CssText` (#123)
- Fixed missing semicolon in `@page` rule (#135)
@ -15,6 +16,7 @@ Released on tbd.
- Fixed `GetInnerText` multi-line / text node behavior (#155) @Seyden
- Fixed computation of relative (`em`) values to absolute (`px`) for `Length` (#136)
- Added further compactification of CSS tuples (#89, #93)
- Added new value types `CssPercentageValue`, `CssNumberValue`, and `CssIntegerValue`
- Added support for CSS nesting in style rules (#148)
- Added resolution of CSS variable names (#62)
- Added support for 8-digit hex color codes (#132)

Просмотреть файл

@ -17,6 +17,7 @@ AngleSharp.Css contains code written by (in order of first pull request / commit
* [Fraaankes](https://github.com/Fraaankes)
* [Eric Mutta](https://github.com/ericmutta)
* [Seyden](https://github.com/Seyden)
* [Dave Dunkin](https://github.com/ddunkin)
Without these awesome people AngleSharp.Css could not exist. Thanks to everyone for your contributions! :beers:

Просмотреть файл

@ -41,10 +41,10 @@ namespace AngleSharp.Css.Tests.Values
var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsNotNull(gradient);
Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.TripleHalfQuarter, gradient.Angle);
Assert.AreEqual(CssAngleValue.TripleHalfQuarter, gradient.Angle);
Assert.AreEqual(2, gradient.Stops.Length);
Assert.AreEqual(red, gradient.Stops.First().Color);
Assert.AreEqual(blue, gradient.Stops.Last().Color);
Assert.AreEqual(red, gradient.Stops.OfType<CssGradientStopValue>().First().Color);
Assert.AreEqual(blue, gradient.Stops.OfType<CssGradientStopValue>().Last().Color);
Assert.AreEqual(source, property.CssText);
}
@ -61,16 +61,16 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(1, value.Items.Length);
var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.Quarter, gradient.Angle);
Assert.AreEqual(CssAngleValue.Quarter, gradient.Angle);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(7, stops.Length);
Assert.AreEqual(CssColors.GetColor("red").Value, stops[0].Color);
Assert.AreEqual(CssColors.GetColor("orange").Value, stops[1].Color);
Assert.AreEqual(CssColors.GetColor("yellow").Value, stops[2].Color);
Assert.AreEqual(CssColors.GetColor("green").Value, stops[3].Color);
Assert.AreEqual(CssColors.GetColor("blue").Value, stops[4].Color);
Assert.AreEqual(CssColors.GetColor("indigo").Value, stops[5].Color);
Assert.AreEqual(CssColors.GetColor("violet").Value, stops[6].Color);
Assert.AreEqual(CssColors.GetColor("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColors.GetColor("orange").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColors.GetColor("yellow").Value, ((CssGradientStopValue)stops[2]).Color);
Assert.AreEqual(CssColors.GetColor("green").Value, ((CssGradientStopValue)stops[3]).Color);
Assert.AreEqual(CssColors.GetColor("blue").Value, ((CssGradientStopValue)stops[4]).Color);
Assert.AreEqual(CssColors.GetColor("indigo").Value, ((CssGradientStopValue)stops[5]).Color);
Assert.AreEqual(CssColors.GetColor("violet").Value, ((CssGradientStopValue)stops[6]).Color);
}
[Test]
@ -85,10 +85,10 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(1, value.Items.Length);
var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.TripleHalfQuarter, gradient.Angle);
Assert.AreEqual(CssAngleValue.TripleHalfQuarter, gradient.Angle);
Assert.AreEqual(2, gradient.Stops.Count());
Assert.AreEqual(CssColorValue.Red, gradient.Stops.First().Color);
Assert.AreEqual(CssColorValue.FromRgba(255, 0, 0, 0), gradient.Stops.Last().Color);
Assert.AreEqual(CssColorValue.Red, gradient.Stops.OfType<CssGradientStopValue>().First().Color);
Assert.AreEqual(CssColorValue.FromRgba(255, 0, 0, 0), gradient.Stops.OfType<CssGradientStopValue>().Last().Color);
}
[Test]
@ -103,10 +103,10 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(1, value.Items.Length);
var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.Half, gradient.Angle);
Assert.AreEqual(CssAngleValue.Half, gradient.Angle);
Assert.AreEqual(2, gradient.Stops.Count());
Assert.AreEqual(CssColorValue.FromHsl(0f, 0.8f, 0.7f), gradient.Stops.First().Color);
Assert.AreEqual(CssColorValue.FromHex("bada55"), gradient.Stops.Last().Color);
Assert.AreEqual(CssColorValue.FromHsl(0f, 0.8f, 0.7f), gradient.Stops.OfType<CssGradientStopValue>().First().Color);
Assert.AreEqual(CssColorValue.FromHex("bada55"), gradient.Stops.OfType<CssGradientStopValue>().Last().Color);
}
[Test]
@ -121,11 +121,11 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(1, value.Items.Length);
var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.Half, gradient.Angle);
Assert.AreEqual(CssAngleValue.Half, gradient.Angle);
Assert.AreEqual(3, gradient.Stops.Count());
Assert.AreEqual(CssColors.GetColor("yellow").Value, gradient.Stops.First().Color);
Assert.AreEqual(CssColors.GetColor("blue").Value, gradient.Stops.Skip(1).First().Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 255, 0), gradient.Stops.Skip(2).First().Color);
Assert.AreEqual(CssColors.GetColor("yellow").Value, gradient.Stops.OfType<CssGradientStopValue>().First().Color);
Assert.AreEqual(CssColors.GetColor("blue").Value, gradient.Stops.OfType<CssGradientStopValue>().Skip(1).First().Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 255, 0), gradient.Stops.OfType<CssGradientStopValue>().Skip(2).First().Color);
}
[Test]
@ -146,9 +146,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromRgb(0, 255, 255), stops[0].Color);
Assert.AreEqual(CssColorValue.FromRgba(0, 0, 255, 0), stops[1].Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 255), stops[2].Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 255, 255), ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromRgba(0, 0, 255, 0), ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 255), ((CssGradientStopValue)stops[2]).Color);
}
[Test]
@ -169,9 +169,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromRgb(0xFF, 0xFF, 0x80), stops[0].Color);
Assert.AreEqual(CssColorValue.FromRgba(204, 153, 153, 0.4f), stops[1].Color);
Assert.AreEqual(CssColorValue.FromRgb(0xE6, 0xE6, 0xFF), stops[2].Color);
Assert.AreEqual(CssColorValue.FromRgb(0xFF, 0xFF, 0x80), ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromRgba(204, 153, 153, 0.4f), ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromRgb(0xE6, 0xE6, 0xFF), ((CssGradientStopValue)stops[2]).Color);
}
[Test]
@ -192,8 +192,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromRgb(255, 0, 0), stops[0].Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 255), stops[1].Color);
Assert.AreEqual(CssColorValue.FromRgb(255, 0, 0), ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 255), ((CssGradientStopValue)stops[1]).Color);
}
[Test]
@ -216,10 +216,10 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssLengthValue.Full, gradient.MinorRadius);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(4, stops.Length);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 0), stops[0].Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 0), stops[1].Color);
Assert.AreEqual(CssColorValue.FromRgba(0, 0, 0, 0.3), stops[2].Color);
Assert.AreEqual(CssColorValue.Transparent, stops[3].Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 0), ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 0), ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromRgba(0, 0, 0, 0.3), ((CssGradientStopValue)stops[2]).Color);
Assert.AreEqual(CssColorValue.Transparent, ((CssGradientStopValue)stops[3]).Color);
}
[Test]
@ -240,8 +240,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[1]).Color);
}
[Test]
@ -262,8 +262,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[1]).Color);
}
[Test]
@ -284,8 +284,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[1]).Color);
}
[Test]
@ -306,8 +306,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[1]).Color);
}
[Test]
@ -328,9 +328,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.ClosestSide, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
}
[Test]
@ -353,9 +353,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(new CssLengthValue(30f, CssLengthValue.Unit.Px), gradient.MinorRadius);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
}
[Test]
@ -376,9 +376,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.ClosestSide, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
}
[Test]
@ -399,9 +399,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestSide, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
}
[Test]
@ -418,9 +418,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.IsTrue(gradient.IsRepeating);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("blue").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[2].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("blue").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[2]).Color);
}
[Test]
@ -441,9 +441,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("blue").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[2].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("blue").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[2]).Color);
}
[Test]
@ -464,11 +464,11 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.ClosestSide, gradient.Mode);
var stops = gradient.Stops.ToArray();
Assert.AreEqual(5, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[3].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[4].Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[3]).Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[4]).Color);
}
}
}

Просмотреть файл

@ -204,11 +204,11 @@ namespace AngleSharp.Css.Tests.Values
public void AngleParseCorrectDegValue()
{
var s = "1.35e2deg";
var v = default(Angle);
var r = Angle.TryParse(s, out v);
var v = default(CssAngleValue);
var r = CssAngleValue.TryParse(s, out v);
Assert.IsTrue(r);
Assert.AreEqual(135f, v.Value);
Assert.AreEqual(Angle.Unit.Deg, v.Type);
Assert.AreEqual(CssAngleValue.Unit.Deg, v.Type);
}
[Test]
@ -248,8 +248,8 @@ namespace AngleSharp.Css.Tests.Values
public void AngleParseIncorrectValue()
{
var s = "123.deg";
var v = default(Angle);
var r = Angle.TryParse(s, out v);
var v = default(CssAngleValue);
var r = CssAngleValue.TryParse(s, out v);
Assert.IsFalse(r);
}
}

Просмотреть файл

@ -26,16 +26,16 @@ namespace AngleSharp.Css
/// <summary>
/// Contains the string-Angle mapping for linear-gradients.s
/// </summary>
public static readonly Dictionary<String, Angle> GradientAngles = new(StringComparer.OrdinalIgnoreCase)
public static readonly Dictionary<String, CssAngleValue> GradientAngles = new(StringComparer.OrdinalIgnoreCase)
{
{ CssKeywords.Left, new Angle(270.0, Angle.Unit.Deg) },
{ CssKeywords.Top, new Angle(0.0, Angle.Unit.Deg) },
{ CssKeywords.Right, new Angle(90.0, Angle.Unit.Deg) },
{ CssKeywords.Bottom, new Angle(180.0, Angle.Unit.Deg) },
{ CssKeywords.LeftTop, new Angle(315.0, Angle.Unit.Deg) },
{ CssKeywords.LeftBottom, new Angle(225.0, Angle.Unit.Deg) },
{ CssKeywords.RightTop, new Angle(45.0, Angle.Unit.Deg) },
{ CssKeywords.RightBottom, new Angle(135.0, Angle.Unit.Deg) },
{ CssKeywords.Left, new CssAngleValue(270.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.Top, new CssAngleValue(0.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.Right, new CssAngleValue(90.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.Bottom, new CssAngleValue(180.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.LeftTop, new CssAngleValue(315.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.LeftBottom, new CssAngleValue(225.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.RightTop, new CssAngleValue(45.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.RightBottom, new CssAngleValue(135.0, CssAngleValue.Unit.Deg) },
};
/// <summary>

Просмотреть файл

@ -108,9 +108,9 @@ namespace AngleSharp.Css.Declarations
return null;
}
private sealed class ContentValue : ICssValue
private sealed class ContentValue : ICssValue, IEquatable<ContentValue>
{
private ICssValue[] _modes;
private readonly ICssValue[] _modes;
public ContentValue(ICssValue[] modes)
{
@ -124,6 +124,30 @@ namespace AngleSharp.Css.Declarations
var modes = _modes.Select(mode => mode.Compute(context)).ToArray();
return new ContentValue(modes);
}
public Boolean Equals(ContentValue other)
{
var l = _modes.Length;
if (l == other._modes.Length)
{
for (var i = 0; i < l; i++)
{
var a = _modes[i];
var b = other._modes[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is ContentValue value && Equals(value);
}
private abstract class ContentMode : ICssValue
@ -134,10 +158,9 @@ namespace AngleSharp.Css.Declarations
public abstract String GetCssText();
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
}
ICssValue ICssValue.Compute(ICssComputeContext context) => this;
public virtual Boolean Equals(ICssValue other) => Object.ReferenceEquals(this, other);
}
/// <summary>
@ -209,6 +232,16 @@ namespace AngleSharp.Css.Declarations
public override String GetCssText() => _text.CssString();
public override String Stringify(IElement element) => _text;
public override Boolean Equals(ICssValue other)
{
if (other is TextContentMode o)
{
return _text.Equals(o._text);
}
return false;
}
}
/// <summary>
@ -228,6 +261,16 @@ namespace AngleSharp.Css.Declarations
public override String GetCssText() => _counter.CssText;
public override String Stringify(IElement element) => String.Empty;
public override Boolean Equals(ICssValue other)
{
if (other is CounterContentMode o)
{
return _counter.Equals(o._counter);
}
return false;
}
}
/// <summary>
@ -246,6 +289,16 @@ namespace AngleSharp.Css.Declarations
public override String GetCssText() => FunctionNames.Attr.CssFunction(_attribute);
public override String Stringify(IElement element) => element.GetAttribute(_attribute) ?? String.Empty;
public override Boolean Equals(ICssValue other)
{
if (other is AttributeContentMode o)
{
return _attribute.Equals(o._attribute);
}
return false;
}
}
/// <summary>
@ -265,6 +318,16 @@ namespace AngleSharp.Css.Declarations
public override String GetCssText() => _url.CssText;
public override String Stringify(IElement element) => String.Empty;
public override Boolean Equals(ICssValue other)
{
if (other is UrlContentMode o)
{
return _url.Equals(o._url);
}
return false;
}
}
}
}

Просмотреть файл

@ -21,20 +21,19 @@ namespace AngleSharp.Css.Declarations
{
public ICssValue Convert(StringSource source)
{
var cursor = default(ICssValue);
var definitions = new List<ICssValue>();
while (!source.IsDone)
{
var imageSource = source.ParseImageSource();
var c = source.SkipSpacesAndComments();
source.SkipSpacesAndComments();
if (imageSource != null)
{
var x = source.ParseNumber();
c = source.SkipSpacesAndComments();
source.SkipSpacesAndComments();
var y = source.ParseNumber();
c = source.SkipSpacesAndComments();
var c = source.SkipSpacesAndComments();
if (x.HasValue != y.HasValue || c != Symbols.Comma)
break;
@ -44,16 +43,14 @@ namespace AngleSharp.Css.Declarations
if (x.HasValue)
{
var xp = new CssLengthValue(x.Value, CssLengthValue.Unit.None);
var yp = new CssLengthValue(y.Value, CssLengthValue.Unit.None);
position = new CssPoint2D(xp, yp);
position = new CssPoint2D(x, y);
}
definitions.Add(new CssCustomCursorValue(imageSource, position));
}
else
{
cursor = source.ParseConstant(Map.SystemCursors);
var cursor = source.ParseConstant(Map.SystemCursors);
if (cursor != null)
{

Просмотреть файл

@ -1,12 +1,12 @@
namespace AngleSharp.Css.Dom
{
using System;
using AngleSharp.Css.Values;
using System;
/// <summary>
/// Represents a value of a CSS property.
/// </summary>
public interface ICssValue
public interface ICssValue : IEquatable<ICssValue>
{
/// <summary>
/// The text representation of the value.

Просмотреть файл

@ -16,17 +16,41 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns>
public static Double AsDouble(this ICssValue value)
{
if (value is CssLengthValue length && length.Type == CssLengthValue.Unit.None)
if (value is null)
{
return length.Value;
return 0.0;
}
else if (value is CssLengthValue l && l.Type == CssLengthValue.Unit.None)
{
return l.Value;
}
else if (value is CssTimeValue t && t.Type == CssTimeValue.Unit.None)
{
return t.Value;
}
else if (value is CssFrequencyValue f && f.Type == CssFrequencyValue.Unit.None)
{
return f.Value;
}
else if (value is CssNumberValue n)
{
return n.Value;
}
else if (value is CssIntegerValue i)
{
return i.Value;
}
else if (value is CssPercentageValue p)
{
return p.Value;
}
else if (value is CssFractionValue fr)
{
return fr.Value;
}
else if (value is CssRatioValue ratio)
else if (value is CssRatioValue r)
{
return ratio.Value;
return r.Top.AsDouble() / r.Bottom.AsDouble();
}
else if (value is ICssMultipleValue multiple && multiple.Count == 1)
{
@ -49,7 +73,11 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns>
public static Double AsPx(this ICssValue value, IRenderDimensions renderDimensions, RenderMode mode)
{
if (value is CssLengthValue length && length.Type != CssLengthValue.Unit.None)
if (value is null)
{
return 0.0;
}
else if (value is CssLengthValue length && length.Type != CssLengthValue.Unit.None)
{
return length.ToPixel(renderDimensions, mode);
}
@ -72,7 +100,11 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns>
public static Double AsMs(this ICssValue value)
{
if (value is CssTimeValue time && time.Type != CssTimeValue.Unit.None)
if (value is null)
{
return 0.0;
}
else if (value is CssTimeValue time && time.Type != CssTimeValue.Unit.None)
{
return time.ToMilliseconds();
}
@ -95,7 +127,11 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns>
public static Double AsHz(this ICssValue value)
{
if (value is CssFrequencyValue freq && freq.Type != CssFrequencyValue.Unit.None)
if (value is null)
{
return 0.0;
}
else if (value is CssFrequencyValue freq && freq.Type != CssFrequencyValue.Unit.None)
{
return freq.ToHertz();
}
@ -118,9 +154,13 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns>
public static Double AsDeg(this ICssValue value)
{
if (value is Angle angle && angle.Type != Angle.Unit.None)
if (value is null)
{
return angle.Value;
return 0.0;
}
else if (value is CssAngleValue angle && angle.Type != CssAngleValue.Unit.None)
{
return angle.ToDegree();
}
else if (value is ICssMultipleValue multiple && multiple.Count == 1)
{
@ -134,6 +174,33 @@ namespace AngleSharp.Css.Dom
return 0.0;
}
/// <summary>
/// Tries to convert the value to a number of degrees.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>The resulting number.</returns>
public static Double AsRad(this ICssValue value)
{
if (value is null)
{
return 0.0;
}
else if (value is CssAngleValue angle && angle.Type != CssAngleValue.Unit.None)
{
return angle.ToRadian();
}
else if (value is ICssMultipleValue multiple && multiple.Count == 1)
{
return multiple[0].AsRad();
}
else if (value is ICssSpecialValue special && special.Value != null)
{
return special.Value.AsRad();
}
return 0.0;
}
/// <summary>
/// Tries to convert the value to a number of dots per inch.
/// </summary>
@ -141,7 +208,11 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns>
public static Double AsDpi(this ICssValue value)
{
if (value is CssResolutionValue res && res.Type != CssResolutionValue.Unit.None)
if (value is null)
{
return 0.0;
}
else if (value is CssResolutionValue res && res.Type != CssResolutionValue.Unit.None)
{
return res.ToDotsPerPixel();
}

Просмотреть файл

@ -166,10 +166,10 @@ namespace AngleSharp.Css.Parser
source.SkipSpacesAndComments();
return new CssTimeValue(result, CssTimeValue.GetUnit(unit.Dimension));
}
else if (Angle.GetUnit(unit.Dimension) != Angle.Unit.None)
else if (CssAngleValue.GetUnit(unit.Dimension) != CssAngleValue.Unit.None)
{
source.SkipSpacesAndComments();
return new Angle(result, Angle.GetUnit(unit.Dimension));
return new CssAngleValue(result, CssAngleValue.GetUnit(unit.Dimension));
}
else if (CssFrequencyValue.GetUnit(unit.Dimension) != CssFrequencyValue.Unit.None)
{

Просмотреть файл

@ -478,11 +478,11 @@ namespace AngleSharp.Css.Parser
if (unit != null &&
Double.TryParse(unit.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var value))
{
var dim = Angle.Unit.Deg;
var dim = CssAngleValue.Unit.Deg;
if (unit.Dimension == String.Empty || (dim = Angle.GetUnit(unit.Dimension)) != Angle.Unit.None)
if (unit.Dimension == String.Empty || (dim = CssAngleValue.GetUnit(unit.Dimension)) != CssAngleValue.Unit.None)
{
var angle = new Angle(value, dim);
var angle = new CssAngleValue(value, dim);
return angle.ToTurns();
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace AngleSharp.Css.Parser
/// <summary>
/// Parses the number (double) value.
/// </summary>
public static Double? ParseNumber(this StringSource source)
public static CssNumberValue? ParseNumber(this StringSource source)
{
var unit = source.ParseUnit();
@ -22,7 +22,7 @@ namespace AngleSharp.Css.Parser
unit.Dimension == String.Empty &&
Double.TryParse(unit.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
return result;
return new CssNumberValue(result);
}
return null;
@ -50,12 +50,12 @@ namespace AngleSharp.Css.Parser
/// <summary>
/// Parses the integer (double) value.
/// </summary>
public static Double? ParseNaturalNumber(this StringSource source)
public static CssNumberValue? ParseNaturalNumber(this StringSource source)
{
var pos = source.Index;
var element = source.ParseNumber();
if (element.HasValue && element.Value >= 0f)
if (element.HasValue && element.Value.Value >= 0f)
{
return element;
}
@ -67,12 +67,12 @@ namespace AngleSharp.Css.Parser
/// <summary>
/// Parses the natural number (double) value.
/// </summary>
public static Double? ParseGreaterOrEqualOneNumber(this StringSource source)
public static CssNumberValue? ParseGreaterOrEqualOneNumber(this StringSource source)
{
var pos = source.Index;
var element = source.ParseNumber();
if (element.HasValue && element.Value >= 1f)
if (element.HasValue && element.Value.Value >= 1f)
{
return element;
}

Просмотреть файл

@ -69,7 +69,7 @@ namespace AngleSharp.Css.Parser
private static CssSkewValue ParseSkew2d(StringSource source)
{
ICssValue x = source.ParseAngleOrCalc();
ICssValue y = Angle.Zero;
ICssValue y = CssAngleValue.Zero;
var c = source.SkipGetSkip();
if (x == null)
@ -148,7 +148,7 @@ namespace AngleSharp.Css.Parser
/// </summary>
private static CssMatrixValue ParseMatrix(StringSource source, Int32 count)
{
var numbers = new Double[count];
var numbers = new ICssValue[count];
var num = source.ParseNumber();
if (num.HasValue)
@ -184,7 +184,7 @@ namespace AngleSharp.Css.Parser
/// </summary>
private static CssRotateValue ParseRotate2d(StringSource source)
{
return ParseRotate(source, Double.NaN, Double.NaN, Double.NaN);
return ParseRotate(source, null, null, null);
}
/// <summary>
@ -214,7 +214,7 @@ namespace AngleSharp.Css.Parser
/// </summary>
private static CssRotateValue ParseRotateX(StringSource source)
{
return ParseRotate(source, 1f, 0f, 0f);
return ParseRotate(source, CssNumberValue.One, null, null);
}
/// <summary>
@ -223,7 +223,7 @@ namespace AngleSharp.Css.Parser
/// </summary>
private static CssRotateValue ParseRotateY(StringSource source)
{
return ParseRotate(source, 0f, 1f, 0f);
return ParseRotate(source, null, CssNumberValue.One, null);
}
/// <summary>
@ -232,21 +232,21 @@ namespace AngleSharp.Css.Parser
/// </summary>
private static CssRotateValue ParseRotateZ(StringSource source)
{
return ParseRotate(source, 0f, 0f, 1f);
return ParseRotate(source, null, null, CssNumberValue.One);
}
/// <summary>
/// A broad variety of rotate transforms.
/// http://www.w3.org/TR/css3-transforms/#funcdef-rotate3d
/// </summary>
private static CssRotateValue ParseRotate(StringSource source, Double x, Double y, Double z)
private static CssRotateValue ParseRotate(StringSource source, ICssValue x, ICssValue y, ICssValue z)
{
var angle = source.ParseAngleOrCalc();
var f = source.SkipGetSkip();
if (angle != null && f == Symbols.RoundBracketClose)
{
return new CssRotateValue(x, z, y, angle);
return new CssRotateValue(x, y, z, angle);
}
return null;
@ -263,7 +263,7 @@ namespace AngleSharp.Css.Parser
if (x.HasValue)
{
var y = default(Double?);
var y = default(ICssValue);
if (f == Symbols.Comma)
{
@ -273,7 +273,7 @@ namespace AngleSharp.Css.Parser
if (f == Symbols.RoundBracketClose)
{
return new CssScaleValue(x.Value, y ?? x.Value, 1.0);
return new CssScaleValue(x.Value, y ?? x.Value, null);
}
}
@ -291,15 +291,15 @@ namespace AngleSharp.Css.Parser
if (x.HasValue)
{
var y = default(Double?);
var z = default(Double?);
var y = default(ICssValue);
var z = default(ICssValue);
if (f == Symbols.Comma)
{
y = source.ParseNumber();
f = source.SkipGetSkip();
if (!y.HasValue)
if (y is null)
{
return null;
}
@ -331,7 +331,7 @@ namespace AngleSharp.Css.Parser
if (x.HasValue && f == Symbols.RoundBracketClose)
{
return new CssScaleValue(x.Value, 1.0, 1.0);
return new CssScaleValue(x.Value, null, null);
}
return null;
@ -348,7 +348,7 @@ namespace AngleSharp.Css.Parser
if (y.HasValue && f == Symbols.RoundBracketClose)
{
return new CssScaleValue(1.0, y.Value, 1.0);
return new CssScaleValue(null, y.Value, null);
}
return null;
@ -365,7 +365,7 @@ namespace AngleSharp.Css.Parser
if (z.HasValue && f == Symbols.RoundBracketClose)
{
return new CssScaleValue(1.0, 1.0, z.Value);
return new CssScaleValue(null, null, z.Value);
}
return null;

Просмотреть файл

@ -119,19 +119,19 @@ namespace AngleSharp.Css.Parser
/// <summary>
/// Parses an angle value.
/// </summary>
public static Angle? ParseAngle(this StringSource source)
public static CssAngleValue? ParseAngle(this StringSource source)
{
var pos = source.Index;
var test = source.ParseUnit();
if (test != null)
{
var unit = Angle.GetUnit(test.Dimension);
var unit = CssAngleValue.GetUnit(test.Dimension);
if (unit != Angle.Unit.None &&
if (unit != CssAngleValue.Unit.None &&
Double.TryParse(test.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var value))
{
return new Angle(value, unit);
return new CssAngleValue(value, unit);
}
source.BackTo(pos);

Просмотреть файл

@ -167,7 +167,7 @@ namespace AngleSharp.Css
/// Represents a number object.
/// https://developer.mozilla.org/en-US/docs/Web/CSS/number
/// </summary>
public static readonly IValueConverter OnlyNumberConverter = new StructValueConverter<CssLengthValue>(FromNumber(NumberParser.ParseNumber));
public static readonly IValueConverter OnlyNumberConverter = new StructValueConverter<CssNumberValue>(NumberParser.ParseNumber);
/// <summary>
/// Represents a (calculated) number object.
@ -202,7 +202,7 @@ namespace AngleSharp.Css
/// <summary>
/// Represents an number object that is zero or greater.
/// </summary>
public static readonly IValueConverter NaturalNumberConverter = new StructValueConverter<CssLengthValue>(FromNumber(NumberParser.ParseNaturalNumber));
public static readonly IValueConverter NaturalNumberConverter = new StructValueConverter<CssNumberValue>(NumberParser.ParseNaturalNumber);
/// <summary>
/// Represents an color object (usually hex or name).
@ -753,7 +753,7 @@ namespace AngleSharp.Css
/// <summary>
/// Represents a converter for the StrokeMiterlimit enumeration.
/// </summary>
public static readonly IValueConverter StrokeMiterlimitConverter = new StructValueConverter<CssLengthValue>(FromNumber(NumberParser.ParseGreaterOrEqualOneNumber));
public static readonly IValueConverter StrokeMiterlimitConverter = new StructValueConverter<CssNumberValue>(NumberParser.ParseGreaterOrEqualOneNumber);
/// <summary>
/// Represents a ratio object.

Просмотреть файл

@ -4,7 +4,7 @@ namespace AngleSharp.Css.Values
using AngleSharp.Text;
using System;
sealed class CssBackgroundLayerValue : ICssCompositeValue
sealed class CssBackgroundLayerValue : ICssCompositeValue, IEquatable<CssBackgroundLayerValue>
{
#region Fields
@ -132,6 +132,22 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssBackgroundLayerValue other)
{
return _clip.Equals(other._clip) &&
_repeat.Equals(other._repeat) &&
_attachment.Equals(other._attachment) &&
_origin.Equals(other._origin) &&
_size.Equals(other._size);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssBackgroundLayerValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var image = _image.Compute(context);

Просмотреть файл

@ -89,6 +89,15 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Compares to another background size.
/// </summary>
/// <param name="other">The other background size.</param>
/// <returns>True if both are equivalent, otherwise false.</returns>
public Boolean Equals(CssBackgroundSizeValue other) => _mode == other._mode && _height.Equals(other._height) && _width.Equals(other._width);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssBackgroundSizeValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
if (_mode == ValueMode.Explicit)
@ -101,13 +110,6 @@ namespace AngleSharp.Css.Values
return this;
}
/// <summary>
/// Compares to another background size.
/// </summary>
/// <param name="other">The other background size.</param>
/// <returns>True if both are equivalent, otherwise false.</returns>
public Boolean Equals(CssBackgroundSizeValue other) => _mode == other._mode && _height == other._height && _width == other._width;
#endregion
#region Value Mode

Просмотреть файл

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS background definition.
/// </summary>
sealed class CssBackgroundValue : ICssCompositeValue
sealed class CssBackgroundValue : ICssCompositeValue, IEquatable<CssBackgroundValue>
{
#region Fields
@ -71,6 +71,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssBackgroundValue other)
{
return _color.Equals(other._color) && _layers.Equals(other._layers);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssBackgroundValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var layers = _layers.Compute(context);

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents the CSS border image slice definition.
/// </summary>
public sealed class CssBorderImageSliceValue : ICssCompositeValue
public sealed class CssBorderImageSliceValue : ICssCompositeValue, IEquatable<CssBorderImageSliceValue>
{
#region Fields
@ -117,6 +117,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssBorderImageSliceValue other)
{
return _filled == other._filled && _bottom.Equals(other._bottom) && _left.Equals(other._left) && _right.Equals(other._right) && _top.Equals(other._top);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssBorderImageSliceValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var bottom = (CssLengthValue)((ICssValue)_bottom).Compute(context);

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS border image definition.
/// </summary>
sealed class CssBorderImageValue : ICssCompositeValue
sealed class CssBorderImageValue : ICssCompositeValue, IEquatable<CssBorderImageValue>
{
#region Fields
@ -113,6 +113,22 @@ namespace AngleSharp.Css.Values
#region
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssBorderImageValue other)
{
return _image.Equals(other._image) &&
_slice.Equals(other._slice) &&
_widths.Equals(other._widths) &&
_outsets.Equals(other._outsets) &&
_repeat.Equals(other._repeat);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssBorderImageValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var image = _image.Compute(context);

Просмотреть файл

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a border radius value.
/// </summary>
sealed class CssBorderRadiusValue : ICssCompositeValue
sealed class CssBorderRadiusValue : ICssCompositeValue, IEquatable<CssBorderRadiusValue>
{
#region Fields
@ -67,6 +67,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssBorderRadiusValue other)
{
return _horizontal.Equals(other._horizontal) && _vertical.Equals(other._vertical);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssBorderRadiusValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var h = ((ICssValue)_horizontal).Compute(context);

Просмотреть файл

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS cursor definition.
/// </summary>
sealed class CssCursorValue : ICssCompositeValue
sealed class CssCursorValue : ICssCompositeValue, IEquatable<CssCursorValue>
{
#region Fields
@ -67,6 +67,36 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssCursorValue other)
{
var l = _definitions.Length;
if (_cursor.Equals(other._cursor) && l == other._definitions.Length)
{
for (var i = 0; i < l; i++)
{
var a = _definitions[i];
var b = other._definitions[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssCursorValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var cursor = _cursor.Compute(context);

Просмотреть файл

@ -4,12 +4,12 @@ namespace AngleSharp.Css.Values
using AngleSharp.Text;
using System;
sealed class CssCustomCursorValue : ICssCompositeValue
sealed class CssCustomCursorValue : ICssCompositeValue, IEquatable<CssCustomCursorValue>
{
#region Fields
private readonly ICssImageValue _source;
private readonly CssPoint2D? _position;
private readonly ICssValue _position;
#endregion
@ -20,7 +20,7 @@ namespace AngleSharp.Css.Values
/// </summary>
/// <param name="source">The image source to display.</param>
/// <param name="position">The position offset, if any.</param>
public CssCustomCursorValue(ICssImageValue source, CssPoint2D? position)
public CssCustomCursorValue(ICssImageValue source, ICssValue position)
{
_source = source;
_position = position;
@ -38,7 +38,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets the positional offset, if any.
/// </summary>
public CssPoint2D? Position => _position;
public ICssValue Position => _position;
/// <summary>
/// Gets the CSS text representation.
@ -51,10 +51,10 @@ namespace AngleSharp.Css.Values
sb.Append(_source.CssText);
if (_position.HasValue)
if (_position is not null)
{
sb.Append(Symbols.Space);
sb.Append(_position.Value.CssText);
sb.Append(_position.CssText);
}
return sb.ToPool();
@ -65,10 +65,22 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssCustomCursorValue other)
{
return _position.Equals(other._position) && _source.Equals(other._source);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssCustomCursorValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var source = (ICssImageValue)_source.Compute(context);
var position = _position.HasValue ? (CssPoint2D?)((ICssValue)_position.Value).Compute(context) : null;
var position = _position?.Compute(context);
return new CssCustomCursorValue(source, position);
}

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS font definition.
/// </summary>
sealed class CssFontValue : ICssCompositeValue
sealed class CssFontValue : ICssCompositeValue, IEquatable<CssFontValue>
{
#region Fields
@ -138,6 +138,24 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssFontValue other)
{
return _lineHeight.Equals(other._lineHeight) &&
_size.Equals(other._size) &&
_weight.Equals(other._weight) &&
_stretch.Equals(other._stretch) &&
_variant.Equals(other._variant) &&
_style.Equals(other._style) &&
_fontFamilies.Equals(other._fontFamilies);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssFontValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var fontFamilies = _fontFamilies.Compute(context);

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// More information can be found at the W3C:
/// http://dev.w3.org/csswg/css-images-3/#color-stop-syntax
/// </summary>
public sealed class CssGradientStopValue : ICssCompositeValue
public sealed class CssGradientStopValue : ICssCompositeValue, IEquatable<CssGradientStopValue>
{
#region Fields
@ -62,6 +62,16 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssGradientStopValue other)
{
return _color.Equals(other._color) && _location.Equals(other._location);
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var color = ((ICssValue)_color).Compute(context);
@ -69,6 +79,8 @@ namespace AngleSharp.Css.Values
return new CssGradientStopValue((CssColorValue)color, location);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssGradientStopValue value && Equals(value);
#endregion
}
}

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS grid template definition.
/// </summary>
sealed class CssGridTemplateValue : ICssCompositeValue
sealed class CssGridTemplateValue : ICssCompositeValue, IEquatable<CssGridTemplateValue>
{
#region Fields
@ -107,6 +107,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssGridTemplateValue other)
{
return _areas.Equals(other._areas) && _columns.Equals(other._columns) && _rows.Equals(other._rows);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssGridTemplateValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var rows = _rows.Compute(context);

Просмотреть файл

@ -9,7 +9,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS grid definition.
/// </summary>
sealed class CssGridValue : ICssCompositeValue
sealed class CssGridValue : ICssCompositeValue, IEquatable<CssGridValue>
{
#region Fields
@ -92,6 +92,37 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssGridValue other)
{
if (_rows.Equals(other._rows) && _columns.Equals(other._columns) && _dense == other._dense)
{
var l = _sizes.Length;
if (l == other._sizes.Length)
{
for (var i = 0; i < l; i++)
{
var a = _sizes[i];
var b = other._sizes[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
}
return false;
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var rows = _rows.Compute(context);
@ -100,6 +131,8 @@ namespace AngleSharp.Css.Values
return new CssGridValue(rows, columns, sizes, _dense);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssGridValue value && Equals(value);
#endregion
}
}

Просмотреть файл

@ -7,11 +7,17 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS image repeat definition.
/// </summary>
public sealed class CssImageRepeatsValue : ICssCompositeValue
public sealed class CssImageRepeatsValue : ICssCompositeValue, IEquatable<CssImageRepeatsValue>
{
#region Fields
private readonly ICssValue _horizontal;
private readonly ICssValue _vertical;
#endregion
#region ctor
/// <summary>
/// Creates a new CSS image repeat definition.
/// </summary>
@ -23,6 +29,10 @@ namespace AngleSharp.Css.Values
_vertical = vertical;
}
#endregion
#region Properties
/// <summary>
/// Gets the value of the horizontal repeat component.
/// </summary>
@ -60,11 +70,29 @@ namespace AngleSharp.Css.Values
}
}
#endregion
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssImageRepeatsValue other)
{
return _horizontal.Equals(other._horizontal) && _vertical.Equals(other._vertical);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssImageRepeatsValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var h = _horizontal.Compute(context);
var v = _vertical.Compute(context);
return new CssImageRepeatsValue(h, v);
}
#endregion
}
}

Просмотреть файл

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS origin definition.
/// </summary>
public sealed class CssOriginValue : ICssCompositeValue
public sealed class CssOriginValue : ICssCompositeValue, IEquatable<CssOriginValue>
{
#region Fields
@ -66,6 +66,16 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssOriginValue other)
{
return _x.Equals(other._x) && _y.Equals(other._y) && _z.Equals(other._z);
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var x = _x.Compute(context);
@ -80,6 +90,8 @@ namespace AngleSharp.Css.Values
return this;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssOriginValue value && Equals(value);
#endregion
}
}

Просмотреть файл

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a point value consisting of two distances.
/// </summary>
public readonly struct CssPoint2D : IEquatable<CssPoint2D>, ICssPrimitiveValue
public readonly struct CssPoint2D : ICssCompositeValue, IEquatable<CssPoint2D>
{
#region Basic values
@ -147,6 +147,16 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssPoint2D other)
{
return _x.Equals(other._x) && _y.Equals(other._y);
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var x = _x.Compute(context);
@ -160,59 +170,7 @@ namespace AngleSharp.Css.Values
return this;
}
#endregion
#region Equality
/// <summary>
/// Checks the equality of the two given points.
/// </summary>
/// <param name="a">The left point.</param>
/// <param name="b">The right point.</param>
/// <returns>True if both points are equal, otherwise false.</returns>
public static Boolean operator ==(CssPoint2D a, CssPoint2D b) => a.Equals(b);
/// <summary>
/// Checks the inequality of the two given points.
/// </summary>
/// <param name="a">The left point.</param>
/// <param name="b">The right point.</param>
/// <returns>True if both points are not equal, otherwise false.</returns>
public static Boolean operator !=(CssPoint2D a, CssPoint2D b) => !a.Equals(b);
/// <summary>
/// Checks if both points are actually equal.
/// </summary>
/// <param name="other">The other point to compare to.</param>
/// <returns>True if both points are equal, otherwise false.</returns>
public Boolean Equals(CssPoint2D other) => _x.Equals(other._x) && _y.Equals(other._y);
/// <summary>
/// Tests if another object is equal to this object.
/// </summary>
/// <param name="obj">The object to test with.</param>
/// <returns>True if the two objects are equal, otherwise false.</returns>
public override Boolean Equals(Object obj)
{
var other = obj as CssPoint2D?;
if (other != null)
{
return Equals(other.Value);
}
return false;
}
/// <summary>
/// Returns a hash code that defines the current point.
/// </summary>
/// <returns>The integer value of the hashcode.</returns>
public override Int32 GetHashCode()
{
var hash = 17 * 37 + _x.GetHashCode();
return hash * 37 + _y.GetHashCode();
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssPoint2D value && Equals(value);
#endregion
}

Просмотреть файл

@ -0,0 +1,81 @@
namespace AngleSharp.Css.Values
{
using AngleSharp.Css.Dom;
using System;
/// <summary>
/// Represents a ratio (top to bottom) value.
/// </summary>
public readonly struct CssRatioValue : ICssCompositeValue, IEquatable<CssRatioValue>
{
#region Fields
private readonly ICssValue _top;
private readonly ICssValue _bottom;
#endregion
#region ctor
/// <summary>
/// Creates a new ratio value.
/// </summary>
/// <param name="top">The first number.</param>
/// <param name="bottom">The second number.</param>
public CssRatioValue(ICssValue top, ICssValue bottom)
{
_top = top;
_bottom = bottom;
}
#endregion
#region Properties
/// <summary>
/// Gets the CSS text representation.
/// </summary>
public String CssText => String.Concat(_top.CssText, "/", _bottom.CssText);
/// <summary>
/// Gets the first number of the ratio.
/// </summary>
public ICssValue Top => _top;
/// <summary>
/// Gets the second number of the ratio.
/// </summary>
public ICssValue Bottom => _bottom;
#endregion
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssRatioValue other)
{
return _top.Equals(other._top) && _bottom.Equals(other._bottom);
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var top = _top.Compute(context);
var bottom = _bottom.Compute(context);
if (top != _top || bottom != _bottom)
{
return new CssRatioValue(top, bottom);
}
return this;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssRatioValue value && Equals(value);
#endregion
}
}

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// The shadow class for holding information about a box or text-shadow.
/// </summary>
public sealed class CssShadowValue : ICssCompositeValue
public sealed class CssShadowValue : ICssCompositeValue, IEquatable<CssShadowValue>
{
#region Fields
@ -115,6 +115,23 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssShadowValue other)
{
return _blurRadius.Equals(other._blurRadius) &&
_spreadRadius.Equals(other._spreadRadius) &&
_color.Equals(other._color) &&
_inset == other._inset &&
_offsetX.Equals(other._offsetX) &&
_offsetY.Equals(other._offsetY);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssShadowValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var offsetX = _offsetX.Compute(context);

Просмотреть файл

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS value that was born from a shorthand.
/// </summary>
class CssChildValue : ICssValue
sealed class CssChildValue : ICssValue, IEquatable<CssChildValue>
{
#region Fields
@ -51,6 +51,16 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssChildValue other)
{
return _parent.Equals(other._parent) && _value.Equals(other._value);
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var parent = _parent.Compute(context);
@ -58,6 +68,8 @@ namespace AngleSharp.Css.Values
return new CssChildValue(parent, value);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssChildValue value && Equals(value);
#endregion
}
}

Просмотреть файл

@ -8,9 +8,15 @@ namespace AngleSharp.Css.Values
/// </summary>
sealed class CssCalcAddExpression : ICssCompositeValue
{
#region Fields
private readonly ICssValue _left;
private readonly ICssValue _right;
#endregion
#region ctor
/// <summary>
/// Creates a new calc add expression.
/// </summary>
@ -22,6 +28,10 @@ namespace AngleSharp.Css.Values
_right = right;
}
#endregion
#region Properties
/// <summary>
/// Gets the left operand.
/// </summary>
@ -37,6 +47,10 @@ namespace AngleSharp.Css.Values
/// </summary>
public String CssText => String.Concat(_left.CssText, " + ", _right.CssText);
#endregion
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var left = _left.Compute(context);
@ -48,8 +62,11 @@ namespace AngleSharp.Css.Values
return (ICssValue)Activator.CreateInstance(x.GetType(), result);
}
// TOOD INVALID
return this;
return null;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => Object.ReferenceEquals(this, other);
#endregion
}
}

Просмотреть файл

@ -8,8 +8,14 @@ namespace AngleSharp.Css.Values
/// </summary>
sealed class CssCalcBracketExpression : ICssCompositeValue
{
#region Fields
private readonly ICssValue _content;
#endregion
#region ctor
/// <summary>
/// Creates a new calc bracket expression.
/// </summary>
@ -19,6 +25,10 @@ namespace AngleSharp.Css.Values
_content = content;
}
#endregion
#region Properties
/// <summary>
/// Gets the bracket's content.
/// </summary>
@ -29,9 +39,14 @@ namespace AngleSharp.Css.Values
/// </summary>
public String CssText => String.Concat("(", _content.CssText, ")");
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return _content.Compute(context);
}
#endregion
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context) => _content.Compute(context);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => Object.ReferenceEquals(this, other);
#endregion
}
}

Просмотреть файл

@ -8,9 +8,15 @@ namespace AngleSharp.Css.Values
/// </summary>
sealed class CssCalcDivExpression : ICssCompositeValue
{
#region Fields
private readonly ICssValue _left;
private readonly ICssValue _right;
#endregion
#region ctor
/// <summary>
/// Creates a new calc division expression.
/// </summary>
@ -22,6 +28,10 @@ namespace AngleSharp.Css.Values
_right = right;
}
#endregion
#region Properties
/// <summary>
/// Gets the left operand.
/// </summary>
@ -37,6 +47,10 @@ namespace AngleSharp.Css.Values
/// </summary>
public String CssText => String.Concat(_left.CssText, " / ", _right.CssText);
#endregion
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var left = _left.Compute(context);
@ -48,8 +62,11 @@ namespace AngleSharp.Css.Values
return (ICssValue)Activator.CreateInstance(x.GetType(), result);
}
// TOOD INVALID
return this;
return null;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => Object.ReferenceEquals(this, other);
#endregion
}
}

Просмотреть файл

@ -8,9 +8,15 @@ namespace AngleSharp.Css.Values
/// </summary>
sealed class CssCalcMulExpression : ICssCompositeValue
{
#region Fields
private readonly ICssValue _left;
private readonly ICssValue _right;
#endregion
#region ctor
/// <summary>
/// Creates a new calc multiplication expression.
/// </summary>
@ -22,6 +28,10 @@ namespace AngleSharp.Css.Values
_right = right;
}
#endregion
#region Properties
/// <summary>
/// Gets the left operand.
/// </summary>
@ -37,6 +47,10 @@ namespace AngleSharp.Css.Values
/// </summary>
public String CssText => String.Concat(_left.CssText, " * ", _right.CssText);
#endregion
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var left = _left.Compute(context);
@ -48,8 +62,11 @@ namespace AngleSharp.Css.Values
return (ICssValue)Activator.CreateInstance(x.GetType(), result);
}
// TOOD INVALID
return this;
return null;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => Object.ReferenceEquals(this, other);
#endregion
}
}

Просмотреть файл

@ -8,9 +8,15 @@ namespace AngleSharp.Css.Values
/// </summary>
sealed class CssCalcSubExpression : ICssCompositeValue
{
#region Fields
private readonly ICssValue _left;
private readonly ICssValue _right;
#endregion
#region ctor
/// <summary>
/// Creates a new calc subtraction expression.
/// </summary>
@ -22,6 +28,10 @@ namespace AngleSharp.Css.Values
_right = right;
}
#endregion
#region Properties
/// <summary>
/// Gets the left operand.
/// </summary>
@ -37,6 +47,10 @@ namespace AngleSharp.Css.Values
/// </summary>
public String CssText => String.Concat(_left.CssText, " - ", _right.CssText);
#endregion
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var left = _left.Compute(context);
@ -48,8 +62,11 @@ namespace AngleSharp.Css.Values
return (ICssValue)Activator.CreateInstance(x.GetType(), result);
}
// TOOD INVALID
return this;
return null;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => Object.ReferenceEquals(this, other);
#endregion
}
}

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS attr function call.
/// </summary>
public sealed class CssAttrValue : ICssFunctionValue
public sealed class CssAttrValue : ICssFunctionValue, IEquatable<CssAttrValue>
{
#region Fields
@ -54,6 +54,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssAttrValue other)
{
return _attribute.Equals(other._attribute);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssAttrValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;

Просмотреть файл

@ -59,10 +59,9 @@ namespace AngleSharp.Css.Values
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return _expression.Compute(context);
}
ICssValue ICssValue.Compute(ICssComputeContext context) => _expression.Compute(context);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => Object.ReferenceEquals(this, other);
#endregion
}

Просмотреть файл

@ -9,11 +9,11 @@ namespace AngleSharp.Css.Values
/// Represents a linear gradient:
/// https://drafts.csswg.org/css-images-4/#conic-gradients
/// </summary>
sealed class CssConicGradientValue : ICssGradientFunctionValue
sealed class CssConicGradientValue : ICssGradientFunctionValue, IEquatable<CssConicGradientValue>
{
#region Fields
private readonly CssGradientStopValue[] _stops;
private readonly ICssValue[] _stops;
private readonly ICssValue _center;
private readonly ICssValue _angle;
private readonly Boolean _repeating;
@ -29,7 +29,7 @@ namespace AngleSharp.Css.Values
/// <param name="center">The center to use.</param>
/// <param name="stops">The stops to use.</param>
/// <param name="repeating">Indicates if the gradient is repeating.</param>
public CssConicGradientValue(ICssValue angle, ICssValue center, CssGradientStopValue[] stops, Boolean repeating = false)
public CssConicGradientValue(ICssValue angle, ICssValue center, ICssValue[] stops, Boolean repeating = false)
{
_stops = stops;
_center = center;
@ -76,7 +76,7 @@ namespace AngleSharp.Css.Values
{
get
{
var defaultAngle = _angle as Angle?;
var defaultAngle = _angle as CssAngleValue?;
var defaultPosition = _center as CssPoint2D?;
var offset = (defaultAngle.HasValue ? 1 : 0) + (defaultPosition.HasValue ? 1 : 0);
var args = new String[_stops.Length + offset];
@ -103,7 +103,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets the angle of the conic gradient.
/// </summary>
public ICssValue Angle => _angle ?? Values.Angle.Half;
public ICssValue Angle => _angle ?? Values.CssAngleValue.Half;
/// <summary>
/// Gets the position of the conic gradient.
@ -113,7 +113,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets all stops.
/// </summary>
public CssGradientStopValue[] Stops => _stops;
public ICssValue[] Stops => _stops;
/// <summary>
/// Gets if the gradient is repeating.
@ -124,6 +124,36 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssConicGradientValue other)
{
var l = _stops.Length;
if (_angle.Equals(other._angle) && _center.Equals(other._center) && _repeating == other._repeating && l == other._stops.Length)
{
for (var i = 0; i < l; i++)
{
var a = _stops[i];
var b = other._stops[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssConicGradientValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var center = _center.Compute(context);

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS content function call.
/// </summary>
public sealed class CssContentValue : ICssFunctionValue
public sealed class CssContentValue : ICssFunctionValue, IEquatable<CssContentValue>
{
#region Fields
@ -54,10 +54,16 @@ namespace AngleSharp.Css.Values
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
}
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssContentValue other) => _type.Equals(other._type);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssContentValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context) => this;
#endregion
}

Просмотреть файл

@ -13,10 +13,10 @@ namespace AngleSharp.Css.Values
{
#region Fields
private readonly Double _x1;
private readonly Double _y1;
private readonly Double _x2;
private readonly Double _y2;
private readonly ICssValue _x1;
private readonly ICssValue _y1;
private readonly ICssValue _x2;
private readonly ICssValue _y2;
/// <summary>
/// The pre-configured ease function.
@ -56,7 +56,7 @@ namespace AngleSharp.Css.Values
/// <param name="y1">The y-coordinate of P1.</param>
/// <param name="x2">The x-coordinate of P2.</param>
/// <param name="y2">The y-coordinate of P2.</param>
public CssCubicBezierValue(Double x1, Double y1, Double x2, Double y2)
public CssCubicBezierValue(ICssValue x1, ICssValue y1, ICssValue x2, ICssValue y2)
{
_x1 = x1;
_y1 = y1;
@ -64,6 +64,20 @@ namespace AngleSharp.Css.Values
_y2 = y2;
}
/// <summary>
/// The four values specify points P1 and P2 of the curve as (x1, y1, x2, y2). Both
/// x values must be in the range [0, 1] or the definition is invalid. The y values
/// can exceed this range.
/// </summary>
/// <param name="x1">The x-coordinate of P1.</param>
/// <param name="y1">The y-coordinate of P1.</param>
/// <param name="x2">The x-coordinate of P2.</param>
/// <param name="y2">The y-coordinate of P2.</param>
public CssCubicBezierValue(Double x1, Double y1, Double x2, Double y2)
: this(new CssNumberValue(x1), new CssNumberValue(y1), new CssNumberValue(x2), new CssNumberValue(y2))
{
}
#endregion
#region Properties
@ -78,10 +92,10 @@ namespace AngleSharp.Css.Values
/// </summary>
public ICssValue[] Arguments => new ICssValue[]
{
new CssLengthValue(_x1, CssLengthValue.Unit.None),
new CssLengthValue(_y1, CssLengthValue.Unit.None),
new CssLengthValue(_x2, CssLengthValue.Unit.None),
new CssLengthValue(_y2, CssLengthValue.Unit.None),
_x1,
_y1,
_x2,
_y2,
};
/// <summary>
@ -119,22 +133,22 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets the x-coordinate of the p1.
/// </summary>
public Double X1 => _x1;
public ICssValue X1 => _x1;
/// <summary>
/// Gets the y-coordinate of the p1.
/// </summary>
public Double Y1 => _y1;
public ICssValue Y1 => _y1;
/// <summary>
/// Gets the x-coordinate of the p2.
/// </summary>
public Double X2 => _x2;
public ICssValue X2 => _x2;
/// <summary>
/// Gets the y-coordinate of the p2.
/// </summary>
public Double Y2 => _y2;
public ICssValue Y2 => _y2;
#endregion
@ -146,13 +160,19 @@ namespace AngleSharp.Css.Values
/// <param name="other">The cubic bezier to compare to.</param>
/// <returns>True if both have the same parameters, otherwise false.</returns>
public Boolean Equals(CssCubicBezierValue other) =>
_x1 == other._x1 && _x2 == other._x2 && _y1 == other._y1 && _y2 == other._y2;
_x1.Equals(other._x1) && _x2.Equals(other._x2) && _y1.Equals(other._y1) && _y2.Equals(other._y2);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
var x1 = _x1.Compute(context);
var x2 = _x2.Compute(context);
var y1 = _y1.Compute(context);
var y2 = _y2.Compute(context);
return new CssCubicBezierValue(x1, y1, x2, y2);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssCubicBezierValue value && Equals(value);
#endregion
}
}

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS fit-content function call.
/// </summary>
sealed class CssFitContentValue : ICssFunctionValue
sealed class CssFitContentValue : ICssFunctionValue, IEquatable<CssFitContentValue>
{
#region Fields
@ -54,6 +54,15 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssFitContentValue other) => _dim.Equals(other._dim);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssFitContentValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var dim = _dim.Compute(context);

Просмотреть файл

@ -5,7 +5,7 @@ namespace AngleSharp.Css.Values
using AngleSharp.Text;
using System;
sealed class CssFontFormatValue : ICssFunctionValue
sealed class CssFontFormatValue : ICssFunctionValue, IEquatable<CssFontFormatValue>
{
#region Fields
@ -34,10 +34,16 @@ namespace AngleSharp.Css.Values
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
}
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssFontFormatValue other) => _fontFormat.Equals(other._fontFormat);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssFontFormatValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context) => this;
#endregion
}

Просмотреть файл

@ -9,11 +9,11 @@ namespace AngleSharp.Css.Values
/// Represents a linear gradient:
/// http://dev.w3.org/csswg/css-images-3/#linear-gradients
/// </summary>
sealed class CssLinearGradientValue : ICssGradientFunctionValue
sealed class CssLinearGradientValue : ICssGradientFunctionValue, IEquatable<CssLinearGradientValue>
{
#region Fields
private readonly CssGradientStopValue[] _stops;
private readonly ICssValue[] _stops;
private readonly ICssValue _angle;
private readonly Boolean _repeating;
@ -27,7 +27,7 @@ namespace AngleSharp.Css.Values
/// <param name="angle">The angle of the linear gradient.</param>
/// <param name="stops">The stops to use.</param>
/// <param name="repeating">Indicates if the gradient is repeating.</param>
public CssLinearGradientValue(ICssValue angle, CssGradientStopValue[] stops, Boolean repeating = false)
public CssLinearGradientValue(ICssValue angle, ICssValue[] stops, Boolean repeating = false)
{
_stops = stops;
_angle = angle;
@ -68,7 +68,7 @@ namespace AngleSharp.Css.Values
{
get
{
var defaultAngle = _angle as Angle?;
var defaultAngle = _angle as CssAngleValue?;
var offset = defaultAngle.HasValue ? 1 : 0;
var args = new String[_stops.Length + offset];
@ -100,12 +100,12 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets the angle of the linear gradient.
/// </summary>
public ICssValue Angle => _angle ?? Values.Angle.Half;
public ICssValue Angle => _angle ?? Values.CssAngleValue.Half;
/// <summary>
/// Gets all stops.
/// </summary>
public CssGradientStopValue[] Stops => _stops;
public ICssValue[] Stops => _stops;
/// <summary>
/// Gets if the gradient is repeating.
@ -116,6 +116,36 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssLinearGradientValue other)
{
var l = _stops.Length;
if (_angle.Equals(other._angle) && _repeating == other._repeating && l == other._stops.Length)
{
for (var i = 0; i < l; i++)
{
var a = _stops[i];
var b = other._stops[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssLinearGradientValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var angle = _angle.Compute(context);

Просмотреть файл

@ -5,7 +5,7 @@ namespace AngleSharp.Css.Values
using AngleSharp.Text;
using System;
sealed class CssLocalFontValue : ICssFunctionValue
sealed class CssLocalFontValue : ICssFunctionValue, IEquatable<CssLocalFontValue>
{
#region Fields
@ -34,10 +34,16 @@ namespace AngleSharp.Css.Values
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
}
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssLocalFontValue other) => _fontName.Equals(other._fontName);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssLocalFontValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context) => this;
#endregion
}

Просмотреть файл

@ -4,21 +4,22 @@ namespace AngleSharp.Css.Values
using AngleSharp.Css.Dom;
using AngleSharp.Text;
using System;
using System.Linq;
/// <summary>
/// Represents the matrix3d transformation.
/// </summary>
sealed class CssMatrixValue : ICssTransformFunctionValue
sealed class CssMatrixValue : ICssTransformFunctionValue, IEquatable<CssMatrixValue>
{
#region Fields
private readonly Double[] _values;
private readonly ICssValue[] _values;
#endregion
#region ctor
internal CssMatrixValue(Double[] values)
internal CssMatrixValue(ICssValue[] values)
{
_values = values;
}
@ -35,20 +36,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets the arguments.
/// </summary>
public ICssValue[] Arguments
{
get
{
var args = new ICssValue[_values.Length];
for (var i = 0; i < args.Length; i++)
{
args[i] = new CssLengthValue(_values[i], CssLengthValue.Unit.None);
}
return args;
}
}
public ICssValue[] Arguments => _values;
/// <summary>
/// Gets the CSS text representation.
@ -60,37 +48,69 @@ namespace AngleSharp.Css.Values
/// </summary>
/// <param name="index">The index to look for.</param>
/// <returns>The value.</returns>
public Double this[Int32 index] => _values[index];
public ICssValue this[Int32 index] => _values[index];
#endregion
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssMatrixValue other)
{
var count = _values.Length;
if (count == other._values.Length)
{
for (var i = 0; i < count; i++)
{
var a = _values[i];
var b = other._values[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssMatrixValue value && Equals(value);
/// <summary>
/// Returns the stored matrix.
/// </summary>
/// <returns>The current transformation.</returns>
public TransformMatrix ComputeMatrix(IRenderDimensions dimensions)
{
var values = _values;
var values = _values.Select(v => v.AsDouble()).ToList();
if (values.Length == 6)
if (values.Count == 6)
{
values = new Double[]
{
_values[0], _values[2], 0.0, _values[4],
_values[1], _values[3], 0.0, _values[5],
1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
values.Add(1.0);
values.Add(0.0);
values.Add(0.0);
values.Add(0.0);
values.Add(0.0);
values.Add(0.0);
values.Add(0.0);
values.Add(1.0);
}
return new TransformMatrix(values);
return new TransformMatrix(values.ToArray());
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
var values = _values.Select(v => v.Compute(context)).ToArray();
return new CssMatrixValue(values);
}
#endregion

Просмотреть файл

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS minmax function call.
/// </summary>
sealed class CssMinMaxValue : ICssFunctionValue
sealed class CssMinMaxValue : ICssFunctionValue, IEquatable<CssMinMaxValue>
{
#region Fields
@ -63,6 +63,16 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssMinMaxValue other)
{
return _min.Equals(other._min) && _max.Equals(other._max);
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var min = _min.Compute(context);
@ -70,6 +80,8 @@ namespace AngleSharp.Css.Values
return new CssMinMaxValue(min, max);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssMinMaxValue value && Equals(value);
#endregion
}
}

Просмотреть файл

@ -17,10 +17,9 @@ namespace AngleSharp.Css.Values
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => Object.ReferenceEquals(this, other);
ICssValue ICssValue.Compute(ICssComputeContext context) => this;
#endregion
}

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents the distance transformation.
/// </summary>
sealed class CssPerspectiveValue : ICssTransformFunctionValue
sealed class CssPerspectiveValue : ICssTransformFunctionValue, IEquatable<CssPerspectiveValue>
{
#region Fields
@ -50,6 +50,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssPerspectiveValue other)
{
return _distance.Equals(other._distance);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssPerspectiveValue value && Equals(value);
/// <summary>
/// Computes the matrix for the given transformation.
/// </summary>

Просмотреть файл

@ -11,11 +11,11 @@ namespace AngleSharp.Css.Values
/// Represents a radial gradient:
/// http://dev.w3.org/csswg/css-images-3/#radial-gradients
/// </summary>
public sealed class CssRadialGradientValue : ICssGradientFunctionValue
public sealed class CssRadialGradientValue : ICssGradientFunctionValue, IEquatable<CssRadialGradientValue>
{
#region Fields
private readonly CssGradientStopValue[] _stops;
private readonly ICssValue[] _stops;
private readonly CssPoint2D _center;
private readonly ICssValue _width;
private readonly ICssValue _height;
@ -37,7 +37,7 @@ namespace AngleSharp.Css.Values
/// <param name="sizeMode">The size mode of the ellipsoid.</param>
/// <param name="stops">A collection of stops to use.</param>
/// <param name="repeating">The repeating setting.</param>
public CssRadialGradientValue(Boolean circle, CssPoint2D center, ICssValue width, ICssValue height, SizeMode sizeMode, CssGradientStopValue[] stops, Boolean repeating = false)
public CssRadialGradientValue(Boolean circle, CssPoint2D center, ICssValue width, ICssValue height, SizeMode sizeMode, ICssValue[] stops, Boolean repeating = false)
{
_stops = stops;
_center = center;
@ -64,7 +64,8 @@ namespace AngleSharp.Css.Values
{
get
{
var isDefault = _center == CssPoint2D.Center && !_circle && _height == null && _width == null && _sizeMode == SizeMode.None;
var center = CssPoint2D.Center;
var isDefault = _center.X == center.X && _center.Y == center.Y && !_circle && _height == null && _width == null && _sizeMode == SizeMode.None;
var args = new List<ICssValue>();
if (!isDefault)
@ -145,7 +146,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets all stops.
/// </summary>
public CssGradientStopValue[] Stops => _stops;
public ICssValue[] Stops => _stops;
/// <summary>
/// Gets if the gradient is repeating.
@ -156,6 +157,37 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssRadialGradientValue other)
{
if (_center.Equals(other._center) && _width.Equals(other._width) && _height.Equals(other._height) && _repeating == other._repeating && _sizeMode == other._sizeMode && _circle == other._circle)
{
var count = _stops.Length;
if (count == other._stops.Length)
{
for (var i = 0; i < count; i++)
{
var a = _stops[i];
var b = other._stops[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
}
return false;
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var center = (CssPoint2D)((ICssValue)_center).Compute(context);
@ -165,6 +197,8 @@ namespace AngleSharp.Css.Values
return new CssRadialGradientValue(_circle, center, width, height, _sizeMode, stops, _repeating);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssRadialGradientValue value && Equals(value);
#endregion
#region Sizes

Просмотреть файл

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS repeat function call.
/// </summary>
sealed class CssRepeatValue : ICssFunctionValue
sealed class CssRepeatValue : ICssFunctionValue, IEquatable<CssRepeatValue>
{
#region Fields
@ -63,6 +63,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssRepeatValue other)
{
return _count.Equals(other._count) && _value.Equals(other._value);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssRepeatValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var count = _count.Compute(context);

Просмотреть файл

@ -8,13 +8,13 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents the rotate3d transformation.
/// </summary>
sealed class CssRotateValue : ICssTransformFunctionValue
sealed class CssRotateValue : ICssTransformFunctionValue, IEquatable<CssRotateValue>
{
#region Fields
private readonly Double _x;
private readonly Double _y;
private readonly Double _z;
private readonly ICssValue _x;
private readonly ICssValue _y;
private readonly ICssValue _z;
private readonly ICssValue _angle;
#endregion
@ -28,7 +28,7 @@ namespace AngleSharp.Css.Values
/// <param name="y">The y coordinate.</param>
/// <param name="z">The z coordinate.</param>
/// <param name="angle">The angle of rotation.</param>
public CssRotateValue(Double x, Double y, Double z, ICssValue angle)
public CssRotateValue(ICssValue x, ICssValue y, ICssValue z, ICssValue angle)
{
_x = x;
_y = y;
@ -47,19 +47,19 @@ namespace AngleSharp.Css.Values
{
get
{
if (Double.IsNaN(_x) && Double.IsNaN(_y) && Double.IsNaN(_z))
if (_x is null && _y is null && _z is null)
{
return FunctionNames.Rotate;
}
else if (_x == 1f && _y == 0f && _z == 0f)
else if (_x is not null && _y is null && _z is null)
{
return FunctionNames.RotateX;
}
else if (_x == 0f && _y == 1f && _z == 0f)
else if (_x is null && _y is not null && _z is null)
{
return FunctionNames.RotateY;
}
else if (_x == 0f && _y == 0f && _z == 1f)
else if (_x is null && _y is null && _z is not null)
{
return FunctionNames.RotateY;
}
@ -73,9 +73,9 @@ namespace AngleSharp.Css.Values
/// </summary>
public ICssValue[] Arguments => new ICssValue[]
{
new CssLengthValue(_x, CssLengthValue.Unit.None),
new CssLengthValue(_y, CssLengthValue.Unit.None),
new CssLengthValue(_z, CssLengthValue.Unit.None),
_x,
_y,
_z,
_angle,
};
@ -101,17 +101,17 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets the value of the x-component of the rotation vector.
/// </summary>
public Double X => _x;
public ICssValue X => _x;
/// <summary>
/// Gets the value of the y-component of the rotation vector.
/// </summary>
public Double Y => _y;
public ICssValue Y => _y;
/// <summary>
/// Gets the value of the z-component of the rotation vector.
/// </summary>
public Double Z => _z;
public ICssValue Z => _z;
/// <summary>
/// Gets the angle.
@ -122,19 +122,34 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssRotateValue other)
{
return _angle.Equals(other._angle) && _x.Equals(other._x) && _y.Equals(other._y) && _z.Equals(other._z);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssRotateValue value && Equals(value);
/// <summary>
/// Computes the matrix for the given transformation.
/// </summary>
/// <returns>The transformation matrix representation.</returns>
public TransformMatrix ComputeMatrix(IRenderDimensions renderDimensions)
{
var norm = 1.0 / Math.Sqrt(_x * _x + _y * _y + _z * _z);
var alpha = _angle as Angle ? ?? Values.Angle.Zero;
var sina = Math.Sin(alpha.ToRadian());
var cosa = Math.Cos(alpha.ToRadian());
var l = _x * norm;
var m = _y * norm;
var n = _z * norm;
var x = _x.AsDouble();
var y = _x.AsDouble();
var z = _x.AsDouble();
var norm = 1.0 / Math.Sqrt(x * x + y * y + z * z);
var alpha = _angle.AsRad();
var sina = Math.Sin(alpha);
var cosa = Math.Cos(alpha);
var l = x * norm;
var m = y * norm;
var n = z * norm;
var omc = (1.0 - cosa);
return new TransformMatrix(
l * l * omc + cosa, m * l * omc - n * sina, n * l * omc + m * sina,
@ -145,8 +160,11 @@ namespace AngleSharp.Css.Values
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var x = _x?.Compute(context);
var y = _y?.Compute(context);
var z = _z?.Compute(context);
var angle = _angle.Compute(context);
return new CssRotateValue(_x, _y, _z, angle);
return new CssRotateValue(x, y, z, angle);
}
#endregion

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS running function call.
/// </summary>
public sealed class CssRunningValue : ICssFunctionValue
public sealed class CssRunningValue : ICssFunctionValue, IEquatable<CssRunningValue>
{
#region Fields
@ -54,10 +54,16 @@ namespace AngleSharp.Css.Values
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
}
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssRunningValue other) => _ident.Equals(other._ident);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssRunningValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context) => this;
#endregion
}

Просмотреть файл

@ -3,18 +3,17 @@ namespace AngleSharp.Css.Values
using AngleSharp.Css.Dom;
using AngleSharp.Text;
using System;
using System.Globalization;
/// <summary>
/// Represents the scale3d transformation.
/// </summary>
sealed class CssScaleValue : ICssTransformFunctionValue
sealed class CssScaleValue : ICssTransformFunctionValue, IEquatable<CssScaleValue>
{
#region Fields
private readonly Double _sx;
private readonly Double _sy;
private readonly Double _sz;
private readonly ICssValue _sx;
private readonly ICssValue _sy;
private readonly ICssValue _sz;
#endregion
@ -26,7 +25,7 @@ namespace AngleSharp.Css.Values
/// <param name="sx">The x scaling factor.</param>
/// <param name="sy">The y scaling factor.</param>
/// <param name="sz">The z scaling factor.</param>
public CssScaleValue(Double sx, Double sy, Double sz)
public CssScaleValue(ICssValue sx, ICssValue sy, ICssValue sz)
{
_sx = sx;
_sy = sy;
@ -44,24 +43,26 @@ namespace AngleSharp.Css.Values
{
get
{
if (_sz == 1f)
if (_sx is null && _sz is null)
{
return FunctionNames.ScaleY;
}
else if (_sy is null && _sz is null)
{
return FunctionNames.ScaleX;
}
else if (_sx is null && _sy is null)
{
return FunctionNames.ScaleX;
}
else if (_sz is null)
{
if (_sx != _sy)
{
if (_sx == 1f)
{
return FunctionNames.ScaleY;
}
else if (_sy == 1f)
{
return FunctionNames.ScaleX;
}
}
return FunctionNames.Scale;
}
return FunctionNames.Scale3d;
else
{
return FunctionNames.Scale3d;
}
}
}
@ -70,9 +71,9 @@ namespace AngleSharp.Css.Values
/// </summary>
public ICssValue[] Arguments => new ICssValue[]
{
new CssLengthValue(_sx, CssLengthValue.Unit.None),
new CssLengthValue(_sy, CssLengthValue.Unit.None),
new CssLengthValue(_sz, CssLengthValue.Unit.None),
_sx,
_sy,
_sz,
};
/// <summary>
@ -82,68 +83,84 @@ namespace AngleSharp.Css.Values
{
get
{
var args = String.Empty;
if (_sz == 1.0)
if (_sx is null && _sz is null)
{
if (_sx == _sy || _sy == 1.0)
{
args = _sx.ToString(CultureInfo.InvariantCulture);
}
else if (_sx == 1.0)
{
args = _sy.ToString(CultureInfo.InvariantCulture);
}
else
{
args = String.Concat(
_sx.ToString(CultureInfo.InvariantCulture), ", ",
_sy.ToString(CultureInfo.InvariantCulture));
}
return FunctionNames.ScaleY.CssFunction(_sy.CssText);
}
else if (_sx != _sy || _sx != _sz)
else if (_sy is null && _sz is null)
{
args = String.Concat(
_sx.ToString(CultureInfo.InvariantCulture), ", ",
_sy.ToString(CultureInfo.InvariantCulture), ", ",
_sz.ToString(CultureInfo.InvariantCulture));
return FunctionNames.ScaleX.CssFunction(_sx.CssText);
}
else if (_sx is null && _sy is null)
{
return FunctionNames.ScaleZ.CssFunction($"{_sz.CssText}");
}
else if (_sz is null && _sx.Equals(_sy))
{
return FunctionNames.Scale.CssFunction(_sx.CssText);
}
else if (_sz is null)
{
return FunctionNames.Scale.CssFunction($"{_sx.CssText}, {_sy.CssText}");
}
else
{
return FunctionNames.Scale3d.CssFunction($"{_sx.CssText}, {_sy.CssText}, {_sz.CssText}");
}
return Name.CssFunction(args);
}
}
/// <summary>
/// Gets the scaling in x-direction.
/// </summary>
public Double ScaleX => _sx;
public ICssValue ScaleX => _sx;
/// <summary>
/// Gets the scaling in y-direction.
/// </summary>
public Double ScaleY => _sy;
public ICssValue ScaleY => _sy;
/// <summary>
/// Gets the scaling in z-direction.
/// </summary>
public Double ScaleZ => _sz;
public ICssValue ScaleZ => _sz;
#endregion
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssScaleValue other)
{
return _sx.Equals(other._sx) && _sy.Equals(other._sy) && _sz.Equals(other._sz);
}
/// <summary>
/// Computes the matrix for the given transformation.
/// </summary>
/// <returns>The transformation matrix representation.</returns>
public TransformMatrix ComputeMatrix(IRenderDimensions renderDimensions) =>
new(_sx, 0f, 0f, 0f, _sy, 0f, 0f, 0f, _sz, 0f, 0f, 0f, 0f, 0f, 0f);
public TransformMatrix ComputeMatrix(IRenderDimensions renderDimensions)
{
var sx = _sx?.AsDouble() ?? 1.0;
var sy = _sy?.AsDouble() ?? 1.0;
var sz = _sz?.AsDouble() ?? 1.0;
return new TransformMatrix(sx, 0f, 0f, 0f, sy, 0f, 0f, 0f, sz, 0f, 0f, 0f, 0f, 0f, 0f);
}
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return new CssScaleValue(_sx, _sy, _sz);
var sx = _sx?.Compute(context);
var sy = _sy?.Compute(context);
var sz = _sz?.Compute(context);
return new CssScaleValue(sx, sy, sz);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssScaleValue value && Equals(value);
#endregion
}
}

Просмотреть файл

@ -9,7 +9,7 @@ namespace AngleSharp.Css.Values
/// Represents a CSS shape.
/// https://developer.mozilla.org/en-US/docs/Web/CSS/shape
/// </summary>
public sealed class CssShapeValue : ICssValue, ICssFunctionValue
public sealed class CssShapeValue : ICssValue, ICssFunctionValue, IEquatable<CssShapeValue>
{
#region Fields
@ -86,6 +86,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssShapeValue other)
{
return _top.Equals(other._top) && _right.Equals(other._right) && _bottom.Equals(other._bottom) && _left.Equals(other._left);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssShapeValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
var top = _top.Compute(context);

Просмотреть файл

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents the skew transformation.
/// </summary>
public sealed class CssSkewValue : ICssTransformFunctionValue
public sealed class CssSkewValue : ICssTransformFunctionValue, IEquatable<CssSkewValue>
{
#region Fields
@ -100,14 +100,26 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssSkewValue other)
{
return _alpha.Equals(other._alpha) && _beta.Equals(other._beta);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssSkewValue value && Equals(value);
/// <summary>
/// Computes the matrix for the given transformation.
/// </summary>
/// <returns>The transformation matrix representation.</returns>
public TransformMatrix ComputeMatrix(IRenderDimensions renderDimensions)
{
var a = Math.Tan((_alpha as Angle ? ?? Angle.Zero).ToRadian());
var b = Math.Tan((_beta as Angle? ?? Angle.Zero).ToRadian());
var a = Math.Tan((_alpha as CssAngleValue ? ?? CssAngleValue.Zero).ToRadian());
var b = Math.Tan((_beta as CssAngleValue? ?? CssAngleValue.Zero).ToRadian());
return new TransformMatrix(1.0, a, 0.0, b, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
}

Просмотреть файл

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// Represents a steps timing-function object.
/// https://developer.mozilla.org/en-US/docs/Web/CSS/timing-function
/// </summary>
sealed class CssStepsValue : ICssTimingFunctionValue
sealed class CssStepsValue : ICssTimingFunctionValue, IEquatable<CssStepsValue>
{
#region Fields
@ -101,6 +101,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssStepsValue other)
{
return _start == other._start && _intervals == other._intervals;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssStepsValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;

Просмотреть файл

@ -9,7 +9,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS symbols function call.
/// </summary>
public sealed class CssSymbolsValue : ICssFunctionValue
public sealed class CssSymbolsValue : ICssFunctionValue, IEquatable<CssSymbolsValue>
{
#region Fields
@ -59,6 +59,36 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssSymbolsValue other)
{
var l = _entries.Count;
if (_type.Equals(other._type) && l == other._entries.Count)
{
for (var i = 0; i < l; i++)
{
var a = _entries[i];
var b = other._entries[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssSymbolsValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
if (_type == null)

Просмотреть файл

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents the translate3d transformation.
/// </summary>
sealed class CssTranslateValue : ICssTransformFunctionValue
sealed class CssTranslateValue : ICssTransformFunctionValue, IEquatable<CssTranslateValue>
{
#region Fields
@ -99,18 +99,27 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssTranslateValue other)
{
return _x.Equals(other._x) && _y.Equals(other._y) && _z.Equals(other._z);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssTranslateValue value && Equals(value);
/// <summary>
/// Computes the matrix for the given transformation.
/// </summary>
/// <returns>The transformation matrix representation.</returns>
public TransformMatrix ComputeMatrix(IRenderDimensions renderDimensions)
{
var x = _x as CssLengthValue? ?? CssLengthValue.Zero;
var y = _y as CssLengthValue? ?? CssLengthValue.Zero;
var z = _z as CssLengthValue? ?? CssLengthValue.Zero;
var dx = x.ToPixel(renderDimensions, RenderMode.Horizontal);
var dy = y.ToPixel(renderDimensions, RenderMode.Vertical);
var dz = z.ToPixel(renderDimensions, RenderMode.Undefined);
var dx = _x.AsPx(renderDimensions, RenderMode.Horizontal);
var dy = _y.AsPx(renderDimensions, RenderMode.Vertical);
var dz = _z.AsPx(renderDimensions, RenderMode.Undefined);
return new TransformMatrix(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, dx, dy, dz, 0.0, 0.0, 0.0);
}

Просмотреть файл

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// Represents an URL object.
/// https://developer.mozilla.org/en-US/docs/Web/CSS/uri
/// </summary>
public sealed class CssUrlValue : ICssImageValue, ICssFunctionValue
public sealed class CssUrlValue : ICssImageValue, ICssFunctionValue, IEquatable<CssUrlValue>
{
#region Fields
@ -55,6 +55,18 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssUrlValue other)
{
return _path.Equals(other._path);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssUrlValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;

Просмотреть файл

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS var replacement.
/// </summary>
public sealed class CssVarValue : ICssFunctionValue
public sealed class CssVarValue : ICssFunctionValue, IEquatable<CssVarValue>
{
#region Fields
@ -96,6 +96,16 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssVarValue other)
{
return _defaultValue.Equals(other._defaultValue) && _variableName.Equals(other._variableName);
}
/// <summary>
/// Resolves the value of the referenced variable. Returns null
/// if the reference is invalid or cannot be resolved.
@ -114,6 +124,8 @@ namespace AngleSharp.Css.Values
return _defaultValue?.Compute(context);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssVarValue value && Equals(value);
#endregion
}
}

Просмотреть файл

@ -1,5 +1,6 @@
namespace AngleSharp.Css.Values
{
using AngleSharp.Css.Dom;
using System;
/// <summary>
@ -10,7 +11,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets an enumeration of all stops.
/// </summary>
CssGradientStopValue[] Stops { get; }
ICssValue[] Stops { get; }
/// <summary>
/// Gets if the gradient is repeating.

Просмотреть файл

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a flow relative CSS value.
/// </summary>
public class CssFlowRelativeValue<T> : ICssMultipleValue
public class CssFlowRelativeValue<T> : ICssMultipleValue, IEquatable<CssFlowRelativeValue<T>>
where T : ICssValue
{
#region Fields
@ -84,6 +84,34 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssFlowRelativeValue<T> other)
{
var count = _values.Length;
if (count == other._values.Length)
{
for (var i = 0; i < count; i++)
{
var a = _values[i];
var b = other._values[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator()
{
yield return Start;
@ -98,6 +126,8 @@ namespace AngleSharp.Css.Values
return new CssFlowRelativeValue<T>(values);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssFlowRelativeValue<T> value && Equals(value);
#endregion
}

Просмотреть файл

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a CSS value list.
/// </summary>
public class CssListValue<T> : ICssMultipleValue
public class CssListValue<T> : ICssMultipleValue, IEquatable<CssListValue<T>>
where T : ICssValue
{
#region Fields
@ -50,6 +50,34 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssListValue<T> other)
{
var count = _items.Length;
if (count == other._items.Length)
{
for (var i = 0; i < count; i++)
{
var a = _items[i];
var b = other._items[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator() =>
_items.OfType<ICssValue>().GetEnumerator();
@ -61,6 +89,8 @@ namespace AngleSharp.Css.Values
return new CssListValue<T>(items);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssListValue<T> value && Equals(value);
#endregion
}

Просмотреть файл

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a periodic CSS value.
/// </summary>
public class CssPeriodicValue<T> : ICssMultipleValue
public class CssPeriodicValue<T> : ICssMultipleValue, IEquatable<CssPeriodicValue<T>>
where T : ICssValue
{
#region Fields
@ -104,6 +104,34 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssPeriodicValue<T> other)
{
var count = _values.Length;
if (count == other._values.Length)
{
for (var i = 0; i < count; i++)
{
var a = _values[i];
var b = other._values[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator()
{
yield return Top;
@ -120,6 +148,8 @@ namespace AngleSharp.Css.Values
return new CssPeriodicValue<T>(values);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssPeriodicValue<T> value && Equals(value);
#endregion
}

Просмотреть файл

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a periodic CSS value.
/// </summary>
public class CssRadiusValue<T> : ICssMultipleValue
public class CssRadiusValue<T> : ICssMultipleValue, IEquatable<CssRadiusValue<T>>
where T : ICssValue
{
#region Fields
@ -84,6 +84,34 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssRadiusValue<T> other)
{
var count = _values.Length;
if (count == other._values.Length)
{
for (var i = 0; i < count; i++)
{
var a = _values[i];
var b = other._values[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator()
{
yield return Width;
@ -98,6 +126,8 @@ namespace AngleSharp.Css.Values
return new CssRadiusValue<T>(values);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssRadiusValue<T> value && Equals(value);
#endregion
}

Просмотреть файл

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a tuple of CSS values.
/// </summary>
public class CssTupleValue<T> : ICssMultipleValue
public class CssTupleValue<T> : ICssMultipleValue, IEquatable<CssTupleValue<T>>
where T : ICssValue
{
#region Fields
@ -58,6 +58,34 @@ namespace AngleSharp.Css.Values
#region Methods
/// <summary>
/// Checks if the current value is equal to the provided one.
/// </summary>
/// <param name="other">The value to check against.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssTupleValue<T> other)
{
var count = _items.Length;
if (_separator.Equals(other._separator) && count == other._items.Length)
{
for (var i = 0; i < count; i++)
{
var a = _items[i];
var b = other._items[i];
if (!a.Equals(b))
{
return false;
}
}
return true;
}
return false;
}
IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator() =>
_items.OfType<ICssValue>().GetEnumerator();
@ -69,6 +97,8 @@ namespace AngleSharp.Css.Values
return new CssTupleValue<T>(items, _separator);
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssTupleValue<T> value && Equals(value);
#endregion
}

Просмотреть файл

@ -7,34 +7,34 @@ namespace AngleSharp.Css.Values
/// Represents an angle object.
/// https://developer.mozilla.org/en-US/docs/Web/CSS/angle
/// </summary>
public readonly struct Angle : IEquatable<Angle>, IComparable<Angle>, ICssMetricValue
public readonly struct CssAngleValue : IEquatable<CssAngleValue>, IComparable<CssAngleValue>, ICssMetricValue
{
#region Basic angles
/// <summary>
/// The zero angle.
/// </summary>
public static readonly Angle Zero = new(0.0, Angle.Unit.Rad);
public static readonly CssAngleValue Zero = new(0.0, CssAngleValue.Unit.Rad);
/// <summary>
/// The 45° angle.
/// </summary>
public static readonly Angle HalfQuarter = new(45.0, Angle.Unit.Deg);
public static readonly CssAngleValue HalfQuarter = new(45.0, CssAngleValue.Unit.Deg);
/// <summary>
/// The 90° angle.
/// </summary>
public static readonly Angle Quarter = new(90.0, Angle.Unit.Deg);
public static readonly CssAngleValue Quarter = new(90.0, CssAngleValue.Unit.Deg);
/// <summary>
/// The 135° angle.
/// </summary>
public static readonly Angle TripleHalfQuarter = new(135.0, Angle.Unit.Deg);
public static readonly CssAngleValue TripleHalfQuarter = new(135.0, CssAngleValue.Unit.Deg);
/// <summary>
/// The 180° angle.
/// </summary>
public static readonly Angle Half = new(180.0, Angle.Unit.Deg);
public static readonly CssAngleValue Half = new(180.0, CssAngleValue.Unit.Deg);
#endregion
@ -51,7 +51,7 @@ namespace AngleSharp.Css.Values
/// Creates a new angle value.
/// </summary>
/// <param name="value">The value of the angle in rad.</param>
public Angle(Double value)
public CssAngleValue(Double value)
: this(value, Unit.Rad)
{
}
@ -61,7 +61,7 @@ namespace AngleSharp.Css.Values
/// </summary>
/// <param name="value">The value of the angle.</param>
/// <param name="unit">The unit of the angle.</param>
public Angle(Double value, Unit unit)
public CssAngleValue(Double value, Unit unit)
{
_value = value;
_unit = unit;
@ -111,7 +111,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Compares the magnitude of two angles.
/// </summary>
public static Boolean operator >=(Angle a, Angle b)
public static Boolean operator >=(CssAngleValue a, CssAngleValue b)
{
var result = a.CompareTo(b);
return result == 0 || result == 1;
@ -120,12 +120,12 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Compares the magnitude of two angles.
/// </summary>
public static Boolean operator >(Angle a, Angle b) => a.CompareTo(b) == 1;
public static Boolean operator >(CssAngleValue a, CssAngleValue b) => a.CompareTo(b) == 1;
/// <summary>
/// Compares the magnitude of two angles.
/// </summary>
public static Boolean operator <=(Angle a, Angle b)
public static Boolean operator <=(CssAngleValue a, CssAngleValue b)
{
var result = a.CompareTo(b);
return result == 0 || result == -1;
@ -134,14 +134,14 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Compares the magnitude of two angles.
/// </summary>
public static Boolean operator <(Angle a, Angle b) => a.CompareTo(b) == -1;
public static Boolean operator <(CssAngleValue a, CssAngleValue b) => a.CompareTo(b) == -1;
/// <summary>
/// Compares the current angle against the given one.
/// </summary>
/// <param name="other">The angle to compare to.</param>
/// <returns>The result of the comparison.</returns>
public Int32 CompareTo(Angle other) => ToRadian().CompareTo(other.ToRadian());
public Int32 CompareTo(CssAngleValue other) => ToRadian().CompareTo(other.ToRadian());
#endregion
@ -152,7 +152,7 @@ namespace AngleSharp.Css.Values
if (_unit != Unit.Rad)
{
var rad = ToRadian();
return new Angle(rad, Unit.Rad);
return new CssAngleValue(rad, Unit.Rad);
}
return this;
@ -164,13 +164,13 @@ namespace AngleSharp.Css.Values
/// <param name="s">The string to convert.</param>
/// <param name="result">The reference to the result.</param>
/// <returns>True if successful, otherwise false.</returns>
public static Boolean TryParse(String s, out Angle result)
public static Boolean TryParse(String s, out CssAngleValue result)
{
var unit = GetUnit(s.CssUnit(out double value));
if (unit != Unit.None)
{
result = new Angle(value, unit);
result = new CssAngleValue(value, unit);
return true;
}
@ -225,12 +225,27 @@ namespace AngleSharp.Css.Values
};
}
/// <summary>
/// Converts the contained value to degree.
/// </summary>
/// <returns>The value in degree.</returns>
public Double ToDegree()
{
return _unit switch
{
Unit.Turn => _value * 360.0,
Unit.Grad => _value * (360.0 / 400.0),
Unit.Rad => _value / (180.0 / Math.PI),
_ => _value,
};
}
/// <summary>
/// Checks for equality with the other angle.
/// </summary>
/// <param name="other">The angle to compare with.</param>
/// <returns>True if both represent the same angle in rad.</returns>
public Boolean Equals(Angle other) => ToRadian() == other.ToRadian();
public Boolean Equals(CssAngleValue other) => ToRadian() == other.ToRadian();
#endregion
@ -270,12 +285,12 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Checks for equality of two angles.
/// </summary>
public static Boolean operator ==(Angle a, Angle b) => a.Equals(b);
public static Boolean operator ==(CssAngleValue a, CssAngleValue b) => a.Equals(b);
/// <summary>
/// Checks for inequality of two angles.
/// </summary>
public static Boolean operator !=(Angle a, Angle b) => !a.Equals(b);
public static Boolean operator !=(CssAngleValue a, CssAngleValue b) => !a.Equals(b);
/// <summary>
/// Tests if another object is equal to this object.
@ -284,7 +299,7 @@ namespace AngleSharp.Css.Values
/// <returns>True if the two objects are equal, otherwise false.</returns>
public override Boolean Equals(Object obj)
{
var other = obj as Angle?;
var other = obj as CssAngleValue?;
if (other != null)
{
@ -294,6 +309,8 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssAngleValue value && Equals(value);
/// <summary>
/// Returns a hash code that defines the current angle.
/// </summary>

Просмотреть файл

@ -585,6 +585,8 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssColorValue value && Equals(value);
Int32 IComparable<CssColorValue>.CompareTo(CssColorValue other) => _hashcode - other._hashcode;
/// <summary>

Просмотреть файл

@ -62,6 +62,8 @@ namespace AngleSharp.Css.Values
public override Boolean Equals(Object obj) =>
obj is CssConstantValue<T> constant && Equals(constant);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssConstantValue<T> value && Equals(value);
/// <summary>
/// Gets the computed hash code of the constant.
/// </summary>

Просмотреть файл

@ -72,6 +72,8 @@ namespace AngleSharp.Css.Values
ListStyle.Is(other.ListStyle) &&
DefinedSeparator.Is(other.DefinedSeparator);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssCounterDefinitionValue value && Equals(value);
/// <summary>
/// Checks for equality against the given object, if
/// the provided object is no counter definition the

Просмотреть файл

@ -59,6 +59,8 @@ namespace AngleSharp.Css.Values
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssCounterValue other) => Name.Is(other.Name) && Value == other.Value;
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssCounterValue value && Equals(value);
/// <summary>
/// Checks for equality against the given object,
/// if the provided object is no counter value the

Просмотреть файл

@ -175,6 +175,8 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssFractionValue value && Equals(value);
/// <summary>
/// Returns a hash code that defines the current fraction.
/// </summary>

Просмотреть файл

@ -228,6 +228,8 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssFrequencyValue value && Equals(value);
/// <summary>
/// Returns a hash code that defines the current frequency.
/// </summary>

Просмотреть файл

@ -61,6 +61,8 @@ namespace AngleSharp.Css.Values
public override Boolean Equals(Object obj) =>
obj is CssIdentifierValue ident && Equals(ident);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssIdentifierValue value && Equals(value);
/// <summary>
/// Gets the hash code of the object.
/// </summary>

Просмотреть файл

@ -120,6 +120,8 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssIntegerValue value && Equals(value);
/// <summary>
/// Returns a hash code that defines the current integer.
/// </summary>

Просмотреть файл

@ -547,6 +547,8 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssLengthValue value && Equals(value);
/// <summary>
/// Returns a hash code that defines the current length.
/// </summary>

Просмотреть файл

@ -71,6 +71,8 @@ namespace AngleSharp.Css.Values
/// <returns>The computed hash code.</returns>
public override Int32 GetHashCode() => CssText.GetHashCode();
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssLineNamesValue value && Equals(value);
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;

Просмотреть файл

@ -8,6 +8,20 @@ namespace AngleSharp.Css.Values
/// </summary>
public readonly struct CssNumberValue : IEquatable<CssNumberValue>, IComparable<CssNumberValue>, ICssMetricValue
{
#region Basic lengths
/// <summary>
/// Gets the 0.0.
/// </summary>
public static readonly CssNumberValue Zero = new(0.0);
/// <summary>
/// Gets the 1.0.
/// </summary>
public static readonly CssNumberValue One = new(0.0);
#endregion
#region Fields
private readonly Double _value;
@ -105,6 +119,7 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssNumberValue value && Equals(value);
/// <summary>
/// Returns a hash code that defines the current number.

Просмотреть файл

@ -8,6 +8,25 @@ namespace AngleSharp.Css.Values
/// </summary>
public readonly struct CssPercentageValue : IEquatable<CssPercentageValue>, IComparable<CssPercentageValue>, ICssMetricValue
{
#region Basic percentages
/// <summary>
/// Gets a zero percentage value.
/// </summary>
public static readonly CssPercentageValue Zero = new(0.0);
/// <summary>
/// Gets the half relative length, i.e. 50%.
/// </summary>
public static readonly CssPercentageValue Half = new(50.0);
/// <summary>
/// Gets the full relative length, i.e. 100%.
/// </summary>
public static readonly CssPercentageValue Full = new(100.0);
#endregion
#region Fields
private readonly Double _value;
@ -175,6 +194,8 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssPercentageValue value && Equals(value);
/// <summary>
/// Returns a hash code that defines the current percentage.
/// </summary>

Просмотреть файл

@ -73,6 +73,7 @@ namespace AngleSharp.Css.Values
/// <returns>True if both are equal, otherwise false.</returns>
public override Boolean Equals(Object obj) =>
obj is CssQuoteValue quote && Equals(quote);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssQuoteValue value && Equals(value);
/// <summary>
/// Gets the hash code of the object.

Просмотреть файл

@ -1,107 +0,0 @@
namespace AngleSharp.Css.Values
{
using AngleSharp.Css.Dom;
using System;
/// <summary>
/// Represents a ratio (top to bottom) value.
/// </summary>
public readonly struct CssRatioValue : IEquatable<CssRatioValue>, IComparable<CssRatioValue>, ICssPrimitiveValue
{
#region Fields
private readonly Double _top;
private readonly Double _bottom;
#endregion
#region ctor
/// <summary>
/// Creates a new ratio value.
/// </summary>
/// <param name="top">The first number.</param>
/// <param name="bottom">The second number.</param>
public CssRatioValue(Double top, Double bottom)
{
_top = top;
_bottom = bottom;
}
#endregion
#region Properties
/// <summary>
/// Gets the CSS text representation.
/// </summary>
public String CssText => String.Concat(_top.CssStringify(), "/", _bottom.CssStringify());
/// <summary>
/// Gets the first number of the ratio.
/// </summary>
public Double Top => _top;
/// <summary>
/// Gets the second number of the ratio.
/// </summary>
public Double Bottom => _bottom;
/// <summary>
/// Gets the normalized (Top / Bottom) value.
/// </summary>
public Double Value => _top / _bottom;
#endregion
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
}
/// <summary>
/// Checks if the current resolution equals the given one.
/// </summary>
/// <param name="other">The given resolution to check for equality.</param>
/// <returns>True if both are equal, otherwise false.</returns>
public Boolean Equals(CssRatioValue other) => Value == other.Value;
#endregion
#region Equality
/// <summary>
/// Compares the current fraction against the given one.
/// </summary>
/// <param name="other">The fraction to compare to.</param>
/// <returns>The result of the comparison.</returns>
public Int32 CompareTo(CssRatioValue other) => Value.CompareTo(other.Value);
/// <summary>
/// Tests if another object is equal to this object.
/// </summary>
/// <param name="obj">The object to test with.</param>
/// <returns>True if the two objects are equal, otherwise false.</returns>
public override Boolean Equals(Object obj)
{
var other = obj as CssRatioValue?;
if (other != null)
{
return Equals(other.Value);
}
return false;
}
/// <summary>
/// Returns a hash code that defines the current fraction.
/// </summary>
/// <returns>The integer value of the hashcode.</returns>
public override Int32 GetHashCode() => Value.GetHashCode();
#endregion
}
}

Просмотреть файл

@ -225,6 +225,8 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssResolutionValue value && Equals(value);
/// <summary>
/// Returns a hash code that defines the current resolution.
/// </summary>

Просмотреть файл

@ -66,6 +66,8 @@ namespace AngleSharp.Css.Values
public override Boolean Equals(Object obj) =>
obj is CssStringValue str && Equals(str);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssStringValue value && Equals(value);
/// <summary>
/// Gets the hash code of the object.
/// </summary>

Просмотреть файл

@ -237,6 +237,8 @@ namespace AngleSharp.Css.Values
return false;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssTimeValue value && Equals(value);
/// <summary>
/// Returns a hash code that defines the current time.
/// </summary>

Просмотреть файл

@ -57,6 +57,8 @@ namespace AngleSharp.Css.Values
return null;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssAnyValue o && _text.Equals(o.CssText);
#endregion
}
}

Просмотреть файл

@ -37,10 +37,9 @@ namespace AngleSharp.Css.Values
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
}
ICssValue ICssValue.Compute(ICssComputeContext context) => this;
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => Object.ReferenceEquals(this, other);
#endregion
}

Просмотреть файл

@ -43,10 +43,9 @@ namespace AngleSharp.Css.Values
#region Methods
ICssValue ICssValue.Compute(ICssComputeContext context)
{
return this;
}
ICssValue ICssValue.Compute(ICssComputeContext context) => this;
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssInitialValue o && _value.Equals(o.Value);
#endregion
}

Просмотреть файл

@ -76,6 +76,8 @@ namespace AngleSharp.Css.Values
return null;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => Object.ReferenceEquals(this, other);
#endregion
}
}

Просмотреть файл

@ -48,6 +48,8 @@ namespace AngleSharp.Css.Values
return this;
}
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssUnsetValue o && _value.Equals(o.Value);
#endregion
}
}

Просмотреть файл

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// Represents a transformation matrix value.
/// http://dev.w3.org/csswg/css-transforms/#mathematical-description
/// </summary>
public class TransformMatrix : IEquatable<TransformMatrix>
public sealed class TransformMatrix : IEquatable<TransformMatrix>
{
#region Fields