diff --git a/src/Markup/Perspex.Markup.Xaml/Parsers/SelectorGrammar.cs b/src/Markup/Perspex.Markup.Xaml/Parsers/SelectorGrammar.cs index ec06b6bbe7..ba3e2fa5ac 100644 --- a/src/Markup/Perspex.Markup.Xaml/Parsers/SelectorGrammar.cs +++ b/src/Markup/Perspex.Markup.Xaml/Parsers/SelectorGrammar.cs @@ -99,8 +99,15 @@ namespace Perspex.Markup.Xaml.Parsers from template in Parse.String("/template/").Token() select new TemplateSyntax(); + public static readonly Parser Is = + from function in Parse.String(":is(") + from type in OfType + from close in Parse.Char(')') + select new IsSyntax { TypeName = type.TypeName, Xmlns = type.Xmlns }; + public static readonly Parser SingleSelector = OfType + .Or(Is) .Or(Name) .Or(Class) .Or(Property) @@ -126,6 +133,18 @@ namespace Perspex.Markup.Xaml.Parsers } } + public class IsSyntax : ISyntax + { + public string TypeName { get; set; } + + public string Xmlns { get; set; } + + public override bool Equals(object obj) + { + return obj is IsSyntax && ((IsSyntax)obj).TypeName == TypeName; + } + } + public class ClassSyntax : ISyntax { public string Class { get; set; } diff --git a/src/Markup/Perspex.Markup.Xaml/Parsers/SelectorParser.cs b/src/Markup/Perspex.Markup.Xaml/Parsers/SelectorParser.cs index 7938336e9e..8e727c3ff7 100644 --- a/src/Markup/Perspex.Markup.Xaml/Parsers/SelectorParser.cs +++ b/src/Markup/Perspex.Markup.Xaml/Parsers/SelectorParser.cs @@ -42,6 +42,7 @@ namespace Perspex.Markup.Xaml.Parsers foreach (var i in syntax) { var ofType = i as SelectorGrammar.OfTypeSyntax; + var @is = i as SelectorGrammar.IsSyntax; var @class = i as SelectorGrammar.ClassSyntax; var name = i as SelectorGrammar.NameSyntax; var property = i as SelectorGrammar.PropertySyntax; @@ -53,6 +54,10 @@ namespace Perspex.Markup.Xaml.Parsers { result = result.OfType(_typeResolver(ofType.TypeName, ofType.Xmlns)); } + if (@is != null) + { + result = result.Is(_typeResolver(@is.TypeName, @is.Xmlns)); + } else if (@class != null) { result = result.Class(@class.Class); diff --git a/tests/Perspex.Markup.Xaml.UnitTests/Parsers/SelectorGrammarTests.cs b/tests/Perspex.Markup.Xaml.UnitTests/Parsers/SelectorGrammarTests.cs index f4325ad46b..4537e8408a 100644 --- a/tests/Perspex.Markup.Xaml.UnitTests/Parsers/SelectorGrammarTests.cs +++ b/tests/Perspex.Markup.Xaml.UnitTests/Parsers/SelectorGrammarTests.cs @@ -54,6 +54,44 @@ namespace Perspex.Xaml.Base.UnitTest.Parsers result); } + [Fact] + public void Is() + { + var result = SelectorGrammar.Selector.Parse(":is(Button)").ToList(); + + Assert.Equal( + new[] { new SelectorGrammar.IsSyntax { TypeName = "Button", Xmlns = null } }, + result); + } + + [Fact] + public void Is_Name() + { + var result = SelectorGrammar.Selector.Parse(":is(Button)#foo").ToList(); + + Assert.Equal( + new SelectorGrammar.ISyntax[] + { + new SelectorGrammar.IsSyntax { TypeName = "Button" }, + new SelectorGrammar.NameSyntax { Name = "foo" }, + }, + result); + } + + [Fact] + public void NamespacedIs_Name() + { + var result = SelectorGrammar.Selector.Parse(":is(x|Button)#foo").ToList(); + + Assert.Equal( + new SelectorGrammar.ISyntax[] + { + new SelectorGrammar.IsSyntax { TypeName = "Button", Xmlns = "x" }, + new SelectorGrammar.NameSyntax { Name = "foo" }, + }, + result); + } + [Fact] public void Class() {