AngleSharp by AngleSharp

<PackageReference Include="AngleSharp" Version="0.9.8" />

.NET API 1,214,976 bytes

 ComplexSelector

Represents a complex selector, i.e. one or more compound selectors separated by combinators.
using AngleSharp.Css; using AngleSharp.Extensions; using AngleSharp.Parser.Css; using System; using System.Collections.Generic; using System.IO; namespace AngleSharp.Dom.Css { internal sealed class ComplexSelector : CssNode, ISelector, ICssNode, IStyleFormattable { private struct CombinatorSelector { public string Delimiter; public Func<IElement, IEnumerable<IElement>> Transform; public ISelector Selector; } private readonly List<CombinatorSelector> _selectors; public Priority Specifity { get { Priority priority = default(Priority); int count = _selectors.Count; for (int i = 0; i < count; i++) { priority += _selectors[i].Selector.Specifity; } return priority; } } public string Text => this.ToCss(); public int Length => _selectors.Count; public bool IsReady { get; set; } public ComplexSelector() { _selectors = new List<CombinatorSelector>(); } public override void ToCss(TextWriter writer, IStyleFormatter formatter) { if (_selectors.Count > 0) { int num = _selectors.Count - 1; for (int i = 0; i < num; i++) { writer.Write(_selectors[i].Selector.Text); writer.Write(_selectors[i].Delimiter); } writer.Write(_selectors[num].Selector.Text); } } public bool Match(IElement element) { int num = _selectors.Count - 1; if (_selectors[num].Selector.Match(element)) { if (num <= 0) return true; return MatchCascade(num - 1, element); } return false; } public void ConcludeSelector(ISelector selector) { if (!IsReady) { _selectors.Add(new CombinatorSelector { Selector = selector, Transform = null, Delimiter = null }); IsReady = true; } } public void AppendSelector(ISelector selector, CssCombinator combinator) { if (!IsReady) _selectors.Add(new CombinatorSelector { Selector = combinator.Change(selector), Transform = combinator.Transform, Delimiter = combinator.Delimiter }); } private bool MatchCascade(int pos, IElement element) { foreach (IElement item in _selectors[pos].Transform(element)) { if (_selectors[pos].Selector.Match(item) && (pos == 0 || MatchCascade(pos - 1, item))) return true; } return false; } } }