Browse Source

Added ":is(Type)" selector support.

Steven Kirk 10 years ago
parent
commit
2f61edcc5f

+ 19 - 0
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<IsSyntax> 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<ISyntax> SingleSelector =
             OfType
+            .Or<ISyntax>(Is)
             .Or<ISyntax>(Name)
             .Or<ISyntax>(Class)
             .Or<ISyntax>(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; }

+ 5 - 0
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);

+ 38 - 0
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()
         {