Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions src/Controls/src/Core/StyleSheets/Selector.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable disable
using System;
using System.Diagnostics;

namespace Microsoft.Maui.Controls.StyleSheets
{
Expand Down Expand Up @@ -313,5 +314,65 @@ public override bool Matches(IStyleSelectable styleable)
//return siblingIndex != -1;
}
}

[DebuggerDisplay("{id} - {class} = {type}")]
public struct SelectorSpecificity
{
int id;
int @class;
int type;

public int Id { get => id; }
public int Class { get => @class; }
public int Type { get => type; }

public static SelectorSpecificity FromSelector(Selector selector)
{
switch(selector)
{
case Selector.Class c:
return new SelectorSpecificity { @class = 1 };
case Selector.Id i:
return new SelectorSpecificity { id = 1 };
case Selector.Element e:
return new SelectorSpecificity { type = 1 };
case Selector.Base b:
return new SelectorSpecificity { type = 1 };
case Selector.And a:
return FromSelector(a.Left) + FromSelector(a.Right);
case Selector.Or o:
return FromSelector(o.Left) + FromSelector(o.Right);
case Selector.Child c:
return FromSelector(c.Left) + FromSelector(c.Right);
case Selector.Descendent d:
return FromSelector(d.Left) + FromSelector(d.Right);
case Selector.Adjacent a:
return FromSelector(a.Left) + FromSelector(a.Right);
case Selector.Sibling s:
return FromSelector(s.Left) + FromSelector(s.Right);
default:
return default;
}
}

public static SelectorSpecificity operator +(SelectorSpecificity left, SelectorSpecificity right)
{
return new SelectorSpecificity
{
id = left.id + right.id,
@class = left.@class + right.@class,
type = left.type + right.type
};
}
public SelectorSpecificity Add(SelectorSpecificity other)
{
return new SelectorSpecificity
{
id = id + other.id,
@class = @class + other.@class,
type = type + other.type
};
}
}
}
}
7 changes: 3 additions & 4 deletions src/Controls/src/Core/StyleSheets/Style.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static Style Parse(CssReader reader, char stopChar = '\0')
return style;
}

public void Apply(VisualElement styleable, bool inheriting = false)
public void Apply(VisualElement styleable, Selector.SelectorSpecificity selectorSpecificity = default, bool inheriting = false)
{
if (styleable == null)
throw new ArgumentNullException(nameof(styleable));
Expand All @@ -71,15 +71,14 @@ public void Apply(VisualElement styleable, bool inheriting = false)
if (property == null)
continue;
if (string.Equals(decl.Value, "initial", StringComparison.OrdinalIgnoreCase))
//FIXME
styleable.ClearValue(property, new SetterSpecificity(SetterSpecificity.StyleImplicit, 0, 0, 0));
styleable.SetValue(property, property.DefaultValue, new SetterSpecificity(SetterSpecificity.StyleImplicit, (byte)selectorSpecificity.Id, (byte)selectorSpecificity.Class, (byte)selectorSpecificity.Type));
else
{
object value;
if (!convertedValues.TryGetValue(decl, out value))
convertedValues[decl] = (value = Convert(styleable, decl.Value, property));
//FIXME: compute distance
styleable.SetValue(property, value, new SetterSpecificity(SetterSpecificity.StyleImplicit, 0, 0, 0));
styleable.SetValue(property, value, new SetterSpecificity(SetterSpecificity.StyleImplicit, (byte)selectorSpecificity.Id, (byte)selectorSpecificity.Class, (byte)selectorSpecificity.Type));
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/Controls/src/Core/StyleSheets/StyleSheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ void Apply(Element styleable)
var style = kvp.Value;
if (!selector.Matches(styleable))
continue;
style.Apply(visualStylable);

style.Apply(visualStylable, Selector.SelectorSpecificity.FromSelector(selector));
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/Issues/Maui18980.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Microsoft.Maui.Controls.Xaml.UnitTests"
x:Class="Microsoft.Maui.Controls.Xaml.UnitTests.Maui18980">
<ContentPage.Resources>
<ResourceDictionary>
<StyleSheet Source="Maui18980Style.css"/>
</ResourceDictionary>
</ContentPage.Resources>
<Button x:Name="button" Text="Hello, World!" StyleClass="buttonClass" />
</ContentPage>
54 changes: 54 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/Issues/Maui18980.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Microsoft.Maui.ApplicationModel;
using Microsoft.Maui.Controls.Core.UnitTests;
using Microsoft.Maui.Controls.Shapes;
using Microsoft.Maui.Devices;
using Microsoft.Maui.Dispatching;

using Microsoft.Maui.Graphics;
using Microsoft.Maui.UnitTests;
using NUnit.Framework;

namespace Microsoft.Maui.Controls.Xaml.UnitTests
{
public partial class Maui18980 : ContentPage
{
public Maui18980()
{
InitializeComponent();
}
public Maui18980(bool useCompiledXaml)
{
//this stub will be replaced at compile time
}

[TestFixture]
class Test
{
[SetUp]
public void Setup()
{
Application.SetCurrentApplication(new MockApplication());
DispatcherProvider.SetCurrent(new DispatcherProviderStub());
}


[TearDown] public void TearDown() => AppInfo.SetCurrent(null);

[Test]
public void CSSnotOverridenbyImplicitStyle([Values(false, true)] bool useCompiledXaml)
{
// var app = new MockApplication();
// app.Resources.Add(new Maui18980Style(useCompiledXaml));
// Application.SetCurrentApplication(app);

var page = new Maui18980(useCompiledXaml);
Assert.That(page.button.BackgroundColor, Is.EqualTo(Colors.Red));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.buttonClass{ background-color: red;}
10 changes: 10 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/Issues/Maui18980Style.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Microsoft.Maui.Controls.Xaml.UnitTests.Maui18980Style">

<Style TargetType="Button">
<Setter Property="BackgroundColor" Value="Blue" />
</Style>

</ResourceDictionary>
30 changes: 30 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/Issues/Maui18980Style.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Microsoft.Maui.ApplicationModel;
using Microsoft.Maui.Controls.Core.UnitTests;
using Microsoft.Maui.Controls.Shapes;
using Microsoft.Maui.Devices;
using Microsoft.Maui.Dispatching;

using Microsoft.Maui.Graphics;
using Microsoft.Maui.UnitTests;
using NUnit.Framework;

namespace Microsoft.Maui.Controls.Xaml.UnitTests
{
public partial class Maui18980Style : ResourceDictionary
{
public Maui18980Style()
{
InitializeComponent();
}

public Maui18980Style(bool useCompiledXaml)
{
//this stub will be replaced at compile time
}
}
}