diff --git a/src/Svg.Custom/Compatibility/SvgCssCompatibilityProcessor.cs b/src/Svg.Custom/Compatibility/SvgCssCompatibilityProcessor.cs index 686a109bfb..371b02b81f 100644 --- a/src/Svg.Custom/Compatibility/SvgCssCompatibilityProcessor.cs +++ b/src/Svg.Custom/Compatibility/SvgCssCompatibilityProcessor.cs @@ -121,6 +121,11 @@ List CreateAppliedDeclarations() var result = new List(); foreach (var declaration in rule.Style) { + if (string.IsNullOrWhiteSpace(declaration.Original)) + { + continue; + } + result.Add(new AppliedDeclaration(declaration.Name, declaration.Original)); } diff --git a/src/Svg.Custom/Compatibility/SvgInlineStyleAttributeParser.cs b/src/Svg.Custom/Compatibility/SvgInlineStyleAttributeParser.cs index c6892dfd35..d1206762af 100644 --- a/src/Svg.Custom/Compatibility/SvgInlineStyleAttributeParser.cs +++ b/src/Svg.Custom/Compatibility/SvgInlineStyleAttributeParser.cs @@ -25,6 +25,12 @@ public void ApplyStyles(SvgElement element, string styleText) { foreach (var declaration in rule.Style) { + if (string.IsNullOrWhiteSpace(declaration.Original) && + !SvgCssVariableResolver.IsCustomPropertyName(declaration.Name)) + { + continue; + } + ApplyDeclaration(element, declaration.Name, declaration.Original, SvgElement.StyleSpecificity_InlineStyle); } } @@ -55,6 +61,12 @@ private static bool TryApplyInlineDeclarations(SvgElement element, string styleT return false; } + if (string.IsNullOrWhiteSpace(value) && + !SvgCssVariableResolver.IsCustomPropertyName(name)) + { + continue; + } + ApplyDeclaration(element, name, value, SvgElement.StyleSpecificity_InlineStyle); } } diff --git a/tests/Svg.Skia.UnitTests/SvgDocumentCompatibilityLoaderTests.cs b/tests/Svg.Skia.UnitTests/SvgDocumentCompatibilityLoaderTests.cs index 9aa109d9da..a927826075 100644 --- a/tests/Svg.Skia.UnitTests/SvgDocumentCompatibilityLoaderTests.cs +++ b/tests/Svg.Skia.UnitTests/SvgDocumentCompatibilityLoaderTests.cs @@ -920,6 +920,114 @@ public void FromSvg_ParsesInlineStyleAttributesCaseInsensitively() Assert.Equal(Color.Orange.ToArgb(), fill.Colour.ToArgb()); } + [Fact] + public void FromSvg_IgnoresInlineStyleDeclarationsWithoutValues() + { + const string svg = """ + + + + + + """; + + var document = SvgDocumentCompatibilityLoader.FromSvg(svg); + var top = document.Descendants().OfType().Single(static element => element.ID == "top"); + var middle = document.Descendants().OfType().Single(static element => element.ID == "middle"); + var bottom = document.Descendants().OfType().Single(static element => element.ID == "bottom"); + var topFill = Assert.IsType(top.Fill); + var middleFill = Assert.IsType(middle.Fill); + var bottomFill = Assert.IsType(bottom.Fill); + var topStroke = Assert.IsType(top.Stroke); + var middleStroke = Assert.IsType(middle.Stroke); + var bottomStroke = Assert.IsType(bottom.Stroke); + + Assert.Equal(Color.Blue.ToArgb(), topFill.Colour.ToArgb()); + Assert.Equal(Color.FromArgb(244, 58, 32).ToArgb(), middleFill.Colour.ToArgb()); + Assert.Equal(Color.Blue.ToArgb(), bottomFill.Colour.ToArgb()); + Assert.Equal(Color.White.ToArgb(), topStroke.Colour.ToArgb()); + Assert.Equal(Color.White.ToArgb(), middleStroke.Colour.ToArgb()); + Assert.Equal(Color.White.ToArgb(), bottomStroke.Colour.ToArgb()); + } + + [Fact] + public void FromSvg_IgnoresFallbackInlineStyleDeclarationsWithoutValues() + { + const string svg = """ + + + + """; + + var document = SvgDocumentCompatibilityLoader.FromSvg(svg); + var rect = document.Descendants().OfType().Single(static element => element.ID == "target"); + var fill = Assert.IsType(rect.Fill); + var stroke = Assert.IsType(rect.Stroke); + + Assert.Equal(Color.Blue.ToArgb(), fill.Colour.ToArgb()); + Assert.Equal(Color.White.ToArgb(), stroke.Colour.ToArgb()); + } + + [Fact] + public void FromSvg_PreservesEmptyInlineCustomPropertyDeclarations() + { + const string svg = """ + + + + + + """; + + var document = SvgDocumentCompatibilityLoader.FromSvg(svg); + var rect = document.Descendants().OfType().Single(static element => element.ID == "target"); + var fill = Assert.IsType(rect.Fill); + + Assert.Equal(Color.Black.ToArgb(), fill.Colour.ToArgb()); + } + + [Fact] + public void FromSvg_PreservesFallbackEmptyInlineCustomPropertyDeclarations() + { + const string svg = """ + + + + + + """; + + var document = SvgDocumentCompatibilityLoader.FromSvg(svg); + var rect = document.Descendants().OfType().Single(static element => element.ID == "target"); + var fill = Assert.IsType(rect.Fill); + + Assert.Equal(Color.Black.ToArgb(), fill.Colour.ToArgb()); + } + + [Fact] + public void FromSvg_IgnoresStylesheetDeclarationsWithoutValues() + { + const string svg = """ + + + + + """; + + var document = SvgDocumentCompatibilityLoader.FromSvg(svg); + var rect = document.Descendants().OfType().Single(static element => element.ID == "target"); + var fill = Assert.IsType(rect.Fill); + var stroke = Assert.IsType(rect.Stroke); + + Assert.Equal(Color.Blue.ToArgb(), fill.Colour.ToArgb()); + Assert.Equal(Color.White.ToArgb(), stroke.Colour.ToArgb()); + } + [Fact] public void FromSvg_ParsesInlineStyleAttributesWithEmptyDeclarationsAndWhitespace() {