CssCombinator
An enumeration with possible CSS combinator values.
using AngleSharp.Css;
using AngleSharp.Dom;
using AngleSharp.Dom.Css;
using AngleSharp.Extensions;
using System;
using System.Collections.Generic;
namespace AngleSharp.Parser.Css
{
internal abstract class CssCombinator
{
private sealed class ChildCombinator : CssCombinator
{
public ChildCombinator()
{
base.Delimiter = '>';
base.Transform = ((IElement el) => Single(el.ParentElement));
}
}
private sealed class DescendentCombinator : CssCombinator
{
public DescendentCombinator()
{
base.Delimiter = ' ';
base.Transform = delegate(IElement el) {
List<IElement> list = new List<IElement>();
for (IElement parentElement = el.ParentElement; parentElement != null; parentElement = parentElement.ParentElement) {
list.Add(parentElement);
}
return list;
};
}
}
private sealed class AdjacentSiblingCombinator : CssCombinator
{
public AdjacentSiblingCombinator()
{
base.Delimiter = '+';
base.Transform = ((IElement el) => Single(el.PreviousElementSibling));
}
}
private sealed class SiblingCombinator : CssCombinator
{
public SiblingCombinator()
{
base.Delimiter = '~';
base.Transform = delegate(IElement el) {
IElement parentElement = el.ParentElement;
if (parentElement == null)
return new IElement[0];
List<IElement> list = new List<IElement>();
foreach (INode childNode in parentElement.ChildNodes) {
IElement element = childNode as IElement;
if (element != null) {
if (object.ReferenceEquals(element, el))
return list;
list.Add(element);
}
}
return list;
};
}
}
private sealed class NamespaceCombinator : CssCombinator
{
public NamespaceCombinator()
{
base.Delimiter = '|';
base.Transform = ((IElement el) => Single(el));
}
public override ISelector Change(ISelector selector)
{
string prefix = selector.Text;
return new SimpleSelector((IElement el) => el.MatchesCssNamespace(prefix), Priority.Zero, prefix);
}
}
private sealed class ColumnCombinator : CssCombinator
{
}
public static readonly CssCombinator Child = new ChildCombinator();
public static readonly CssCombinator Descendent = new DescendentCombinator();
public static readonly CssCombinator AdjacentSibling = new AdjacentSiblingCombinator();
public static readonly CssCombinator Sibling = new SiblingCombinator();
public static readonly CssCombinator Namespace = new NamespaceCombinator();
public static readonly CssCombinator Column = new ColumnCombinator();
public Func<IElement, IEnumerable<IElement>> Transform { get; set; }
public char Delimiter { get; set; }
public virtual ISelector Change(ISelector selector)
{
return selector;
}
protected static IEnumerable<IElement> Single(IElement element)
{
if (element != null)
yield return element;
}
}
}