diff --git a/src/AngleSharp.Css/Constants/InitialValues.cs b/src/AngleSharp.Css/Constants/InitialValues.cs index 6fa6a640..21c9a7c5 100644 --- a/src/AngleSharp.Css/Constants/InitialValues.cs +++ b/src/AngleSharp.Css/Constants/InitialValues.cs @@ -95,10 +95,18 @@ static class InitialValues public static readonly ICssValue MinWidthDecl = new Constant(CssKeywords.Auto, Length.Auto); public static readonly ICssValue MaxHeightDecl = new Constant(CssKeywords.None, null); public static readonly ICssValue MaxWidthDecl = new Constant(CssKeywords.None, null); + public static readonly ICssValue MarginBlockEndDecl = Length.Zero; + public static readonly ICssValue MarginBlockStartDecl = Length.Zero; + public static readonly ICssValue MarginInlineEndDecl = Length.Zero; + public static readonly ICssValue MarginInlineStartDecl = Length.Zero; public static readonly ICssValue MarginLeftDecl = Length.Zero; public static readonly ICssValue MarginBottomDecl = Length.Zero; public static readonly ICssValue MarginRightDecl = Length.Zero; public static readonly ICssValue MarginTopDecl = Length.Zero; + public static readonly ICssValue PaddingBlockEndDecl = Length.Zero; + public static readonly ICssValue PaddingBlockStartDecl = Length.Zero; + public static readonly ICssValue PaddingInlineEndDecl = Length.Zero; + public static readonly ICssValue PaddingInlineStartDecl = Length.Zero; public static readonly ICssValue PaddingLeftDecl = Length.Zero; public static readonly ICssValue PaddingBottomDecl = Length.Zero; public static readonly ICssValue PaddingRightDecl = Length.Zero; diff --git a/src/AngleSharp.Css/Constants/PropertyNames.cs b/src/AngleSharp.Css/Constants/PropertyNames.cs index e08efff8..00467c91 100644 --- a/src/AngleSharp.Css/Constants/PropertyNames.cs +++ b/src/AngleSharp.Css/Constants/PropertyNames.cs @@ -676,7 +676,7 @@ public static class PropertyNames /// The layout-grid-line declaration. /// public static readonly String LayoutGridLine = "layout-grid-line"; - + /// /// The grid-template-rows declaration. /// @@ -802,6 +802,36 @@ public static class PropertyNames /// public static readonly String ListStyle = "list-style"; + /// + /// The margin-block declaration. + /// + public static readonly String MarginBlock = "margin-block"; + + /// + /// The margin-block-end declaration. + /// + public static readonly String MarginBlockEnd = "margin-block-end"; + + /// + /// The margin-block-start declaration. + /// + public static readonly String MarginBlockStart = "margin-block-start"; + + /// + /// The margin-inline declaration. + /// + public static readonly String MarginInline = "margin-inline"; + + /// + /// The margin-inline-end declaration. + /// + public static readonly String MarginInlineEnd = "margin-inline-end"; + + /// + /// The margin-inline-start declaration. + /// + public static readonly String MarginInlineStart = "margin-inline-start"; + /// /// The margin-right declaration. /// @@ -927,6 +957,36 @@ public static class PropertyNames /// public static readonly String OverflowWrap = "overflow-wrap"; + /// + /// The padding-block declaration. + /// + public static readonly String PaddingBlock = "padding-block"; + + /// + /// The padding-block-end declaration. + /// + public static readonly String PaddingBlockEnd = "padding-block-end"; + + /// + /// The padding-block-start declaration. + /// + public static readonly String PaddingBlockStart = "padding-block-start"; + + /// + /// The padding-inline declaration. + /// + public static readonly String PaddingInline = "padding-inline"; + + /// + /// The padding-inline-end declaration. + /// + public static readonly String PaddingInlineEnd = "padding-inline-end"; + + /// + /// The padding-inline-start declaration. + /// + public static readonly String PaddingInlineStart = "padding-inline-start"; + /// /// The padding-top declaration. /// diff --git a/src/AngleSharp.Css/Converters/FlowRelativeValueConverter.cs b/src/AngleSharp.Css/Converters/FlowRelativeValueConverter.cs new file mode 100644 index 00000000..5994deeb --- /dev/null +++ b/src/AngleSharp.Css/Converters/FlowRelativeValueConverter.cs @@ -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 FlowRelativeValueConverter : IValueConverter + { + private readonly IValueConverter _converter; + + public FlowRelativeValueConverter(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 CssFlowRelativeValue(values); + } + + return null; + } + } +} diff --git a/src/AngleSharp.Css/Declarations/MarginBlockDeclaration.cs b/src/AngleSharp.Css/Declarations/MarginBlockDeclaration.cs new file mode 100644 index 00000000..91dfc287 --- /dev/null +++ b/src/AngleSharp.Css/Declarations/MarginBlockDeclaration.cs @@ -0,0 +1,56 @@ +namespace AngleSharp.Css.Declarations +{ + using AngleSharp.Css.Converters; + using AngleSharp.Css.Dom; + using AngleSharp.Css.Values; + using AngleSharp.Text; + using System; + using static ValueConverters; + + static class MarginBlockDeclaration + { + public static String Name = PropertyNames.MarginBlock; + + public static IValueConverter Converter = new MarginBlockAggregator(); + + public static ICssValue InitialValue = null; + + public static PropertyFlags Flags = PropertyFlags.Shorthand; + + public static String[] Longhands = new[] + { + PropertyNames.MarginBlockStart, + PropertyNames.MarginBlockEnd, + }; + + sealed class MarginBlockAggregator : IValueAggregator, IValueConverter + { + private static readonly IValueConverter converter = Or(AutoLengthOrPercentConverter, AssignInitial(Length.Zero)).FlowRelative(); + + public ICssValue Convert(StringSource source) => converter.Convert(source); + + public ICssValue Merge(ICssValue[] values) + { + var start = values[0]; + var end = values[1]; + + if (start != null && end != null) + { + return new CssFlowRelativeValue(new[] { start, end }); + } + + return null; + } + + public ICssValue[] Split(ICssValue value) + { + if (value is CssFlowRelativeValue flowRelative) + { + return new[] { flowRelative.Start, flowRelative.End }; + } + + return null; + } + } + } +} diff --git a/src/AngleSharp.Css/Declarations/MarginBlockEndDeclaration.cs b/src/AngleSharp.Css/Declarations/MarginBlockEndDeclaration.cs new file mode 100644 index 00000000..4d65526d --- /dev/null +++ b/src/AngleSharp.Css/Declarations/MarginBlockEndDeclaration.cs @@ -0,0 +1,22 @@ +namespace AngleSharp.Css.Declarations +{ + using System; + using Dom; + using static ValueConverters; + + public class MarginBlockEndDeclaration + { + public static String Name = PropertyNames.MarginBlockEnd; + + public static String[] Shorthands = new[] + { + PropertyNames.MarginBlock, + }; + + public static IValueConverter Converter = AutoLengthOrPercentConverter; + + public static ICssValue InitialValue = InitialValues.MarginBlockEndDecl; + + public static PropertyFlags Flags = PropertyFlags.Unitless | PropertyFlags.Animatable; + } +} diff --git a/src/AngleSharp.Css/Declarations/MarginBlockStartDeclaration.cs b/src/AngleSharp.Css/Declarations/MarginBlockStartDeclaration.cs new file mode 100644 index 00000000..35e82ca7 --- /dev/null +++ b/src/AngleSharp.Css/Declarations/MarginBlockStartDeclaration.cs @@ -0,0 +1,22 @@ +namespace AngleSharp.Css.Declarations +{ + using System; + using Dom; + using static ValueConverters; + + public class MarginBlockStartDeclaration + { + public static String Name = PropertyNames.MarginBlockStart; + + public static String[] Shorthands = new[] + { + PropertyNames.MarginBlock, + }; + + public static IValueConverter Converter = AutoLengthOrPercentConverter; + + public static ICssValue InitialValue = InitialValues.MarginBlockStartDecl; + + public static PropertyFlags Flags = PropertyFlags.Unitless | PropertyFlags.Animatable; + } +} diff --git a/src/AngleSharp.Css/Declarations/MarginInlineDeclaration.cs b/src/AngleSharp.Css/Declarations/MarginInlineDeclaration.cs new file mode 100644 index 00000000..9e18f10e --- /dev/null +++ b/src/AngleSharp.Css/Declarations/MarginInlineDeclaration.cs @@ -0,0 +1,56 @@ +namespace AngleSharp.Css.Declarations +{ + using AngleSharp.Css.Converters; + using AngleSharp.Css.Dom; + using AngleSharp.Css.Values; + using AngleSharp.Text; + using System; + using static ValueConverters; + + static class MarginInlineDeclaration + { + public static String Name = PropertyNames.MarginInline; + + public static IValueConverter Converter = new MarginInlineAggregator(); + + public static ICssValue InitialValue = null; + + public static PropertyFlags Flags = PropertyFlags.Shorthand; + + public static String[] Longhands = new[] + { + PropertyNames.MarginInlineStart, + PropertyNames.MarginInlineEnd, + }; + + sealed class MarginInlineAggregator : IValueAggregator, IValueConverter + { + private static readonly IValueConverter converter = Or(AutoLengthOrPercentConverter, AssignInitial(Length.Zero)).FlowRelative(); + + public ICssValue Convert(StringSource source) => converter.Convert(source); + + public ICssValue Merge(ICssValue[] values) + { + var start = values[0]; + var end = values[1]; + + if (start != null && end != null) + { + return new CssFlowRelativeValue(new[] { start, end }); + } + + return null; + } + + public ICssValue[] Split(ICssValue value) + { + if (value is CssFlowRelativeValue flowRelative) + { + return new[] { flowRelative.Start, flowRelative.End }; + } + + return null; + } + } + } +} diff --git a/src/AngleSharp.Css/Declarations/MarginInlineEndDeclaration.cs b/src/AngleSharp.Css/Declarations/MarginInlineEndDeclaration.cs new file mode 100644 index 00000000..82bd709c --- /dev/null +++ b/src/AngleSharp.Css/Declarations/MarginInlineEndDeclaration.cs @@ -0,0 +1,22 @@ +namespace AngleSharp.Css.Declarations +{ + using System; + using Dom; + using static ValueConverters; + + public class MarginInlineEndDeclaration + { + public static String Name = PropertyNames.MarginInlineEnd; + + public static String[] Shorthands = new[] + { + PropertyNames.MarginInline, + }; + + public static IValueConverter Converter = AutoLengthOrPercentConverter; + + public static ICssValue InitialValue = InitialValues.MarginInlineEndDecl; + + public static PropertyFlags Flags = PropertyFlags.Unitless | PropertyFlags.Animatable; + } +} diff --git a/src/AngleSharp.Css/Declarations/MarginInlineStartDeclaration.cs b/src/AngleSharp.Css/Declarations/MarginInlineStartDeclaration.cs new file mode 100644 index 00000000..5af190ce --- /dev/null +++ b/src/AngleSharp.Css/Declarations/MarginInlineStartDeclaration.cs @@ -0,0 +1,22 @@ +namespace AngleSharp.Css.Declarations +{ + using System; + using Dom; + using static ValueConverters; + + public class MarginInlineStartDeclaration + { + public static String Name = PropertyNames.MarginInlineStart; + + public static String[] Shorthands = new[] + { + PropertyNames.MarginInline, + }; + + public static IValueConverter Converter = AutoLengthOrPercentConverter; + + public static ICssValue InitialValue = InitialValues.MarginInlineStartDecl; + + public static PropertyFlags Flags = PropertyFlags.Unitless | PropertyFlags.Animatable; + } +} diff --git a/src/AngleSharp.Css/Declarations/PaddingBlockDeclaration.cs b/src/AngleSharp.Css/Declarations/PaddingBlockDeclaration.cs new file mode 100644 index 00000000..f24d51cb --- /dev/null +++ b/src/AngleSharp.Css/Declarations/PaddingBlockDeclaration.cs @@ -0,0 +1,56 @@ +namespace AngleSharp.Css.Declarations +{ + using AngleSharp.Css.Converters; + using AngleSharp.Css.Dom; + using AngleSharp.Css.Values; + using AngleSharp.Text; + using System; + using static ValueConverters; + + static class PaddingBlockDeclaration + { + public static String Name = PropertyNames.PaddingBlock; + + public static IValueConverter Converter = new PaddingBlockAggregator(); + + public static ICssValue InitialValue = null; + + public static PropertyFlags Flags = PropertyFlags.Shorthand; + + public static String[] Longhands = new[] + { + PropertyNames.PaddingBlockStart, + PropertyNames.PaddingBlockEnd, + }; + + sealed class PaddingBlockAggregator : IValueAggregator, IValueConverter + { + private static readonly IValueConverter converter = Or(AutoLengthOrPercentConverter, AssignInitial(Length.Zero)).FlowRelative(); + + public ICssValue Convert(StringSource source) => converter.Convert(source); + + public ICssValue Merge(ICssValue[] values) + { + var start = values[0]; + var end = values[1]; + + if (start != null && end != null) + { + return new CssFlowRelativeValue(new[] { start, end }); + } + + return null; + } + + public ICssValue[] Split(ICssValue value) + { + if (value is CssFlowRelativeValue flowRelative) + { + return new[] { flowRelative.Start, flowRelative.End }; + } + + return null; + } + } + } +} diff --git a/src/AngleSharp.Css/Declarations/PaddingBlockEndDeclaration.cs b/src/AngleSharp.Css/Declarations/PaddingBlockEndDeclaration.cs new file mode 100644 index 00000000..482dcb76 --- /dev/null +++ b/src/AngleSharp.Css/Declarations/PaddingBlockEndDeclaration.cs @@ -0,0 +1,22 @@ +namespace AngleSharp.Css.Declarations +{ + using System; + using Dom; + using static ValueConverters; + + public class PaddingBlockEndDeclaration + { + public static String Name = PropertyNames.PaddingBlockEnd; + + public static String[] Shorthands = new[] + { + PropertyNames.PaddingBlock, + }; + + public static IValueConverter Converter = AutoLengthOrPercentConverter; + + public static ICssValue InitialValue = InitialValues.PaddingBlockEndDecl; + + public static PropertyFlags Flags = PropertyFlags.Unitless | PropertyFlags.Animatable; + } +} diff --git a/src/AngleSharp.Css/Declarations/PaddingBlockStartDeclaration.cs b/src/AngleSharp.Css/Declarations/PaddingBlockStartDeclaration.cs new file mode 100644 index 00000000..a1575e79 --- /dev/null +++ b/src/AngleSharp.Css/Declarations/PaddingBlockStartDeclaration.cs @@ -0,0 +1,22 @@ +namespace AngleSharp.Css.Declarations +{ + using System; + using Dom; + using static ValueConverters; + + public class PaddingBlockStartDeclaration + { + public static String Name = PropertyNames.PaddingBlockStart; + + public static String[] Shorthands = new[] + { + PropertyNames.PaddingBlock, + }; + + public static IValueConverter Converter = AutoLengthOrPercentConverter; + + public static ICssValue InitialValue = InitialValues.PaddingBlockStartDecl; + + public static PropertyFlags Flags = PropertyFlags.Unitless | PropertyFlags.Animatable; + } +} diff --git a/src/AngleSharp.Css/Declarations/PaddingInlineDeclaration.cs b/src/AngleSharp.Css/Declarations/PaddingInlineDeclaration.cs new file mode 100644 index 00000000..06942170 --- /dev/null +++ b/src/AngleSharp.Css/Declarations/PaddingInlineDeclaration.cs @@ -0,0 +1,56 @@ +namespace AngleSharp.Css.Declarations +{ + using AngleSharp.Css.Converters; + using AngleSharp.Css.Dom; + using AngleSharp.Css.Values; + using AngleSharp.Text; + using System; + using static ValueConverters; + + static class PaddingInlineDeclaration + { + public static String Name = PropertyNames.PaddingInline; + + public static IValueConverter Converter = new PaddingInlineAggregator(); + + public static ICssValue InitialValue = null; + + public static PropertyFlags Flags = PropertyFlags.Shorthand; + + public static String[] Longhands = new[] + { + PropertyNames.PaddingInlineStart, + PropertyNames.PaddingInlineEnd, + }; + + sealed class PaddingInlineAggregator : IValueAggregator, IValueConverter + { + private static readonly IValueConverter converter = Or(AutoLengthOrPercentConverter, AssignInitial(Length.Zero)).FlowRelative(); + + public ICssValue Convert(StringSource source) => converter.Convert(source); + + public ICssValue Merge(ICssValue[] values) + { + var start = values[0]; + var end = values[1]; + + if (start != null && end != null) + { + return new CssFlowRelativeValue(new[] { start, end }); + } + + return null; + } + + public ICssValue[] Split(ICssValue value) + { + if (value is CssFlowRelativeValue flowRelative) + { + return new[] { flowRelative.Start, flowRelative.End }; + } + + return null; + } + } + } +} diff --git a/src/AngleSharp.Css/Declarations/PaddingInlineEndDeclaration.cs b/src/AngleSharp.Css/Declarations/PaddingInlineEndDeclaration.cs new file mode 100644 index 00000000..1fb6862e --- /dev/null +++ b/src/AngleSharp.Css/Declarations/PaddingInlineEndDeclaration.cs @@ -0,0 +1,22 @@ +namespace AngleSharp.Css.Declarations +{ + using System; + using Dom; + using static ValueConverters; + + public class PaddingInlineEndDeclaration + { + public static String Name = PropertyNames.PaddingInlineEnd; + + public static String[] Shorthands = new[] + { + PropertyNames.PaddingInline, + }; + + public static IValueConverter Converter = AutoLengthOrPercentConverter; + + public static ICssValue InitialValue = InitialValues.PaddingInlineEndDecl; + + public static PropertyFlags Flags = PropertyFlags.Unitless | PropertyFlags.Animatable; + } +} diff --git a/src/AngleSharp.Css/Declarations/PaddingInlineStartDeclaration.cs b/src/AngleSharp.Css/Declarations/PaddingInlineStartDeclaration.cs new file mode 100644 index 00000000..6aefcb87 --- /dev/null +++ b/src/AngleSharp.Css/Declarations/PaddingInlineStartDeclaration.cs @@ -0,0 +1,22 @@ +namespace AngleSharp.Css.Declarations +{ + using System; + using Dom; + using static ValueConverters; + + public class PaddingInlineStartDeclaration + { + public static String Name = PropertyNames.PaddingInlineStart; + + public static String[] Shorthands = new[] + { + PropertyNames.PaddingInline, + }; + + public static IValueConverter Converter = AutoLengthOrPercentConverter; + + public static ICssValue InitialValue = InitialValues.PaddingInlineStartDecl; + + public static PropertyFlags Flags = PropertyFlags.Unitless | PropertyFlags.Animatable; + } +} diff --git a/src/AngleSharp.Css/Extensions/ValueConverterExtensions.cs b/src/AngleSharp.Css/Extensions/ValueConverterExtensions.cs index 17b59636..92f8f5ab 100644 --- a/src/AngleSharp.Css/Extensions/ValueConverterExtensions.cs +++ b/src/AngleSharp.Css/Extensions/ValueConverterExtensions.cs @@ -37,6 +37,9 @@ public static IValueConverter FromList(this IValueConverter converter) => public static IValueConverter ToConverter(this Dictionary values) => new DictionaryValueConverter(values); + public static IValueConverter FlowRelative(this IValueConverter converter) => + new FlowRelativeValueConverter(converter); + public static IValueConverter Periodic(this IValueConverter converter) => new PeriodicValueConverter(converter); diff --git a/src/AngleSharp.Css/Factories/DefaultDeclarationFactory.cs b/src/AngleSharp.Css/Factories/DefaultDeclarationFactory.cs index 2cdcb0f7..ea602062 100644 --- a/src/AngleSharp.Css/Factories/DefaultDeclarationFactory.cs +++ b/src/AngleSharp.Css/Factories/DefaultDeclarationFactory.cs @@ -770,6 +770,38 @@ public class DefaultDeclarationFactory : IDeclarationFactory flags: ColumnRuleColorDeclaration.Flags, shorthands: ColumnRuleColorDeclaration.Shorthands) }, + { + PaddingBlockEndDeclaration.Name, new DeclarationInfo( + name: PaddingBlockEndDeclaration.Name, + converter: PaddingBlockEndDeclaration.Converter, + initialValue: PaddingBlockEndDeclaration.InitialValue, + flags: PaddingBlockEndDeclaration.Flags, + shorthands: PaddingBlockEndDeclaration.Shorthands) + }, + { + PaddingBlockStartDeclaration.Name, new DeclarationInfo( + name: PaddingBlockStartDeclaration.Name, + converter: PaddingBlockStartDeclaration.Converter, + initialValue: PaddingBlockStartDeclaration.InitialValue, + flags: PaddingBlockStartDeclaration.Flags, + shorthands: PaddingBlockStartDeclaration.Shorthands) + }, + { + PaddingInlineEndDeclaration.Name, new DeclarationInfo( + name: PaddingInlineEndDeclaration.Name, + converter: PaddingInlineEndDeclaration.Converter, + initialValue: PaddingInlineEndDeclaration.InitialValue, + flags: PaddingInlineEndDeclaration.Flags, + shorthands: PaddingInlineEndDeclaration.Shorthands) + }, + { + PaddingInlineStartDeclaration.Name, new DeclarationInfo( + name: PaddingInlineStartDeclaration.Name, + converter: PaddingInlineStartDeclaration.Converter, + initialValue: PaddingInlineStartDeclaration.InitialValue, + flags: PaddingInlineStartDeclaration.Flags, + shorthands: PaddingInlineStartDeclaration.Shorthands) + }, { PaddingTopDeclaration.Name, new DeclarationInfo( name: PaddingTopDeclaration.Name, @@ -802,6 +834,38 @@ public class DefaultDeclarationFactory : IDeclarationFactory flags: PaddingBottomDeclaration.Flags, shorthands: PaddingBottomDeclaration.Shorthands) }, + { + MarginBlockEndDeclaration.Name, new DeclarationInfo( + name: MarginBlockEndDeclaration.Name, + converter: MarginBlockEndDeclaration.Converter, + initialValue: MarginBlockEndDeclaration.InitialValue, + flags: MarginBlockEndDeclaration.Flags, + shorthands: MarginBlockEndDeclaration.Shorthands) + }, + { + MarginBlockStartDeclaration.Name, new DeclarationInfo( + name: MarginBlockStartDeclaration.Name, + converter: MarginBlockStartDeclaration.Converter, + initialValue: MarginBlockStartDeclaration.InitialValue, + flags: MarginBlockStartDeclaration.Flags, + shorthands: MarginBlockStartDeclaration.Shorthands) + }, + { + MarginInlineEndDeclaration.Name, new DeclarationInfo( + name: MarginInlineEndDeclaration.Name, + converter: MarginInlineEndDeclaration.Converter, + initialValue: MarginInlineEndDeclaration.InitialValue, + flags: MarginInlineEndDeclaration.Flags, + shorthands: MarginInlineEndDeclaration.Shorthands) + }, + { + MarginInlineStartDeclaration.Name, new DeclarationInfo( + name: MarginInlineStartDeclaration.Name, + converter: MarginInlineStartDeclaration.Converter, + initialValue: MarginInlineStartDeclaration.InitialValue, + flags: MarginInlineStartDeclaration.Flags, + shorthands: MarginInlineStartDeclaration.Shorthands) + }, { MarginTopDeclaration.Name, new DeclarationInfo( name: MarginTopDeclaration.Name, @@ -1324,6 +1388,22 @@ public class DefaultDeclarationFactory : IDeclarationFactory flags: PaddingDeclaration.Flags, longhands: PaddingDeclaration.Longhands) }, + { + PaddingBlockDeclaration.Name, new DeclarationInfo( + name: PaddingBlockDeclaration.Name, + converter: PaddingBlockDeclaration.Converter, + initialValue: PaddingBlockDeclaration.InitialValue, + flags: PaddingBlockDeclaration.Flags, + longhands: PaddingBlockDeclaration.Longhands) + }, + { + PaddingInlineDeclaration.Name, new DeclarationInfo( + name: PaddingInlineDeclaration.Name, + converter: PaddingInlineDeclaration.Converter, + initialValue: PaddingInlineDeclaration.InitialValue, + flags: PaddingInlineDeclaration.Flags, + longhands: PaddingInlineDeclaration.Longhands) + }, { MarginDeclaration.Name, new DeclarationInfo( name: MarginDeclaration.Name, @@ -1332,6 +1412,22 @@ public class DefaultDeclarationFactory : IDeclarationFactory flags: MarginDeclaration.Flags, longhands: MarginDeclaration.Longhands) }, + { + MarginBlockDeclaration.Name, new DeclarationInfo( + name: MarginBlockDeclaration.Name, + converter: MarginBlockDeclaration.Converter, + initialValue: MarginBlockDeclaration.InitialValue, + flags: MarginBlockDeclaration.Flags, + longhands: MarginBlockDeclaration.Longhands) + }, + { + MarginInlineDeclaration.Name, new DeclarationInfo( + name: MarginInlineDeclaration.Name, + converter: MarginInlineDeclaration.Converter, + initialValue: MarginInlineDeclaration.InitialValue, + flags: MarginInlineDeclaration.Flags, + longhands: MarginInlineDeclaration.Longhands) + }, { BorderRadiusDeclaration.Name, new DeclarationInfo( name: BorderRadiusDeclaration.Name, diff --git a/src/AngleSharp.Css/Values/Multiples/CssFlowRelativeValue.cs b/src/AngleSharp.Css/Values/Multiples/CssFlowRelativeValue.cs new file mode 100644 index 00000000..4036b948 --- /dev/null +++ b/src/AngleSharp.Css/Values/Multiples/CssFlowRelativeValue.cs @@ -0,0 +1,114 @@ +namespace AngleSharp.Css.Values +{ + using AngleSharp.Css.Dom; + using AngleSharp.Text; + using System; + using System.Collections; + using System.Collections.Generic; + + /// + /// Represents a flow relative CSS value. + /// + public class CssFlowRelativeValue : ICssMultipleValue + where T : ICssValue + { + #region Fields + + private readonly T[] _values; + + #endregion + + #region ctor + + /// + /// Creates a new CSS flow relative value container. + /// + /// The items to contain. + public CssFlowRelativeValue(T[] values = null) + { + _values = values ?? Array.Empty(); + } + + #endregion + + #region Properties + + /// + public ICssValue this[Int32 index] + { + get + { + switch (index) + { + case 0: + return Start; + case 1: + return End; + default: + throw new ArgumentOutOfRangeException(nameof(index)); + } + } + } + + /// + 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); + } + } + + /// + public T Start => _values.Length > 0 ? _values[0] : default; + + /// + public T End => _values.Length > 1 ? _values[1] : Start; + + /// + public Int32 Count => 2; + + #endregion + + #region Methods + + IEnumerator IEnumerable.GetEnumerator() + { + yield return Start; + yield return End; + } + + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)this).GetEnumerator(); + + #endregion + } + + /// + /// Represents a flow relative CSS value. + /// + sealed class CssFlowRelativeValue : CssFlowRelativeValue + { + #region ctor + + public CssFlowRelativeValue(ICssValue[] values = null) + : base(values) + { + } + + #endregion + } +}