AngleSharp by AngleSharp

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

 SourceSet

public sealed class SourceSet
Represents a useful helper for dealing with source sets.
using AngleSharp.Css.Values; using AngleSharp.Dom; using AngleSharp.Extensions; using System.Collections.Generic; using System.Text.RegularExpressions; namespace AngleSharp.Html { public sealed class SourceSet { private sealed class MediaSize { public string Media { get; set; } public string Length { get; set; } } public sealed class ImageCandidate { public string Url { get; set; } public string Descriptor { get; set; } } private static readonly string FullWidth = "100vw"; private static readonly Regex SizeParser = CreateRegex(); private readonly IDocument _document; private static Regex CreateRegex() { string pattern = "(\\([^)]+\\))?\\s*(.+)"; try { return new Regex(pattern, RegexOptions.ECMAScript | RegexOptions.CultureInvariant); } catch { return new Regex(pattern, RegexOptions.ECMAScript); } } public SourceSet(IDocument document) { _document = document; } public static IEnumerable<ImageCandidate> Parse(string srcset) { string[] sources = srcset.Trim().SplitSpaces(); for (int i = 0; i < sources.Length; i++) { string text = sources[i]; string text2 = null; if (text.Length != 0) { if (text[text.Length - 1] == ',') { text = text.Remove(text.Length - 1); text2 = string.Empty; } else { int num = i + 1; i = num; if (num < sources.Length) { text2 = sources[i]; int num2 = text2.IndexOf(','); if (num2 != -1) { sources[i] = text2.Substring(num2 + 1); text2 = text2.Substring(0, num2); num = i - 1; i = num; } } } yield return new ImageCandidate { Url = text, Descriptor = text2 }; } } } private static MediaSize ParseSize(string sourceSizeStr) { Match match = SizeParser.Match(sourceSizeStr); return new MediaSize { Media = ((match.Success && match.Groups[1].Success) ? match.Groups[1].Value : string.Empty), Length = ((match.Success && match.Groups[2].Success) ? match.Groups[2].Value : string.Empty) }; } private double ParseDescriptor(string descriptor, string sizesattr = null) { string sourceSizes = sizesattr ?? FullWidth; string text = descriptor.Trim(); double widthFromSourceSize = GetWidthFromSourceSize(sourceSizes); double result = 1; string[] array = text.Split(new char[1] { ' ' }); for (int num = array.Length - 1; num >= 0; num--) { string text2 = array[num]; char c = (text2.Length > 0) ? text2[text2.Length - 1] : ''; if ((c == 'h' || c == 'w') && text2.Length > 2 && text2[text2.Length] == 'v') result = (double)text2.Substring(0, text2.Length - 2).ToInteger(0) / widthFromSourceSize; else if (c == 'x' && text2.Length > 0) { result = text2.Substring(0, text2.Length - 1).ToDouble(1); } } return result; } private double GetWidthFromLength(string length) { Length result = default(Length); Length.TryParse(length, out result); return 0; } private double GetWidthFromSourceSize(string sourceSizes) { string[] array = sourceSizes.Trim().Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { MediaSize mediaSize = ParseSize(array[i]); string length = mediaSize.Length; string media = mediaSize.Media; if (!string.IsNullOrEmpty(length) && (string.IsNullOrEmpty(media) || _document.DefaultView.MatchMedia(media).IsMatched)) return GetWidthFromLength(length); } return GetWidthFromLength(FullWidth); } public IEnumerable<string> GetCandidates(string srcset, string sizes) { if (!string.IsNullOrEmpty(srcset)) { foreach (ImageCandidate item in Parse(srcset)) { yield return item.Url; } } } } }