AngleSharp by AngleSharp

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

 ApiExtensions

public static class ApiExtensions
A set of useful extension methods when dealing with the DOM.
using AngleSharp.Dom; using AngleSharp.Dom.Events; using AngleSharp.Dom.Html; using AngleSharp.Html; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; namespace AngleSharp.Extensions { public static class ApiExtensions { public static TElement CreateElement<TElement>(this IDocument document) where TElement : IElement { if (document == null) throw new ArgumentNullException("document"); Type type = (from m in PortableExtensions.GetTypes(typeof(ApiExtensions).GetAssembly()) where m.Implements<TElement>() select m).FirstOrDefault((Type m) => !m.IsAbstractClass()); if ((object)type == null) return default(TElement); ConstructorInfo[] constructors = PortableExtensions.GetConstructors(type); foreach (ConstructorInfo item in (IEnumerable<ConstructorInfo>)(from m in constructors orderby m.GetParameters().Length select m)) { ParameterInfo[] parameters = item.GetParameters(); object[] array = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { bool flag = (object)parameters[i].ParameterType == typeof(Document); array[i] = (flag ? document : parameters[i].DefaultValue); } object obj = item.Invoke(array); if (obj != null) { TElement val = (TElement)obj; document.Adopt((INode)(object)val); return val; } } throw new ArgumentException("No element could be created for the provided interface."); } private static IDocumentFragment CreateFromHtml(this IDocument document, string html) { if (document == null) throw new ArgumentNullException("document"); Element element = document.Body as Element; if (element == null) throw new ArgumentException("The provided document does not have a valid body element."); return new DocumentFragment(element, html ?? string.Empty); } public static async Task<Event> AwaitEvent<TEventTarget>(this TEventTarget node, string eventName) where TEventTarget : IEventTarget { if (node == null) throw new ArgumentNullException("node"); if (eventName != null) { TaskCompletionSource<Event> completion = new TaskCompletionSource<Event>(); DomEventHandler handler = delegate(object s, Event ev) { completion.TrySetResult(ev); }; node.AddEventListener(eventName, handler, false); try { return await completion.Task.ConfigureAwait(false); } finally { node.RemoveEventListener(eventName, handler, false); } } throw new ArgumentNullException("eventName"); } public static async Task WhenLoadFired<TElement>(this IDocument document) where TElement : IElement { IEnumerable<TElement> elements = ApiExtensions.QuerySelectorAll<TElement>((IParentNode)document, "*"); Task<Event>[] tasks = Enumerable.ToArray<Task<Event>>(Enumerable.Select<TElement, Task<Event>>(elements, (Func<TElement, Task<Event>>)((TElement m) => ApiExtensions.AwaitEvent<TElement>(m, EventNames.Load)))); for (int i = 0; i < tasks.Length; i++) { await tasks[i].ConfigureAwait(false); } } public static TElement AppendElement<TElement>(this INode parent, TElement element) where TElement : class, IElement { if (parent == null) throw new ArgumentNullException("parent"); return parent.AppendChild(element) as TElement; } public static TElement InsertElement<TElement>(this INode parent, TElement newElement, INode referenceElement) where TElement : class, IElement { if (parent == null) throw new ArgumentNullException("parent"); return parent.InsertBefore(newElement, referenceElement) as TElement; } public static TElement RemoveElement<TElement>(this INode parent, TElement element) where TElement : class, IElement { if (parent == null) throw new ArgumentNullException("parent"); return parent.RemoveChild(element) as TElement; } public static TElement QuerySelector<TElement>(this IParentNode parent, string selectors) where TElement : class, IElement { if (parent == null) throw new ArgumentNullException("parent"); if (selectors == null) throw new ArgumentNullException("selectors"); return parent.QuerySelector(selectors) as TElement; } public static IEnumerable<TElement> QuerySelectorAll<TElement>(this IParentNode parent, string selectors) where TElement : IElement { if (parent == null) throw new ArgumentNullException("parent"); if (selectors == null) throw new ArgumentNullException("selectors"); return parent.QuerySelectorAll(selectors).OfType<TElement>(); } public static IEnumerable<TNode> Descendents<TNode>(this INode parent) { return parent.Descendents().OfType<TNode>(); } public static IEnumerable<INode> Descendents(this INode parent) { if (parent == null) throw new ArgumentNullException("parent"); return parent.GetDescendants(); } public static IEnumerable<TNode> Ancestors<TNode>(this INode child) { return child.Ancestors().OfType<TNode>(); } public static IEnumerable<INode> Ancestors(this INode child) { if (child == null) throw new ArgumentNullException("child"); return child.GetAncestors(); } public static Task<IDocument> Navigate<TElement>(this TElement element) where TElement : IUrlUtilities, IElement { return element.Navigate(CancellationToken.None); } public static Task<IDocument> Navigate<TElement>(this TElement element, CancellationToken cancel) where TElement : IUrlUtilities, IElement { if (element == null) throw new ArgumentNullException("element"); string href = element.Href; Url url = Url.Create(href); return element.Owner.Context.OpenAsync(url, cancel); } public static Task<IDocument> Submit(this IHtmlFormElement form, object fields) { return form.Submit(fields.ToDictionary()); } public static Task<IDocument> Submit(this IHtmlFormElement form, IDictionary<string, string> fields) { if (form == null) throw new ArgumentNullException("form"); if (fields == null) throw new ArgumentNullException("fields"); IHtmlFormControlsCollection elements = form.Elements; foreach (IHtmlInputElement item in elements.OfType<IHtmlInputElement>()) { string value = null; if (fields.TryGetValue(item.Name ?? string.Empty, out value)) item.Value = value; } return form.Submit(); } public static T Attr<T>(this T elements, string attributeName, string attributeValue) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); if (attributeName == null) throw new ArgumentNullException("attributeName"); foreach (IElement item in (IEnumerable<IElement>)elements) { item.SetAttribute(attributeName, attributeValue); } return elements; } public static T Attr<T>(this T elements, IEnumerable<KeyValuePair<string, string>> attributes) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); if (attributes == null) throw new ArgumentNullException("attributes"); foreach (IElement item in (IEnumerable<IElement>)elements) { foreach (KeyValuePair<string, string> attribute in attributes) { item.SetAttribute(attribute.Key, attribute.Value); } } return elements; } public static T Attr<T>(this T elements, object attributes) where T : IEnumerable<IElement> { Dictionary<string, string> attributes2 = attributes.ToDictionary(); return elements.Attr(attributes2); } public static T Empty<T>(this T elements) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); foreach (IElement item in (IEnumerable<IElement>)elements) { item.InnerHtml = string.Empty; } return elements; } public static T Css<T>(this T elements, string propertyName, string propertyValue) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); if (propertyName == null) throw new ArgumentNullException("propertyName"); foreach (IHtmlElement item in ((IEnumerable)(object)elements).OfType<IHtmlElement>()) { item.Style.SetProperty(propertyName, propertyValue, null); } return elements; } public static T Css<T>(this T elements, IEnumerable<KeyValuePair<string, string>> properties) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); if (properties == null) throw new ArgumentNullException("properties"); foreach (IHtmlElement item in ((IEnumerable)(object)elements).OfType<IHtmlElement>()) { foreach (KeyValuePair<string, string> property in properties) { item.Style.SetProperty(property.Key, property.Value, null); } } return elements; } public static T Css<T>(this T elements, object properties) where T : IEnumerable<IElement> { Dictionary<string, string> properties2 = properties.ToDictionary(); return elements.Css(properties2); } public static string Html<T>(this T element) where T : IElement { if (element == null) throw new ArgumentNullException("element"); return element.InnerHtml; } public static T Html<T>(this T elements, string html) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); foreach (IElement item in (IEnumerable<IElement>)elements) { item.InnerHtml = html; } return elements; } public static T AddClass<T>(this T elements, string className) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); if (className == null) throw new ArgumentNullException("className"); string[] tokens = className.SplitSpaces(); foreach (IElement item in (IEnumerable<IElement>)elements) { item.ClassList.Add(tokens); } return elements; } public static T RemoveClass<T>(this T elements, string className) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); if (className == null) throw new ArgumentNullException("className"); string[] tokens = className.SplitSpaces(); foreach (IElement item in (IEnumerable<IElement>)elements) { item.ClassList.Remove(tokens); } return elements; } public static T ToggleClass<T>(this T elements, string className) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); if (className == null) throw new ArgumentNullException("className"); string[] array = className.SplitSpaces(); foreach (IElement item in (IEnumerable<IElement>)elements) { string[] array2 = array; foreach (string token in array2) { item.ClassList.Toggle(token, false); } } return elements; } public static bool HasClass<T>(this T elements, string className) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); if (className == null) throw new ArgumentNullException("className"); bool flag = false; string[] array = className.SplitSpaces(); foreach (IElement item in (IEnumerable<IElement>)elements) { flag = true; string[] array2 = array; foreach (string token in array2) { if (!item.ClassList.Contains(token)) { flag = false; break; } } if (flag) return flag; } return flag; } public static T Before<T>(this T elements, string html) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); foreach (IElement item in (IEnumerable<IElement>)elements) { IElement parentElement = item.ParentElement; if (parentElement != null) { IDocumentFragment newElement = parentElement.CreateFragment(html); parentElement.InsertBefore(newElement, item); } } return elements; } public static T After<T>(this T elements, string html) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); foreach (IElement item in (IEnumerable<IElement>)elements) { IElement parentElement = item.ParentElement; if (parentElement != null) { IDocumentFragment newElement = parentElement.CreateFragment(html); parentElement.InsertBefore(newElement, item.NextSibling); } } return elements; } public static T Append<T>(this T elements, string html) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); foreach (IElement item in (IEnumerable<IElement>)elements) { IDocumentFragment documentFragment = item.CreateFragment(html); item.Append(documentFragment); } return elements; } public static T Prepend<T>(this T elements, string html) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); foreach (IElement item in (IEnumerable<IElement>)elements) { IDocumentFragment newElement = item.CreateFragment(html); item.InsertBefore(newElement, item.FirstChild); } return elements; } public static T Wrap<T>(this T elements, string html) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); foreach (IElement item in (IEnumerable<IElement>)elements) { IDocumentFragment documentFragment = item.CreateFragment(html); IElement innerMostElement = documentFragment.GetInnerMostElement(); item.Parent?.InsertBefore(documentFragment, item); innerMostElement.AppendChild(item); } return elements; } public static T WrapInner<T>(this T elements, string html) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); foreach (IElement item in (IEnumerable<IElement>)elements) { IDocumentFragment documentFragment = item.CreateFragment(html); IElement innerMostElement = documentFragment.GetInnerMostElement(); while (item.ChildNodes.Length > 0) { innerMostElement.AppendChild(item.ChildNodes[0]); } item.AppendChild(documentFragment); } return elements; } public static T WrapAll<T>(this T elements, string html) where T : IEnumerable<IElement> { if (elements == null) throw new ArgumentNullException("elements"); IElement element = ((IEnumerable<IElement>)(object)elements).FirstOrDefault(); if (element != null) { IDocumentFragment documentFragment = element.CreateFragment(html); IElement innerMostElement = documentFragment.GetInnerMostElement(); element.Parent?.InsertBefore(documentFragment, element); { foreach (IElement item in (IEnumerable<IElement>)elements) { innerMostElement.AppendChild(item); } return elements; } } return elements; } public static string Text<T>(this T element) where T : INode { if (element == null) throw new ArgumentNullException("element"); return element.TextContent; } public static T Text<T>(this T elements, string text) where T : IEnumerable<INode> { if (elements == null) throw new ArgumentNullException("elements"); foreach (INode item in (IEnumerable<INode>)elements) { item.TextContent = text; } return elements; } public static int Index<T>(this IEnumerable<T> elements, T item) where T : INode { if (elements == null) throw new ArgumentNullException("elements"); if (item != null) { int num = 0; foreach (T element in elements) { if (object.ReferenceEquals(element, item)) return num; num++; } } return -1; } private static IDocumentFragment CreateFragment(this IElement context, string html) { return new DocumentFragment(context as Element, html ?? string.Empty); } private static IElement GetInnerMostElement(this IDocumentFragment fragment) { if (fragment.ChildElementCount != 1) throw new InvalidOperationException("The provided HTML code did not result in any element."); IElement element = null; IElement firstElementChild = fragment.FirstElementChild; do { element = firstElementChild; firstElementChild = element.FirstElementChild; } while (firstElementChild != null); return element; } } }