diff --git a/src/AngleSharp.Css.Tests/Declarations/CssBorderProperty.cs b/src/AngleSharp.Css.Tests/Declarations/CssBorderProperty.cs index 98f667e..535bf07 100644 --- a/src/AngleSharp.Css.Tests/Declarations/CssBorderProperty.cs +++ b/src/AngleSharp.Css.Tests/Declarations/CssBorderProperty.cs @@ -586,5 +586,130 @@ public void CssBorderAggregation() style.SetBorderColor("black"); Assert.AreEqual(expectedCss, style.CssText); } + + [Test] + public void CssBorderInheritShouldResolveToParentValues() + { + var source = @" + + + +
Cell
+ +"; + var document = source.ToHtmlDocument(Configuration.Default.WithCss()); + var td = document.QuerySelector("td"); + var style = td.ComputeCurrentStyle(); + Assert.AreEqual("solid", style.GetBorderTopStyle()); + Assert.AreEqual("3px", style.GetBorderTopWidth()); + } + + [Test] + public void CssBorderInheritShouldResolveAllSides() + { + var source = @" + + + +
Content
+ +"; + var document = source.ToHtmlDocument(Configuration.Default.WithCss()); + var child = document.QuerySelector("div.child"); + var style = child.ComputeCurrentStyle(); + Assert.AreEqual("dashed", style.GetBorderTopStyle()); + Assert.AreEqual("dashed", style.GetBorderBottomStyle()); + Assert.AreEqual("dashed", style.GetBorderLeftStyle()); + Assert.AreEqual("dashed", style.GetBorderRightStyle()); + Assert.AreEqual("2px", style.GetBorderTopWidth()); + Assert.AreEqual("2px", style.GetBorderBottomWidth()); + } + + [Test] + public void CssBorderStyleInheritShouldResolveToParentValues() + { + var source = @" + + + +
Content
+ +"; + var document = source.ToHtmlDocument(Configuration.Default.WithCss()); + var child = document.QuerySelector("div.child"); + var style = child.ComputeCurrentStyle(); + Assert.AreEqual("dotted", style.GetBorderTopStyle()); + Assert.AreEqual("dotted", style.GetBorderRightStyle()); + } + + [Test] + public void CssBorderWidthInheritShouldResolveToParentValues() + { + var source = @" + + + +
Content
+ +"; + var document = source.ToHtmlDocument(Configuration.Default.WithCss()); + var child = document.QuerySelector("div.child"); + var style = child.ComputeCurrentStyle(); + Assert.AreEqual("5px", style.GetBorderTopWidth()); + Assert.AreEqual("5px", style.GetBorderLeftWidth()); + } + + [Test] + public void CssBorderInheritThroughMultipleLevels() + { + var source = @" + + + +
Deep
+ +"; + var document = source.ToHtmlDocument(Configuration.Default.WithCss()); + var inner = document.QuerySelector("div.inner"); + var style = inner.ComputeCurrentStyle(); + Assert.AreEqual("solid", style.GetBorderTopStyle()); + Assert.AreEqual("4px", style.GetBorderTopWidth()); + } + + [Test] + public void CssBorderInheritWithExplicitChildOverride() + { + var source = @" + + + +
Content
+ +"; + var document = source.ToHtmlDocument(Configuration.Default.WithCss()); + var child = document.QuerySelector("div.child"); + var style = child.ComputeCurrentStyle(); + Assert.AreEqual("dotted", style.GetBorderTopStyle()); + Assert.AreEqual("solid", style.GetBorderBottomStyle()); + Assert.AreEqual("3px", style.GetBorderTopWidth()); + } } } diff --git a/src/AngleSharp.Css.Tests/Library/ComputedStyle.cs b/src/AngleSharp.Css.Tests/Library/ComputedStyle.cs index 6ee3f88..3d5bb05 100644 --- a/src/AngleSharp.Css.Tests/Library/ComputedStyle.cs +++ b/src/AngleSharp.Css.Tests/Library/ComputedStyle.cs @@ -1,9 +1,11 @@ namespace AngleSharp.Css.Tests.Library { + using AngleSharp.Css.Dom; using AngleSharp.Dom; using AngleSharp.Html.Dom; using NUnit.Framework; using System.Threading.Tasks; + using static CssConstructionFunctions; [TestFixture] public class ComputedStyleTests @@ -25,5 +27,82 @@ public async Task TransformEmToPx_Issue136() Assert.AreEqual("24px", fontSize.Value); } + + [Test] + public void MarginInheritShouldResolveToParentValues() + { + var source = @" + + + +
Content
+ +"; + var document = ParseDocument(source); + var child = document.QuerySelector("div.child"); + var style = child.ComputeCurrentStyle(); + Assert.AreEqual("10px", style.GetMarginTop()); + Assert.AreEqual("20px", style.GetMarginRight()); + Assert.AreEqual("10px", style.GetMarginBottom()); + Assert.AreEqual("20px", style.GetMarginLeft()); + } + + [Test] + public void PaddingInheritShouldResolveToParentValues() + { + var source = @" + + + +
Content
+ +"; + var document = ParseDocument(source); + var child = document.QuerySelector("div.child"); + var style = child.ComputeCurrentStyle(); + Assert.AreEqual("5px", style.GetPaddingTop()); + Assert.AreEqual("15px", style.GetPaddingRight()); + Assert.AreEqual("10px", style.GetPaddingBottom()); + Assert.AreEqual("15px", style.GetPaddingLeft()); + } + + [Test] + public void InheritOnNonInheritablePropertyShouldResolveFromParent() + { + var source = @" + + + +
Content
+ +"; + var document = ParseDocument(source); + var child = document.QuerySelector("div.child"); + var style = child.ComputeCurrentStyle(); + Assert.AreEqual("solid", style.GetBorderTopStyle()); + Assert.AreEqual("1px", style.GetBorderTopWidth()); + Assert.AreEqual("8px", style.GetPaddingTop()); + } + + [Test] + public void BorderInheritShouldSerializeCorrectly() + { + var html = @""; + var dom = ParseDocument(html); + var styleSheet = dom.StyleSheets[0] as ICssStyleSheet; + var rule = styleSheet.Rules[0] as ICssStyleRule; + Assert.AreEqual("inherit", rule.Style.GetPropertyValue("border-top-style")); + Assert.AreEqual("inherit", rule.Style.GetPropertyValue("border-top-width")); + Assert.AreEqual("inherit", rule.Style.GetPropertyValue("border-top-color")); + } } } diff --git a/src/AngleSharp.Css/DeclarationInfo.cs b/src/AngleSharp.Css/DeclarationInfo.cs index 9391ac7..d12f6f6 100644 --- a/src/AngleSharp.Css/DeclarationInfo.cs +++ b/src/AngleSharp.Css/DeclarationInfo.cs @@ -21,7 +21,7 @@ public class DeclarationInfo public DeclarationInfo(String name, IValueConverter converter, PropertyFlags flags = PropertyFlags.None, ICssValue initialValue = null, String[] shorthands = null, String[] longhands = null) { Name = name; - Converter = initialValue != null ? Or(converter, AssignInitial(initialValue)) : converter; + Converter = initialValue != null || longhands?.Length > 0 ? Or(AssignInitial(initialValue), converter) : converter; Aggregator = converter as IValueAggregator; Flags = flags; InitialValue = initialValue; diff --git a/src/AngleSharp.Css/Dom/Internal/CssStyleDeclaration.cs b/src/AngleSharp.Css/Dom/Internal/CssStyleDeclaration.cs index 11f937e..7924436 100644 --- a/src/AngleSharp.Css/Dom/Internal/CssStyleDeclaration.cs +++ b/src/AngleSharp.Css/Dom/Internal/CssStyleDeclaration.cs @@ -397,6 +397,7 @@ private void ChangeDeclarations(IEnumerable decls, Predicate() .ToArray(); } + else if (value is CssInheritValue) + { + return Enumerable + .Repeat(value, longhands.Length) + .ToArray(); + } + else if (value is CssUnsetValue) + { + return longhands + .Select(name => new CssUnsetValue(factory.Create(name)?.InitialValue)) + .OfType() + .ToArray(); + } return info.Aggregator?.Split(value); }