@@ -3,19 +3,22 @@ namespace AngleSharp.Css.Dom
33 using AngleSharp . Css ;
44 using AngleSharp . Dom ;
55 using System ;
6+ using System . Collections . Generic ;
67 using System . Diagnostics ;
78 using System . IO ;
9+ using System . Linq ;
810
911 /// <summary>
1012 /// Represents a CSS style rule.
1113 /// </summary>
1214 [ DebuggerDisplay ( null , Name = "CssStyleRule ({SelectorText})" ) ]
13- sealed class CssStyleRule : CssRule , ICssStyleRule
15+ sealed class CssStyleRule : CssRule , ICssStyleRule , ISelectorVisitor
1416 {
1517 #region Fields
1618
1719 private readonly CssStyleDeclaration _style ;
1820 private ISelector _selector ;
21+ private IEnumerable < ISelector > _selectorList ;
1922
2023 #endregion
2124
@@ -25,18 +28,23 @@ internal CssStyleRule(ICssStyleSheet owner)
2528 : base ( owner , CssRuleType . Style )
2629 {
2730 _style = new CssStyleDeclaration ( this ) ;
31+ _selectorList = null ;
2832 }
2933
3034 #endregion
3135
3236 #region Properties
3337
34- public ISelector Selector => _selector ;
38+ public ISelector Selector
39+ {
40+ get => _selector ;
41+ private set => ChangeSelector ( value ) ;
42+ }
3543
3644 public String SelectorText
3745 {
3846 get => _selector ? . Text ;
39- set => _selector = ParseSelector ( value ) ;
47+ set => ChangeSelector ( ParseSelector ( value ) ) ;
4048 }
4149
4250 ICssStyleDeclaration ICssStyleRule . Style => _style ;
@@ -55,10 +63,34 @@ internal void SetInvalidSelector(String selectorText)
5563 protected override void ReplaceWith ( ICssRule rule )
5664 {
5765 var newRule = ( ICssStyleRule ) rule ;
58- _selector = newRule . Selector ;
66+ ChangeSelector ( newRule . Selector ) ;
5967 _style . SetDeclarations ( newRule . Style ) ;
6068 }
6169
70+ public Boolean TryMatch ( IElement element , IElement ? scope , out Priority specificity )
71+ {
72+ if ( _selectorList is not null )
73+ {
74+ foreach ( var selector in _selectorList . OrderByDescending ( m => m . Specificity ) )
75+ {
76+ if ( selector . Match ( element , scope ) )
77+ {
78+ specificity = selector . Specificity ;
79+ return true ;
80+ }
81+ }
82+ }
83+
84+ if ( _selector is not null && _selector . Match ( element , scope ) )
85+ {
86+ specificity = _selector . Specificity ;
87+ return true ;
88+ }
89+
90+ specificity = default ;
91+ return false ;
92+ }
93+
6294 public override void ToCss ( TextWriter writer , IStyleFormatter formatter )
6395 {
6496 var block = _style . ToCssBlock ( formatter ) ;
@@ -69,7 +101,55 @@ public override void ToCss(TextWriter writer, IStyleFormatter formatter)
69101
70102 #region Selector
71103
72- class InvalidSelector : ISelector
104+ private void ChangeSelector ( ISelector value )
105+ {
106+ _selectorList = null ;
107+ _selector = value ;
108+ value ? . Accept ( this ) ;
109+ }
110+
111+ void ISelectorVisitor . Attribute ( string name , string op , string value )
112+ {
113+ }
114+
115+ void ISelectorVisitor . Type ( string name )
116+ {
117+ }
118+
119+ void ISelectorVisitor . Id ( string value )
120+ {
121+ }
122+
123+ void ISelectorVisitor . Child ( string name , int step , int offset , ISelector selector )
124+ {
125+ }
126+
127+ void ISelectorVisitor . Class ( string name )
128+ {
129+ }
130+
131+ void ISelectorVisitor . PseudoClass ( string name )
132+ {
133+ }
134+
135+ void ISelectorVisitor . PseudoElement ( string name )
136+ {
137+ }
138+
139+ void ISelectorVisitor . List ( IEnumerable < ISelector > selectors )
140+ {
141+ _selectorList = selectors ;
142+ }
143+
144+ void ISelectorVisitor . Combinator ( IEnumerable < ISelector > selectors , IEnumerable < string > symbols )
145+ {
146+ }
147+
148+ void ISelectorVisitor . Many ( IEnumerable < ISelector > selectors )
149+ {
150+ }
151+
152+ sealed class InvalidSelector : ISelector
73153 {
74154 private readonly String _text ;
75155
0 commit comments