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 to use AngleSharp 1.0 (#150)
- Updated media parsing to media L4 spec (#133) - 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 when updating shorthands with invalid values (#129)
- Fixed issue with appended EOF character in `CssText` (#123) - Fixed issue with appended EOF character in `CssText` (#123)
- Fixed missing semicolon in `@page` rule (#135) - Fixed missing semicolon in `@page` rule (#135)
@ -15,6 +16,7 @@ Released on tbd.
- Fixed `GetInnerText` multi-line / text node behavior (#155) @Seyden - Fixed `GetInnerText` multi-line / text node behavior (#155) @Seyden
- Fixed computation of relative (`em`) values to absolute (`px`) for `Length` (#136) - Fixed computation of relative (`em`) values to absolute (`px`) for `Length` (#136)
- Added further compactification of CSS tuples (#89, #93) - 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 support for CSS nesting in style rules (#148)
- Added resolution of CSS variable names (#62) - Added resolution of CSS variable names (#62)
- Added support for 8-digit hex color codes (#132) - 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) * [Fraaankes](https://github.com/Fraaankes)
* [Eric Mutta](https://github.com/ericmutta) * [Eric Mutta](https://github.com/ericmutta)
* [Seyden](https://github.com/Seyden) * [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: 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; var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsNotNull(gradient); Assert.IsNotNull(gradient);
Assert.IsFalse(gradient.IsRepeating); Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.TripleHalfQuarter, gradient.Angle); Assert.AreEqual(CssAngleValue.TripleHalfQuarter, gradient.Angle);
Assert.AreEqual(2, gradient.Stops.Length); Assert.AreEqual(2, gradient.Stops.Length);
Assert.AreEqual(red, gradient.Stops.First().Color); Assert.AreEqual(red, gradient.Stops.OfType<CssGradientStopValue>().First().Color);
Assert.AreEqual(blue, gradient.Stops.Last().Color); Assert.AreEqual(blue, gradient.Stops.OfType<CssGradientStopValue>().Last().Color);
Assert.AreEqual(source, property.CssText); Assert.AreEqual(source, property.CssText);
} }
@ -61,16 +61,16 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(1, value.Items.Length); Assert.AreEqual(1, value.Items.Length);
var gradient = value.Items[0] as CssLinearGradientValue; var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsFalse(gradient.IsRepeating); Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.Quarter, gradient.Angle); Assert.AreEqual(CssAngleValue.Quarter, gradient.Angle);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(7, stops.Length); Assert.AreEqual(7, stops.Length);
Assert.AreEqual(CssColors.GetColor("red").Value, stops[0].Color); Assert.AreEqual(CssColors.GetColor("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColors.GetColor("orange").Value, stops[1].Color); Assert.AreEqual(CssColors.GetColor("orange").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColors.GetColor("yellow").Value, stops[2].Color); Assert.AreEqual(CssColors.GetColor("yellow").Value, ((CssGradientStopValue)stops[2]).Color);
Assert.AreEqual(CssColors.GetColor("green").Value, stops[3].Color); Assert.AreEqual(CssColors.GetColor("green").Value, ((CssGradientStopValue)stops[3]).Color);
Assert.AreEqual(CssColors.GetColor("blue").Value, stops[4].Color); Assert.AreEqual(CssColors.GetColor("blue").Value, ((CssGradientStopValue)stops[4]).Color);
Assert.AreEqual(CssColors.GetColor("indigo").Value, stops[5].Color); Assert.AreEqual(CssColors.GetColor("indigo").Value, ((CssGradientStopValue)stops[5]).Color);
Assert.AreEqual(CssColors.GetColor("violet").Value, stops[6].Color); Assert.AreEqual(CssColors.GetColor("violet").Value, ((CssGradientStopValue)stops[6]).Color);
} }
[Test] [Test]
@ -85,10 +85,10 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(1, value.Items.Length); Assert.AreEqual(1, value.Items.Length);
var gradient = value.Items[0] as CssLinearGradientValue; var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsFalse(gradient.IsRepeating); Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.TripleHalfQuarter, gradient.Angle); Assert.AreEqual(CssAngleValue.TripleHalfQuarter, gradient.Angle);
Assert.AreEqual(2, gradient.Stops.Count()); Assert.AreEqual(2, gradient.Stops.Count());
Assert.AreEqual(CssColorValue.Red, gradient.Stops.First().Color); Assert.AreEqual(CssColorValue.Red, gradient.Stops.OfType<CssGradientStopValue>().First().Color);
Assert.AreEqual(CssColorValue.FromRgba(255, 0, 0, 0), gradient.Stops.Last().Color); Assert.AreEqual(CssColorValue.FromRgba(255, 0, 0, 0), gradient.Stops.OfType<CssGradientStopValue>().Last().Color);
} }
[Test] [Test]
@ -103,10 +103,10 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(1, value.Items.Length); Assert.AreEqual(1, value.Items.Length);
var gradient = value.Items[0] as CssLinearGradientValue; var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsFalse(gradient.IsRepeating); Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.Half, gradient.Angle); Assert.AreEqual(CssAngleValue.Half, gradient.Angle);
Assert.AreEqual(2, gradient.Stops.Count()); Assert.AreEqual(2, gradient.Stops.Count());
Assert.AreEqual(CssColorValue.FromHsl(0f, 0.8f, 0.7f), gradient.Stops.First().Color); Assert.AreEqual(CssColorValue.FromHsl(0f, 0.8f, 0.7f), gradient.Stops.OfType<CssGradientStopValue>().First().Color);
Assert.AreEqual(CssColorValue.FromHex("bada55"), gradient.Stops.Last().Color); Assert.AreEqual(CssColorValue.FromHex("bada55"), gradient.Stops.OfType<CssGradientStopValue>().Last().Color);
} }
[Test] [Test]
@ -121,11 +121,11 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(1, value.Items.Length); Assert.AreEqual(1, value.Items.Length);
var gradient = value.Items[0] as CssLinearGradientValue; var gradient = value.Items[0] as CssLinearGradientValue;
Assert.IsFalse(gradient.IsRepeating); Assert.IsFalse(gradient.IsRepeating);
Assert.AreEqual(Angle.Half, gradient.Angle); Assert.AreEqual(CssAngleValue.Half, gradient.Angle);
Assert.AreEqual(3, gradient.Stops.Count()); Assert.AreEqual(3, gradient.Stops.Count());
Assert.AreEqual(CssColors.GetColor("yellow").Value, gradient.Stops.First().Color); Assert.AreEqual(CssColors.GetColor("yellow").Value, gradient.Stops.OfType<CssGradientStopValue>().First().Color);
Assert.AreEqual(CssColors.GetColor("blue").Value, gradient.Stops.Skip(1).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.Skip(2).First().Color); Assert.AreEqual(CssColorValue.FromRgb(0, 255, 0), gradient.Stops.OfType<CssGradientStopValue>().Skip(2).First().Color);
} }
[Test] [Test]
@ -146,9 +146,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length); Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromRgb(0, 255, 255), stops[0].Color); Assert.AreEqual(CssColorValue.FromRgb(0, 255, 255), ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromRgba(0, 0, 255, 0), stops[1].Color); Assert.AreEqual(CssColorValue.FromRgba(0, 0, 255, 0), ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 255), stops[2].Color); Assert.AreEqual(CssColorValue.FromRgb(0, 0, 255), ((CssGradientStopValue)stops[2]).Color);
} }
[Test] [Test]
@ -169,9 +169,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length); Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromRgb(0xFF, 0xFF, 0x80), stops[0].Color); Assert.AreEqual(CssColorValue.FromRgb(0xFF, 0xFF, 0x80), ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromRgba(204, 153, 153, 0.4f), stops[1].Color); Assert.AreEqual(CssColorValue.FromRgba(204, 153, 153, 0.4f), ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromRgb(0xE6, 0xE6, 0xFF), stops[2].Color); Assert.AreEqual(CssColorValue.FromRgb(0xE6, 0xE6, 0xFF), ((CssGradientStopValue)stops[2]).Color);
} }
[Test] [Test]
@ -192,8 +192,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length); Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromRgb(255, 0, 0), stops[0].Color); Assert.AreEqual(CssColorValue.FromRgb(255, 0, 0), ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 255), stops[1].Color); Assert.AreEqual(CssColorValue.FromRgb(0, 0, 255), ((CssGradientStopValue)stops[1]).Color);
} }
[Test] [Test]
@ -216,10 +216,10 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssLengthValue.Full, gradient.MinorRadius); Assert.AreEqual(CssLengthValue.Full, gradient.MinorRadius);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(4, stops.Length); Assert.AreEqual(4, stops.Length);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 0), stops[0].Color); Assert.AreEqual(CssColorValue.FromRgb(0, 0, 0), ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromRgb(0, 0, 0), stops[1].Color); Assert.AreEqual(CssColorValue.FromRgb(0, 0, 0), ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromRgba(0, 0, 0, 0.3), stops[2].Color); Assert.AreEqual(CssColorValue.FromRgba(0, 0, 0, 0.3), ((CssGradientStopValue)stops[2]).Color);
Assert.AreEqual(CssColorValue.Transparent, stops[3].Color); Assert.AreEqual(CssColorValue.Transparent, ((CssGradientStopValue)stops[3]).Color);
} }
[Test] [Test]
@ -240,8 +240,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length); Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[1]).Color);
} }
[Test] [Test]
@ -262,8 +262,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length); Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[1]).Color);
} }
[Test] [Test]
@ -284,8 +284,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length); Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[1]).Color);
} }
[Test] [Test]
@ -306,8 +306,8 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestCorner, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(2, stops.Length); Assert.AreEqual(2, stops.Length);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[1]).Color);
} }
[Test] [Test]
@ -328,9 +328,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.ClosestSide, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.ClosestSide, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length); Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color); Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
} }
[Test] [Test]
@ -353,9 +353,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(new CssLengthValue(30f, CssLengthValue.Unit.Px), gradient.MinorRadius); Assert.AreEqual(new CssLengthValue(30f, CssLengthValue.Unit.Px), gradient.MinorRadius);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length); Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color); Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
} }
[Test] [Test]
@ -376,9 +376,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.ClosestSide, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.ClosestSide, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length); Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color); Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
} }
[Test] [Test]
@ -399,9 +399,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestSide, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.FarthestSide, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length); Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color); Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
} }
[Test] [Test]
@ -418,9 +418,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.IsTrue(gradient.IsRepeating); Assert.IsTrue(gradient.IsRepeating);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length); Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("blue").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("blue").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[2].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[2]).Color);
} }
[Test] [Test]
@ -441,9 +441,9 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.None, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(3, stops.Length); Assert.AreEqual(3, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("blue").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("blue").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[2].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[2]).Color);
} }
[Test] [Test]
@ -464,11 +464,11 @@ namespace AngleSharp.Css.Tests.Values
Assert.AreEqual(CssRadialGradientValue.SizeMode.ClosestSide, gradient.Mode); Assert.AreEqual(CssRadialGradientValue.SizeMode.ClosestSide, gradient.Mode);
var stops = gradient.Stops.ToArray(); var stops = gradient.Stops.ToArray();
Assert.AreEqual(5, stops.Length); Assert.AreEqual(5, stops.Length);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[0].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[0]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[1].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[1]).Color);
Assert.AreEqual(CssColorValue.FromName("green").Value, stops[2].Color); Assert.AreEqual(CssColorValue.FromName("green").Value, ((CssGradientStopValue)stops[2]).Color);
Assert.AreEqual(CssColorValue.FromName("yellow").Value, stops[3].Color); Assert.AreEqual(CssColorValue.FromName("yellow").Value, ((CssGradientStopValue)stops[3]).Color);
Assert.AreEqual(CssColorValue.FromName("red").Value, stops[4].Color); Assert.AreEqual(CssColorValue.FromName("red").Value, ((CssGradientStopValue)stops[4]).Color);
} }
} }
} }

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

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

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

@ -26,16 +26,16 @@ namespace AngleSharp.Css
/// <summary> /// <summary>
/// Contains the string-Angle mapping for linear-gradients.s /// Contains the string-Angle mapping for linear-gradients.s
/// </summary> /// </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.Left, new CssAngleValue(270.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.Top, new Angle(0.0, Angle.Unit.Deg) }, { CssKeywords.Top, new CssAngleValue(0.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.Right, new Angle(90.0, Angle.Unit.Deg) }, { CssKeywords.Right, new CssAngleValue(90.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.Bottom, new Angle(180.0, Angle.Unit.Deg) }, { CssKeywords.Bottom, new CssAngleValue(180.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.LeftTop, new Angle(315.0, Angle.Unit.Deg) }, { CssKeywords.LeftTop, new CssAngleValue(315.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.LeftBottom, new Angle(225.0, Angle.Unit.Deg) }, { CssKeywords.LeftBottom, new CssAngleValue(225.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.RightTop, new Angle(45.0, Angle.Unit.Deg) }, { CssKeywords.RightTop, new CssAngleValue(45.0, CssAngleValue.Unit.Deg) },
{ CssKeywords.RightBottom, new Angle(135.0, Angle.Unit.Deg) }, { CssKeywords.RightBottom, new CssAngleValue(135.0, CssAngleValue.Unit.Deg) },
}; };
/// <summary> /// <summary>

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

@ -108,9 +108,9 @@ namespace AngleSharp.Css.Declarations
return null; 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) public ContentValue(ICssValue[] modes)
{ {
@ -124,6 +124,30 @@ namespace AngleSharp.Css.Declarations
var modes = _modes.Select(mode => mode.Compute(context)).ToArray(); var modes = _modes.Select(mode => mode.Compute(context)).ToArray();
return new ContentValue(modes); 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 private abstract class ContentMode : ICssValue
@ -134,10 +158,9 @@ namespace AngleSharp.Css.Declarations
public abstract String GetCssText(); public abstract String GetCssText();
ICssValue ICssValue.Compute(ICssComputeContext context) ICssValue ICssValue.Compute(ICssComputeContext context) => this;
{
return this; public virtual Boolean Equals(ICssValue other) => Object.ReferenceEquals(this, other);
}
} }
/// <summary> /// <summary>
@ -209,6 +232,16 @@ namespace AngleSharp.Css.Declarations
public override String GetCssText() => _text.CssString(); public override String GetCssText() => _text.CssString();
public override String Stringify(IElement element) => _text; 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> /// <summary>
@ -228,6 +261,16 @@ namespace AngleSharp.Css.Declarations
public override String GetCssText() => _counter.CssText; public override String GetCssText() => _counter.CssText;
public override String Stringify(IElement element) => String.Empty; 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> /// <summary>
@ -246,6 +289,16 @@ namespace AngleSharp.Css.Declarations
public override String GetCssText() => FunctionNames.Attr.CssFunction(_attribute); public override String GetCssText() => FunctionNames.Attr.CssFunction(_attribute);
public override String Stringify(IElement element) => element.GetAttribute(_attribute) ?? String.Empty; 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> /// <summary>
@ -265,6 +318,16 @@ namespace AngleSharp.Css.Declarations
public override String GetCssText() => _url.CssText; public override String GetCssText() => _url.CssText;
public override String Stringify(IElement element) => String.Empty; 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) public ICssValue Convert(StringSource source)
{ {
var cursor = default(ICssValue);
var definitions = new List<ICssValue>(); var definitions = new List<ICssValue>();
while (!source.IsDone) while (!source.IsDone)
{ {
var imageSource = source.ParseImageSource(); var imageSource = source.ParseImageSource();
var c = source.SkipSpacesAndComments(); source.SkipSpacesAndComments();
if (imageSource != null) if (imageSource != null)
{ {
var x = source.ParseNumber(); var x = source.ParseNumber();
c = source.SkipSpacesAndComments(); source.SkipSpacesAndComments();
var y = source.ParseNumber(); var y = source.ParseNumber();
c = source.SkipSpacesAndComments(); var c = source.SkipSpacesAndComments();
if (x.HasValue != y.HasValue || c != Symbols.Comma) if (x.HasValue != y.HasValue || c != Symbols.Comma)
break; break;
@ -44,16 +43,14 @@ namespace AngleSharp.Css.Declarations
if (x.HasValue) if (x.HasValue)
{ {
var xp = new CssLengthValue(x.Value, CssLengthValue.Unit.None); position = new CssPoint2D(x, y);
var yp = new CssLengthValue(y.Value, CssLengthValue.Unit.None);
position = new CssPoint2D(xp, yp);
} }
definitions.Add(new CssCustomCursorValue(imageSource, position)); definitions.Add(new CssCustomCursorValue(imageSource, position));
} }
else else
{ {
cursor = source.ParseConstant(Map.SystemCursors); var cursor = source.ParseConstant(Map.SystemCursors);
if (cursor != null) if (cursor != null)
{ {

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

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

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

@ -16,17 +16,41 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns> /// <returns>The resulting number.</returns>
public static Double AsDouble(this ICssValue value) 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) else if (value is CssFractionValue fr)
{ {
return fr.Value; 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) else if (value is ICssMultipleValue multiple && multiple.Count == 1)
{ {
@ -49,7 +73,11 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns> /// <returns>The resulting number.</returns>
public static Double AsPx(this ICssValue value, IRenderDimensions renderDimensions, RenderMode mode) 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); return length.ToPixel(renderDimensions, mode);
} }
@ -72,7 +100,11 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns> /// <returns>The resulting number.</returns>
public static Double AsMs(this ICssValue value) 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(); return time.ToMilliseconds();
} }
@ -95,7 +127,11 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns> /// <returns>The resulting number.</returns>
public static Double AsHz(this ICssValue value) 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(); return freq.ToHertz();
} }
@ -118,9 +154,13 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns> /// <returns>The resulting number.</returns>
public static Double AsDeg(this ICssValue value) 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) else if (value is ICssMultipleValue multiple && multiple.Count == 1)
{ {
@ -134,6 +174,33 @@ namespace AngleSharp.Css.Dom
return 0.0; 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> /// <summary>
/// Tries to convert the value to a number of dots per inch. /// Tries to convert the value to a number of dots per inch.
/// </summary> /// </summary>
@ -141,7 +208,11 @@ namespace AngleSharp.Css.Dom
/// <returns>The resulting number.</returns> /// <returns>The resulting number.</returns>
public static Double AsDpi(this ICssValue value) 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(); return res.ToDotsPerPixel();
} }

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

@ -166,10 +166,10 @@ namespace AngleSharp.Css.Parser
source.SkipSpacesAndComments(); source.SkipSpacesAndComments();
return new CssTimeValue(result, CssTimeValue.GetUnit(unit.Dimension)); 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(); 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) else if (CssFrequencyValue.GetUnit(unit.Dimension) != CssFrequencyValue.Unit.None)
{ {

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

@ -478,11 +478,11 @@ namespace AngleSharp.Css.Parser
if (unit != null && if (unit != null &&
Double.TryParse(unit.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var value)) 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(); return angle.ToTurns();
} }
} }

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

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

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

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

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

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

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

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

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

@ -4,7 +4,7 @@ namespace AngleSharp.Css.Values
using AngleSharp.Text; using AngleSharp.Text;
using System; using System;
sealed class CssBackgroundLayerValue : ICssCompositeValue sealed class CssBackgroundLayerValue : ICssCompositeValue, IEquatable<CssBackgroundLayerValue>
{ {
#region Fields #region Fields
@ -132,6 +132,22 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var image = _image.Compute(context); var image = _image.Compute(context);

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

@ -89,6 +89,15 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
if (_mode == ValueMode.Explicit) if (_mode == ValueMode.Explicit)
@ -101,13 +110,6 @@ namespace AngleSharp.Css.Values
return this; 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 #endregion
#region Value Mode #region Value Mode

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

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS background definition. /// Represents a CSS background definition.
/// </summary> /// </summary>
sealed class CssBackgroundValue : ICssCompositeValue sealed class CssBackgroundValue : ICssCompositeValue, IEquatable<CssBackgroundValue>
{ {
#region Fields #region Fields
@ -71,6 +71,18 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var layers = _layers.Compute(context); var layers = _layers.Compute(context);

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents the CSS border image slice definition. /// Represents the CSS border image slice definition.
/// </summary> /// </summary>
public sealed class CssBorderImageSliceValue : ICssCompositeValue public sealed class CssBorderImageSliceValue : ICssCompositeValue, IEquatable<CssBorderImageSliceValue>
{ {
#region Fields #region Fields
@ -117,6 +117,18 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var bottom = (CssLengthValue)((ICssValue)_bottom).Compute(context); var bottom = (CssLengthValue)((ICssValue)_bottom).Compute(context);

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS border image definition. /// Represents a CSS border image definition.
/// </summary> /// </summary>
sealed class CssBorderImageValue : ICssCompositeValue sealed class CssBorderImageValue : ICssCompositeValue, IEquatable<CssBorderImageValue>
{ {
#region Fields #region Fields
@ -113,6 +113,22 @@ namespace AngleSharp.Css.Values
#region #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var image = _image.Compute(context); var image = _image.Compute(context);

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

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a border radius value. /// Represents a border radius value.
/// </summary> /// </summary>
sealed class CssBorderRadiusValue : ICssCompositeValue sealed class CssBorderRadiusValue : ICssCompositeValue, IEquatable<CssBorderRadiusValue>
{ {
#region Fields #region Fields
@ -67,6 +67,18 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var h = ((ICssValue)_horizontal).Compute(context); var h = ((ICssValue)_horizontal).Compute(context);

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

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS cursor definition. /// Represents a CSS cursor definition.
/// </summary> /// </summary>
sealed class CssCursorValue : ICssCompositeValue sealed class CssCursorValue : ICssCompositeValue, IEquatable<CssCursorValue>
{ {
#region Fields #region Fields
@ -67,6 +67,36 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var cursor = _cursor.Compute(context); var cursor = _cursor.Compute(context);

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

@ -4,12 +4,12 @@ namespace AngleSharp.Css.Values
using AngleSharp.Text; using AngleSharp.Text;
using System; using System;
sealed class CssCustomCursorValue : ICssCompositeValue sealed class CssCustomCursorValue : ICssCompositeValue, IEquatable<CssCustomCursorValue>
{ {
#region Fields #region Fields
private readonly ICssImageValue _source; private readonly ICssImageValue _source;
private readonly CssPoint2D? _position; private readonly ICssValue _position;
#endregion #endregion
@ -20,7 +20,7 @@ namespace AngleSharp.Css.Values
/// </summary> /// </summary>
/// <param name="source">The image source to display.</param> /// <param name="source">The image source to display.</param>
/// <param name="position">The position offset, if any.</param> /// <param name="position">The position offset, if any.</param>
public CssCustomCursorValue(ICssImageValue source, CssPoint2D? position) public CssCustomCursorValue(ICssImageValue source, ICssValue position)
{ {
_source = source; _source = source;
_position = position; _position = position;
@ -38,7 +38,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Gets the positional offset, if any. /// Gets the positional offset, if any.
/// </summary> /// </summary>
public CssPoint2D? Position => _position; public ICssValue Position => _position;
/// <summary> /// <summary>
/// Gets the CSS text representation. /// Gets the CSS text representation.
@ -51,10 +51,10 @@ namespace AngleSharp.Css.Values
sb.Append(_source.CssText); sb.Append(_source.CssText);
if (_position.HasValue) if (_position is not null)
{ {
sb.Append(Symbols.Space); sb.Append(Symbols.Space);
sb.Append(_position.Value.CssText); sb.Append(_position.CssText);
} }
return sb.ToPool(); return sb.ToPool();
@ -65,10 +65,22 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var source = (ICssImageValue)_source.Compute(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); return new CssCustomCursorValue(source, position);
} }

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS font definition. /// Represents a CSS font definition.
/// </summary> /// </summary>
sealed class CssFontValue : ICssCompositeValue sealed class CssFontValue : ICssCompositeValue, IEquatable<CssFontValue>
{ {
#region Fields #region Fields
@ -138,6 +138,24 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var fontFamilies = _fontFamilies.Compute(context); var fontFamilies = _fontFamilies.Compute(context);

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// More information can be found at the W3C: /// More information can be found at the W3C:
/// http://dev.w3.org/csswg/css-images-3/#color-stop-syntax /// http://dev.w3.org/csswg/css-images-3/#color-stop-syntax
/// </summary> /// </summary>
public sealed class CssGradientStopValue : ICssCompositeValue public sealed class CssGradientStopValue : ICssCompositeValue, IEquatable<CssGradientStopValue>
{ {
#region Fields #region Fields
@ -62,6 +62,16 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var color = ((ICssValue)_color).Compute(context); var color = ((ICssValue)_color).Compute(context);
@ -69,6 +79,8 @@ namespace AngleSharp.Css.Values
return new CssGradientStopValue((CssColorValue)color, location); return new CssGradientStopValue((CssColorValue)color, location);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssGradientStopValue value && Equals(value);
#endregion #endregion
} }
} }

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS grid template definition. /// Represents a CSS grid template definition.
/// </summary> /// </summary>
sealed class CssGridTemplateValue : ICssCompositeValue sealed class CssGridTemplateValue : ICssCompositeValue, IEquatable<CssGridTemplateValue>
{ {
#region Fields #region Fields
@ -107,6 +107,18 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var rows = _rows.Compute(context); var rows = _rows.Compute(context);

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

@ -9,7 +9,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS grid definition. /// Represents a CSS grid definition.
/// </summary> /// </summary>
sealed class CssGridValue : ICssCompositeValue sealed class CssGridValue : ICssCompositeValue, IEquatable<CssGridValue>
{ {
#region Fields #region Fields
@ -92,6 +92,37 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var rows = _rows.Compute(context); var rows = _rows.Compute(context);
@ -100,6 +131,8 @@ namespace AngleSharp.Css.Values
return new CssGridValue(rows, columns, sizes, _dense); return new CssGridValue(rows, columns, sizes, _dense);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssGridValue value && Equals(value);
#endregion #endregion
} }
} }

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

@ -7,11 +7,17 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS image repeat definition. /// Represents a CSS image repeat definition.
/// </summary> /// </summary>
public sealed class CssImageRepeatsValue : ICssCompositeValue public sealed class CssImageRepeatsValue : ICssCompositeValue, IEquatable<CssImageRepeatsValue>
{ {
#region Fields
private readonly ICssValue _horizontal; private readonly ICssValue _horizontal;
private readonly ICssValue _vertical; private readonly ICssValue _vertical;
#endregion
#region ctor
/// <summary> /// <summary>
/// Creates a new CSS image repeat definition. /// Creates a new CSS image repeat definition.
/// </summary> /// </summary>
@ -23,6 +29,10 @@ namespace AngleSharp.Css.Values
_vertical = vertical; _vertical = vertical;
} }
#endregion
#region Properties
/// <summary> /// <summary>
/// Gets the value of the horizontal repeat component. /// Gets the value of the horizontal repeat component.
/// </summary> /// </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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var h = _horizontal.Compute(context); var h = _horizontal.Compute(context);
var v = _vertical.Compute(context); var v = _vertical.Compute(context);
return new CssImageRepeatsValue(h, v); return new CssImageRepeatsValue(h, v);
} }
#endregion
} }
} }

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

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS origin definition. /// Represents a CSS origin definition.
/// </summary> /// </summary>
public sealed class CssOriginValue : ICssCompositeValue public sealed class CssOriginValue : ICssCompositeValue, IEquatable<CssOriginValue>
{ {
#region Fields #region Fields
@ -66,6 +66,16 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var x = _x.Compute(context); var x = _x.Compute(context);
@ -80,6 +90,8 @@ namespace AngleSharp.Css.Values
return this; return this;
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssOriginValue value && Equals(value);
#endregion #endregion
} }
} }

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

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a point value consisting of two distances. /// Represents a point value consisting of two distances.
/// </summary> /// </summary>
public readonly struct CssPoint2D : IEquatable<CssPoint2D>, ICssPrimitiveValue public readonly struct CssPoint2D : ICssCompositeValue, IEquatable<CssPoint2D>
{ {
#region Basic values #region Basic values
@ -147,6 +147,16 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var x = _x.Compute(context); var x = _x.Compute(context);
@ -160,59 +170,7 @@ namespace AngleSharp.Css.Values
return this; return this;
} }
#endregion Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssPoint2D value && Equals(value);
#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();
}
#endregion #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> /// <summary>
/// The shadow class for holding information about a box or text-shadow. /// The shadow class for holding information about a box or text-shadow.
/// </summary> /// </summary>
public sealed class CssShadowValue : ICssCompositeValue public sealed class CssShadowValue : ICssCompositeValue, IEquatable<CssShadowValue>
{ {
#region Fields #region Fields
@ -115,6 +115,23 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var offsetX = _offsetX.Compute(context); var offsetX = _offsetX.Compute(context);

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

@ -6,7 +6,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS value that was born from a shorthand. /// Represents a CSS value that was born from a shorthand.
/// </summary> /// </summary>
class CssChildValue : ICssValue sealed class CssChildValue : ICssValue, IEquatable<CssChildValue>
{ {
#region Fields #region Fields
@ -51,6 +51,16 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var parent = _parent.Compute(context); var parent = _parent.Compute(context);
@ -58,6 +68,8 @@ namespace AngleSharp.Css.Values
return new CssChildValue(parent, value); return new CssChildValue(parent, value);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssChildValue value && Equals(value);
#endregion #endregion
} }
} }

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

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

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

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

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

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

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

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

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS attr function call. /// Represents a CSS attr function call.
/// </summary> /// </summary>
public sealed class CssAttrValue : ICssFunctionValue public sealed class CssAttrValue : ICssFunctionValue, IEquatable<CssAttrValue>
{ {
#region Fields #region Fields
@ -54,6 +54,18 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
return this; return this;

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

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

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

@ -9,11 +9,11 @@ namespace AngleSharp.Css.Values
/// Represents a linear gradient: /// Represents a linear gradient:
/// https://drafts.csswg.org/css-images-4/#conic-gradients /// https://drafts.csswg.org/css-images-4/#conic-gradients
/// </summary> /// </summary>
sealed class CssConicGradientValue : ICssGradientFunctionValue sealed class CssConicGradientValue : ICssGradientFunctionValue, IEquatable<CssConicGradientValue>
{ {
#region Fields #region Fields
private readonly CssGradientStopValue[] _stops; private readonly ICssValue[] _stops;
private readonly ICssValue _center; private readonly ICssValue _center;
private readonly ICssValue _angle; private readonly ICssValue _angle;
private readonly Boolean _repeating; private readonly Boolean _repeating;
@ -29,7 +29,7 @@ namespace AngleSharp.Css.Values
/// <param name="center">The center to use.</param> /// <param name="center">The center to use.</param>
/// <param name="stops">The stops to use.</param> /// <param name="stops">The stops to use.</param>
/// <param name="repeating">Indicates if the gradient is repeating.</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; _stops = stops;
_center = center; _center = center;
@ -76,7 +76,7 @@ namespace AngleSharp.Css.Values
{ {
get get
{ {
var defaultAngle = _angle as Angle?; var defaultAngle = _angle as CssAngleValue?;
var defaultPosition = _center as CssPoint2D?; var defaultPosition = _center as CssPoint2D?;
var offset = (defaultAngle.HasValue ? 1 : 0) + (defaultPosition.HasValue ? 1 : 0); var offset = (defaultAngle.HasValue ? 1 : 0) + (defaultPosition.HasValue ? 1 : 0);
var args = new String[_stops.Length + offset]; var args = new String[_stops.Length + offset];
@ -103,7 +103,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Gets the angle of the conic gradient. /// Gets the angle of the conic gradient.
/// </summary> /// </summary>
public ICssValue Angle => _angle ?? Values.Angle.Half; public ICssValue Angle => _angle ?? Values.CssAngleValue.Half;
/// <summary> /// <summary>
/// Gets the position of the conic gradient. /// Gets the position of the conic gradient.
@ -113,7 +113,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Gets all stops. /// Gets all stops.
/// </summary> /// </summary>
public CssGradientStopValue[] Stops => _stops; public ICssValue[] Stops => _stops;
/// <summary> /// <summary>
/// Gets if the gradient is repeating. /// Gets if the gradient is repeating.
@ -124,6 +124,36 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var center = _center.Compute(context); var center = _center.Compute(context);

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS content function call. /// Represents a CSS content function call.
/// </summary> /// </summary>
public sealed class CssContentValue : ICssFunctionValue public sealed class CssContentValue : ICssFunctionValue, IEquatable<CssContentValue>
{ {
#region Fields #region Fields
@ -54,10 +54,16 @@ namespace AngleSharp.Css.Values
#region Methods #region Methods
ICssValue ICssValue.Compute(ICssComputeContext context) /// <summary>
{ /// Checks if the current value is equal to the provided one.
return this; /// </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 #endregion
} }

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

@ -13,10 +13,10 @@ namespace AngleSharp.Css.Values
{ {
#region Fields #region Fields
private readonly Double _x1; private readonly ICssValue _x1;
private readonly Double _y1; private readonly ICssValue _y1;
private readonly Double _x2; private readonly ICssValue _x2;
private readonly Double _y2; private readonly ICssValue _y2;
/// <summary> /// <summary>
/// The pre-configured ease function. /// The pre-configured ease function.
@ -56,7 +56,7 @@ namespace AngleSharp.Css.Values
/// <param name="y1">The y-coordinate of P1.</param> /// <param name="y1">The y-coordinate of P1.</param>
/// <param name="x2">The x-coordinate of P2.</param> /// <param name="x2">The x-coordinate of P2.</param>
/// <param name="y2">The y-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; _x1 = x1;
_y1 = y1; _y1 = y1;
@ -64,6 +64,20 @@ namespace AngleSharp.Css.Values
_y2 = y2; _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 #endregion
#region Properties #region Properties
@ -78,10 +92,10 @@ namespace AngleSharp.Css.Values
/// </summary> /// </summary>
public ICssValue[] Arguments => new ICssValue[] public ICssValue[] Arguments => new ICssValue[]
{ {
new CssLengthValue(_x1, CssLengthValue.Unit.None), _x1,
new CssLengthValue(_y1, CssLengthValue.Unit.None), _y1,
new CssLengthValue(_x2, CssLengthValue.Unit.None), _x2,
new CssLengthValue(_y2, CssLengthValue.Unit.None), _y2,
}; };
/// <summary> /// <summary>
@ -119,22 +133,22 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Gets the x-coordinate of the p1. /// Gets the x-coordinate of the p1.
/// </summary> /// </summary>
public Double X1 => _x1; public ICssValue X1 => _x1;
/// <summary> /// <summary>
/// Gets the y-coordinate of the p1. /// Gets the y-coordinate of the p1.
/// </summary> /// </summary>
public Double Y1 => _y1; public ICssValue Y1 => _y1;
/// <summary> /// <summary>
/// Gets the x-coordinate of the p2. /// Gets the x-coordinate of the p2.
/// </summary> /// </summary>
public Double X2 => _x2; public ICssValue X2 => _x2;
/// <summary> /// <summary>
/// Gets the y-coordinate of the p2. /// Gets the y-coordinate of the p2.
/// </summary> /// </summary>
public Double Y2 => _y2; public ICssValue Y2 => _y2;
#endregion #endregion
@ -146,13 +160,19 @@ namespace AngleSharp.Css.Values
/// <param name="other">The cubic bezier to compare to.</param> /// <param name="other">The cubic bezier to compare to.</param>
/// <returns>True if both have the same parameters, otherwise false.</returns> /// <returns>True if both have the same parameters, otherwise false.</returns>
public Boolean Equals(CssCubicBezierValue other) => 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) 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 #endregion
} }
} }

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS fit-content function call. /// Represents a CSS fit-content function call.
/// </summary> /// </summary>
sealed class CssFitContentValue : ICssFunctionValue sealed class CssFitContentValue : ICssFunctionValue, IEquatable<CssFitContentValue>
{ {
#region Fields #region Fields
@ -54,6 +54,15 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var dim = _dim.Compute(context); var dim = _dim.Compute(context);

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

@ -5,7 +5,7 @@ namespace AngleSharp.Css.Values
using AngleSharp.Text; using AngleSharp.Text;
using System; using System;
sealed class CssFontFormatValue : ICssFunctionValue sealed class CssFontFormatValue : ICssFunctionValue, IEquatable<CssFontFormatValue>
{ {
#region Fields #region Fields
@ -34,10 +34,16 @@ namespace AngleSharp.Css.Values
#region Methods #region Methods
ICssValue ICssValue.Compute(ICssComputeContext context) /// <summary>
{ /// Checks if the current value is equal to the provided one.
return this; /// </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 #endregion
} }

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

@ -9,11 +9,11 @@ namespace AngleSharp.Css.Values
/// Represents a linear gradient: /// Represents a linear gradient:
/// http://dev.w3.org/csswg/css-images-3/#linear-gradients /// http://dev.w3.org/csswg/css-images-3/#linear-gradients
/// </summary> /// </summary>
sealed class CssLinearGradientValue : ICssGradientFunctionValue sealed class CssLinearGradientValue : ICssGradientFunctionValue, IEquatable<CssLinearGradientValue>
{ {
#region Fields #region Fields
private readonly CssGradientStopValue[] _stops; private readonly ICssValue[] _stops;
private readonly ICssValue _angle; private readonly ICssValue _angle;
private readonly Boolean _repeating; private readonly Boolean _repeating;
@ -27,7 +27,7 @@ namespace AngleSharp.Css.Values
/// <param name="angle">The angle of the linear gradient.</param> /// <param name="angle">The angle of the linear gradient.</param>
/// <param name="stops">The stops to use.</param> /// <param name="stops">The stops to use.</param>
/// <param name="repeating">Indicates if the gradient is repeating.</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; _stops = stops;
_angle = angle; _angle = angle;
@ -68,7 +68,7 @@ namespace AngleSharp.Css.Values
{ {
get get
{ {
var defaultAngle = _angle as Angle?; var defaultAngle = _angle as CssAngleValue?;
var offset = defaultAngle.HasValue ? 1 : 0; var offset = defaultAngle.HasValue ? 1 : 0;
var args = new String[_stops.Length + offset]; var args = new String[_stops.Length + offset];
@ -100,12 +100,12 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Gets the angle of the linear gradient. /// Gets the angle of the linear gradient.
/// </summary> /// </summary>
public ICssValue Angle => _angle ?? Values.Angle.Half; public ICssValue Angle => _angle ?? Values.CssAngleValue.Half;
/// <summary> /// <summary>
/// Gets all stops. /// Gets all stops.
/// </summary> /// </summary>
public CssGradientStopValue[] Stops => _stops; public ICssValue[] Stops => _stops;
/// <summary> /// <summary>
/// Gets if the gradient is repeating. /// Gets if the gradient is repeating.
@ -116,6 +116,36 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var angle = _angle.Compute(context); var angle = _angle.Compute(context);

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

@ -5,7 +5,7 @@ namespace AngleSharp.Css.Values
using AngleSharp.Text; using AngleSharp.Text;
using System; using System;
sealed class CssLocalFontValue : ICssFunctionValue sealed class CssLocalFontValue : ICssFunctionValue, IEquatable<CssLocalFontValue>
{ {
#region Fields #region Fields
@ -34,10 +34,16 @@ namespace AngleSharp.Css.Values
#region Methods #region Methods
ICssValue ICssValue.Compute(ICssComputeContext context) /// <summary>
{ /// Checks if the current value is equal to the provided one.
return this; /// </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 #endregion
} }

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

@ -4,21 +4,22 @@ namespace AngleSharp.Css.Values
using AngleSharp.Css.Dom; using AngleSharp.Css.Dom;
using AngleSharp.Text; using AngleSharp.Text;
using System; using System;
using System.Linq;
/// <summary> /// <summary>
/// Represents the matrix3d transformation. /// Represents the matrix3d transformation.
/// </summary> /// </summary>
sealed class CssMatrixValue : ICssTransformFunctionValue sealed class CssMatrixValue : ICssTransformFunctionValue, IEquatable<CssMatrixValue>
{ {
#region Fields #region Fields
private readonly Double[] _values; private readonly ICssValue[] _values;
#endregion #endregion
#region ctor #region ctor
internal CssMatrixValue(Double[] values) internal CssMatrixValue(ICssValue[] values)
{ {
_values = values; _values = values;
} }
@ -35,20 +36,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Gets the arguments. /// Gets the arguments.
/// </summary> /// </summary>
public ICssValue[] Arguments public ICssValue[] Arguments => _values;
{
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;
}
}
/// <summary> /// <summary>
/// Gets the CSS text representation. /// Gets the CSS text representation.
@ -60,37 +48,69 @@ namespace AngleSharp.Css.Values
/// </summary> /// </summary>
/// <param name="index">The index to look for.</param> /// <param name="index">The index to look for.</param>
/// <returns>The value.</returns> /// <returns>The value.</returns>
public Double this[Int32 index] => _values[index]; public ICssValue this[Int32 index] => _values[index];
#endregion #endregion
#region Methods #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> /// <summary>
/// Returns the stored matrix. /// Returns the stored matrix.
/// </summary> /// </summary>
/// <returns>The current transformation.</returns> /// <returns>The current transformation.</returns>
public TransformMatrix ComputeMatrix(IRenderDimensions dimensions) 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.Add(1.0);
{ values.Add(0.0);
_values[0], _values[2], 0.0, _values[4], values.Add(0.0);
_values[1], _values[3], 0.0, _values[5], values.Add(0.0);
1.0, 0.0, 0.0, 0.0, values.Add(0.0);
0.0, 0.0, 0.0, 1.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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
return this; var values = _values.Select(v => v.Compute(context)).ToArray();
return new CssMatrixValue(values);
} }
#endregion #endregion

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

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS minmax function call. /// Represents a CSS minmax function call.
/// </summary> /// </summary>
sealed class CssMinMaxValue : ICssFunctionValue sealed class CssMinMaxValue : ICssFunctionValue, IEquatable<CssMinMaxValue>
{ {
#region Fields #region Fields
@ -63,6 +63,16 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var min = _min.Compute(context); var min = _min.Compute(context);
@ -70,6 +80,8 @@ namespace AngleSharp.Css.Values
return new CssMinMaxValue(min, max); return new CssMinMaxValue(min, max);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssMinMaxValue value && Equals(value);
#endregion #endregion
} }
} }

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

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

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents the distance transformation. /// Represents the distance transformation.
/// </summary> /// </summary>
sealed class CssPerspectiveValue : ICssTransformFunctionValue sealed class CssPerspectiveValue : ICssTransformFunctionValue, IEquatable<CssPerspectiveValue>
{ {
#region Fields #region Fields
@ -50,6 +50,18 @@ namespace AngleSharp.Css.Values
#region Methods #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> /// <summary>
/// Computes the matrix for the given transformation. /// Computes the matrix for the given transformation.
/// </summary> /// </summary>

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

@ -11,11 +11,11 @@ namespace AngleSharp.Css.Values
/// Represents a radial gradient: /// Represents a radial gradient:
/// http://dev.w3.org/csswg/css-images-3/#radial-gradients /// http://dev.w3.org/csswg/css-images-3/#radial-gradients
/// </summary> /// </summary>
public sealed class CssRadialGradientValue : ICssGradientFunctionValue public sealed class CssRadialGradientValue : ICssGradientFunctionValue, IEquatable<CssRadialGradientValue>
{ {
#region Fields #region Fields
private readonly CssGradientStopValue[] _stops; private readonly ICssValue[] _stops;
private readonly CssPoint2D _center; private readonly CssPoint2D _center;
private readonly ICssValue _width; private readonly ICssValue _width;
private readonly ICssValue _height; private readonly ICssValue _height;
@ -37,7 +37,7 @@ namespace AngleSharp.Css.Values
/// <param name="sizeMode">The size mode of the ellipsoid.</param> /// <param name="sizeMode">The size mode of the ellipsoid.</param>
/// <param name="stops">A collection of stops to use.</param> /// <param name="stops">A collection of stops to use.</param>
/// <param name="repeating">The repeating setting.</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; _stops = stops;
_center = center; _center = center;
@ -64,7 +64,8 @@ namespace AngleSharp.Css.Values
{ {
get 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>(); var args = new List<ICssValue>();
if (!isDefault) if (!isDefault)
@ -145,7 +146,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Gets all stops. /// Gets all stops.
/// </summary> /// </summary>
public CssGradientStopValue[] Stops => _stops; public ICssValue[] Stops => _stops;
/// <summary> /// <summary>
/// Gets if the gradient is repeating. /// Gets if the gradient is repeating.
@ -156,6 +157,37 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var center = (CssPoint2D)((ICssValue)_center).Compute(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); return new CssRadialGradientValue(_circle, center, width, height, _sizeMode, stops, _repeating);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssRadialGradientValue value && Equals(value);
#endregion #endregion
#region Sizes #region Sizes

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

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS repeat function call. /// Represents a CSS repeat function call.
/// </summary> /// </summary>
sealed class CssRepeatValue : ICssFunctionValue sealed class CssRepeatValue : ICssFunctionValue, IEquatable<CssRepeatValue>
{ {
#region Fields #region Fields
@ -63,6 +63,18 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var count = _count.Compute(context); var count = _count.Compute(context);

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

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

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS running function call. /// Represents a CSS running function call.
/// </summary> /// </summary>
public sealed class CssRunningValue : ICssFunctionValue public sealed class CssRunningValue : ICssFunctionValue, IEquatable<CssRunningValue>
{ {
#region Fields #region Fields
@ -54,10 +54,16 @@ namespace AngleSharp.Css.Values
#region Methods #region Methods
ICssValue ICssValue.Compute(ICssComputeContext context) /// <summary>
{ /// Checks if the current value is equal to the provided one.
return this; /// </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 #endregion
} }

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

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

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

@ -9,7 +9,7 @@ namespace AngleSharp.Css.Values
/// Represents a CSS shape. /// Represents a CSS shape.
/// https://developer.mozilla.org/en-US/docs/Web/CSS/shape /// https://developer.mozilla.org/en-US/docs/Web/CSS/shape
/// </summary> /// </summary>
public sealed class CssShapeValue : ICssValue, ICssFunctionValue public sealed class CssShapeValue : ICssValue, ICssFunctionValue, IEquatable<CssShapeValue>
{ {
#region Fields #region Fields
@ -86,6 +86,18 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
var top = _top.Compute(context); var top = _top.Compute(context);

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

@ -7,7 +7,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents the skew transformation. /// Represents the skew transformation.
/// </summary> /// </summary>
public sealed class CssSkewValue : ICssTransformFunctionValue public sealed class CssSkewValue : ICssTransformFunctionValue, IEquatable<CssSkewValue>
{ {
#region Fields #region Fields
@ -100,14 +100,26 @@ namespace AngleSharp.Css.Values
#region Methods #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> /// <summary>
/// Computes the matrix for the given transformation. /// Computes the matrix for the given transformation.
/// </summary> /// </summary>
/// <returns>The transformation matrix representation.</returns> /// <returns>The transformation matrix representation.</returns>
public TransformMatrix ComputeMatrix(IRenderDimensions renderDimensions) public TransformMatrix ComputeMatrix(IRenderDimensions renderDimensions)
{ {
var a = Math.Tan((_alpha as Angle ? ?? Angle.Zero).ToRadian()); var a = Math.Tan((_alpha as CssAngleValue ? ?? CssAngleValue.Zero).ToRadian());
var b = Math.Tan((_beta as Angle? ?? Angle.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); 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. /// Represents a steps timing-function object.
/// https://developer.mozilla.org/en-US/docs/Web/CSS/timing-function /// https://developer.mozilla.org/en-US/docs/Web/CSS/timing-function
/// </summary> /// </summary>
sealed class CssStepsValue : ICssTimingFunctionValue sealed class CssStepsValue : ICssTimingFunctionValue, IEquatable<CssStepsValue>
{ {
#region Fields #region Fields
@ -101,6 +101,18 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
return this; return this;

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

@ -9,7 +9,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS symbols function call. /// Represents a CSS symbols function call.
/// </summary> /// </summary>
public sealed class CssSymbolsValue : ICssFunctionValue public sealed class CssSymbolsValue : ICssFunctionValue, IEquatable<CssSymbolsValue>
{ {
#region Fields #region Fields
@ -59,6 +59,36 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
if (_type == null) if (_type == null)

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

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents the translate3d transformation. /// Represents the translate3d transformation.
/// </summary> /// </summary>
sealed class CssTranslateValue : ICssTransformFunctionValue sealed class CssTranslateValue : ICssTransformFunctionValue, IEquatable<CssTranslateValue>
{ {
#region Fields #region Fields
@ -99,18 +99,27 @@ namespace AngleSharp.Css.Values
#region Methods #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> /// <summary>
/// Computes the matrix for the given transformation. /// Computes the matrix for the given transformation.
/// </summary> /// </summary>
/// <returns>The transformation matrix representation.</returns> /// <returns>The transformation matrix representation.</returns>
public TransformMatrix ComputeMatrix(IRenderDimensions renderDimensions) public TransformMatrix ComputeMatrix(IRenderDimensions renderDimensions)
{ {
var x = _x as CssLengthValue? ?? CssLengthValue.Zero; var dx = _x.AsPx(renderDimensions, RenderMode.Horizontal);
var y = _y as CssLengthValue? ?? CssLengthValue.Zero; var dy = _y.AsPx(renderDimensions, RenderMode.Vertical);
var z = _z as CssLengthValue? ?? CssLengthValue.Zero; var dz = _z.AsPx(renderDimensions, RenderMode.Undefined);
var dx = x.ToPixel(renderDimensions, RenderMode.Horizontal);
var dy = y.ToPixel(renderDimensions, RenderMode.Vertical);
var dz = z.ToPixel(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); 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. /// Represents an URL object.
/// https://developer.mozilla.org/en-US/docs/Web/CSS/uri /// https://developer.mozilla.org/en-US/docs/Web/CSS/uri
/// </summary> /// </summary>
public sealed class CssUrlValue : ICssImageValue, ICssFunctionValue public sealed class CssUrlValue : ICssImageValue, ICssFunctionValue, IEquatable<CssUrlValue>
{ {
#region Fields #region Fields
@ -55,6 +55,18 @@ namespace AngleSharp.Css.Values
#region Methods #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) ICssValue ICssValue.Compute(ICssComputeContext context)
{ {
return this; return this;

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

@ -8,7 +8,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS var replacement. /// Represents a CSS var replacement.
/// </summary> /// </summary>
public sealed class CssVarValue : ICssFunctionValue public sealed class CssVarValue : ICssFunctionValue, IEquatable<CssVarValue>
{ {
#region Fields #region Fields
@ -96,6 +96,16 @@ namespace AngleSharp.Css.Values
#region Methods #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> /// <summary>
/// Resolves the value of the referenced variable. Returns null /// Resolves the value of the referenced variable. Returns null
/// if the reference is invalid or cannot be resolved. /// if the reference is invalid or cannot be resolved.
@ -114,6 +124,8 @@ namespace AngleSharp.Css.Values
return _defaultValue?.Compute(context); return _defaultValue?.Compute(context);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssVarValue value && Equals(value);
#endregion #endregion
} }
} }

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

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

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

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a flow relative CSS value. /// Represents a flow relative CSS value.
/// </summary> /// </summary>
public class CssFlowRelativeValue<T> : ICssMultipleValue public class CssFlowRelativeValue<T> : ICssMultipleValue, IEquatable<CssFlowRelativeValue<T>>
where T : ICssValue where T : ICssValue
{ {
#region Fields #region Fields
@ -84,6 +84,34 @@ namespace AngleSharp.Css.Values
#region Methods #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() IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator()
{ {
yield return Start; yield return Start;
@ -98,6 +126,8 @@ namespace AngleSharp.Css.Values
return new CssFlowRelativeValue<T>(values); return new CssFlowRelativeValue<T>(values);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssFlowRelativeValue<T> value && Equals(value);
#endregion #endregion
} }

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

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a CSS value list. /// Represents a CSS value list.
/// </summary> /// </summary>
public class CssListValue<T> : ICssMultipleValue public class CssListValue<T> : ICssMultipleValue, IEquatable<CssListValue<T>>
where T : ICssValue where T : ICssValue
{ {
#region Fields #region Fields
@ -50,6 +50,34 @@ namespace AngleSharp.Css.Values
#region Methods #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() => IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator() =>
_items.OfType<ICssValue>().GetEnumerator(); _items.OfType<ICssValue>().GetEnumerator();
@ -61,6 +89,8 @@ namespace AngleSharp.Css.Values
return new CssListValue<T>(items); return new CssListValue<T>(items);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssListValue<T> value && Equals(value);
#endregion #endregion
} }

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

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a periodic CSS value. /// Represents a periodic CSS value.
/// </summary> /// </summary>
public class CssPeriodicValue<T> : ICssMultipleValue public class CssPeriodicValue<T> : ICssMultipleValue, IEquatable<CssPeriodicValue<T>>
where T : ICssValue where T : ICssValue
{ {
#region Fields #region Fields
@ -104,6 +104,34 @@ namespace AngleSharp.Css.Values
#region Methods #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() IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator()
{ {
yield return Top; yield return Top;
@ -120,6 +148,8 @@ namespace AngleSharp.Css.Values
return new CssPeriodicValue<T>(values); return new CssPeriodicValue<T>(values);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssPeriodicValue<T> value && Equals(value);
#endregion #endregion
} }

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

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a periodic CSS value. /// Represents a periodic CSS value.
/// </summary> /// </summary>
public class CssRadiusValue<T> : ICssMultipleValue public class CssRadiusValue<T> : ICssMultipleValue, IEquatable<CssRadiusValue<T>>
where T : ICssValue where T : ICssValue
{ {
#region Fields #region Fields
@ -84,6 +84,34 @@ namespace AngleSharp.Css.Values
#region Methods #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() IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator()
{ {
yield return Width; yield return Width;
@ -98,6 +126,8 @@ namespace AngleSharp.Css.Values
return new CssRadiusValue<T>(values); return new CssRadiusValue<T>(values);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssRadiusValue<T> value && Equals(value);
#endregion #endregion
} }

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

@ -10,7 +10,7 @@ namespace AngleSharp.Css.Values
/// <summary> /// <summary>
/// Represents a tuple of CSS values. /// Represents a tuple of CSS values.
/// </summary> /// </summary>
public class CssTupleValue<T> : ICssMultipleValue public class CssTupleValue<T> : ICssMultipleValue, IEquatable<CssTupleValue<T>>
where T : ICssValue where T : ICssValue
{ {
#region Fields #region Fields
@ -58,6 +58,34 @@ namespace AngleSharp.Css.Values
#region Methods #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() => IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator() =>
_items.OfType<ICssValue>().GetEnumerator(); _items.OfType<ICssValue>().GetEnumerator();
@ -69,6 +97,8 @@ namespace AngleSharp.Css.Values
return new CssTupleValue<T>(items, _separator); return new CssTupleValue<T>(items, _separator);
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssTupleValue<T> value && Equals(value);
#endregion #endregion
} }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -8,6 +8,20 @@ namespace AngleSharp.Css.Values
/// </summary> /// </summary>
public readonly struct CssNumberValue : IEquatable<CssNumberValue>, IComparable<CssNumberValue>, ICssMetricValue 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 #region Fields
private readonly Double _value; private readonly Double _value;
@ -105,6 +119,7 @@ namespace AngleSharp.Css.Values
return false; return false;
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssNumberValue value && Equals(value);
/// <summary> /// <summary>
/// Returns a hash code that defines the current number. /// Returns a hash code that defines the current number.

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

@ -8,6 +8,25 @@ namespace AngleSharp.Css.Values
/// </summary> /// </summary>
public readonly struct CssPercentageValue : IEquatable<CssPercentageValue>, IComparable<CssPercentageValue>, ICssMetricValue 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 #region Fields
private readonly Double _value; private readonly Double _value;
@ -175,6 +194,8 @@ namespace AngleSharp.Css.Values
return false; return false;
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssPercentageValue value && Equals(value);
/// <summary> /// <summary>
/// Returns a hash code that defines the current percentage. /// Returns a hash code that defines the current percentage.
/// </summary> /// </summary>

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

@ -73,6 +73,7 @@ namespace AngleSharp.Css.Values
/// <returns>True if both are equal, otherwise false.</returns> /// <returns>True if both are equal, otherwise false.</returns>
public override Boolean Equals(Object obj) => public override Boolean Equals(Object obj) =>
obj is CssQuoteValue quote && Equals(quote); obj is CssQuoteValue quote && Equals(quote);
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssQuoteValue value && Equals(value);
/// <summary> /// <summary>
/// Gets the hash code of the object. /// 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; return false;
} }
Boolean IEquatable<ICssValue>.Equals(ICssValue other) => other is CssResolutionValue value && Equals(value);
/// <summary> /// <summary>
/// Returns a hash code that defines the current resolution. /// Returns a hash code that defines the current resolution.
/// </summary> /// </summary>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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