AngleSharp by Florian Rappl

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

 DocumentExtensions

static class DocumentExtensions
Useful methods for document objects.
using AngleSharp.Dom; using AngleSharp.Dom.Collections; using AngleSharp.Dom.Html; using AngleSharp.Network; using AngleSharp.Services; using AngleSharp.Services.Media; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AngleSharp.Extensions { [DebuggerStepThrough] internal static class DocumentExtensions { public static void ForEachRange(this Document document, Predicate<AngleSharp.Dom.Collections.Range> condition, Action<AngleSharp.Dom.Collections.Range> action) { if (document != null) { foreach (AngleSharp.Dom.Collections.Range range in document.Ranges) { if (condition(range)) action(range); } } } public static void AdoptNode(this IDocument document, INode node) { Node node2 = node as Node; if (node2 == null) throw new DomException(DomError.NotSupported); if (node2.Parent != null) node2.Parent.RemoveChild(node2, false); node2.Owner = (document as Document); } public static void QueueTask(this Document document, Action action) { IEventService service = document.Options.GetService<IEventService>(); if (service != null) service.Enqueue(new Task(action)); else action(); } public static void QueueTask(this Document document, Task task) { IEventService service = document.Options.GetService<IEventService>(); if (service != null) service.Enqueue(task); else if (task.Status == TaskStatus.Created) { task.Start(); } } public static async Task SpinLoop(this Document document, Func<bool> predicate) { IEventService eventLoop = document.Options.GetService<IEventService>(); if (eventLoop == null) { while (!predicate()) { } } else await eventLoop.Spin(predicate).ConfigureAwait(false); } public static void QueueMutation(this Document document, MutationRecord record) { if (document != null) { MutationObserver[] array = document.Mutations.Observers.ToArray(); if (array.Length != 0) { IEnumerable<INode> inclusiveAncestors = record.Target.GetInclusiveAncestors(); foreach (MutationObserver mutationObserver in array) { bool? nullable = null; foreach (INode item in inclusiveAncestors) { MutationObserverInit mutationObserverInit = mutationObserver.ResolveOptions(item); if (mutationObserverInit != null && (item == record.Target || mutationObserverInit.IsObservingSubtree) && (!record.IsAttribute || mutationObserverInit.IsObservingAttributes.Value) && (!record.IsAttribute || mutationObserverInit.AttributeFilters == null || (mutationObserverInit.AttributeFilters.Contains(record.AttributeName) && record.AttributeNamespace == null)) && (!record.IsCharacterData || mutationObserverInit.IsObservingCharacterData.Value) && (!record.IsChildList || mutationObserverInit.IsObservingChildNodes) && (!nullable.HasValue || nullable.Value)) nullable = ((record.IsAttribute && !mutationObserverInit.IsExaminingOldAttributeValue.Value) || (record.IsCharacterData && !mutationObserverInit.IsExaminingOldCharacterData.Value)); } if (nullable.HasValue) mutationObserver.Enqueue(record.Copy(nullable.Value)); } document.PerformMicrotaskCheckpoint(); } } } public static void AddTransientObserver(this Document document, INode node) { if (document != null) { IEnumerable<INode> ancestors = node.GetAncestors(); IEnumerable<MutationObserver> observers = document.Mutations.Observers; foreach (INode item in ancestors) { foreach (MutationObserver item2 in observers) { item2.AddTransient(item, node); } } } } public static void ApplyManifest(this Document document) { if (document.IsInBrowsingContext) { IHtmlHtmlElement htmlHtmlElement = document.DocumentElement as IHtmlHtmlElement; if (htmlHtmlElement != null) { string manifest = htmlHtmlElement.Manifest; Predicate<string> predicate = (string str) => false; if (!string.IsNullOrEmpty(manifest)) predicate(manifest); } } } public static void PerformMicrotaskCheckpoint(this Document document) { document.Mutations.ScheduleCallback(); } public static void ProvideStableState(this Document document) { } public static bool HasScriptBlockingStyleSheet(this Document document) { if (document.IsInBrowsingContext && document.Context.Parent != null) { Document document2 = document.Context.Parent.Active as Document; if (document2 != null) return document2.HasScriptBlockingStyleSheet(); } return false; } public static async Task WaitForReady(this Document document) { if (document.HasScriptBlockingStyleSheet() || document.IsWaitingForScript()) await SpinLoop(predicate: delegate { if (!document.HasScriptBlockingStyleSheet()) return !document.IsWaitingForScript(); return false; }, document: document).ConfigureAwait(false); } public static IBrowsingContext GetTarget(this Document document, string target) { if (string.IsNullOrEmpty(target) || target.Equals("_self", StringComparison.Ordinal)) return document.Context; if (target.Equals("_parent", StringComparison.Ordinal)) return document.Context.Parent ?? document.Context; if (target.Equals("_top", StringComparison.Ordinal)) return document.Context; return document.Options.FindContext(target); } public static IBrowsingContext CreateTarget(this Document document, string target) { Sandboxes security = Sandboxes.None; if (target.Equals("_blank", StringComparison.Ordinal)) return document.Options.NewContext(security); return document.NewContext(target, security); } public static IBrowsingContext NewContext(this Document document, string name, Sandboxes security) { IConfiguration options = document.Options; IContextService service = options.GetService<IContextService>(); if (service == null) return new BrowsingContext(document.Context, security); return service.Create(document.Context, name, security); } public static IBrowsingContext NewChildContext(this Document document, Sandboxes security) { return document.NewContext(string.Empty, security); } public static IWindow CreateWindow(this Document document) { IWindowService service = document.Options.GetService<IWindowService>(); if (service == null) return new Window(document); return service.Create(document); } public static void ReleaseStorageMutex(this Document document) { } public static IResourceLoader CreateLoader(this Document document) { return document.Options.GetService<ILoaderService>()?.CreateResourceLoader(document); } public static Task<TResource> LoadResource<TResource>(this Document document, ResourceRequest request) where TResource : IResourceInfo { IResourceLoader loader = document.Loader; TResource resource = (TResource)default(TResource); return document.Tasks.Add(async delegate(CancellationToken cancel) { IResponse response = await loader.FetchAsync(request, cancel).ConfigureAwait(false); if (response != null) { IConfiguration options = document.Options; IEnumerable<IResourceService<TResource>> resourceServices = ConfigurationExtensions.GetServices<IResourceService<TResource>>(options); foreach (IResourceService<TResource> item in resourceServices) { if (item.SupportsType(response.Headers[HeaderNames.ContentType])) { resource = (TResource)(await item.CreateAsync(response, cancel).ConfigureAwait(false)); break; } } response.Dispose(); } return (TResource)resource; }); } } }