@ -47,7 +47,7 @@ namespace Avalonia.Styling
// right-to-left, so MatchUntilCombinator reverses this order because the type selector
// right-to-left, so MatchUntilCombinator reverses this order because the type selector
// will be on the left.
// will be on the left.
var match = MatchUntilCombinator ( control , this , parent , subscribe , out var combinator ) ;
var match = MatchUntilCombinator ( control , this , parent , subscribe , out var combinator ) ;
// If the pre-combinator selector matches, we can now match the combinator, if any.
// If the pre-combinator selector matches, we can now match the combinator, if any.
if ( match . IsMatch & & combinator is object )
if ( match . IsMatch & & combinator is object )
{
{
@ -76,6 +76,10 @@ namespace Avalonia.Styling
/// <param name="owner">The owner style.</param>
/// <param name="owner">The owner style.</param>
public abstract string ToString ( Style ? owner ) ;
public abstract string ToString ( Style ? owner ) ;
/// <inheritdoc cref="ToString(Style?)"/>
/// <param name="hasNext">Whether there is a selector that comes after this one.</param>
internal virtual string ToString ( Style ? owner , bool hasNext ) = > ToString ( owner ) ;
/// <summary>
/// <summary>
/// Evaluates the selector for a match.
/// Evaluates the selector for a match.
/// </summary>
/// </summary>
@ -100,30 +104,31 @@ namespace Avalonia.Styling
/// </summary>
/// </summary>
private protected abstract Selector ? MovePreviousOrParent ( ) ;
private protected abstract Selector ? MovePreviousOrParent ( ) ;
internal virtual void ValidateNestingSelector ( bool inControlTheme )
internal virtual void ValidateNestingSelector ( bool inControlTheme , int templateCount = 0 )
{
{
var s = this ;
var s = this ;
var templateCount = 0 ;
do
if ( inControlTheme )
{
{
if ( inControlTheme )
if ( ! s . InTemplate & & s . IsCombinator )
{
throw new InvalidOperationException (
if ( ! s . InTemplate & & s . IsCombinator )
"ControlTheme style may not directly contain a child or descendent selector." ) ;
throw new InvalidOperationException (
if ( s is TemplateSelector & & templateCount + + > 0 )
"ControlTheme style may not directly contain a child or descendent selector." ) ;
throw new InvalidOperationException (
if ( s is TemplateSelector & & templateCount + + > 0 )
"ControlTemplate styles cannot contain multiple template selectors." ) ;
throw new InvalidOperationException (
}
"ControlTemplate styles cannot contain multiple template selectors." ) ;
}
var previous = s . MovePreviousOrParent ( ) ;
var previous = s . MovePreviousOrParent ( ) ;
if ( previous is null & & s is not NestingSelector )
if ( previous is null )
{
if ( s is not NestingSelector )
throw new InvalidOperationException ( "Child styles must have a nesting selector." ) ;
throw new InvalidOperationException ( "Child styles must have a nesting selector." ) ;
}
s = previous ;
else
} while ( s is not null ) ;
{
previous . ValidateNestingSelector ( inControlTheme , templateCount ) ;
}
}
}
private static SelectorMatch MatchUntilCombinator (
private static SelectorMatch MatchUntilCombinator (