AngleSharp by AngleSharp

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

 ImportLinkRelation

using AngleSharp.Dom; using AngleSharp.Dom.Html; using AngleSharp.Extensions; using AngleSharp.Network; using AngleSharp.Network.RequestProcessors; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace AngleSharp.Html.LinkRels { internal class ImportLinkRelation : BaseLinkRelation { private sealed class ImportList { private readonly List<ImportEntry> _list; public ImportList() { _list = new List<ImportEntry>(); } public bool Contains(Url location) { for (int i = 0; i < _list.Count; i++) { if (_list[i].Relation.Url.Equals(location)) return true; } return false; } public void Add(ImportEntry item) { _list.Add(item); } public void Remove(ImportEntry item) { _list.Remove(item); } } private struct ImportEntry { public ImportLinkRelation Relation; public bool IsCycle; } private static readonly ConditionalWeakTable<IDocument, ImportList> ImportLists = new ConditionalWeakTable<IDocument, ImportList>(); private bool _isasync; public IDocument Import => (base.Processor as DocumentRequestProcessor)?.ChildDocument; public bool IsAsync => _isasync; public ImportLinkRelation(HtmlLinkElement link) : base(link, DocumentRequestProcessor.Create(link)) { } public override Task LoadAsync() { HtmlLinkElement link = base.Link; Document owner = link.Owner; ImportList orCreateValue = ImportLists.GetOrCreateValue(owner); Url url = base.Url; IRequestProcessor processor = base.Processor; ImportEntry importEntry = new ImportEntry { Relation = this, IsCycle = CheckCycle(owner, url) }; orCreateValue.Add(importEntry); if (!importEntry.IsCycle) { ResourceRequest request = link.CreateRequestFor(url); _isasync = link.HasAttribute(AttributeNames.Async); return processor?.ProcessAsync(request); } return null; } private static bool CheckCycle(IDocument document, Url location) { IDocument importAncestor = document.ImportAncestor; ImportList value = null; while (importAncestor != null && ImportLists.TryGetValue(importAncestor, out value)) { if (value.Contains(location)) return true; importAncestor = importAncestor.ImportAncestor; } return false; } } }