public void NamespacedOfType() { var result = SelectorGrammar.Parse("x|Button"); Assert.Equal( new[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button", Xmlns = "x" } }, result); }
public void Name() { var result = SelectorGrammar.Parse("#foo"); Assert.Equal( new[] { new SelectorGrammar.NameSyntax { Name = "foo" }, }, result); }
public void Pseudoclass() { var result = SelectorGrammar.Parse(":foo"); Assert.Equal( new[] { new SelectorGrammar.ClassSyntax { Class = ":foo" } }, result); }
public void Not_Nesting() { var result = SelectorGrammar.Parse(":not(^)"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.NotSyntax { Argument = new[] { new SelectorGrammar.NestingSyntax() }, } }, result); }
public void Nesting_Class() { var result = SelectorGrammar.Parse("^.foo"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.NestingSyntax(), new SelectorGrammar.ClassSyntax { Class = "foo" }, }, result); }
public void Nesting_Property() { var result = SelectorGrammar.Parse("^[Foo=bar]"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.NestingSyntax(), new SelectorGrammar.PropertySyntax { Property = "Foo", Value = "bar" }, }, result); }
public void NthLastChild_Variations(string input, int step, int offset) { var result = SelectorGrammar.Parse(input); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.NthLastChildSyntax() { Step = step, Offset = offset } }, result); }
public void OfType_Name() { var result = SelectorGrammar.Parse("Button#foo"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, new SelectorGrammar.NameSyntax { Name = "foo" }, }, result); }
public void NamespacedIs_Name() { var result = SelectorGrammar.Parse(":is(x|Button)#foo"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.IsSyntax { TypeName = "Button", Xmlns = "x" }, new SelectorGrammar.NameSyntax { Name = "foo" }, }, result); }
public void OfType_Property() { var result = SelectorGrammar.Parse("Button[Foo=bar]"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, new SelectorGrammar.PropertySyntax { Property = "Foo", Value = "bar" }, }, result); }
public void OfType_Class() { var result = SelectorGrammar.Parse("Button.foo"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, new SelectorGrammar.ClassSyntax { Class = "foo" }, }, result); }
public void Nesting_NthChild() { var result = SelectorGrammar.Parse("^:nth-child(2n+1)"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.NestingSyntax(), new SelectorGrammar.NthChildSyntax() { Step = 2, Offset = 1 } }, result); }
public void OfType_Template_Nesting() { var result = SelectorGrammar.Parse("Button /template/ ^"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, new SelectorGrammar.TemplateSyntax { }, new SelectorGrammar.NestingSyntax(), }, result); }
public void OfType_NthChild_Even() { var result = SelectorGrammar.Parse("Button:nth-child(even)"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, new SelectorGrammar.NthChildSyntax() { Step = 2, Offset = 0 } }, result); }
public void OfType_NthLastChild() { var result = SelectorGrammar.Parse("Button:nth-last-child(2n+1)"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, new SelectorGrammar.NthLastChildSyntax() { Step = 2, Offset = 1 } }, result); }
public void OfType_NthChild_Without_Offset() { var result = SelectorGrammar.Parse("Button:nth-child(2147483647n)"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, new SelectorGrammar.NthChildSyntax() { Step = int.MaxValue, Offset = 0 } }, result); }
public void Not_OfType() { var result = SelectorGrammar.Parse(":not(Button)"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.NotSyntax { Argument = new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, }, } }, result); }
public void OfType_AttachedProperty_WithNamespace() { var result = SelectorGrammar.Parse("Button[(x|Grid.Column)=1]"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, new SelectorGrammar.AttachedPropertySyntax { Xmlns = "x", TypeName = "Grid", Property = "Column", Value = "1" }, }, result); }
public void OfType_Comma_Is_Class() { var result = SelectorGrammar.Parse("TextBlock, :is(Button).foo"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "TextBlock" }, new SelectorGrammar.CommaSyntax(), new SelectorGrammar.IsSyntax { TypeName = "Button" }, new SelectorGrammar.ClassSyntax { Class = "foo" }, }, result); }
public void OfType_Not_Class() { var result = SelectorGrammar.Parse("Button:not(.foo)"); Assert.Equal( new SelectorGrammar.ISyntax[] { new SelectorGrammar.OfTypeSyntax { TypeName = "Button" }, new SelectorGrammar.NotSyntax { Argument = new SelectorGrammar.ISyntax[] { new SelectorGrammar.ClassSyntax { Class = "foo" }, }, } }, result); }
public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node) { if (!(node is XamlIlAstObjectNode on && on.Type.GetClrType().FullName == "Avalonia.Styling.Style")) { return(node); } var pn = on.Children.OfType <XamlIlAstXamlPropertyValueNode>() .FirstOrDefault(p => p.Property.GetClrProperty().Name == "Selector"); if (pn == null) { return(node); } if (pn.Values.Count != 1) { throw new XamlIlParseException("Selector property should should have exactly one value", node); } if (pn.Values[0] is XamlIlSelectorNode) { //Deja vu. I've just been in this place before return(node); } if (!(pn.Values[0] is XamlIlAstTextNode tn)) { throw new XamlIlParseException("Selector property should be a text node", node); } var selectorType = pn.Property.GetClrProperty().Getter.ReturnType; var initialNode = new XamlIlSelectorInitialNode(node, selectorType); XamlIlSelectorNode Create(IEnumerable <SelectorGrammar.ISyntax> syntax, Func <string, string, XamlIlAstClrTypeReference> typeResolver) { XamlIlSelectorNode result = initialNode; XamlIlOrSelectorNode results = null; foreach (var i in syntax) { switch (i) { case SelectorGrammar.OfTypeSyntax ofType: result = new XamlIlTypeSelector(result, typeResolver(ofType.Xmlns, ofType.TypeName).Type, true); break; case SelectorGrammar.IsSyntax @is: result = new XamlIlTypeSelector(result, typeResolver(@is.Xmlns, @is.TypeName).Type, false); break; case SelectorGrammar.ClassSyntax @class: result = new XamlIlStringSelector(result, XamlIlStringSelector.SelectorType.Class, @class.Class); break; case SelectorGrammar.NameSyntax name: result = new XamlIlStringSelector(result, XamlIlStringSelector.SelectorType.Name, name.Name); break; case SelectorGrammar.PropertySyntax property: { var type = result?.TargetType; if (type == null) { throw new XamlIlParseException("Property selectors must be applied to a type.", node); } var targetProperty = type.GetAllProperties().FirstOrDefault(p => p.Name == property.Property); if (targetProperty == null) { throw new XamlIlParseException($"Cannot find '{property.Property}' on '{type}", node); } if (!XamlIlTransformHelpers.TryGetCorrectlyTypedValue(context, new XamlIlAstTextNode(node, property.Value, context.Configuration.WellKnownTypes.String), targetProperty.PropertyType, out var typedValue)) { throw new XamlIlParseException( $"Cannot convert '{property.Value}' to '{targetProperty.PropertyType.GetFqn()}", node); } result = new XamlIlPropertyEqualsSelector(result, targetProperty, typedValue); break; } case SelectorGrammar.ChildSyntax child: result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.SelectorType.Child); break; case SelectorGrammar.DescendantSyntax descendant: result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.SelectorType.Descendant); break; case SelectorGrammar.TemplateSyntax template: result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.SelectorType.Template); break; case SelectorGrammar.NotSyntax not: result = new XamlIlNotSelector(result, Create(not.Argument, typeResolver)); break; case SelectorGrammar.CommaSyntax comma: if (results == null) { results = new XamlIlOrSelectorNode(node, selectorType); } results.Add(result); result = initialNode; break; default: throw new XamlIlParseException($"Unsupported selector grammar '{i.GetType()}'.", node); } } if (results != null && result != null) { results.Add(result); } return(results ?? result); } IEnumerable <SelectorGrammar.ISyntax> parsed; try { parsed = SelectorGrammar.Parse(tn.Text); } catch (Exception e) { throw new XamlIlParseException("Unable to parse selector: " + e.Message, node); } var selector = Create(parsed, (p, n) => XamlIlTypeReferenceResolver.ResolveType(context, $"{p}:{n}", true, node, true)); pn.Values[0] = selector; return(new AvaloniaXamlIlTargetTypeMetadataNode(on, new XamlIlAstClrTypeReference(selector, selector.TargetType, false), AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style)); }
public void Not_Without_Closing_Parenthesis_Fails() { Assert.Throws <ExpressionParseException>(() => SelectorGrammar.Parse(":not(Button")); }
public void Not_Without_Argument_Fails() { Assert.Throws <ExpressionParseException>(() => SelectorGrammar.Parse(":not()")); }
public void Invalid_Class_Fails() { Assert.Throws <ExpressionParseException>(() => SelectorGrammar.Parse(".%foo")); }
public void Invalid_Identifier_Fails() { Assert.Throws <ExpressionParseException>(() => SelectorGrammar.Parse("%foo")); }
public void Dot_Alone_Fails() { Assert.Throws <ExpressionParseException>(() => SelectorGrammar.Parse(". dot")); }
public void Namespace_Alone_Fails() { Assert.Throws <ExpressionParseException>(() => SelectorGrammar.Parse("ns|")); }
public void NthChild_Invalid_Inputs(string input) { Assert.Throws <ExpressionParseException>(() => SelectorGrammar.Parse(input)); }