Optimized the border radius converter and initial values

This commit is contained in:
Florian Rappl 2019-05-12 10:23:42 +02:00
Родитель 0dc9599f8f
Коммит 2c06be0945
23 изменённых файлов: 256 добавлений и 257 удалений

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

@ -1,6 +1,6 @@
# 0.12.0
Released on Thursday, May 5 2019.
Released on Sunday, May 12 2019.
- Reference latest AngleSharp
- Fixed empty value when removing properties (#14)
@ -10,6 +10,7 @@ Released on Thursday, May 5 2019.
- Fixed exception when not providing an `IRenderDevice` (#20)
- Fixed missing `CssStylingService.Default` in cascade (#21)
- Added extension helper `SetStyle` to modify all styles of many elements (#22)
- Fixed expansion of shorthand properties to longhand (#23)
- Opened CSSOM, e.g., declared `ICssFunctionValue` `public` (#24)
- Introduced special converter for the `src` declaration (#25)
- Fixed bug regarding CSS grid serialization (#27)

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

@ -15,7 +15,7 @@ namespace AngleSharp.Css.Tests.Declarations
Assert.IsFalse(property.IsImportant);
Assert.IsFalse(property.IsInherited);
Assert.IsTrue(property.HasValue);
Assert.AreEqual("40px 40px", property.Value);
Assert.AreEqual("40px", property.Value);
}
[Test]

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

@ -29,6 +29,9 @@ namespace AngleSharp.Css
public static readonly ICssValue FontStretchDecl = new Constant<FontStretch>(CssKeywords.Normal, FontStretch.Normal);
public static readonly ICssValue FontSizeDecl = new Constant<Length>(CssKeywords.Medium, Length.Medium);
public static readonly ICssValue FontFamilyDecl = new Label("Times New Roman");
public static readonly ICssValue BorderWidthDecl = new Constant<Length>(CssKeywords.Medium, Length.Medium);
public static readonly ICssValue BorderStyleDecl = new Constant<LineStyle>(CssKeywords.None, LineStyle.None);
public static readonly ICssValue BorderColorDecl = new Constant<Color>(CssKeywords.CurrentColor, Color.CurrentColor);
public static readonly ICssValue LineHeightDecl = new Constant<Length>(CssKeywords.Normal, Length.Normal);
public static readonly ICssValue BorderTopWidthDecl = new Constant<Length>(CssKeywords.Medium, Length.Medium);
public static readonly ICssValue BorderRightWidthDecl = new Constant<Length>(CssKeywords.Medium, Length.Medium);

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

@ -4,12 +4,12 @@ namespace AngleSharp.Css.Converters
using AngleSharp.Css.Values;
using AngleSharp.Text;
sealed class OptionValueConverter<T> : IValueConverter
sealed class OptionValueConverter : IValueConverter
{
private readonly IValueConverter _converter;
private readonly T _defaultValue;
private readonly ICssValue _defaultValue;
public OptionValueConverter(IValueConverter converter, T defaultValue)
public OptionValueConverter(IValueConverter converter, ICssValue defaultValue)
{
_converter = converter;
_defaultValue = defaultValue;
@ -19,7 +19,7 @@ namespace AngleSharp.Css.Converters
{
if (source.IsDone || source.Current == Symbols.Comma)
{
return new CssDefaultValue<T>(_defaultValue);
return new CssDefaultValue(_defaultValue);
}
return _converter.Convert(source);

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

@ -0,0 +1,44 @@
namespace AngleSharp.Css.Converters
{
using AngleSharp.Css.Dom;
using AngleSharp.Css.Parser;
using AngleSharp.Css.Values;
using AngleSharp.Text;
using System;
sealed class RadiusValueConverter : IValueConverter
{
private readonly IValueConverter _converter;
public RadiusValueConverter(IValueConverter converter)
{
_converter = converter;
}
public ICssValue Convert(StringSource source)
{
var options = new ICssValue[2];
var length = 0;
for (var i = 0; i < options.Length; i++)
{
options[i] = _converter.Convert(source);
source.SkipSpacesAndComments();
if (options[length] != null)
{
length++;
}
}
if (length > 0)
{
var values = new ICssValue[length];
Array.Copy(options, values, length);
return new CssRadiusValue(values);
}
return null;
}
}
}

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

@ -39,6 +39,9 @@ namespace AngleSharp.Css.Converters
public static IValueConverter Periodic(this IValueConverter converter) =>
new PeriodicValueConverter(converter);
public static IValueConverter Radius(this IValueConverter converter) =>
new RadiusValueConverter(converter);
public static IValueConverter Exclusive(this IValueConverter converter)
{
return new ClassValueConverter<ICssValue>(source =>
@ -57,11 +60,8 @@ namespace AngleSharp.Css.Converters
});
}
public static IValueConverter Option(this IValueConverter converter) =>
new OptionValueConverter<Object>(converter, null);
public static IValueConverter Option<T>(this IValueConverter converter, T defaultValue) =>
new OptionValueConverter<T>(converter, defaultValue);
public static IValueConverter Option(this IValueConverter converter, ICssValue defaultValue) =>
new OptionValueConverter(converter, defaultValue);
public static String Join<T>(this T[] values, String separator)
where T : ICssValue

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

@ -33,14 +33,14 @@ namespace AngleSharp.Css.Declarations
sealed class AnimationAggregator : IValueAggregator, IValueConverter
{
private static readonly IValueConverter ListConverter = WithAny(
TimeConverter.Option(),
TransitionConverter.Option(),
TimeConverter.Option(),
PositiveOrInfiniteNumberConverter.Option(),
AnimationDirectionConverter.Option(),
AnimationFillStyleConverter.Option(),
PlayStateConverter.Option(),
IdentifierConverter.Option()).FromList();
TimeConverter.Option(InitialValues.AnimationDurationDecl),
TransitionConverter.Option(InitialValues.AnimationTimingFunctionDecl),
TimeConverter.Option(InitialValues.AnimationDelayDecl),
PositiveOrInfiniteNumberConverter.Option(InitialValues.AnimationIterationCountDecl),
AnimationDirectionConverter.Option(InitialValues.AnimationDirectionDecl),
AnimationFillStyleConverter.Option(InitialValues.AnimationFillModeDecl),
PlayStateConverter.Option(InitialValues.AnimationPlayStateDecl),
IdentifierConverter.Option(InitialValues.AnimationNameDecl)).FromList();
public ICssValue Convert(StringSource source) => ListConverter.Convert(source);

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

@ -8,17 +8,20 @@ namespace AngleSharp.Css.Declarations
{
public static String Name = PropertyNames.BorderBottom;
public static IValueConverter Converter = AggregateTuple(BorderSideConverter);
public static ICssValue InitialValue = null;
public static PropertyFlags Flags = PropertyFlags.Animatable | PropertyFlags.Shorthand;
public static String[] Shorthands = new[]
{
PropertyNames.Border,
};
public static IValueConverter Converter = WithBorderSide(
InitialValues.BorderBottomWidthDecl,
InitialValues.BorderBottomStyleDecl,
InitialValues.BorderBottomColorDecl);
public static ICssValue InitialValue = null;
public static PropertyFlags Flags = PropertyFlags.Animatable | PropertyFlags.Shorthand;
public static String[] Longhands = new[]
{
PropertyNames.BorderBottomWidth,

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

@ -25,19 +25,12 @@ namespace AngleSharp.Css.Declarations
PropertyNames.BorderColor,
};
sealed class BorderValueConverter : IValueConverter
{
private static readonly IValueConverter converter = WithAny(
LineWidthConverter.Option(),
LineStyleConverter.Option(),
CurrentColorConverter.Option());
public ICssValue Convert(StringSource source) => converter.Convert(source);
}
sealed class BorderAggregator : IValueAggregator, IValueConverter
{
private static readonly IValueConverter converter = new BorderValueConverter();
private static readonly IValueConverter converter = WithAny(
LineWidthConverter.Option(InitialValues.BorderWidthDecl),
LineStyleConverter.Option(InitialValues.BorderStyleDecl),
CurrentColorConverter.Option(InitialValues.BorderColorDecl));
public ICssValue Convert(StringSource source) => converter.Convert(source);

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

@ -13,7 +13,10 @@ namespace AngleSharp.Css.Declarations
PropertyNames.Border,
};
public static IValueConverter Converter = AggregateTuple(BorderSideConverter);
public static IValueConverter Converter = WithBorderSide(
InitialValues.BorderLeftWidthDecl,
InitialValues.BorderLeftStyleDecl,
InitialValues.BorderLeftColorDecl);
public static ICssValue InitialValue = null;

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

@ -26,7 +26,7 @@ namespace AngleSharp.Css.Declarations
PropertyNames.BorderBottomLeftRadius,
};
sealed class BorderRadiusValueConverter : IValueConverter
sealed class BorderRadiusAggregator : IValueAggregator, IValueConverter
{
private readonly IValueConverter _converter = LengthOrPercentConverter.Periodic();
@ -45,33 +45,20 @@ namespace AngleSharp.Css.Declarations
return vertical != null ? new CssBorderRadiusValue(horizontal, vertical) : null;
}
}
sealed class BorderRadiusAggregator : IValueAggregator, IValueConverter
{
private static readonly IValueConverter converter = new BorderRadiusValueConverter();
public ICssValue Convert(StringSource source)
{
return converter.Convert(source);
}
private static ICssValue Both(ICssValue horizontal, ICssValue vertical)
{
return new CssTupleValue(new[] { horizontal, vertical });
}
private static ICssValue Both(params ICssValue[] values) => new CssRadiusValue(values);
public ICssValue Merge(ICssValue[] values)
{
var topLeft = values[0] as CssTupleValue;
var topRight = values[1] as CssTupleValue;
var bottomRight = values[2] as CssTupleValue;
var bottomLeft = values[3] as CssTupleValue;
var topLeft = values[0] as CssRadiusValue;
var topRight = values[1] as CssRadiusValue;
var bottomRight = values[2] as CssRadiusValue;
var bottomLeft = values[3] as CssRadiusValue;
if (topLeft != null && topRight != null && bottomRight != null && bottomLeft != null)
{
var horizontal = new CssPeriodicValue(new[] { topLeft.Items[0], topRight.Items[0], bottomRight.Items[0], bottomLeft.Items[0] });
var vertical = new CssPeriodicValue(new[] { topLeft.Items[1], topRight.Items[1], bottomRight.Items[1], bottomLeft.Items[1] });
var horizontal = new CssPeriodicValue(new[] { topLeft.Width, topRight.Width, bottomRight.Width, bottomLeft.Width });
var vertical = new CssPeriodicValue(new[] { topLeft.Height, topRight.Height, bottomRight.Height, bottomLeft.Height });
return new CssBorderRadiusValue(horizontal, vertical);
}

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

@ -13,7 +13,10 @@ namespace AngleSharp.Css.Declarations
PropertyNames.Border,
};
public static IValueConverter Converter = AggregateTuple(BorderSideConverter);
public static IValueConverter Converter = WithBorderSide(
InitialValues.BorderRightWidthDecl,
InitialValues.BorderRightStyleDecl,
InitialValues.BorderRightColorDecl);
public static ICssValue InitialValue = null;

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

@ -13,7 +13,10 @@ namespace AngleSharp.Css.Declarations
PropertyNames.Border,
};
public static IValueConverter Converter = AggregateTuple(BorderSideConverter);
public static IValueConverter Converter = WithBorderSide(
InitialValues.BorderTopWidthDecl,
InitialValues.BorderTopStyleDecl,
InitialValues.BorderTopColorDecl);
public static ICssValue InitialValue = null;

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

@ -2,8 +2,6 @@ namespace AngleSharp.Css.Declarations
{
using AngleSharp.Css.Converters;
using AngleSharp.Css.Dom;
using AngleSharp.Css.Values;
using AngleSharp.Text;
using System;
using static ValueConverters;
@ -11,7 +9,11 @@ namespace AngleSharp.Css.Declarations
{
public static String Name = PropertyNames.ListStyle;
public static IValueConverter Converter = new ListStyleAggregator();
public static IValueConverter Converter = AggregateTuple(
WithAny(
ListStyleConverter.Option(InitialValues.ListStyleTypeDecl),
ListPositionConverter.Option(InitialValues.ListStylePositionDecl),
OptionalImageSourceConverter.Option(InitialValues.ListStyleImageDecl)));
public static ICssValue InitialValue = null;
@ -23,59 +25,5 @@ namespace AngleSharp.Css.Declarations
PropertyNames.ListStylePosition,
PropertyNames.ListStyleImage,
};
sealed class ListStyleValueConverter : IValueConverter
{
private static readonly IValueConverter converter = WithAny(
ListStyleConverter.Option(),
ListPositionConverter.Option(),
OptionalImageSourceConverter.Option());
public ICssValue Convert(StringSource source)
{
return converter.Convert(source);
}
}
sealed class ListStyleAggregator : IValueAggregator, IValueConverter
{
private static readonly IValueConverter converter = new ListStyleValueConverter();
public ICssValue Convert(StringSource source)
{
return converter.Convert(source);
}
public ICssValue Merge(ICssValue[] values)
{
var type = values[0];
var position = values[1];
var image = values[2];
if (type != null || position != null || image != null)
{
return new CssTupleValue(new[] { type, position, image });
}
return null;
}
public ICssValue[] Split(ICssValue value)
{
var options = value as CssTupleValue;
if (options != null)
{
return new[]
{
options.Items[0],
options.Items[1],
options.Items[2],
};
}
return null;
}
}
}
}

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

@ -2,8 +2,6 @@ namespace AngleSharp.Css.Declarations
{
using AngleSharp.Css.Converters;
using AngleSharp.Css.Dom;
using AngleSharp.Css.Values;
using AngleSharp.Text;
using System;
using static ValueConverters;
@ -11,7 +9,11 @@ namespace AngleSharp.Css.Declarations
{
public static String Name = PropertyNames.Outline;
public static IValueConverter Converter = new OutlineAggregator();
public static IValueConverter Converter = AggregateTuple(
WithAny(
LineWidthConverter.Option(InitialValues.OutlineWidthDecl),
LineStyleConverter.Option(InitialValues.OutlineStyleDecl),
InvertedColorConverter.Option(InitialValues.OutlineColorDecl)));
public static ICssValue InitialValue = null;
@ -23,59 +25,5 @@ namespace AngleSharp.Css.Declarations
PropertyNames.OutlineStyle,
PropertyNames.OutlineColor,
};
sealed class OutlineValueConverter : IValueConverter
{
private static readonly IValueConverter converter = WithAny(
LineWidthConverter.Option(),
LineStyleConverter.Option(),
InvertedColorConverter.Option());
public ICssValue Convert(StringSource source)
{
return converter.Convert(source);
}
}
sealed class OutlineAggregator : IValueAggregator, IValueConverter
{
private static readonly IValueConverter converter = new OutlineValueConverter();
public ICssValue Convert(StringSource source)
{
return converter.Convert(source);
}
public ICssValue Merge(ICssValue[] values)
{
var width = values[0];
var style = values[1];
var color = values[2];
if (width != null || style != null || color != null)
{
return new CssTupleValue(new[] { width, style, color });
}
return null;
}
public ICssValue[] Split(ICssValue value)
{
var options = value as CssTupleValue;
if (options != null)
{
return new[]
{
options.Items[0],
options.Items[1],
options.Items[2],
};
}
return null;
}
}
}
}

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

@ -2,8 +2,6 @@ namespace AngleSharp.Css.Declarations
{
using AngleSharp.Css.Converters;
using AngleSharp.Css.Dom;
using AngleSharp.Css.Values;
using AngleSharp.Text;
using System;
using static ValueConverters;
@ -11,7 +9,11 @@ namespace AngleSharp.Css.Declarations
{
public static String Name = PropertyNames.TextDecoration;
public static IValueConverter Converter = new TextDecorationAggregator();
public static IValueConverter Converter = AggregateTuple(
WithAny(
ColorConverter.Option(InitialValues.TextDecorationColorDecl),
TextDecorationStyleConverter.Option(InitialValues.TextDecorationLineDecl),
TextDecorationLinesConverter.Option(InitialValues.TextDecorationStyleDecl)));
public static ICssValue InitialValue = null;
@ -23,59 +25,5 @@ namespace AngleSharp.Css.Declarations
PropertyNames.TextDecorationLine,
PropertyNames.TextDecorationStyle,
};
sealed class TextDecorationValueConverter : IValueConverter
{
private static readonly IValueConverter converter = WithAny(
ColorConverter.Option(),
TextDecorationStyleConverter.Option(),
TextDecorationLinesConverter.Option());
public ICssValue Convert(StringSource source)
{
return converter.Convert(source);
}
}
sealed class TextDecorationAggregator : IValueAggregator, IValueConverter
{
private static readonly IValueConverter converter = new TextDecorationValueConverter();
public ICssValue Convert(StringSource source)
{
return converter.Convert(source);
}
public ICssValue Merge(ICssValue[] values)
{
var color = values[0];
var line = values[1];
var style = values[2];
if (color != null || style != null || line != null)
{
return new CssTupleValue(new[] { color, style, line });
}
return null;
}
public ICssValue[] Split(ICssValue value)
{
var options = value as CssTupleValue;
if (options != null)
{
return new[]
{
options.Items[0],
options.Items[1],
options.Items[2],
};
}
return null;
}
}
}
}

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

@ -26,20 +26,13 @@ namespace AngleSharp.Css.Declarations
PropertyNames.TransitionDelay,
};
sealed class TransitionValueConverter : IValueConverter
{
private static readonly IValueConverter converter = WithAny(
AnimatableConverter.Option(),
TimeConverter.Option(),
TransitionConverter.Option(),
TimeConverter.Option()).FromList();
public ICssValue Convert(StringSource source) => converter.Convert(source);
}
sealed class TransitionAggregator : IValueAggregator, IValueConverter
{
private static readonly IValueConverter converter = new TransitionValueConverter();
private static readonly IValueConverter converter = WithAny(
AnimatableConverter.Option(InitialValues.TransitionPropertyDecl),
TimeConverter.Option(InitialValues.TransitionDurationDecl),
TransitionConverter.Option(InitialValues.TransitionTimingFunctionDecl),
TimeConverter.Option(InitialValues.TransitionDelayDecl)).FromList();
public ICssValue Convert(StringSource source) => converter.Convert(source);

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

@ -1,7 +1,8 @@
namespace AngleSharp.Css.FeatureValidators
namespace AngleSharp.Css.FeatureValidators
{
using AngleSharp.Css.Converters;
using AngleSharp.Css.Dom;
using AngleSharp.Css.Values;
using System;
using static ValueConverters;
@ -9,7 +10,8 @@
{
public Boolean Validate(IMediaFeature feature, IRenderDevice device)
{
var converter = feature.IsMinimum || feature.IsMaximum ? PositiveIntegerConverter : PositiveIntegerConverter.Option(1);
var defaultValue = new Length(1.0, Length.Unit.None);
var converter = feature.IsMinimum || feature.IsMaximum ? PositiveIntegerConverter : PositiveIntegerConverter.Option(defaultValue);
var color = converter.Convert(feature.Value);
if (color != null)

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

@ -1,7 +1,8 @@
namespace AngleSharp.Css.FeatureValidators
namespace AngleSharp.Css.FeatureValidators
{
using AngleSharp.Css.Converters;
using AngleSharp.Css.Dom;
using AngleSharp.Css.Values;
using System;
using static ValueConverters;
@ -9,7 +10,8 @@
{
public Boolean Validate(IMediaFeature feature, IRenderDevice device)
{
var converter = feature.IsMinimum || feature.IsMaximum ? NaturalIntegerConverter : NaturalIntegerConverter.Option(1);
var defaultValue = new Length(1.0, Length.Unit.None);
var converter = feature.IsMinimum || feature.IsMaximum ? NaturalIntegerConverter : NaturalIntegerConverter.Option(defaultValue);
var index = converter.Convert(feature.Value);
if (index != null)

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

@ -1,7 +1,8 @@
namespace AngleSharp.Css.FeatureValidators
namespace AngleSharp.Css.FeatureValidators
{
using AngleSharp.Css.Converters;
using AngleSharp.Css.Dom;
using AngleSharp.Css.Values;
using System;
using static ValueConverters;
@ -9,7 +10,8 @@
{
public Boolean Validate(IMediaFeature feature, IRenderDevice device)
{
var converter = feature.IsMinimum || feature.IsMaximum ? NaturalIntegerConverter : NaturalIntegerConverter.Option(1);
var defaultValue = new Length(1.0, Length.Unit.None);
var converter = feature.IsMinimum || feature.IsMaximum ? NaturalIntegerConverter : NaturalIntegerConverter.Option(defaultValue);
var index = converter.Convert(feature.Value);
if (index != null)

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

@ -699,9 +699,7 @@ namespace AngleSharp.Css
/// <summary>
/// Represents the border-radius (horizontal / vertical; radius) converter.
/// </summary>
public static readonly IValueConverter BorderRadiusLonghandConverter = WithOrder(
LengthOrPercentConverter,
LengthOrPercentConverter.Option());
public static readonly IValueConverter BorderRadiusLonghandConverter = LengthOrPercentConverter.Radius();
/// <summary>
/// Represents a converter for font families.
@ -840,7 +838,11 @@ namespace AngleSharp.Css
#region Premade
public static readonly IValueConverter BorderSideConverter = WithAny(LineWidthConverter.Option(), LineStyleConverter.Option(), CurrentColorConverter.Option());
public static IValueConverter WithBorderSide(ICssValue lineWidth, ICssValue lineStyle, ICssValue lineColor) => AggregateTuple(
WithAny(
LineWidthConverter.Option(lineWidth),
LineStyleConverter.Option(lineStyle),
CurrentColorConverter.Option(lineColor)));
public static readonly IValueConverter GridTemplateConverter = Or(None, TrackListConverter.Exclusive(), AutoTrackListConverter.Exclusive());

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

@ -0,0 +1,114 @@
namespace AngleSharp.Css.Values
{
using AngleSharp.Css.Dom;
using AngleSharp.Text;
using System;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// Represents a periodic CSS value.
/// </summary>
public class CssRadiusValue<T> : ICssMultipleValue
where T : ICssValue
{
#region Fields
private readonly T[] _values;
#endregion
#region ctor
/// <summary>
/// Creates a new CSS radius value container.
/// </summary>
/// <param name="values">The items to contain.</param>
public CssRadiusValue(T[] values = null)
{
_values = values ?? Array.Empty<T>();
}
#endregion
#region Properties
/// <inheritdoc />
public ICssValue this[Int32 index]
{
get
{
switch (index)
{
case 0:
return Width;
case 1:
return Height;
default:
throw new ArgumentOutOfRangeException(nameof(index));
}
}
}
/// <inheritdoc />
public String CssText
{
get
{
var l = _values.Length;
var parts = new String[l];
for (var i = 0; i < l; i++)
{
parts[i] = _values[i].CssText;
}
if (l == 2 && parts[1].Is(parts[0]))
{
l = 1;
parts = new[] { parts[0] };
}
return String.Join(" ", parts);
}
}
/// <inheritdoc />
public T Width => _values.Length > 0 ? _values[0] : default(T);
/// <inheritdoc />
public T Height => _values.Length > 1 ? _values[1] : Width;
/// <inheritdoc />
public Int32 Count => 2;
#endregion
#region Methods
IEnumerator<ICssValue> IEnumerable<ICssValue>.GetEnumerator()
{
yield return Width;
yield return Height;
}
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<ICssValue>)this).GetEnumerator();
#endregion
}
/// <summary>
/// Represents a radius (w, h) CSS value.
/// </summary>
sealed class CssRadiusValue : CssRadiusValue<ICssValue>
{
#region ctor
public CssRadiusValue(ICssValue[] values = null)
: base(values)
{
}
#endregion
}
}

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

@ -6,11 +6,11 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Represents a default value.
/// </summary>
sealed class CssDefaultValue<T> : ICssValue
sealed class CssDefaultValue : ICssValue
{
#region Fields
private readonly T _value;
private readonly ICssValue _value;
#endregion
@ -20,7 +20,7 @@ namespace AngleSharp.Css.Values
/// Creates a new default value.
/// </summary>
/// <param name="value">The used value.</param>
public CssDefaultValue(T value)
public CssDefaultValue(ICssValue value)
{
_value = value;
}
@ -37,7 +37,7 @@ namespace AngleSharp.Css.Values
/// <summary>
/// Gets the default value.
/// </summary>
public T Value => _value;
public ICssValue Value => _value;
#endregion
}