ElementExtensions
Useful methods for element objects.
using AngleSharp.Dom;
using AngleSharp.Dom.Html;
using AngleSharp.Html;
using AngleSharp.Network;
using AngleSharp.Network.RequestProcessors;
using AngleSharp.Services.Media;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace AngleSharp.Extensions
{
[DebuggerStepThrough]
internal static class ElementExtensions
{
public static string LocatePrefix(this IElement element, string namespaceUri)
{
if (element == null)
return null;
if (element.NamespaceUri.Is(namespaceUri) && element.Prefix != null)
return element.Prefix;
foreach (IAttr attribute in element.Attributes) {
if (attribute.Prefix.Is(NamespaceNames.XmlNsPrefix) && attribute.Value.Is(namespaceUri))
return attribute.LocalName;
}
return element.ParentElement.LocatePrefix(namespaceUri);
}
public static string LocateNamespace(this IElement element, string prefix)
{
if (element == null)
return null;
string namespaceUri = element.NamespaceUri;
string prefix2 = element.Prefix;
if (!string.IsNullOrEmpty(namespaceUri) && prefix2.Is(prefix))
return namespaceUri;
Predicate<IAttr> predicate = (prefix == null) ? ((Predicate<IAttr>)delegate(IAttr attr) {
if (attr.NamespaceUri.Is(NamespaceNames.XmlNsUri) && attr.Prefix == null)
return attr.LocalName.Is(NamespaceNames.XmlNsPrefix);
return false;
}) : ((Predicate<IAttr>)delegate(IAttr attr) {
if (attr.NamespaceUri.Is(NamespaceNames.XmlNsUri) && attr.Prefix.Is(NamespaceNames.XmlNsPrefix))
return attr.LocalName.Is(prefix);
return false;
});
foreach (IAttr attribute in element.Attributes) {
if (predicate(attribute)) {
string text = attribute.Value;
if (string.IsNullOrEmpty(text))
text = null;
return text;
}
}
return element.ParentElement.LocateNamespace(prefix);
}
public static ResourceRequest CreateRequestFor(this IElement element, Url url)
{
return new ResourceRequest(element, url);
}
public static bool MatchesCssNamespace(this IElement el, string prefix)
{
if (prefix.Is(Keywords.Asterisk))
return true;
string current = el.GetAttribute(NamespaceNames.XmlNsPrefix) ?? el.NamespaceUri;
if (prefix.Is(string.Empty))
return current.Is(string.Empty);
return current.Is(el.GetCssNamespace(prefix));
}
public static string GetCssNamespace(this IElement el, string prefix)
{
return el.Owner.StyleSheets.LocateNamespace(prefix) ?? el.LocateNamespace(prefix);
}
public static bool IsHovered(this IElement element)
{
return false;
}
public static bool IsOnlyOfType(this IElement element)
{
IElement parentElement = element.ParentElement;
if (parentElement != null) {
for (int i = 0; i < parentElement.ChildNodes.Length; i++) {
if (parentElement.ChildNodes[i].NodeName.Is(element.NodeName) && parentElement.ChildNodes[i] != element)
return false;
}
return true;
}
return false;
}
public static bool IsFirstOfType(this IElement element)
{
IElement parentElement = element.ParentElement;
if (parentElement != null) {
for (int i = 0; i < parentElement.ChildNodes.Length; i++) {
if (parentElement.ChildNodes[i].NodeName.Is(element.NodeName))
return parentElement.ChildNodes[i] == element;
}
}
return false;
}
public static bool IsLastOfType(this IElement element)
{
IElement parentElement = element.ParentElement;
if (parentElement != null) {
for (int num = parentElement.ChildNodes.Length - 1; num >= 0; num--) {
if (parentElement.ChildNodes[num].NodeName.Is(element.NodeName))
return parentElement.ChildNodes[num] == element;
}
}
return false;
}
public static bool IsTarget(this IElement element)
{
IDocument owner = element.Owner;
string id = element.Id;
if (owner != null && id != null) {
string hash = owner.Location.Hash;
return string.Compare(id, 0, hash, (hash.Length > 0) ? 1 : 0, 2147483647) == 0;
}
return false;
}
public static bool IsEnabled(this IElement element)
{
if (element is HtmlAnchorElement || element is HtmlAreaElement || element is HtmlLinkElement) {
string attribute = element.GetAttribute(null, AttributeNames.Href);
return !string.IsNullOrEmpty(attribute);
}
if (element is HtmlButtonElement)
return !((HtmlButtonElement)element).IsDisabled;
if (element is HtmlInputElement)
return !((HtmlInputElement)element).IsDisabled;
if (element is HtmlSelectElement)
return !((HtmlSelectElement)element).IsDisabled;
if (element is HtmlTextAreaElement)
return !((HtmlTextAreaElement)element).IsDisabled;
if (element is HtmlOptionElement)
return !((HtmlOptionElement)element).IsDisabled;
if (element is HtmlOptionsGroupElement || element is HtmlMenuItemElement || element is HtmlFieldSetElement) {
string attribute2 = element.GetAttribute(null, AttributeNames.Disabled);
return string.IsNullOrEmpty(attribute2);
}
return false;
}
public static bool IsDisabled(this IElement element)
{
if (element is HtmlButtonElement)
return ((HtmlButtonElement)element).IsDisabled;
if (element is HtmlInputElement)
return ((HtmlInputElement)element).IsDisabled;
if (element is HtmlSelectElement)
return ((HtmlSelectElement)element).IsDisabled;
if (element is HtmlTextAreaElement)
return ((HtmlTextAreaElement)element).IsDisabled;
if (element is HtmlOptionElement)
return ((HtmlOptionElement)element).IsDisabled;
if (element is HtmlOptionsGroupElement || element is HtmlMenuItemElement || element is HtmlFieldSetElement) {
string attribute = element.GetAttribute(null, AttributeNames.Disabled);
return !string.IsNullOrEmpty(attribute);
}
return false;
}
public static bool IsDefault(this IElement element)
{
if (element is HtmlButtonElement) {
HtmlButtonElement htmlButtonElement = (HtmlButtonElement)element;
IHtmlFormElement form = htmlButtonElement.Form;
if (form != null)
return true;
} else if (element is HtmlInputElement) {
HtmlInputElement htmlInputElement = (HtmlInputElement)element;
string type = htmlInputElement.Type;
if (type == InputTypeNames.Submit || type == InputTypeNames.Image) {
IHtmlFormElement form2 = htmlInputElement.Form;
if (form2 != null)
return true;
}
} else if (element is HtmlOptionElement) {
string attribute = element.GetAttribute(null, AttributeNames.Selected);
return !string.IsNullOrEmpty(attribute);
}
return false;
}
public static bool IsPseudo(this IElement element, string name)
{
return (element as PseudoElement)?.PseudoName.Is(name) ?? false;
}
public static bool IsChecked(this IElement element)
{
if (element is HtmlInputElement) {
HtmlInputElement htmlInputElement = (HtmlInputElement)element;
string type = htmlInputElement.Type;
if (type.IsOneOf(InputTypeNames.Checkbox, InputTypeNames.Radio))
return htmlInputElement.IsChecked;
return false;
}
if (element is HtmlMenuItemElement) {
HtmlMenuItemElement htmlMenuItemElement = (HtmlMenuItemElement)element;
string type2 = htmlMenuItemElement.Type;
if (type2.IsOneOf(InputTypeNames.Checkbox, InputTypeNames.Radio))
return htmlMenuItemElement.IsChecked;
return false;
}
if (element is HtmlOptionElement) {
HtmlOptionElement htmlOptionElement = (HtmlOptionElement)element;
return htmlOptionElement.IsSelected;
}
return false;
}
public static bool IsIndeterminate(this IElement element)
{
if (element is HtmlInputElement) {
HtmlInputElement htmlInputElement = (HtmlInputElement)element;
if (htmlInputElement.Type.Is(InputTypeNames.Checkbox))
return htmlInputElement.IsIndeterminate;
return false;
}
if (element is HtmlProgressElement) {
string attribute = element.GetAttribute(null, AttributeNames.Value);
return string.IsNullOrEmpty(attribute);
}
return false;
}
public static bool IsPlaceholderShown(this IElement element)
{
HtmlInputElement htmlInputElement = element as HtmlInputElement;
if (htmlInputElement != null) {
bool flag = !string.IsNullOrEmpty(htmlInputElement.Placeholder);
bool result = string.IsNullOrEmpty(htmlInputElement.Value);
if (flag)
return result;
return false;
}
return false;
}
public static bool IsUnchecked(this IElement element)
{
if (element is HtmlInputElement) {
HtmlInputElement htmlInputElement = (HtmlInputElement)element;
string type = htmlInputElement.Type;
if (type.IsOneOf(InputTypeNames.Checkbox, InputTypeNames.Radio))
return !htmlInputElement.IsChecked;
return false;
}
if (element is HtmlMenuItemElement) {
HtmlMenuItemElement htmlMenuItemElement = (HtmlMenuItemElement)element;
string type2 = htmlMenuItemElement.Type;
if (type2.IsOneOf(InputTypeNames.Checkbox, InputTypeNames.Radio))
return !htmlMenuItemElement.IsChecked;
return false;
}
if (element is HtmlOptionElement) {
HtmlOptionElement htmlOptionElement = (HtmlOptionElement)element;
return !htmlOptionElement.IsSelected;
}
return false;
}
public static bool IsActive(this IElement element)
{
if (element is HtmlAnchorElement) {
HtmlAnchorElement htmlAnchorElement = (HtmlAnchorElement)element;
string attribute = element.GetAttribute(null, AttributeNames.Href);
if (!string.IsNullOrEmpty(attribute))
return htmlAnchorElement.IsActive;
return false;
}
if (element is HtmlAreaElement) {
HtmlAreaElement htmlAreaElement = (HtmlAreaElement)element;
string attribute2 = element.GetAttribute(null, AttributeNames.Href);
if (!string.IsNullOrEmpty(attribute2))
return htmlAreaElement.IsActive;
return false;
}
if (element is HtmlLinkElement) {
HtmlLinkElement htmlLinkElement = (HtmlLinkElement)element;
string attribute3 = element.GetAttribute(null, AttributeNames.Href);
if (!string.IsNullOrEmpty(attribute3))
return htmlLinkElement.IsActive;
return false;
}
if (element is HtmlButtonElement) {
HtmlButtonElement htmlButtonElement = (HtmlButtonElement)element;
if (!htmlButtonElement.IsDisabled)
return htmlButtonElement.IsActive;
return false;
}
if (element is HtmlInputElement) {
HtmlInputElement htmlInputElement = (HtmlInputElement)element;
string type = htmlInputElement.Type;
if (type.IsOneOf(InputTypeNames.Submit, InputTypeNames.Image, InputTypeNames.Reset, InputTypeNames.Button))
return htmlInputElement.IsActive;
return false;
}
if (element is HtmlMenuItemElement) {
HtmlMenuItemElement htmlMenuItemElement = (HtmlMenuItemElement)element;
if (!htmlMenuItemElement.IsDisabled)
return htmlMenuItemElement.IsActive;
return false;
}
return false;
}
public static bool IsVisited(this IElement element)
{
if (element is HtmlAnchorElement) {
string attribute = element.GetAttribute(null, AttributeNames.Href);
HtmlAnchorElement htmlAnchorElement = (HtmlAnchorElement)element;
if (!string.IsNullOrEmpty(attribute))
return htmlAnchorElement.IsVisited;
return false;
}
if (element is HtmlAreaElement) {
string attribute2 = element.GetAttribute(null, AttributeNames.Href);
HtmlAreaElement htmlAreaElement = (HtmlAreaElement)element;
if (!string.IsNullOrEmpty(attribute2))
return htmlAreaElement.IsVisited;
return false;
}
if (element is HtmlLinkElement) {
string attribute3 = element.GetAttribute(null, AttributeNames.Href);
HtmlLinkElement htmlLinkElement = (HtmlLinkElement)element;
if (!string.IsNullOrEmpty(attribute3))
return htmlLinkElement.IsVisited;
return false;
}
return false;
}
public static bool IsLink(this IElement element)
{
if (element is HtmlAnchorElement) {
string attribute = element.GetAttribute(null, AttributeNames.Href);
HtmlAnchorElement htmlAnchorElement = (HtmlAnchorElement)element;
if (!string.IsNullOrEmpty(attribute))
return !htmlAnchorElement.IsVisited;
return false;
}
if (element is HtmlAreaElement) {
string attribute2 = element.GetAttribute(null, AttributeNames.Href);
HtmlAreaElement htmlAreaElement = (HtmlAreaElement)element;
if (!string.IsNullOrEmpty(attribute2))
return !htmlAreaElement.IsVisited;
return false;
}
if (element is HtmlLinkElement) {
string attribute3 = element.GetAttribute(null, AttributeNames.Href);
HtmlLinkElement htmlLinkElement = (HtmlLinkElement)element;
if (!string.IsNullOrEmpty(attribute3))
return !htmlLinkElement.IsVisited;
return false;
}
return false;
}
public static bool IsShadow(this IElement element)
{
if (element != null)
return element.ShadowRoot != null;
return false;
}
public static bool IsOptional(this IElement element)
{
if (element is HtmlInputElement) {
HtmlInputElement htmlInputElement = (HtmlInputElement)element;
return !htmlInputElement.IsRequired;
}
if (element is HtmlSelectElement) {
HtmlSelectElement htmlSelectElement = (HtmlSelectElement)element;
return !htmlSelectElement.IsRequired;
}
if (element is HtmlTextAreaElement) {
HtmlTextAreaElement htmlTextAreaElement = (HtmlTextAreaElement)element;
return !htmlTextAreaElement.IsRequired;
}
return false;
}
public static bool IsRequired(this IElement element)
{
if (element is HtmlInputElement) {
HtmlInputElement htmlInputElement = (HtmlInputElement)element;
return htmlInputElement.IsRequired;
}
if (element is HtmlSelectElement) {
HtmlSelectElement htmlSelectElement = (HtmlSelectElement)element;
return htmlSelectElement.IsRequired;
}
if (element is HtmlTextAreaElement) {
HtmlTextAreaElement htmlTextAreaElement = (HtmlTextAreaElement)element;
return htmlTextAreaElement.IsRequired;
}
return false;
}
public static bool IsInvalid(this IElement element)
{
if (element is IValidation) {
IValidation validation = (IValidation)element;
return !validation.CheckValidity();
}
if (element is HtmlFormElement) {
HtmlFormElement htmlFormElement = (HtmlFormElement)element;
return !htmlFormElement.CheckValidity();
}
return false;
}
public static bool IsValid(this IElement element)
{
if (element is IValidation) {
IValidation validation = (IValidation)element;
return validation.CheckValidity();
}
if (element is HtmlFormElement) {
HtmlFormElement htmlFormElement = (HtmlFormElement)element;
return htmlFormElement.CheckValidity();
}
return false;
}
public static bool IsReadOnly(this IElement element)
{
if (element is HtmlInputElement) {
HtmlInputElement htmlInputElement = (HtmlInputElement)element;
return !htmlInputElement.IsMutable;
}
if (element is HtmlTextAreaElement) {
HtmlTextAreaElement htmlTextAreaElement = (HtmlTextAreaElement)element;
return !htmlTextAreaElement.IsMutable;
}
if (element is IHtmlElement) {
IHtmlElement htmlElement = (IHtmlElement)element;
return !htmlElement.IsContentEditable;
}
return true;
}
public static bool IsEditable(this IElement element)
{
if (element is HtmlInputElement) {
HtmlInputElement htmlInputElement = (HtmlInputElement)element;
return htmlInputElement.IsMutable;
}
if (element is HtmlTextAreaElement) {
HtmlTextAreaElement htmlTextAreaElement = (HtmlTextAreaElement)element;
return htmlTextAreaElement.IsMutable;
}
if (element is IHtmlElement) {
IHtmlElement htmlElement = (IHtmlElement)element;
return htmlElement.IsContentEditable;
}
return false;
}
public static bool IsOutOfRange(this IElement element)
{
IValidation validation = element as IValidation;
if (validation != null) {
IValidityState validity = validation.Validity;
if (!validity.IsRangeOverflow)
return validity.IsRangeUnderflow;
return true;
}
return false;
}
public static bool IsInRange(this IElement element)
{
IValidation validation = element as IValidation;
if (validation != null) {
IValidityState validity = validation.Validity;
if (!validity.IsRangeOverflow)
return !validity.IsRangeUnderflow;
return false;
}
return false;
}
public static bool IsOnlyChild(this IElement element)
{
IElement parentElement = element.ParentElement;
if (parentElement != null && parentElement.ChildElementCount == 1)
return parentElement.FirstElementChild == element;
return false;
}
public static bool IsFirstChild(this IElement element)
{
IElement parentElement = element.ParentElement;
if (parentElement != null)
return parentElement.FirstElementChild == element;
return false;
}
public static bool IsLastChild(this IElement element)
{
IElement parentElement = element.ParentElement;
if (parentElement != null)
return parentElement.LastElementChild == element;
return false;
}
public static void Process(this Element element, IRequestProcessor processor, Url url)
{
if (processor != null) {
ResourceRequest request = element.CreateRequestFor(url);
Document owner = element.Owner;
Task task = processor.ProcessAsync(request);
owner.DelayLoad(task);
}
}
public static Url GetImageCandidate(this HtmlImageElement img)
{
Document owner = img.Owner;
SourceSet sourceSet = new SourceSet(owner);
IConfiguration options = owner.Options;
Stack<IHtmlSourceElement> sources = img.GetSources();
while (sources.Count > 0) {
IHtmlSourceElement htmlSourceElement = sources.Pop();
string type = htmlSourceElement.Type;
if (string.IsNullOrEmpty(type) || options.GetResourceService<IImageInfo>(type) != null) {
using (IEnumerator<string> enumerator = sourceSet.GetCandidates(htmlSourceElement.SourceSet, htmlSourceElement.Sizes).GetEnumerator()) {
if (enumerator.MoveNext()) {
string current = enumerator.Current;
return new Url(img.BaseUrl, current);
}
}
}
}
using (IEnumerator<string> enumerator2 = sourceSet.GetCandidates(img.SourceSet, img.Sizes).GetEnumerator()) {
if (enumerator2.MoveNext()) {
string current2 = enumerator2.Current;
return new Url(img.BaseUrl, current2);
}
}
return Url.Create(img.Source);
}
public static async Task<IDocument> (this Element element, DocumentRequest request)
{
IDownload download = element.Owner.Context.Loader.DownloadAsync(request);
return await BrowsingContextExtensions.OpenAsync(response: await download.Task.ConfigureAwait(false), cancel: CancellationToken.None, context: element.Owner.Context).ConfigureAwait(false);
}
public static string GetOwnAttribute(this Element element, string name)
{
return element.Attributes.GetNamedItem(null, name)?.Value;
}
public static bool HasOwnAttribute(this Element element, string name)
{
IAttr namedItem = element.Attributes.GetNamedItem(null, name);
return namedItem != null;
}
public static string GetUrlAttribute(this Element element, string name)
{
string ownAttribute = element.GetOwnAttribute(name);
Url url = (ownAttribute != null) ? new Url(element.BaseUrl, ownAttribute) : null;
if (url == null || url.IsInvalid)
return string.Empty;
return url.Href;
}
public static void SetOwnAttribute(this Element element, string name, string value, bool suppressCallbacks = false)
{
element.Attributes.SetNamedItemWithNamespaceUri(new Attr(name, value), suppressCallbacks);
}
private static Stack<IHtmlSourceElement> GetSources(this IHtmlImageElement img)
{
IElement parentElement = img.ParentElement;
Stack<IHtmlSourceElement> stack = new Stack<IHtmlSourceElement>();
if (parentElement != null && parentElement.LocalName.Is(TagNames.Picture)) {
for (IHtmlSourceElement htmlSourceElement = img.PreviousElementSibling as IHtmlSourceElement; htmlSourceElement != null; htmlSourceElement = (htmlSourceElement.PreviousElementSibling as IHtmlSourceElement)) {
stack.Push(htmlSourceElement);
}
}
return stack;
}
}
}