CollectionExtensions
A bunch of methods for getting DOM elements.
using AngleSharp.Dom;
using AngleSharp.Html;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace AngleSharp.Extensions
{
[DebuggerStepThrough]
internal static class CollectionExtensions
{
public static IEnumerable<T> Concat<T>(this IEnumerable<T> items, T element)
{
foreach (T item in items) {
yield return item;
}
yield return element;
}
public static IEnumerable<T> GetElements<T>(this INode parent, bool deep = true, Predicate<T> predicate = null) where T : class, INode
{
predicate = (predicate ?? ((Predicate<T>)((T m) => true)));
if (!deep)
return parent.GetDescendendElements(predicate);
return parent.GetAllElements(predicate);
}
public static IElement GetElementById(this INodeList children, string id)
{
for (int i = 0; i < children.Length; i++) {
IElement element = children[i] as IElement;
if (element != null) {
if (element.Id == id)
return element;
element = element.ChildNodes.GetElementById(id);
if (element != null)
return element;
}
}
return null;
}
public static void GetElementsByName(this INodeList children, string name, List<IElement> result)
{
for (int i = 0; i < children.Length; i++) {
IElement element = children[i] as IElement;
if (element != null) {
if (element.GetAttribute(null, AttributeNames.Name) == name)
result.Add(element);
element.ChildNodes.GetElementsByName(name, result);
}
}
}
public static bool Accepts(this FilterSettings filter, INode node)
{
switch (node.NodeType) {
case NodeType.Attribute:
return filter.HasFlag(FilterSettings.Attribute);
case NodeType.CharacterData:
return filter.HasFlag(FilterSettings.CharacterData);
case NodeType.Comment:
return filter.HasFlag(FilterSettings.Comment);
case NodeType.Document:
return filter.HasFlag(FilterSettings.Document);
case NodeType.DocumentFragment:
return filter.HasFlag(FilterSettings.DocumentFragment);
case NodeType.DocumentType:
return filter.HasFlag(FilterSettings.DocumentType);
case NodeType.Element:
return filter.HasFlag(FilterSettings.Element);
case NodeType.Entity:
return filter.HasFlag(FilterSettings.Entity);
case NodeType.EntityReference:
return filter.HasFlag(FilterSettings.EntityReference);
case NodeType.ProcessingInstruction:
return filter.HasFlag(FilterSettings.ProcessingInstruction);
case NodeType.Notation:
return filter.HasFlag(FilterSettings.Notation);
case NodeType.Text:
return filter.HasFlag(FilterSettings.Text);
default:
return filter == FilterSettings.All;
}
}
public static IEnumerable<T> GetElements<T>(this INode parent, FilterSettings filter) where T : class, INode
{
return parent.GetElements(true, (T node) => filter.Accepts(node));
}
public static T GetElementById<T>(this IEnumerable<T> elements, string id) where T : class, IElement
{
foreach (T element in elements) {
T current = element;
if (current.Id == id)
return current;
}
foreach (T element2 in elements) {
T current2 = element2;
if (current2.GetAttribute(null, AttributeNames.Name) == id)
return current2;
}
return null;
}
private static IEnumerable<T> GetAllElements<T>(this INode parent, Predicate<T> predicate) where T : class, INode
{
for (int i = 0; i < parent.ChildNodes.Length; i++) {
T child = parent.ChildNodes[i] as T;
if (child != null && predicate(child))
yield return child;
foreach (T allElement in CollectionExtensions.GetAllElements<T>(parent.ChildNodes[i], predicate)) {
yield return allElement;
}
}
}
private static IEnumerable<T> GetDescendendElements<T>(this INode parent, Predicate<T> predicate) where T : class, INode
{
for (int i = 0; i < parent.ChildNodes.Length; i++) {
T child = parent.ChildNodes[i] as T;
if (child != null && predicate(child))
yield return child;
}
}
}
}