using System; using System.Buffers; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using AngleSharp.Attributes; using AngleSharp.Browser; using AngleSharp.Browser.Dom; using AngleSharp.Browser.Dom.Events; using AngleSharp.Common; using AngleSharp.Css; using AngleSharp.Css.Dom; using AngleSharp.Css.Parser; using AngleSharp.Dom; using AngleSharp.Dom.Events; using AngleSharp.Html; using AngleSharp.Html.Construction; using AngleSharp.Html.Dom; using AngleSharp.Html.Dom.Events; using AngleSharp.Html.Forms; using AngleSharp.Html.Forms.Submitters; using AngleSharp.Html.Forms.Submitters.Json; using AngleSharp.Html.InputTypes; using AngleSharp.Html.LinkRels; using AngleSharp.Html.Parser; using AngleSharp.Html.Parser.Tokens; using AngleSharp.Html.Parser.Tokens.Struct; using AngleSharp.Io; using AngleSharp.Io.Dom; using AngleSharp.Io.Processors; using AngleSharp.Mathml; using AngleSharp.Mathml.Dom; using AngleSharp.Media; using AngleSharp.Media.Dom; using AngleSharp.Scripting; using AngleSharp.Svg; using AngleSharp.Svg.Dom; using AngleSharp.Text; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCopyright("Copyright © AngleSharp, 2013-2024")] [assembly: ComVisible(false)] [assembly: InternalsVisibleTo("AngleSharp.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010001adf274fa2b375134e8e4558d606f1a0f96f5cd0c6b99970f7cce9887477209d7c29f814e2508d8bd2526e99e8cd273bd1158a3984f1ea74830ec5329a77c6ff201a15edeb8b36ab046abd1bce211fe8dbb076d7d806f46b15bfda44def04ead0669971e96c5f666c9eda677f28824fff7aa90d32929ed91d529a7a41699893")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("AngleSharp")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("AngleSharp is the ultimate angle brackets parser library. It parses HTML5, CSS3, and XML to construct a DOM based on the official W3C specification.")] [assembly: AssemblyFileVersion("1.1.2.0")] [assembly: AssemblyInformationalVersion("1.1.2+6aa79f6f5ea9201af122ec112faa244081cdd493")] [assembly: AssemblyProduct("AngleSharp")] [assembly: AssemblyTitle("AngleSharp")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/AngleSharp/AngleSharp")] [assembly: AssemblyVersion("1.1.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AngleSharp { public sealed class BrowsingContext : EventTarget, IBrowsingContext, IEventTarget, IDisposable { private readonly IEnumerable _originalServices; private readonly List _services; private readonly Sandboxes _security; private readonly IBrowsingContext? _parent; private readonly IDocument? _creator; private readonly IHistory? _history; private readonly Dictionary> _children; public IDocument? Active { get; set; } public IDocument? Creator => _creator; public IEnumerable OriginalServices => _originalServices; public IWindow? Current => Active?.DefaultView; public IBrowsingContext? Parent => _parent; public IHistory? SessionHistory => _history; public Sandboxes Security => _security; public BrowsingContext(IConfiguration? configuration = null) : this((configuration ?? Configuration.Default).Services, Sandboxes.None) { } private BrowsingContext(Sandboxes security) { _services = new List(); _originalServices = _services; _security = security; _children = new Dictionary>(); } internal BrowsingContext(IEnumerable services, Sandboxes security) : this(security) { _services.AddRange(services); _originalServices = services; _history = GetService(); } internal BrowsingContext(IBrowsingContext parent, Sandboxes security) : this(parent.OriginalServices, security) { _parent = parent; _creator = _parent.Active; } public T? GetService() where T : class { int count = _services.Count; int num = 0; while (num < count) { object obj = _services[num]; T val = obj as T; if (val == null) { if (!(obj is Func func)) { num++; continue; } val = func(this); _services[num] = val; } return val; } return null; } public IEnumerable GetServices() where T : class { int count = _services.Count; for (int i = 0; i < count; i++) { object obj = _services[i]; T val = obj as T; if (val == null) { if (!(obj is Func func)) { continue; } val = func(this); _services[i] = val; } yield return val; } } public IBrowsingContext CreateChild(string? name, Sandboxes security) { BrowsingContext browsingContext = new BrowsingContext(this, security); if (name != null && name.Length > 0) { _children[name] = new WeakReference(browsingContext); } return browsingContext; } public IBrowsingContext? FindChild(string name) { IBrowsingContext target = null; if (!string.IsNullOrEmpty(name) && _children.TryGetValue(name, out WeakReference value)) { value.TryGetTarget(out target); } return target; } public static IBrowsingContext New(IConfiguration? configuration = null) { if (configuration == null) { configuration = Configuration.Default; } return new BrowsingContext(configuration.Services, Sandboxes.None); } public static IBrowsingContext NewFrom(TService instance) { return new BrowsingContext(Configuration.Default.WithOnly(instance).Services, Sandboxes.None); } void IDisposable.Dispose() { Active?.Dispose(); Active = null; } } public static class BrowsingContextExtensions { public static Task OpenNewAsync(this IBrowsingContext context, string? url = null, CancellationToken cancellation = default(CancellationToken)) { return context.OpenAsync(delegate(VirtualResponse m) { m.Address(url ?? "http://localhost/"); }, cancellation); } public static Task OpenAsync(this IBrowsingContext context, IResponse response, CancellationToken cancel = default(CancellationToken)) { response = response ?? throw new ArgumentNullException("response"); if (context == null) { context = BrowsingContext.New(); } Encoding defaultEncoding = context.GetDefaultEncoding(); IDocumentFactory factory = context.GetFactory(); CreateDocumentOptions options = new CreateDocumentOptions(response, defaultEncoding); return factory.CreateAsync(context, options, cancel); } public static Task OpenAsync(this IBrowsingContext context, DocumentRequest request, CancellationToken cancel = default(CancellationToken)) { request = request ?? throw new ArgumentNullException("request"); if (context == null) { context = BrowsingContext.New(); } return context.NavigateToAsync(request, cancel); } public static Task OpenAsync(this IBrowsingContext context, Url url, CancellationToken cancel = default(CancellationToken)) { url = url ?? throw new ArgumentNullException("url"); return context.OpenAsync(DocumentRequest.Get(url, null, context?.Active?.DocumentUri), cancel); } public static async Task OpenAsync(this IBrowsingContext context, Action request, CancellationToken cancel = default(CancellationToken)) { request = request ?? throw new ArgumentNullException("request"); using IResponse response = VirtualResponse.Create(request); return await context.OpenAsync(response, cancel).ConfigureAwait(continueOnCapturedContext: false); } public static Task OpenAsync(this IBrowsingContext context, string address, CancellationToken cancellation = default(CancellationToken)) { address = address ?? throw new ArgumentNullException("address"); return context.OpenAsync(Url.Create(address), cancellation); } internal static Task NavigateToAsync(this IBrowsingContext context, DocumentRequest request, CancellationToken cancel = default(CancellationToken)) { return context.GetNavigationHandler(request.Target)?.NavigateAsync(request, cancel) ?? Task.FromResult(null); } public static void NavigateTo(this IBrowsingContext context, IDocument document) { context.SessionHistory?.PushState(document, document.Title, document.Url); context.Active = document; } public static INavigationHandler? GetNavigationHandler(this IBrowsingContext context, Url url) { return context.GetServices().FirstOrDefault((INavigationHandler m) => m.SupportsProtocol(url.Scheme)); } public static Encoding GetDefaultEncoding(this IBrowsingContext context) { IEncodingProvider? provider = context.GetProvider(); string language = context.GetLanguage(); return provider?.Suggest(language) ?? Encoding.UTF8; } public static CultureInfo GetCulture(this IBrowsingContext context) { return context.GetService() ?? CultureInfo.CurrentUICulture; } public static CultureInfo GetCultureFrom(this IBrowsingContext context, string language) { try { return new CultureInfo(language); } catch (CultureNotFoundException ex) { context.TrackError(ex); return context.GetCulture(); } } public static string GetLanguage(this IBrowsingContext context) { return context.GetCulture().Name; } public static TFactory GetFactory(this IBrowsingContext context) where TFactory : class { return context.GetServices().Single(); } public static TProvider? GetProvider(this IBrowsingContext context) where TProvider : class { return context.GetServices().SingleOrDefault(); } public static IResourceService? GetResourceService(this IBrowsingContext context, string type) where TResource : IResourceInfo { foreach (IResourceService service in context.GetServices>()) { if (service.SupportsType(type)) { return service; } } return null; } public static string GetCookie(this IBrowsingContext context, Url url) { return context.GetProvider()?.GetCookie(url) ?? string.Empty; } public static void SetCookie(this IBrowsingContext context, Url url, string value) { context.GetProvider()?.SetCookie(url, value); } public static ISpellCheckService? GetSpellCheck(this IBrowsingContext context, string language) { ISpellCheckService spellCheckService = null; IEnumerable services = context.GetServices(); CultureInfo cultureFrom = context.GetCultureFrom(language); string twoLetterISOLanguageName = cultureFrom.TwoLetterISOLanguageName; foreach (ISpellCheckService item in services) { CultureInfo culture = item.Culture; if (culture != null) { string twoLetterISOLanguageName2 = culture.TwoLetterISOLanguageName; if (culture.Equals(cultureFrom)) { return item; } if (spellCheckService == null && twoLetterISOLanguageName2.Is(twoLetterISOLanguageName)) { spellCheckService = item; } } } return spellCheckService; } public static IStylingService? GetCssStyling(this IBrowsingContext context) { return context.GetStyling(MimeTypeNames.Css); } public static IStylingService? GetStyling(this IBrowsingContext context, string type) { foreach (IStylingService service in context.GetServices()) { if (service.SupportsType(type)) { return service; } } return null; } public static bool IsScripting(this IBrowsingContext context) { return context.GetServices().Any(); } public static IScriptingService? GetJsScripting(this IBrowsingContext context) { return context.GetScripting(MimeTypeNames.DefaultJavaScript); } public static IScriptingService? GetScripting(this IBrowsingContext context, string type) { foreach (IScriptingService service in context.GetServices()) { if (service.SupportsType(type)) { return service; } } return null; } public static ICommand? GetCommand(this IBrowsingContext context, string commandId) { return context.GetProvider()?.GetCommand(commandId); } public static void TrackError(this IBrowsingContext context, Exception ex) { AngleSharp.Browser.Dom.Events.TrackEvent eventData = new AngleSharp.Browser.Dom.Events.TrackEvent("error", ex); context.Fire(eventData); } public static Task InteractAsync(this IBrowsingContext context, string eventName, T data) { InteractivityEvent interactivityEvent = new InteractivityEvent(eventName, data); context.Fire(interactivityEvent); return interactivityEvent.Result ?? Task.FromResult(result: false); } public static IBrowsingContext ResolveTargetContext(this IBrowsingContext context, string? target) { bool flag = false; IBrowsingContext browsingContext = context; if (target != null && target.Length > 0) { browsingContext = context.FindChildFor(target); flag = browsingContext == null; } if (flag) { browsingContext = context.CreateChildFor(target); } return browsingContext; } public static IBrowsingContext CreateChildFor(this IBrowsingContext context, string? target) { Sandboxes security = Sandboxes.None; if (target == "_blank") { target = null; } return context.CreateChild(target, security); } public static IBrowsingContext? FindChildFor(this IBrowsingContext context, string target) { if (!string.IsNullOrEmpty(target)) { switch (target) { case "_self": break; case "_parent": return context.Parent ?? context; case "_top": return context; default: return context.FindChild(target); } } return context; } public static IEnumerable GetDownloads(this IBrowsingContext context) where T : INode { IResourceLoader service = context.GetService(); if (service == null) { return Array.Empty(); } return from m in service.GetDownloads() where m.Source is T select m.Task; } } public class Configuration : IConfiguration { private readonly IEnumerable _services; public static IConfiguration Default => new Configuration(); public IEnumerable Services => _services; private static T Instance(T instance) { return instance; } private static Func Creator(Func creator) { return creator; } public Configuration(IEnumerable? services = null) { _services = services ?? new object[17] { Instance((IElementFactory)new HtmlElementFactory()), Instance((IElementFactory)new MathElementFactory()), Instance((IElementFactory)new SvgElementFactory()), Instance((IEventFactory)new DefaultEventFactory()), Instance((IInputTypeFactory)new DefaultInputTypeFactory()), Instance((IAttributeSelectorFactory)new DefaultAttributeSelectorFactory()), Instance((IPseudoElementSelectorFactory)new DefaultPseudoElementSelectorFactory()), Instance((IPseudoClassSelectorFactory)new DefaultPseudoClassSelectorFactory()), Instance((ILinkRelationFactory)new DefaultLinkRelationFactory()), Instance((IDocumentFactory)new DefaultDocumentFactory()), Instance((IAttributeObserver)new DefaultAttributeObserver()), Instance((IMetaHandler)new EncodingMetaHandler()), Instance((IHtmlEncoder)new DefaultHtmlEncoder()), Creator((Func)((IBrowsingContext ctx) => new CssSelectorParser(ctx))), Creator((Func)((IBrowsingContext ctx) => new HtmlParser(ctx))), Creator((Func)((IBrowsingContext ctx) => new DefaultNavigationHandler(ctx))), Creator((Func)((IBrowsingContext ctx) => new HtmlDomConstructionFactory(ctx))) }; } } public static class ConfigurationExtensions { public static IConfiguration With(this IConfiguration configuration, object service) { configuration = configuration ?? throw new ArgumentNullException("configuration"); service = service ?? throw new ArgumentNullException("service"); return new Configuration(configuration.Services.Concat(service)); } public static IConfiguration WithOnly(this IConfiguration configuration, TService service) { if (service == null) { throw new ArgumentNullException("service"); } return configuration.Without().With(service); } public static IConfiguration WithOnly(this IConfiguration configuration, Func creator) { creator = creator ?? throw new ArgumentNullException("creator"); return configuration.Without().With(creator); } public static IConfiguration Without(this IConfiguration configuration, object service) { configuration = configuration ?? throw new ArgumentNullException("configuration"); service = service ?? throw new ArgumentNullException("service"); return new Configuration(configuration.Services.Except(service)); } public static IConfiguration With(this IConfiguration configuration, IEnumerable services) { configuration = configuration ?? throw new ArgumentNullException("configuration"); services = services ?? throw new ArgumentNullException("services"); return new Configuration(services.Concat(configuration.Services)); } public static IConfiguration Without(this IConfiguration configuration, IEnumerable services) { configuration = configuration ?? throw new ArgumentNullException("configuration"); services = services ?? throw new ArgumentNullException("services"); return new Configuration(configuration.Services.Except(services)); } public static IConfiguration With(this IConfiguration configuration, Func creator) { creator = creator ?? throw new ArgumentNullException("creator"); return configuration.With((object)creator); } public static IConfiguration Without(this IConfiguration configuration) { configuration = configuration ?? throw new ArgumentNullException("configuration"); IEnumerable services = configuration.Services.OfType().Cast(); IEnumerable> services2 = configuration.Services.OfType>(); return configuration.Without(services).Without(services2); } public static bool Has(this IConfiguration configuration) { configuration = configuration ?? throw new ArgumentNullException("configuration"); if (!configuration.Services.OfType().Any()) { return configuration.Services.OfType>().Any(); } return true; } public static IConfiguration WithDefaultLoader(this IConfiguration configuration, LoaderOptions? setup = null) { LoaderOptions config = setup ?? new LoaderOptions(); if (!configuration.Has()) { configuration = configuration.With(new DefaultHttpRequester()); } if (!config.IsNavigationDisabled) { configuration = configuration.With((Func)((IBrowsingContext ctx) => new DefaultDocumentLoader(ctx, config.Filter))); } if (config.IsResourceLoadingEnabled) { configuration = configuration.With((Func)((IBrowsingContext ctx) => new DefaultResourceLoader(ctx, config.Filter))); } return configuration; } public static IConfiguration WithCulture(this IConfiguration configuration, string name) { CultureInfo culture = new CultureInfo(name); return configuration.WithCulture(culture); } public static IConfiguration WithCulture(this IConfiguration configuration, CultureInfo culture) { return configuration.With(culture); } public static IConfiguration WithMetaRefresh(this IConfiguration configuration, Predicate? shouldRefresh = null) { RefreshMetaHandler service = new RefreshMetaHandler(shouldRefresh); return configuration.With(service); } public static IConfiguration WithLocaleBasedEncoding(this IConfiguration configuration) { LocaleEncodingProvider service = new LocaleEncodingProvider(); return configuration.With(service); } public static IConfiguration WithDefaultCookies(this IConfiguration configuration) { MemoryCookieProvider service = new MemoryCookieProvider(); return configuration.With(service); } } public static class FormatExtensions { public static string ToCss(this IStyleFormattable style) { return style.ToCss(CssStyleFormatter.Instance); } public static string ToCss(this IStyleFormattable style, IStyleFormatter formatter) { StringBuilder sb = StringBuilderPool.Obtain(); using (StringWriter writer = new StringWriter(sb)) { style.ToCss(writer, formatter); } return sb.ToPool(); } public static void ToCss(this IStyleFormattable style, TextWriter writer) { style.ToCss(writer, CssStyleFormatter.Instance); } public static Task ToCssAsync(this IStyleFormattable style, TextWriter writer) { return writer.WriteAsync(style.ToCss()); } public static async Task ToCssAsync(this IStyleFormattable style, Stream stream) { using StreamWriter writer = new StreamWriter(stream); await style.ToCssAsync(writer).ConfigureAwait(continueOnCapturedContext: false); } public static string ToHtml(this IMarkupFormattable markup) { return markup.ToHtml(HtmlMarkupFormatter.Instance); } public static string ToHtml(this IMarkupFormattable markup, IMarkupFormatter formatter) { StringBuilder sb = StringBuilderPool.Obtain(); using (StringWriter writer = new StringWriter(sb)) { markup.ToHtml(writer, formatter); } return sb.ToPool(); } public static void ToHtml(this IMarkupFormattable markup, TextWriter writer) { markup.ToHtml(writer, HtmlMarkupFormatter.Instance); } public static string Minify(this IMarkupFormattable markup) { return markup.ToHtml(new MinifyMarkupFormatter()); } public static string Prettify(this IMarkupFormattable markup) { return markup.ToHtml(new PrettyMarkupFormatter()); } public static Task ToHtmlAsync(this IMarkupFormattable markup, TextWriter writer) { return writer.WriteAsync(markup.ToHtml()); } public static async Task ToHtmlAsync(this IMarkupFormattable markup, Stream stream) { using StreamWriter writer = new StreamWriter(stream); await markup.ToHtmlAsync(writer).ConfigureAwait(continueOnCapturedContext: false); } } public interface IBrowsingContext : IEventTarget, IDisposable { IWindow? Current { get; } IDocument? Active { get; set; } IHistory? SessionHistory { get; } Sandboxes Security { get; } IBrowsingContext? Parent { get; } IDocument? Creator { get; } IEnumerable OriginalServices { get; } T? GetService() where T : class; IEnumerable GetServices() where T : class; IBrowsingContext CreateChild(string? name, Sandboxes security); IBrowsingContext? FindChild(string name); } public interface IConfiguration { IEnumerable Services { get; } } public interface IMarkupFormattable { void ToHtml(TextWriter writer, IMarkupFormatter formatter); } public interface IMarkupFormatter { string Text(ICharacterData text); string LiteralText(ICharacterData text); string Comment(IComment comment); string Processing(IProcessingInstruction processing); string Doctype(IDocumentType doctype); string OpenTag(IElement element, bool selfClosing); string CloseTag(IElement element, bool selfClosing); } public interface IStyleFormattable { void ToCss(TextWriter writer, IStyleFormatter formatter); } public interface IStyleFormatter { string Sheet(IEnumerable rules); string Declaration(string name, string value, bool important); string BlockDeclarations(IEnumerable declarations); string Rule(string name, string value); string Rule(string name, string prelude, string rules); string BlockRules(IEnumerable rules); string Comment(string data); } } namespace AngleSharp.Xhtml { public class XhtmlMarkupFormatter : IMarkupFormatter { public static readonly IMarkupFormatter Instance = new XhtmlMarkupFormatter(); private readonly bool _emptyTagsToSelfClosing; public bool IsSelfClosingEmptyTags => _emptyTagsToSelfClosing; public XhtmlMarkupFormatter() : this(emptyTagsToSelfClosing: true) { } public XhtmlMarkupFormatter(bool emptyTagsToSelfClosing) { _emptyTagsToSelfClosing = emptyTagsToSelfClosing; } public virtual string CloseTag(IElement element, bool selfClosing) { string prefix = element.Prefix; string localName = element.LocalName; string text = ((!string.IsNullOrEmpty(prefix)) ? (prefix + ":" + localName) : localName); if (!selfClosing && (!_emptyTagsToSelfClosing || element.HasChildNodes)) { return ""; } return string.Empty; } public virtual string Comment(IComment comment) { return ""; } public virtual string Doctype(IDocumentType doctype) { string publicIdentifier = doctype.PublicIdentifier; string systemIdentifier = doctype.SystemIdentifier; string text = ((string.IsNullOrEmpty(publicIdentifier) && string.IsNullOrEmpty(systemIdentifier)) ? string.Empty : (" " + (string.IsNullOrEmpty(publicIdentifier) ? ("SYSTEM \"" + systemIdentifier + "\"") : ("PUBLIC \"" + publicIdentifier + "\" \"" + systemIdentifier + "\"")))); return ""; } public virtual string OpenTag(IElement element, bool selfClosing) { string prefix = element.Prefix; StringBuilder stringBuilder = StringBuilderPool.Obtain(); stringBuilder.Append('<'); if (!string.IsNullOrEmpty(prefix)) { stringBuilder.Append(prefix).Append(':'); } stringBuilder.Append(element.LocalName); foreach (IAttr attribute in element.Attributes) { stringBuilder.Append(' ').Append(Attribute(attribute)); } if (selfClosing || (_emptyTagsToSelfClosing && !element.HasChildNodes)) { stringBuilder.Append(" /"); } stringBuilder.Append('>'); return stringBuilder.ToPool(); } public virtual string Processing(IProcessingInstruction processing) { string text = processing.Target + " " + processing.Data; return ""; } public virtual string LiteralText(ICharacterData text) { return text.Data; } public virtual string Text(ICharacterData text) { return EscapeText(text.Data); } protected virtual string Attribute(IAttr attribute) { string namespaceUri = attribute.NamespaceUri; string localName = attribute.LocalName; string value = attribute.Value; StringBuilder stringBuilder = StringBuilderPool.Obtain(); if (string.IsNullOrEmpty(namespaceUri)) { stringBuilder.Append(localName); } else if (namespaceUri.Is(NamespaceNames.XmlUri)) { stringBuilder.Append(NamespaceNames.XmlPrefix).Append(':').Append(localName); } else if (namespaceUri.Is(NamespaceNames.XLinkUri)) { stringBuilder.Append(NamespaceNames.XLinkPrefix).Append(':').Append(localName); } else if (namespaceUri.Is(NamespaceNames.XmlNsUri)) { stringBuilder.Append(XmlNamespaceLocalName(localName)); } else { stringBuilder.Append(attribute.Name); } stringBuilder.Append('=').Append('"'); for (int i = 0; i < value.Length; i++) { switch (value[i]) { case '&': stringBuilder.Append("&"); break; case '\u00a0': stringBuilder.Append(" "); break; case '<': stringBuilder.Append("<"); break; case '"': stringBuilder.Append("""); break; default: stringBuilder.Append(value[i]); break; } } return stringBuilder.Append('"').ToPool(); } public static string EscapeText(string content) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); for (int i = 0; i < content.Length; i++) { switch (content[i]) { case '&': stringBuilder.Append("&"); break; case '\u00a0': stringBuilder.Append(" "); break; case '>': stringBuilder.Append(">"); break; case '<': stringBuilder.Append("<"); break; default: stringBuilder.Append(content[i]); break; } } return stringBuilder.ToPool(); } public static string XmlNamespaceLocalName(string localName) { if (localName.Is(NamespaceNames.XmlNsPrefix)) { return localName; } return NamespaceNames.XmlNsPrefix + ':' + localName; } } } namespace AngleSharp.Text { public sealed class CharArrayTextSource : IReadOnlyTextSource, IDisposable { private int _index; private string? _content; private readonly char[] _array; private readonly ReadOnlyMemory _memory; private readonly int _length; public string Text => _content ?? (_content = new string(_array, 0, _length)); public char this[int index] => _array[index]; public int Length => _length; public Encoding CurrentEncoding { get { return TextEncoding.Utf8; } set { } } public int Index { get { return _index; } set { _index = value; } } public CharArrayTextSource(char[] array, int length) { _array = array; _length = length; _memory = array.AsMemory(0, length); } public void Dispose() { } public char ReadCharacter() { if (_index < _length) { return _array[_index++]; } _index++; return '\uffff'; } public string ReadCharacters(int characters) { return ReadMemory(characters).ToString(); } public StringOrMemory ReadMemory(int characters) { int index = _index; if (index + characters <= _length) { _index += characters; return _memory.Slice(index, characters); } _index += characters; characters = Math.Min(characters, _length - index); return _memory.Slice(index, characters); } public Task PrefetchAsync(int length, CancellationToken cancellationToken) { return Task.CompletedTask; } public Task PrefetchAllAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } public bool TryGetContentLength(out int length) { length = _length; return true; } } public static class CharExtensions { public static int FromHex(this char c) { if (!c.IsDigit()) { return c - (c.IsLowercaseAscii() ? 87 : 55); } return c - 48; } public static string ToHex(this byte num) { Span span = stackalloc char[2]; int num2 = num >> 4; span[0] = (char)(num2 + ((num2 < 10) ? 48 : 55)); num2 = num - 16 * num2; span[1] = (char)(num2 + ((num2 < 10) ? 48 : 55)); return span.ToString(); } public static string ToHex(this char character) { int num = character; return num.ToString("x"); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsInRange(this char c, int lower, int upper) { if (c >= lower) { return c <= upper; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNormalQueryCharacter(this char c) { if (c.IsInRange(33, 126) && c != '"' && c != '`' && c != '#' && c != '<') { return c != '>'; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNormalPathCharacter(this char c) { if (c.IsInRange(32, 126) && c != '"' && c != '`' && c != '#' && c != '<' && c != '>' && c != ' ') { return c != '?'; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsUppercaseAscii(this char c) { if (c >= 'A') { return c <= 'Z'; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsLowercaseAscii(this char c) { if (c >= 'a') { return c <= 'z'; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsAlphanumericAscii(this char c) { if (!c.IsDigit() && !c.IsUppercaseAscii()) { return c.IsLowercaseAscii(); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHex(this char c) { if (!c.IsDigit() && (c < 'A' || c > 'F')) { if (c >= 'a') { return c <= 'f'; } return false; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNonAscii(this char c) { if (c != '\uffff') { return c >= '\u0080'; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNonPrintable(this char c) { if ((c < '\0' || c > '\b') && (c < '\u000e' || c > '\u001f')) { if (c >= '\u007f') { return c <= '\u009f'; } return false; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsLetter(this char c) { if (!c.IsUppercaseAscii()) { return c.IsLowercaseAscii(); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsName(this char c) { if (!c.IsNonAscii() && !c.IsLetter() && c != '_' && c != '-') { return c.IsDigit(); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsCustomElementName(this char c) { if (c != '_' && c != '-' && c != '.' && !c.IsDigit() && !c.IsLowercaseAscii() && c != '·' && !c.IsInRange(192, 214) && !c.IsInRange(216, 246) && !c.IsInRange(248, 893) && !c.IsInRange(895, 8191) && !c.IsInRange(8204, 8205) && !c.IsInRange(8255, 8256) && !c.IsInRange(8304, 8591) && !c.IsInRange(11264, 12271) && !c.IsInRange(12289, 55295) && !c.IsInRange(63744, 64975) && !c.IsInRange(65008, 65533)) { return c.IsInRange(65536, 2031615); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNameStart(this char c) { if (!c.IsNonAscii() && !c.IsUppercaseAscii() && !c.IsLowercaseAscii()) { return c == '_'; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsLineBreak(this char c) { if (c != '\n') { return c == '\r'; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsSpaceCharacter(this char c) { if (c != ' ' && c != '\t' && c != '\n' && c != '\r') { return c == '\f'; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsWhiteSpaceCharacter(this char c) { if (!c.IsInRange(9, 13) && c != ' ' && c != '\u0085' && c != '\u00a0' && c != '\u1680' && c != '\u180e' && !c.IsInRange(8192, 8202) && c != '\u2028' && c != '\u2029' && c != '\u202f' && c != '\u205f') { return c == '\u3000'; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsDigit(this char c) { if (c >= '0') { return c <= '9'; } return false; } public static bool IsUrlCodePoint(this char c) { if (!c.IsAlphanumericAscii() && c != '!' && c != '$' && c != '&' && c != '\'' && c != '(' && c != ')' && c != '*' && c != '+' && c != '-' && c != ',' && c != '.' && c != '/' && c != ':' && c != ';' && c != '=' && c != '?' && c != '@' && c != '_' && c != '~' && !c.IsInRange(160, 55295) && !c.IsInRange(57344, 64975) && !c.IsInRange(65008, 65533) && !c.IsInRange(65536, 131069) && !c.IsInRange(131072, 196605) && !c.IsInRange(196608, 262141) && !c.IsInRange(262144, 327677) && !c.IsInRange(327680, 393213) && !c.IsInRange(393216, 458749) && !c.IsInRange(458752, 524285) && !c.IsInRange(524288, 589821) && !c.IsInRange(589824, 655357) && !c.IsInRange(655360, 720893) && !c.IsInRange(720896, 786429) && !c.IsInRange(786432, 851965) && !c.IsInRange(851968, 917501) && !c.IsInRange(917504, 983037) && !c.IsInRange(983040, 1048573)) { return c.IsInRange(1048576, 1114109); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsInvalid(this int c) { if (c != 0 && c <= 1114111) { if (c > 55296) { return c < 57343; } return false; } return true; } } public interface ITextSource : IReadOnlyTextSource, IDisposable { void InsertText(string content); } public interface IReadOnlyTextSource : IDisposable { string Text { get; } int Length { get; } Encoding CurrentEncoding { get; set; } int Index { get; set; } char this[int index] { get; } char ReadCharacter(); string ReadCharacters(int characters); StringOrMemory ReadMemory(int characters); Task PrefetchAsync(int length, CancellationToken cancellationToken); Task PrefetchAllAsync(CancellationToken cancellationToken); bool TryGetContentLength(out int length); } public static class Punycode { private const int PunycodeBase = 36; private const int Tmin = 1; private const int Tmax = 26; private static readonly string acePrefix = "xn--"; private static readonly char[] possibleDots = new char[4] { '.', '。', '.', '。' }; public static IDictionary Symbols = new Dictionary { { '。', '.' }, { '.', '.' }, { 'G', 'g' }, { 'o', 'o' }, { 'c', 'c' }, { 'X', 'x' }, { '0', '0' }, { '1', '1' }, { '2', '2' }, { '5', '5' }, { '⁰', '0' }, { '¹', '1' }, { '²', '2' }, { '³', '3' }, { '⁴', '4' }, { '⁵', '5' }, { '⁶', '6' }, { '⁷', '7' }, { '⁸', '8' }, { '⁹', '9' }, { '₀', '0' }, { '₁', '1' }, { '₂', '2' }, { '₃', '3' }, { '₄', '4' }, { '₅', '5' }, { '₆', '6' }, { '₇', '7' }, { '₈', '8' }, { '₉', '9' }, { 'ᵃ', 'a' }, { 'ᵇ', 'b' }, { 'ᶜ', 'c' }, { 'ᵈ', 'd' }, { 'ᵉ', 'e' }, { 'ᶠ', 'f' }, { 'ᵍ', 'g' }, { 'ʰ', 'h' }, { 'ⁱ', 'i' }, { 'ʲ', 'j' }, { 'ᵏ', 'k' }, { 'ˡ', 'l' }, { 'ᵐ', 'm' }, { 'ⁿ', 'n' }, { 'ᵒ', 'o' }, { 'ᵖ', 'p' }, { 'ʳ', 'r' }, { 'ˢ', 's' }, { 'ᵗ', 't' }, { 'ᵘ', 'u' }, { 'ᵛ', 'v' }, { 'ʷ', 'w' }, { 'ˣ', 'x' }, { 'ʸ', 'y' }, { 'ᶻ', 'z' }, { 'ᴬ', 'A' }, { 'ᴮ', 'B' }, { 'ᴰ', 'D' }, { 'ᴱ', 'E' }, { 'ᴳ', 'G' }, { 'ᴴ', 'H' }, { 'ᴵ', 'I' }, { 'ᴶ', 'J' }, { 'ᴷ', 'K' }, { 'ᴸ', 'L' }, { 'ᴹ', 'M' }, { 'ᴺ', 'N' }, { 'ᴼ', 'O' }, { 'ᴾ', 'P' }, { 'ᴿ', 'R' }, { 'ᵀ', 'T' }, { 'ᵁ', 'U' }, { 'ⱽ', 'V' }, { 'ᵂ', 'W' } }; public static string Encode(string text) { if (text.Length == 0) { return text; } StringBuilder stringBuilder = new StringBuilder(text.Length); int num = 0; int num2 = 0; int num3 = 0; while (num < text.Length) { num = text.IndexOfAny(possibleDots, num2); if (num < 0) { num = text.Length; } if (num == num2) { break; } stringBuilder.Append(acePrefix); int num4 = 0; int num5 = 0; for (num4 = num2; num4 < num; num4++) { if (text[num4] < '\u0080') { stringBuilder.Append(EncodeBasic(text[num4])); num5++; } else if (char.IsSurrogatePair(text, num4)) { num4++; } } int num6 = num5; if (num6 == num - num2) { stringBuilder.Remove(num3, acePrefix.Length); } else { if (text.Length - num2 >= acePrefix.Length && text.Substring(num2, acePrefix.Length).Isi(acePrefix)) { break; } int num7 = 0; if (num6 > 0) { stringBuilder.Append('-'); } int num8 = 128; int num9 = 0; int num10 = 72; while (num5 < num - num2) { int num11 = 0; int num12 = 0; int num13 = 0; num12 = 134217727; for (num11 = num2; num11 < num; num11 += ((!IsSupplementary(num13)) ? 1 : 2)) { num13 = char.ConvertToUtf32(text, num11); if (num13 >= num8 && num13 < num12) { num12 = num13; } } num9 += (num12 - num8) * (num5 - num7 + 1); num8 = num12; for (num11 = num2; num11 < num; num11 += ((!IsSupplementary(num13)) ? 1 : 2)) { num13 = char.ConvertToUtf32(text, num11); if (num13 < num8) { num9++; } else { if (num13 != num8) { continue; } int num14 = num9; int num15 = 36; while (true) { int num16 = ((num15 <= num10) ? 1 : ((num15 >= num10 + 26) ? 26 : (num15 - num10))); if (num14 < num16) { break; } stringBuilder.Append(EncodeDigit(num16 + (num14 - num16) % (36 - num16))); num14 = (num14 - num16) / (36 - num16); num15 += 36; } stringBuilder.Append(EncodeDigit(num14)); num10 = AdaptChar(num9, num5 - num7 + 1, num5 == num6); num9 = 0; num5++; if (IsSupplementary(num12)) { num5++; num7++; } } } num9++; num8++; } } if (stringBuilder.Length - num3 > 63) { throw new ArgumentException(); } if (num != text.Length) { stringBuilder.Append(possibleDots[0]); } num2 = num + 1; num3 = stringBuilder.Length; } int num17 = ((!IsDot(text[text.Length - 1])) ? 1 : 0); int num18 = 255 - num17; if (stringBuilder.Length > num18) { stringBuilder.Remove(num18, stringBuilder.Length - num18); } return stringBuilder.ToString(); } private static bool IsSupplementary(int test) { return test >= 65536; } private static bool IsDot(char c) { for (int i = 0; i < possibleDots.Length; i++) { if (possibleDots[i] == c) { return true; } } return false; } private static char EncodeDigit(int digit) { if (digit > 25) { return (char)(digit + 22); } return (char)(digit + 97); } private static char EncodeBasic(char character) { if (char.IsUpper(character)) { character = (char)(character + 32); } return character; } private static int AdaptChar(int delta, int numPoints, bool firstTime) { uint num = 0u; delta = (firstTime ? (delta / 700) : (delta / 2)); delta += delta / numPoints; num = 0u; while (delta > 455) { delta /= 35; num += 36; } return (int)(num + 36 * delta / (delta + 38)); } } public sealed class ReadOnlyMemoryTextSource : IReadOnlyTextSource, IDisposable { private int _index; private string? _content; private readonly ReadOnlyMemory _memory; private readonly int _length; public string Text => _content ?? (_content = _memory.Span.ToString()); public char this[int index] { get { if (_content == null) { return _memory.Span[index]; } return _content[index]; } } public int Length => _length; public Encoding CurrentEncoding { get { return TextEncoding.Utf8; } set { } } public int Index { get { return _index; } set { _index = value; } } public ReadOnlyMemoryTextSource(ReadOnlyMemory memory) { _memory = memory; _length = memory.Length; } public ReadOnlyMemoryTextSource(string str) { _content = str; _memory = str.AsMemory(); _length = _memory.Length; } public void Dispose() { } public char ReadCharacter() { if (_index < _length) { return _memory.Span[_index++]; } _index++; return '\uffff'; } public string ReadCharacters(int characters) { return ReadMemory(characters).ToString(); } public StringOrMemory ReadMemory(int characters) { int index = _index; if (index + characters <= _length) { _index += characters; return _memory.Slice(index, characters); } _index += characters; characters = Math.Min(characters, _length - index); return _memory.Slice(index, characters); } public Task PrefetchAsync(int length, CancellationToken cancellationToken) { return Task.CompletedTask; } public Task PrefetchAllAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } public bool TryGetContentLength(out int length) { length = _length; return true; } } public static class StringBuilderPool { private static readonly Stack _builder = new Stack(); private static readonly object _lock = new object(); private static int _count = 4; private static int _limit = 85000; public static int MaxCount { get { return _count; } set { _count = Math.Max(1, value); } } public static int SizeLimit { get { return _limit; } set { _limit = Math.Max(1024, value); } } public static StringBuilder Obtain() { lock (_lock) { if (_builder.Count == 0) { return new StringBuilder(1024); } return _builder.Pop().Clear(); } } public static string ToPool(this StringBuilder sb) { string result = sb.ToString(); sb.ReturnToPool(); return result; } internal static void ReturnToPool(this StringBuilder sb) { lock (_lock) { int count = _builder.Count; if (sb.Capacity <= _limit) { if (count == _count) { DropMinimum(sb); } else if (count < Math.Min(2, _count) || _builder.Peek().Capacity < sb.Capacity) { _builder.Push(sb); } } } } private static void DropMinimum(StringBuilder sb) { int capacity = sb.Capacity; StringBuilder[] instances = _builder.ToArray(); int num = FindIndex(instances, capacity); if (num > -1) { RebuildPool(sb, instances, num); } } private static void RebuildPool(StringBuilder sb, StringBuilder[] instances, int index) { _builder.Clear(); int num = instances.Length - 1; while (num > index) { _builder.Push(instances[num--]); } while (num > 0) { _builder.Push(instances[--num]); } _builder.Push(sb); } private static int FindIndex(StringBuilder[] instances, int minimum) { int result = -1; for (int i = 0; i < instances.Length; i++) { int capacity = instances[i].Capacity; if (capacity < minimum) { minimum = capacity; result = i; } } return result; } } public static class StringExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Has([NotNullWhen(true)] this string? value, char chr, int index = 0) { if (value != null && value.Length > index) { return value[index] == chr; } return false; } internal static string GetCompatiblity(this QuirksMode mode) { string result = "CSS1Compat"; string text = mode.ToString(); if (text != null) { FieldInfo field = typeof(QuirksMode).GetField(text); if (field != null) { DomDescriptionAttribute customAttribute = field.GetCustomAttribute(); if (customAttribute != null) { result = customAttribute.Description; } } } return result; } public static StringOrMemory HtmlLower(this StringOrMemory value) { int length = value.Length; for (int i = 0; i < length; i++) { if (value[i].IsUppercaseAscii()) { if (length < 128) { Span result = stackalloc char[length]; return Slow(value, i, result); } char[] array = ArrayPool.Shared.Rent(length); Span result2 = array.AsSpan(0, length); string text = Slow(value, i, result2); ArrayPool.Shared.Return(array); return text; } } return value; static string Slow(StringOrMemory stringOrMemory, int num, Span span) { for (int j = 0; j < num; j++) { span[j] = stringOrMemory[j]; } char c = stringOrMemory[num]; span[num] = char.ToLowerInvariant(c); for (int k = num + 1; k < stringOrMemory.Length; k++) { c = stringOrMemory[k]; if (c.IsUppercaseAscii()) { c = char.ToLowerInvariant(c); } span[k] = c; } return span.ToString(); } } public static string HtmlLower(this string value) { return new StringOrMemory(value).HtmlLower().ToString(); } public static Sandboxes ParseSecuritySettings(this string value, bool allowFullscreen = false) { string[] list = value.SplitSpaces(); Sandboxes sandboxes = Sandboxes.Navigation | Sandboxes.Plugins | Sandboxes.DocumentDomain; if (!list.Contains("allow-popups", StringComparison.OrdinalIgnoreCase)) { sandboxes |= Sandboxes.AuxiliaryNavigation; } if (!list.Contains("allow-top-navigation", StringComparison.OrdinalIgnoreCase)) { sandboxes |= Sandboxes.TopLevelNavigation; } if (!list.Contains("allow-same-origin", StringComparison.OrdinalIgnoreCase)) { sandboxes |= Sandboxes.Origin; } if (!list.Contains("allow-forms", StringComparison.OrdinalIgnoreCase)) { sandboxes |= Sandboxes.Forms; } if (!list.Contains("allow-pointer-lock", StringComparison.OrdinalIgnoreCase)) { sandboxes |= Sandboxes.PointerLock; } if (!list.Contains("allow-scripts", StringComparison.OrdinalIgnoreCase)) { sandboxes |= Sandboxes.Scripts; sandboxes |= Sandboxes.AutomaticFeatures; } if (!list.Contains("allow-presentation", StringComparison.OrdinalIgnoreCase)) { sandboxes |= Sandboxes.Presentation; } if (!allowFullscreen) { sandboxes |= Sandboxes.Fullscreen; } return sandboxes; } public static T ToEnum(this string? value, T defaultValue) where T : struct, Enum { if (!string.IsNullOrEmpty(value) && Enum.TryParse(value, ignoreCase: true, out var result)) { return result; } return defaultValue; } public static double ToDouble(this string? value, double defaultValue = 0.0) { if (!string.IsNullOrEmpty(value) && double.TryParse(value, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out var result)) { return result; } return defaultValue; } public static int ToInteger(this string? value, int defaultValue = 0) { if (!string.IsNullOrEmpty(value) && int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result)) { return result; } return defaultValue; } public static uint ToInteger(this string? value, uint defaultValue = 0u) { if (!string.IsNullOrEmpty(value) && uint.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result)) { return result; } return defaultValue; } public static bool ToBoolean(this string? value, bool defaultValue = false) { if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out var result)) { return result; } return defaultValue; } public static string ReplaceFirst(this string text, string search, string replace) { int num = text.IndexOf(search); if (num < 0) { return text; } return text.Substring(0, num) + replace + text.Substring(num + search.Length); } public static string CollapseAndStrip(this string str) { if (str.Length == 0) { return str; } char[] array = ArrayPool.Shared.Rent(str.Length); bool flag = true; int num = 0; int length = str.Length; for (int i = 0; i < length; i++) { if (str[i].IsSpaceCharacter()) { if (!flag) { flag = true; array[num++] = ' '; } } else { flag = false; array[num++] = str[i]; } } if (flag && num > 0) { num--; } string result = new string(array, 0, num); ArrayPool.Shared.Return(array); return result; } public static string Collapse(this string str) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); bool flag = false; int length = str.Length; for (int i = 0; i < length; i++) { if (str[i].IsSpaceCharacter()) { if (!flag) { stringBuilder.Append(' '); flag = true; } } else { flag = false; stringBuilder.Append(str[i]); } } return stringBuilder.ToPool(); } public static bool Contains(this string[] list, string element, StringComparison comparison = StringComparison.Ordinal) { int num = list.Length; for (int i = 0; i < num; i++) { if (list[i].Equals(element, comparison)) { return true; } } return false; } public static bool IsCustomElement(this string tag) { if (tag.IndexOf('-') != -1 && !TagNames.DisallowedCustomElementNames.Contains(tag)) { int length = tag.Length; for (int i = 0; i < length; i++) { if (!tag[i].IsCustomElementName()) { return false; } } return true; } return false; } public static bool IsCustomElement(this StringOrMemory tag) { if (tag.Memory.Span.IndexOf('-') != -1 && !TagNames.DisallowedCustomElementNames.Contains(tag)) { int length = tag.Length; for (int i = 0; i < length; i++) { if (!tag[i].IsCustomElementName()) { return false; } } return true; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this string? current, string? other) { return string.Equals(current, other, StringComparison.Ordinal); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this string? current, StringOrMemory other) { return other.Memory.Span.SequenceEqual(current.AsSpan()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this Span current, string? other) { if (other == null) { return false; } return current.SequenceEqual(other.AsSpan()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this ReadOnlySpan current, ReadOnlyMemory other) { return current.SequenceEqual(other.Span); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this ReadOnlySpan current, ReadOnlySpan other) { return current.SequenceEqual(other); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Isi(this string? current, string? other) { return string.Equals(current, other, StringComparison.OrdinalIgnoreCase); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Isi(this string? current, StringOrMemory other) { return MemoryExtensions.Equals(current.AsSpan(), other.Memory.Span, StringComparison.OrdinalIgnoreCase); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Isi(this Span current, string? other) { if (other == null) { return false; } return MemoryExtensions.Equals(current, other.AsSpan(), StringComparison.OrdinalIgnoreCase); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Isi(this Span current, ReadOnlySpan other) { return MemoryExtensions.Equals(current, other, StringComparison.OrdinalIgnoreCase); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Isi(this Span current, ReadOnlyMemory other) { return MemoryExtensions.Equals(current, other.Span, StringComparison.OrdinalIgnoreCase); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Isi(this ReadOnlySpan current, string? other) { if (other == null) { return false; } return MemoryExtensions.Equals(current, other.AsSpan(), StringComparison.OrdinalIgnoreCase); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsOneOf(this string? element, string item1, string item2) { if (!element.Is(item1)) { return element.Is(item2); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsOneOf(this string element, string item1, string item2, string item3) { if (!element.Is(item1) && !element.Is(item2)) { return element.Is(item3); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsOneOf(this string element, string item1, string item2, string item3, string item4) { if (!element.Is(item1) && !element.Is(item2) && !element.Is(item3)) { return element.Is(item4); } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsOneOf(this string element, string item1, string item2, string item3, string item4, string item5) { if (!element.Is(item1) && !element.Is(item2) && !element.Is(item3) && !element.Is(item4)) { return element.Is(item5); } return true; } public static string StripLineBreaks(this string str) { char[] array = str.ToCharArray(); int num = 0; int num2 = array.Length; int num3 = 0; while (num3 < num2) { array[num3] = array[num3 + num]; if (array[num3].IsLineBreak()) { num++; num2--; } else { num3++; } } return new string(array, 0, num2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string StripLeadingTrailingSpaces(this string str) { int i = 0; int num = str.Length - 1; for (; i < str.Length && str[i].IsSpaceCharacter(); i++) { } while (num > i && str[num].IsSpaceCharacter()) { num--; } return str.Substring(i, 1 + num - i); } public static string[] SplitWithoutTrimming(this string str, char c) { List list = new List(); int num = 0; int length = str.Length; for (int i = 0; i < length; i++) { if (str[i] == c) { if (i > num) { list.Add(str.Substring(num, i - num)); } num = i + 1; } } if (length > num) { list.Add(str.Substring(num, length - num)); } return list.ToArray(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string[] SplitCommas(this string str) { return str.SplitWithTrimming(','); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasHyphen(this string str, string value, StringComparison comparison = StringComparison.Ordinal) { if (!string.Equals(str, value, comparison)) { if (str.Length > value.Length && str.StartsWith(value, comparison)) { return str[value.Length] == '-'; } return false; } return true; } public static string[] SplitSpaces(this string str) { List list = new List(); char[] array = ArrayPool.Shared.Rent(str.Length); int num = 0; for (int i = 0; i <= str.Length; i++) { if (i == str.Length || str[i].IsSpaceCharacter()) { if (num > 0) { string text = new string(array, 0, num).StripLeadingTrailingSpaces(); if (text.Length != 0) { list.Add(text); } num = 0; } } else { array[num] = str[i]; num++; } } ArrayPool.Shared.Return(array); return list.ToArray(); } public static string[] SplitWithTrimming(this string str, char ch) { List list = new List(); char[] array = ArrayPool.Shared.Rent(str.Length); int num = 0; for (int i = 0; i <= str.Length; i++) { if (i == str.Length || str[i] == ch) { if (num > 0) { string text = new string(array, 0, num).StripLeadingTrailingSpaces(); if (text.Length != 0) { list.Add(text); } num = 0; } } else { array[num] = str[i]; num++; } } ArrayPool.Shared.Return(array); return list.ToArray(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromHex(this string s) { return int.Parse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromDec(this string s) { return int.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string HtmlEncode(this string value, Encoding encoding) { return value; } public static string CssString(this string value) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); stringBuilder.Append('"'); if (!string.IsNullOrEmpty(value)) { int length = value.Length; for (int i = 0; i < length; i++) { char c = value[i]; switch (c) { case '\0': stringBuilder.ReturnToPool(); throw new DomException(DomError.InvalidCharacter); case '"': case '\\': stringBuilder.Append('\\').Append(c); continue; } if (c.IsInRange(1, 31) || c == '{') { stringBuilder.Append('\\').Append(c.ToHex()).Append((i + 1 != length) ? " " : ""); } else { stringBuilder.Append(c); } } } stringBuilder.Append('"'); return stringBuilder.ToPool(); } public static string CssFunction(this string value, string argument) { return value + "(" + argument + ")"; } public static string UrlEncode(this byte[] content) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); int num = content.Length; for (int i = 0; i < num; i++) { char c = (char)content[i]; switch (c) { case ' ': stringBuilder.Append('+'); break; default: if (!c.IsAlphanumericAscii()) { stringBuilder.Append('%').Append(content[i].ToString("X2")); break; } goto case '*'; case '*': case '-': case '.': case '_': case '~': stringBuilder.Append(c); break; } } return stringBuilder.ToPool(); } public static byte[] UrlDecode(this string value) { MemoryStream memoryStream = new MemoryStream(); int length = value.Length; for (int i = 0; i < length; i++) { char c = value[i]; switch (c) { case '+': { byte value4 = 32; memoryStream.WriteByte(value4); break; } case '%': { if (i + 2 >= length) { throw new FormatException(); } byte value3 = (byte)(16 * value[++i].FromHex() + value[++i].FromHex()); memoryStream.WriteByte(value3); break; } default: { byte value2 = (byte)c; memoryStream.WriteByte(value2); break; } } } return memoryStream.ToArray(); } public static string NormalizeLineEndings(this string value) { if (!string.IsNullOrEmpty(value)) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); bool flag = false; int length = value.Length; for (int i = 0; i < length; i++) { char c = value[i]; bool flag2 = c == '\n'; if (flag && !flag2) { stringBuilder.Append('\n'); } else if (!flag && flag2) { stringBuilder.Append('\r'); } flag = c == '\r'; stringBuilder.Append(c); } if (flag) { stringBuilder.Append('\n'); } return stringBuilder.ToPool(); } return value; } public static string? ToEncodingType(this string? encType) { if (!encType.Isi(MimeTypeNames.Plain) && !encType.Isi(MimeTypeNames.MultipartForm) && !encType.Isi(MimeTypeNames.ApplicationJson)) { return null; } return encType?.ToLowerInvariant(); } public static string? ToFormMethod(this string? method) { if (!method.Isi(FormMethodNames.Get) && !method.Isi(FormMethodNames.Post) && !method.Isi(FormMethodNames.Dialog)) { return null; } return method?.ToLowerInvariant(); } } public sealed class StringSource { private readonly string _content; private readonly int _last; private int _index; private char _current; public char Current => _current; public bool IsDone => _current == '\uffff'; public int Index => _index; public string Content => _content; public StringSource(string content) { _content = content ?? string.Empty; _last = _content.Length - 1; _index = 0; _current = ((_last == -1) ? '\uffff' : content[0]); } public char Next() { if (_index == _last) { _current = '\uffff'; _index = _content.Length; } else if (_index < _content.Length) { _current = _content[++_index]; } return _current; } public char Back() { if (_index > 0) { _current = _content[--_index]; } return _current; } } public static class StringSourceExtensions { public static char SkipSpaces(this StringSource source) { char c = source.Current; while (c.IsSpaceCharacter()) { c = source.Next(); } return c; } public static char Next(this StringSource source, int n) { for (int i = 0; i < n; i++) { source.Next(); } return source.Current; } public static char Back(this StringSource source, int n) { for (int i = 0; i < n; i++) { source.Back(); } return source.Current; } public static char Peek(this StringSource source) { char result = source.Next(); source.Back(); return result; } } public sealed class StringTextSource : IReadOnlyTextSource, IDisposable { private readonly string _string; private readonly ReadOnlyMemory _memory; private readonly int _length; private int _index; public string Text => _string; public char this[int index] => _string[index]; public int Length => _length; public Encoding CurrentEncoding { get { return TextEncoding.Utf8; } set { } } public int Index { get { return _index; } set { _index = value; } } public StringTextSource(string source) { _string = source; _length = source.Length; _memory = source.AsMemory(); } public void Dispose() { } public char ReadCharacter() { if (_index < _length) { return _string[_index++]; } _index++; return '\uffff'; } public string ReadCharacters(int characters) { return ReadMemory(characters).ToString(); } public StringOrMemory ReadMemory(int characters) { int index = _index; if (index + characters <= _length) { _index += characters; return _memory.Slice(index, characters); } _index += characters; characters = Math.Min(characters, _length - index); return _memory.Slice(index, characters); } public Task PrefetchAsync(int length, CancellationToken cancellationToken) { return Task.CompletedTask; } public Task PrefetchAllAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } public bool TryGetContentLength(out int length) { length = _length; return true; } } public static class Symbols { public const char EndOfFile = '\uffff'; public const char Tilde = '~'; public const char Pipe = '|'; public const char Null = '\0'; public const char Ampersand = '&'; public const char Num = '#'; public const char Dollar = '$'; public const char Semicolon = ';'; public const char Asterisk = '*'; public const char Equality = '='; public const char Plus = '+'; public const char Minus = '-'; public const char Comma = ','; public const char Dot = '.'; public const char Accent = '^'; public const char At = '@'; public const char LessThan = '<'; public const char GreaterThan = '>'; public const char SingleQuote = '\''; public const char DoubleQuote = '"'; public const char CurvedQuote = '`'; public const char QuestionMark = '?'; public const char Tab = '\t'; public const char LineFeed = '\n'; public const char CarriageReturn = '\r'; public const char FormFeed = '\f'; public const char Space = ' '; public const char Solidus = '/'; public const char NoBreakSpace = '\u00a0'; public const char ReverseSolidus = '\\'; public const char Colon = ':'; public const char ExclamationMark = '!'; public const char Replacement = '\ufffd'; public const char Underscore = '_'; public const char RoundBracketOpen = '('; public const char RoundBracketClose = ')'; public const char SquareBracketOpen = '['; public const char SquareBracketClose = ']'; public const char CurlyBracketOpen = '{'; public const char CurlyBracketClose = '}'; public const char Percent = '%'; public const int MaximumCodepoint = 1114111; } public static class TextEncoding { public static readonly Encoding Utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); public static readonly Encoding Utf16Be = new UnicodeEncoding(bigEndian: true, byteOrderMark: false); public static readonly Encoding Utf16Le = new UnicodeEncoding(bigEndian: false, byteOrderMark: false); public static readonly Encoding Utf32Le = GetEncoding("UTF-32LE"); public static readonly Encoding Utf32Be = GetEncoding("UTF-32BE"); public static readonly Encoding Gb18030 = GetEncoding("GB18030"); public static readonly Encoding Big5 = GetEncoding("big5"); public static readonly Encoding Windows874 = GetEncoding("windows-874"); public static readonly Encoding Windows1250 = GetEncoding("windows-1250"); public static readonly Encoding Windows1251 = GetEncoding("windows-1251"); public static readonly Encoding Windows1252 = GetEncoding("windows-1252"); public static readonly Encoding Windows1253 = GetEncoding("windows-1253"); public static readonly Encoding Windows1254 = GetEncoding("windows-1254"); public static readonly Encoding Windows1255 = GetEncoding("windows-1255"); public static readonly Encoding Windows1256 = GetEncoding("windows-1256"); public static readonly Encoding Windows1257 = GetEncoding("windows-1257"); public static readonly Encoding Windows1258 = GetEncoding("windows-1258"); public static readonly Encoding Latin2 = GetEncoding("iso-8859-2"); public static readonly Encoding Latin3 = GetEncoding("iso-8859-3"); public static readonly Encoding Latin4 = GetEncoding("iso-8859-4"); public static readonly Encoding Latin5 = GetEncoding("iso-8859-5"); public static readonly Encoding Latin13 = GetEncoding("iso-8859-13"); public static readonly Encoding UsAscii = GetEncoding("us-ascii"); public static readonly Encoding Korean = GetEncoding("ks_c_5601-1987"); private static readonly Dictionary encodings = CreateEncodings(); public static bool IsUnicode(this Encoding encoding) { if (encoding != Utf16Be) { return encoding == Utf16Le; } return true; } public static Encoding? Parse(string content) { string charset = string.Empty; int num = 0; for (int i = num; i < content.Length - 7; i++) { if (content.Substring(i).StartsWith(AttributeNames.Charset, StringComparison.OrdinalIgnoreCase)) { num = i + 7; break; } } if (num > 0 && num < content.Length) { for (int j = num; j < content.Length - 1 && content[j].IsSpaceCharacter(); j++) { num++; } if (content[num] != '=') { return Parse(content.Substring(num)); } num++; for (int k = num; k < content.Length && content[k].IsSpaceCharacter(); k++) { num++; } if (num < content.Length) { if (content[num] == '"') { content = content.Substring(num + 1); int num2 = content.IndexOf('"'); if (num2 != -1) { charset = content.Substring(0, num2); } } else if (content[num] == '\'') { content = content.Substring(num + 1); int num3 = content.IndexOf('\''); if (num3 != -1) { charset = content.Substring(0, num3); } } else { content = content.Substring(num); int num4 = 0; for (int l = 0; l < content.Length && !content[l].IsSpaceCharacter() && content[l] != ';'; l++) { num4++; } charset = content.Substring(0, num4); } } } if (!IsSupported(charset)) { return null; } return Resolve(charset); } public static bool IsSupported(string charset) { return encodings.ContainsKey(charset); } public static Encoding Resolve(string? charset) { if (charset != null && encodings.TryGetValue(charset, out Encoding value)) { return value; } return Utf8; } private static Encoding GetEncoding(string name, Encoding? fallback = null) { try { return Encoding.GetEncoding(name); } catch (Exception) { return fallback ?? Utf8; } } private static Dictionary CreateEncodings() { Dictionary obj = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "unicode-1-1-utf-8", Utf8 }, { "utf-8", Utf8 }, { "utf8", Utf8 }, { "utf-16be", Utf16Be }, { "utf-16", Utf16Le }, { "utf-16le", Utf16Le }, { "dos-874", Windows874 }, { "iso-8859-11", Windows874 }, { "iso8859-11", Windows874 }, { "iso885911", Windows874 }, { "tis-620", Windows874 }, { "windows-874", Windows874 }, { "cp1250", Windows1250 }, { "windows-1250", Windows1250 }, { "x-cp1250", Windows1250 }, { "cp1251", Windows1251 }, { "windows-1251", Windows1251 }, { "x-cp1251", Windows1251 }, { "x-user-defined", Windows1252 }, { "ansi_x3.4-1968", Windows1252 }, { "ascii", Windows1252 }, { "cp1252", Windows1252 }, { "cp819", Windows1252 }, { "csisolatin1", Windows1252 }, { "ibm819", Windows1252 }, { "iso-8859-1", Windows1252 }, { "iso-ir-100", Windows1252 }, { "iso8859-1", Windows1252 }, { "iso88591", Windows1252 }, { "iso_8859-1", Windows1252 }, { "iso_8859-1:1987", Windows1252 }, { "l1", Windows1252 }, { "latin1", Windows1252 }, { "us-ascii", Windows1252 }, { "windows-1252", Windows1252 }, { "x-cp1252", Windows1252 }, { "cp1253", Windows1253 }, { "windows-1253", Windows1253 }, { "x-cp1253", Windows1253 }, { "cp1254", Windows1254 }, { "csisolatin5", Windows1254 }, { "iso-8859-9", Windows1254 }, { "iso-ir-148", Windows1254 }, { "iso8859-9", Windows1254 }, { "iso88599", Windows1254 }, { "iso_8859-9", Windows1254 }, { "iso_8859-9:1989", Windows1254 }, { "l5", Windows1254 }, { "latin5", Windows1254 }, { "windows-1254", Windows1254 }, { "x-cp1254", Windows1254 }, { "cp1255", Windows1255 }, { "windows-1255", Windows1255 }, { "x-cp1255", Windows1255 }, { "cp1256", Windows1256 }, { "windows-1256", Windows1256 }, { "x-cp1256", Windows1256 }, { "cp1257", Windows1257 }, { "windows-1257", Windows1257 }, { "x-cp1257", Windows1257 }, { "cp1258", Windows1258 }, { "windows-1258", Windows1258 }, { "x-cp1258", Windows1258 } }; Encoding encoding = GetEncoding("macintosh"); obj.Add("csmacintosh", encoding); obj.Add("mac", encoding); obj.Add("macintosh", encoding); obj.Add("x-mac-roman", encoding); Encoding encoding2 = GetEncoding("x-mac-cyrillic"); obj.Add("x-mac-cyrillic", encoding2); obj.Add("x-mac-ukrainian", encoding2); Encoding encoding3 = GetEncoding("cp866"); obj.Add("866", encoding3); obj.Add("cp866", encoding3); obj.Add("csibm866", encoding3); obj.Add("ibm866", encoding3); obj.Add("csisolatin2", Latin2); obj.Add("iso-8859-2", Latin2); obj.Add("iso-ir-101", Latin2); obj.Add("iso8859-2", Latin2); obj.Add("iso88592", Latin2); obj.Add("iso_8859-2", Latin2); obj.Add("iso_8859-2:1987", Latin2); obj.Add("l2", Latin2); obj.Add("latin2", Latin2); obj.Add("csisolatin3", Latin3); obj.Add("iso-8859-3", Latin3); obj.Add("iso-ir-109", Latin3); obj.Add("iso8859-3", Latin3); obj.Add("iso88593", Latin3); obj.Add("iso_8859-3", Latin3); obj.Add("iso_8859-3:1988", Latin3); obj.Add("l3", Latin3); obj.Add("latin3", Latin3); obj.Add("csisolatin4", Latin4); obj.Add("iso-8859-4", Latin4); obj.Add("iso-ir-110", Latin4); obj.Add("iso8859-4", Latin4); obj.Add("iso88594", Latin4); obj.Add("iso_8859-4", Latin4); obj.Add("iso_8859-4:1988", Latin4); obj.Add("l4", Latin4); obj.Add("latin4", Latin4); obj.Add("csisolatincyrillic", Latin5); obj.Add("cyrillic", Latin5); obj.Add("iso-8859-5", Latin5); obj.Add("iso-ir-144", Latin5); obj.Add("iso8859-5", Latin5); obj.Add("iso88595", Latin5); obj.Add("iso_8859-5", Latin5); obj.Add("iso_8859-5:1988", Latin5); Encoding encoding4 = GetEncoding("iso-8859-6"); obj.Add("arabic", encoding4); obj.Add("asmo-708", encoding4); obj.Add("csiso88596e", encoding4); obj.Add("csiso88596i", encoding4); obj.Add("csisolatinarabic", encoding4); obj.Add("ecma-114", encoding4); obj.Add("iso-8859-6", encoding4); obj.Add("iso-8859-6-e", encoding4); obj.Add("iso-8859-6-i", encoding4); obj.Add("iso-ir-127", encoding4); obj.Add("iso8859-6", encoding4); obj.Add("iso88596", encoding4); obj.Add("iso_8859-6", encoding4); obj.Add("iso_8859-6:1987", encoding4); Encoding encoding5 = GetEncoding("iso-8859-7"); obj.Add("csisolatingreek", encoding5); obj.Add("ecma-118", encoding5); obj.Add("elot_928", encoding5); obj.Add("greek", encoding5); obj.Add("greek8", encoding5); obj.Add("iso-8859-7", encoding5); obj.Add("iso-ir-126", encoding5); obj.Add("iso8859-7", encoding5); obj.Add("iso88597", encoding5); obj.Add("iso_8859-7", encoding5); obj.Add("iso_8859-7:1987", encoding5); obj.Add("sun_eu_greek", encoding5); Encoding encoding6 = GetEncoding("iso-8859-8"); obj.Add("csiso88598e", encoding6); obj.Add("csisolatinhebrew", encoding6); obj.Add("hebrew", encoding6); obj.Add("iso-8859-8", encoding6); obj.Add("iso-8859-8-e", encoding6); obj.Add("iso-ir-138", encoding6); obj.Add("iso8859-8", encoding6); obj.Add("iso88598", encoding6); obj.Add("iso_8859-8", encoding6); obj.Add("iso_8859-8:1988", encoding6); obj.Add("visual", encoding6); Encoding encoding7 = GetEncoding("iso-8859-8-i"); obj.Add("csiso88598i", encoding7); obj.Add("iso-8859-8-i", encoding7); obj.Add("logical", encoding7); Encoding encoding8 = GetEncoding("iso-8859-13"); obj.Add("iso-8859-13", encoding8); obj.Add("iso8859-13", encoding8); obj.Add("iso885913", encoding8); Encoding encoding9 = GetEncoding("iso-8859-15"); obj.Add("csisolatin9", encoding9); obj.Add("iso-8859-15", encoding9); obj.Add("iso8859-15", encoding9); obj.Add("iso885915", encoding9); obj.Add("iso_8859-15", encoding9); obj.Add("l9", encoding9); Encoding encoding10 = GetEncoding("koi8-r"); obj.Add("cskoi8r", encoding10); obj.Add("koi", encoding10); obj.Add("koi8", encoding10); obj.Add("koi8-r", encoding10); obj.Add("koi8_r", encoding10); obj.Add("koi8-u", GetEncoding("koi8-u")); Encoding encoding11 = GetEncoding("GB18030", GetEncoding("x-cp20936")); obj.Add("chinese", encoding11); obj.Add("csgb2312", encoding11); obj.Add("csiso58gb231280", encoding11); obj.Add("gb2312", encoding11); obj.Add("gb_2312", encoding11); obj.Add("gb_2312-80", encoding11); obj.Add("gbk", encoding11); obj.Add("iso-ir-58", encoding11); obj.Add("x-gbk", encoding11); obj.Add("hz-gb-2312", GetEncoding("hz-gb-2312")); obj.Add("gb18030", Gb18030); Encoding encoding12 = GetEncoding("x-cp50227"); obj.Add("x-cp50227", encoding12); obj.Add("iso-22-cn", encoding12); obj.Add("big5", Big5); obj.Add("big5-hkscs", Big5); obj.Add("cn-big5", Big5); obj.Add("csbig5", Big5); obj.Add("x-x-big5", Big5); Encoding encoding13 = GetEncoding("iso-2022-jp"); obj.Add("csiso2022jp", encoding13); obj.Add("iso-2022-jp", encoding13); Encoding encoding14 = GetEncoding("iso-2022-kr"); obj.Add("csiso2022kr", encoding14); obj.Add("iso-2022-kr", encoding14); Encoding encoding15 = GetEncoding("iso-2022-cn"); obj.Add("iso-2022-cn", encoding15); obj.Add("iso-2022-cn-ext", encoding15); obj.Add("shift_jis", GetEncoding("shift_jis")); Encoding encoding16 = GetEncoding("euc-jp"); obj.Add("euc-jp", encoding16); Encoding encoding17 = GetEncoding("euc-kr"); obj.Add("euc-kr", encoding17); return obj; } } public readonly struct TextPosition : IEquatable, IComparable { public static readonly TextPosition Empty; private readonly ushort _line; private readonly ushort _column; private readonly int _position; public int Line => _line; public int Column => _column; public int Position => _position; public int Index => _position - 1; public TextPosition(ushort line, ushort column, int position) { _line = line; _column = column; _position = position; } public TextPosition Shift(int columns) { return new TextPosition(_line, (ushort)(_column + columns), _position + columns); } public TextPosition After(char chr) { ushort num = _line; ushort num2 = _column; if (chr == '\n') { num++; num2 = 0; } return new TextPosition(num, ++num2, _position + 1); } public TextPosition After(string str) { ushort num = _line; ushort num2 = _column; for (int i = 0; i < str.Length; i++) { if (str[i] == '\n') { num++; num2 = 0; } num2++; } return new TextPosition(num, num2, _position + str.Length); } public override string ToString() { return $"Ln {_line}, Col {_column}, Pos {_position}"; } public override int GetHashCode() { return _position ^ ((_line | _column) + _line); } public override bool Equals(object? obj) { if (obj is TextPosition other) { return Equals(other); } return false; } public bool Equals(TextPosition other) { if (_position == other._position && _column == other._column) { return _line == other._line; } return false; } public static bool operator >(TextPosition a, TextPosition b) { return a._position > b._position; } public static bool operator <(TextPosition a, TextPosition b) { return a._position < b._position; } public int CompareTo(TextPosition other) { if (!Equals(other)) { if (!(this > other)) { return -1; } return 1; } return 0; } } [DebuggerStepThrough] public readonly struct TextRange : IEquatable, IComparable { private readonly TextPosition _start; private readonly TextPosition _end; public TextPosition Start => _start; public TextPosition End => _end; public TextRange(TextPosition start, TextPosition end) { _start = start; _end = end; } public override string ToString() { return $"({_start}) -- ({_end})"; } public override int GetHashCode() { return _end.GetHashCode() ^ _start.GetHashCode(); } public override bool Equals(object? obj) { if (obj is TextRange other) { return Equals(other); } return false; } public bool Equals(TextRange other) { if (_start.Equals(other._start)) { return _end.Equals(other._end); } return false; } public static bool operator >(TextRange a, TextRange b) { return a._start > b._end; } public static bool operator <(TextRange a, TextRange b) { return a._end < b._start; } public int CompareTo(TextRange other) { if (this > other) { return 1; } if (other > this) { return -1; } return 0; } } public sealed class TextSource : ITextSource, IReadOnlyTextSource, IDisposable { private readonly WritableTextSource _writableSource; private readonly IReadOnlyTextSource _readOnlyTextSource; public string Text => _readOnlyTextSource.Text; public int Length => _readOnlyTextSource.Length; public Encoding CurrentEncoding { get { return _readOnlyTextSource.CurrentEncoding; } set { if (_writableSource != null) { _writableSource.CurrentEncoding = value; } } } public int Index { get { return _readOnlyTextSource.Index; } set { _readOnlyTextSource.Index = value; } } public char this[int index] => _readOnlyTextSource[index]; public TextSource(string source) { _writableSource = new WritableTextSource(source); _readOnlyTextSource = _writableSource; } public TextSource(Stream baseStream, Encoding encoding = null) { _writableSource = new WritableTextSource(baseStream, encoding); _readOnlyTextSource = _writableSource; } public TextSource(ReadOnlyMemoryTextSource source) { _writableSource = null; _readOnlyTextSource = source; } public TextSource(CharArrayTextSource source) { _writableSource = null; _readOnlyTextSource = source; } public TextSource(StringTextSource source) { _writableSource = null; _readOnlyTextSource = source; } public char ReadCharacter() { return _readOnlyTextSource.ReadCharacter(); } public string ReadCharacters(int characters) { return _readOnlyTextSource.ReadCharacters(characters); } public StringOrMemory ReadMemory(int characters) { return _readOnlyTextSource.ReadMemory(characters); } public Task PrefetchAsync(int length, CancellationToken cancellationToken) { return _readOnlyTextSource.PrefetchAsync(length, cancellationToken); } public Task PrefetchAllAsync(CancellationToken cancellationToken) { return _readOnlyTextSource.PrefetchAllAsync(cancellationToken); } public bool TryGetContentLength(out int length) { return _readOnlyTextSource.TryGetContentLength(out length); } public void InsertText(string content) { if (_writableSource == null) { throw new InvalidOperationException("Cannot insert text into a read-only text source."); } _writableSource.InsertText(content); } public void Dispose() { _readOnlyTextSource.Dispose(); } public IReadOnlyTextSource GetUnderlyingTextSource() { return _readOnlyTextSource; } } public class TextView { private readonly TextSource _source; private readonly TextRange _range; public TextRange Range => _range; public string Text { get { int num = Math.Max(_range.Start.Position - 1, 0); int num2 = _range.End.Position + 1 - _range.Start.Position; string text = _source.Text; if (num + num2 > text.Length) { num2 = text.Length - num; } return text.Substring(num, num2); } } public TextView(TextSource source, TextRange range) { _source = source; _range = range; } } internal sealed class WritableTextSource : ITextSource, IReadOnlyTextSource, IDisposable { private enum EncodingConfidence : byte { Tentative, Certain, Irrelevant } private const int BufferSize = 4096; private readonly Stream _baseStream; private readonly MemoryStream _raw; private readonly byte[] _buffer; private readonly char[] _chars; private StringBuilder _content; private EncodingConfidence _confidence; private bool _finished; private Encoding _encoding; private Decoder _decoder; private int _index; [MemberNotNull("_content")] public string Text { [MemberNotNull("_content")] get { return _content.ToString(); } } public char this[int index] => Replace(_content[index]); public int Length => _content.Length; public Encoding CurrentEncoding { get { return _encoding; } set { if (_confidence != EncodingConfidence.Tentative) { return; } if (_encoding.IsUnicode()) { _confidence = EncodingConfidence.Certain; return; } if (value.IsUnicode()) { value = TextEncoding.Utf8; } if (value == _encoding) { _confidence = EncodingConfidence.Certain; return; } _encoding = value; _decoder = value.GetDecoder(); byte[] array = _raw.ToArray(); char[] array2 = new char[_encoding.GetMaxCharCount(array.Length)]; int chars = _decoder.GetChars(array, 0, array.Length, array2, 0); string text = new string(array2, 0, chars); int num = Math.Min(_index, text.Length); if (text.Substring(0, num).Is(_content.ToString(0, num))) { _confidence = EncodingConfidence.Certain; _content.Remove(num, _content.Length - num); _content.Append(text.Substring(num)); return; } _index = 0; _content.Clear().Append(text); throw new NotSupportedException(); } } public int Index { get { return _index; } set { _index = value; } } private WritableTextSource(Encoding encoding, bool allocateBuffers) { if (allocateBuffers) { _buffer = new byte[4096]; _chars = new char[4097]; } _raw = new MemoryStream(); _index = 0; _encoding = encoding ?? TextEncoding.Utf8; _decoder = _encoding.GetDecoder(); } public WritableTextSource(string source) : this(null, TextEncoding.Utf8) { _finished = true; _content.Append(source); _confidence = EncodingConfidence.Irrelevant; } public WritableTextSource(Stream baseStream, Encoding encoding = null) : this(encoding, baseStream != null) { _baseStream = baseStream; _content = StringBuilderPool.Obtain(); _confidence = EncodingConfidence.Tentative; } public void Dispose() { if (_content != null) { _raw.Dispose(); _content.Clear().ReturnToPool(); _content = null; } } public char ReadCharacter() { if (_index < _content.Length) { return Replace(_content[_index++]); } ExpandBuffer(4096L); int num = _index++; if (num >= _content.Length) { return '\uffff'; } return Replace(_content[num]); } public string ReadCharacters(int characters) { int index = _index; if (index + characters <= _content.Length) { _index += characters; return _content.ToString(index, characters); } ExpandBuffer(Math.Max(4096, characters)); _index += characters; characters = Math.Min(characters, _content.Length - index); return _content.ToString(index, characters); } public StringOrMemory ReadMemory(int characters) { return new StringOrMemory(ReadCharacters(characters)); } public Task PrefetchAsync(int length, CancellationToken cancellationToken) { return ExpandBufferAsync(length, cancellationToken); } public async Task PrefetchAllAsync(CancellationToken cancellationToken) { if (_baseStream != null && _content.Length == 0) { await DetectByteOrderMarkAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } while (!_finished) { await ReadIntoBufferAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } } public bool TryGetContentLength(out int length) { length = 0; return false; } public void InsertText(string content) { if (_index >= 0 && _index < _content.Length) { _content.Insert(_index, content); } else { _content.Append(content); } _index += content.Length; } private static char Replace(char c) { if (c != '\uffff') { return c; } return '\ufffd'; } private async Task DetectByteOrderMarkAsync(CancellationToken cancellationToken) { int num = await _baseStream.ReadAsync(_buffer, 0, 4096).ConfigureAwait(continueOnCapturedContext: false); int num2 = 0; if (num > 2 && _buffer[0] == 239 && _buffer[1] == 187 && _buffer[2] == 191) { _encoding = TextEncoding.Utf8; num2 = 3; } else if (num > 3 && _buffer[0] == byte.MaxValue && _buffer[1] == 254 && _buffer[2] == 0 && _buffer[3] == 0) { _encoding = TextEncoding.Utf32Le; num2 = 4; } else if (num > 3 && _buffer[0] == 0 && _buffer[1] == 0 && _buffer[2] == 254 && _buffer[3] == byte.MaxValue) { _encoding = TextEncoding.Utf32Be; num2 = 4; } else if (num > 1 && _buffer[0] == 254 && _buffer[1] == byte.MaxValue) { _encoding = TextEncoding.Utf16Be; num2 = 2; } else if (num > 1 && _buffer[0] == byte.MaxValue && _buffer[1] == 254) { _encoding = TextEncoding.Utf16Le; num2 = 2; } else if (num > 3 && _buffer[0] == 132 && _buffer[1] == 49 && _buffer[2] == 149 && _buffer[3] == 51) { _encoding = TextEncoding.Gb18030; num2 = 4; } if (num2 > 0) { num -= num2; Array.Copy(_buffer, num2, _buffer, 0, num); _decoder = _encoding.GetDecoder(); _confidence = EncodingConfidence.Certain; } AppendContentFromBuffer(num); } private async Task ExpandBufferAsync(long size, CancellationToken cancellationToken) { if (!_finished && _content.Length == 0) { await DetectByteOrderMarkAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } while (!_finished && size + _index > _content.Length) { await ReadIntoBufferAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } } private async Task ReadIntoBufferAsync(CancellationToken cancellationToken) { AppendContentFromBuffer(await _baseStream.ReadAsync(_buffer, 0, 4096, cancellationToken).ConfigureAwait(continueOnCapturedContext: false)); } private void ExpandBuffer(long size) { if (!_finished && _content.Length == 0) { DetectByteOrderMarkAsync(CancellationToken.None).Wait(); } while (!_finished && size + _index > _content.Length) { ReadIntoBuffer(); } } private void ReadIntoBuffer() { int size = _baseStream.Read(_buffer, 0, 4096); AppendContentFromBuffer(size); } private void AppendContentFromBuffer(int size) { _finished = size == 0; int chars = _decoder.GetChars(_buffer, 0, size, _chars, 0); if (_confidence != EncodingConfidence.Certain) { _raw.Write(_buffer, 0, size); } _content.Append(_chars, 0, chars); } } public static class XmlExtensions { public static bool IsPubidChar(this char c) { if (!c.IsAlphanumericAscii() && c != '-' && c != '\'' && c != '+' && c != ',' && c != '.' && c != '/' && c != ':' && c != '?' && c != '=' && c != '!' && c != '*' && c != '#' && c != '@' && c != '$' && c != '_' && c != '(' && c != ')' && c != ';' && c != '%') { return c.IsSpaceCharacter(); } return true; } public static bool IsXmlNameStart(this char c) { if (!c.IsLetter() && c != ':' && c != '_' && !c.IsInRange(192, 214) && !c.IsInRange(216, 246) && !c.IsInRange(248, 767) && !c.IsInRange(880, 893) && !c.IsInRange(895, 8191) && !c.IsInRange(8204, 8205) && !c.IsInRange(8304, 8591) && !c.IsInRange(11264, 12271) && !c.IsInRange(12289, 55295) && !c.IsInRange(63744, 64975) && !c.IsInRange(65008, 65533)) { return c.IsInRange(65536, 983039); } return true; } public static bool IsXmlName(this char c) { if (!c.IsXmlNameStart() && !c.IsDigit() && c != '-' && c != '.' && c != '·' && !c.IsInRange(768, 879)) { return c.IsInRange(8255, 8256); } return true; } public static bool IsXmlName(this string str) { return new StringOrMemory(str).IsXmlName(); } public static bool IsXmlName(this StringOrMemory str) { if (str.Length > 0 && str[0].IsXmlNameStart()) { for (int i = 1; i < str.Length; i++) { if (!str[i].IsXmlName()) { return false; } } return true; } return false; } public static bool IsQualifiedName(this string str) { return new StringOrMemory(str).IsQualifiedName(); } public static bool IsQualifiedName(this StringOrMemory str) { int num = str.Memory.Span.IndexOf(':'); if (num == -1) { return str.IsXmlName(); } if (num > 0 && str[0].IsXmlNameStart()) { for (int i = 1; i < num; i++) { if (!str[i].IsXmlName()) { return false; } } num++; } if (str.Length > num && str[num++].IsXmlNameStart()) { for (int j = num; j < str.Length; j++) { if (str[j] == ':' || !str[j].IsXmlName()) { return false; } } return true; } return false; } public static bool IsXmlChar(this char chr) { if (chr != '\t' && chr != '\n' && chr != '\r' && (chr < ' ' || chr > '\ud7ff')) { if (chr >= '\ue000') { return chr <= '\ufffd'; } return false; } return true; } public static bool IsValidAsCharRef(this int chr) { if (chr != 9 && chr != 10 && chr != 13 && (chr < 32 || chr > 55295) && (chr < 57344 || chr > 65533)) { if (chr >= 65536) { return chr <= 1114111; } return false; } return true; } } } namespace AngleSharp.Svg { internal sealed class SvgElementFactory : IElementFactory { private delegate SvgElement Creator(Document owner, string? prefix); private readonly Dictionary creators = new Dictionary(StringComparer.OrdinalIgnoreCase) { { TagNames.Svg, (Document document, string? prefix) => new SvgSvgElement(document, prefix) }, { TagNames.Circle, (Document document, string? prefix) => new SvgCircleElement(document, prefix) }, { TagNames.Desc, (Document document, string? prefix) => new SvgDescElement(document, prefix) }, { TagNames.ForeignObject, (Document document, string? prefix) => new SvgForeignObjectElement(document, prefix) }, { TagNames.Title, (Document document, string? prefix) => new SvgTitleElement(document, prefix) } }; internal static readonly SvgElementFactory Instance = new SvgElementFactory(); public SvgElement Create(Document document, string localName, string? prefix = null, NodeFlags flags = NodeFlags.None) { if (creators.TryGetValue(localName, out Creator value)) { return value(document, prefix); } return new SvgElement(document, localName, prefix, flags); } } } namespace AngleSharp.Svg.Dom { internal sealed class SvgCircleElement : SvgElement, ISvgCircleElement, ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { public SvgCircleElement(Document owner, string? prefix = null) : base(owner, TagNames.Circle, prefix) { } } internal sealed class SvgDescElement : SvgElement, ISvgDescriptionElement, ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { public SvgDescElement(Document owner, string? prefix = null) : base(owner, TagNames.Desc, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.HtmlTip) { } } public class SvgElement : Element, ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IConstructableSvgElement, IConstructableElement, IConstructableNode { public SvgElement(Document owner, string name, string? prefix = null, NodeFlags flags = NodeFlags.None) : base(owner, name, prefix, NamespaceNames.SvgUri, flags | NodeFlags.SvgMember) { } public override IElement ParseSubtree(string html) { return this.ParseHtmlSubtree(html); } public override Node Clone(Document owner, bool deep) { SvgElement svgElement = base.Context.GetFactory>().Create(owner, base.LocalName, base.Prefix); CloneElement(svgElement, owner, deep); return svgElement; } } internal sealed class SvgForeignObjectElement : SvgElement, ISvgForeignObjectElement, ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { public SvgForeignObjectElement(Document owner, string? prefix = null) : base(owner, TagNames.ForeignObject, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.HtmlTip) { } } internal sealed class SvgSvgElement : SvgElement, ISvgSvgElement, ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { public SvgSvgElement(Document owner, string? prefix = null) : base(owner, TagNames.Svg, prefix) { } } internal sealed class SvgTitleElement : SvgElement, ISvgTitleElement, ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { public SvgTitleElement(Document owner, string? prefix = null) : base(owner, TagNames.Title, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.HtmlTip) { } } [DomName("SVGCircleElement")] public interface ISvgCircleElement : ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { } [DomName("SVGDescElement")] public interface ISvgDescriptionElement : ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { } [DomName("SVGElement")] public interface ISvgElement : IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { } [DomName("SVGForeignObjectElement")] public interface ISvgForeignObjectElement : ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { } [DomName("SVGSVGElement")] public interface ISvgSvgElement : ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { } [DomName("SVGTitleElement")] public interface ISvgTitleElement : ISvgElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { } } namespace AngleSharp.Scripting { public interface IScriptingService { bool SupportsType(string mimeType); Task EvaluateScriptAsync(IResponse response, ScriptOptions options, CancellationToken cancel); } public sealed class ScriptOptions { public IEventLoop EventLoop { get; } public IDocument Document { get; } public IHtmlScriptElement? Element { get; set; } public Encoding? Encoding { get; set; } public ScriptOptions(IDocument document, IEventLoop loop) { Document = document; EventLoop = loop; } } } namespace AngleSharp.Media { public interface IAudioInfo : IMediaInfo, IResourceInfo { } public interface IImageInfo : IResourceInfo { int Width { get; } int Height { get; } } public interface IMediaInfo : IResourceInfo { IMediaController Controller { get; } } public interface IObjectInfo : IResourceInfo { int Width { get; } int Height { get; } } public interface IResourceInfo { Url Source { get; set; } } public interface IResourceService where TResource : IResourceInfo { bool SupportsType(string mimeType); Task CreateAsync(IResponse response, CancellationToken cancel); } public interface IVideoInfo : IMediaInfo, IResourceInfo { int Width { get; } int Height { get; } } } namespace AngleSharp.Media.Dom { [DomName("AudioTrack")] public interface IAudioTrack { [DomName("id")] string? Id { get; } [DomName("kind")] string? Kind { get; } [DomName("label")] string? Label { get; } [DomName("language")] string? Language { get; } [DomName("enabled")] bool IsEnabled { get; set; } } [DomName("AudioTrackList")] public interface IAudioTrackList : IEventTarget, IEnumerable, IEnumerable { [DomName("length")] int Length { get; } [DomAccessor(Accessors.Getter)] IAudioTrack this[int index] { get; } [DomName("onchange")] event DomEventHandler Changed; [DomName("onaddtrack")] event DomEventHandler TrackAdded; [DomName("onremovetrack")] event DomEventHandler TrackRemoved; [DomName("getTrackById")] IAudioTrack GetTrackById(string id); } [DomName("CanvasRenderingContext2D")] public interface ICanvasRenderingContext2D : IRenderingContext { [DomName("canvas")] IHtmlCanvasElement Canvas { get; } [DomName("width")] int Width { get; set; } [DomName("height")] int Height { get; set; } [DomName("save")] void SaveState(); [DomName("restore")] void RestoreState(); } [DomName("MediaController")] public interface IMediaController { [DomName("buffered")] ITimeRanges? BufferedTime { get; } [DomName("seekable")] ITimeRanges? SeekableTime { get; } [DomName("played")] ITimeRanges? PlayedTime { get; } [DomName("duration")] double Duration { get; } [DomName("currentTime")] double CurrentTime { get; set; } [DomName("defaultPlaybackRate")] double DefaultPlaybackRate { get; set; } [DomName("playbackRate")] double PlaybackRate { get; set; } [DomName("volume")] double Volume { get; set; } [DomName("muted")] bool IsMuted { get; set; } [DomName("paused")] bool IsPaused { get; } [DomName("readyState")] MediaReadyState ReadyState { get; } [DomName("playbackState")] MediaControllerPlaybackState PlaybackState { get; } [DomName("onemptied")] event DomEventHandler Emptied; [DomName("onloadedmetadata")] event DomEventHandler LoadedMetadata; [DomName("onloadeddata")] event DomEventHandler LoadedData; [DomName("oncanplay")] event DomEventHandler CanPlay; [DomName("oncanplaythrough")] event DomEventHandler CanPlayThrough; [DomName("onended")] event DomEventHandler Ended; [DomName("onwaiting")] event DomEventHandler Waiting; [DomName("ondurationchange")] event DomEventHandler DurationChanged; [DomName("ontimeupdate")] event DomEventHandler TimeUpdated; [DomName("onpause")] event DomEventHandler Paused; [DomName("onplay")] event DomEventHandler Played; [DomName("onplaying")] event DomEventHandler Playing; [DomName("onratechange")] event DomEventHandler RateChanged; [DomName("onvolumechange")] event DomEventHandler VolumeChanged; [DomName("play")] void Play(); [DomName("pause")] void Pause(); } [DomName("MediaError")] public interface IMediaError { [DomName("code")] MediaErrorCode Code { get; } } [DomName("RenderingContext")] public interface IRenderingContext { string ContextId { get; } bool IsFixed { get; } IHtmlCanvasElement Host { get; } byte[] ToImage(string type); } public interface IRenderingService { bool IsSupportingContext(string contextId); IRenderingContext CreateContext(IHtmlCanvasElement host, string contextId); } [DomName("TextTrack")] public interface ITextTrack : IEventTarget { [DomName("kind")] string? Kind { get; } [DomName("label")] string? Label { get; } [DomName("language")] string? Language { get; } [DomName("mode")] TextTrackMode Mode { get; set; } [DomName("cues")] ITextTrackCueList Cues { get; } [DomName("activeCues")] ITextTrackCueList ActiveCues { get; } [DomName("oncuechange")] event DomEventHandler CueChanged; [DomName("addCue")] void Add(ITextTrackCue cue); [DomName("removeCue")] void Remove(ITextTrackCue cue); } [DomName("TextTrackCue")] public interface ITextTrackCue : IEventTarget { [DomName("id")] string Id { get; set; } [DomName("track")] ITextTrack Track { get; } [DomName("startTime")] double StartTime { get; set; } [DomName("endTime")] double EndTime { get; set; } [DomName("pauseOnExit")] bool IsPausedOnExit { get; set; } [DomName("vertical")] string Vertical { get; set; } [DomName("snapToLines")] bool IsSnappedToLines { get; set; } [DomName("line")] int Line { get; set; } [DomName("position")] int Position { get; set; } [DomName("size")] int Size { get; set; } [DomName("align")] string Alignment { get; set; } [DomName("text")] string Text { get; set; } [DomName("onenter")] DomEventHandler Entered { get; set; } [DomName("onexit")] DomEventHandler Exited { get; set; } [DomName("getCueAsHTML")] IDocumentFragment AsHtml(); } [DomName("TextTrackCueList")] public interface ITextTrackCueList : IEnumerable, IEnumerable { [DomName("length")] int Length { get; } ITextTrackCue this[int index] { get; } [DomName("getCueById")] IVideoTrack GetCueById(string id); } [DomName("TextTrackList")] public interface ITextTrackList : IEventTarget, IEnumerable, IEnumerable { [DomName("length")] int Length { get; } [DomAccessor(Accessors.Getter)] ITextTrack this[int index] { get; } [DomName("onaddtrack")] event DomEventHandler TrackAdded; [DomName("onremovetrack")] event DomEventHandler TrackRemoved; } [DomName("TimeRanges")] public interface ITimeRanges { [DomName("length")] int Length { get; } [DomName("start")] double Start(int index); [DomName("end")] double End(int index); } [DomName("VideoTrack")] public interface IVideoTrack { [DomName("id")] string? Id { get; } [DomName("kind")] string? Kind { get; } [DomName("label")] string? Label { get; } [DomName("language")] string? Language { get; } [DomName("selected")] bool IsSelected { get; set; } } [DomName("VideoTrackList")] public interface IVideoTrackList : IEventTarget, IEnumerable, IEnumerable { [DomName("length")] int Length { get; } [DomName("selectedIndex")] int SelectedIndex { get; } [DomAccessor(Accessors.Getter)] IVideoTrack this[int index] { get; } [DomName("onchange")] event DomEventHandler Changed; [DomName("onaddtrack")] event DomEventHandler TrackAdded; [DomName("onremovetrack")] event DomEventHandler TrackRemoved; [DomName("getTrackById")] IVideoTrack GetTrackById(string id); } [DomName("MediaControllerPlaybackState")] public enum MediaControllerPlaybackState : byte { [DomName("waiting")] Waiting, [DomName("playing")] Playing, [DomName("ended")] Ended } [DomName("MediaError")] public enum MediaErrorCode : byte { [DomName("MEDIA_ERR_ABORTED")] Aborted = 1, [DomName("MEDIA_ERR_NETWORK")] Network, [DomName("MEDIA_ERR_DECODE")] Decode, [DomName("MEDIA_ERR_SRC_NOT_SUPPORTED")] SourceNotSupported } [DomName("HTMLMediaElement")] public enum MediaNetworkState : byte { [DomName("NETWORK_EMPTY")] Empty, [DomName("NETWORK_IDLE")] Idle, [DomName("NETWORK_LOADING")] Loading, [DomName("NETWORK_NO_SOURCE")] NoSource } [DomName("HTMLMediaElement")] public enum MediaReadyState : byte { [DomName("HAVE_NOTHING")] Nothing, [DomName("HAVE_METADATA")] Metadata, [DomName("HAVE_CURRENT_DATA")] CurrentData, [DomName("HAVE_FUTURE_DATA")] FutureData, [DomName("HAVE_ENOUGH_DATA")] EnoughData } [DomName("TextTrackMode")] public enum TextTrackMode : byte { [DomName("disabled")] Disabled, [DomName("hidden")] Hidden, [DomName("showing")] Showing } } namespace AngleSharp.Mathml { internal sealed class MathElementFactory : IElementFactory { private delegate MathElement Creator(Document owner, string? prefix); private readonly Dictionary creators = new Dictionary(StringComparer.OrdinalIgnoreCase) { { TagNames.Mn, (Document document, string? prefix) => new MathNumberElement(document, prefix) }, { TagNames.Mo, (Document document, string? prefix) => new MathOperatorElement(document, prefix) }, { TagNames.Mi, (Document document, string? prefix) => new MathIdentifierElement(document, prefix) }, { TagNames.Ms, (Document document, string? prefix) => new MathStringElement(document, prefix) }, { TagNames.Mtext, (Document document, string? prefix) => new MathTextElement(document, prefix) }, { TagNames.AnnotationXml, (Document document, string? prefix) => new MathAnnotationXmlElement(document, prefix) } }; internal static readonly MathElementFactory Instance = new MathElementFactory(); public MathElement Create(Document document, string localName, string? prefix = null, NodeFlags flags = NodeFlags.None) { if (creators.TryGetValue(localName, out Creator value)) { return value(document, prefix); } return new MathElement(document, localName, prefix, flags); } } } namespace AngleSharp.Mathml.Dom { internal sealed class MathAnnotationXmlElement : MathElement { public MathAnnotationXmlElement(Document owner, string? prefix = null) : base(owner, TagNames.AnnotationXml, prefix, NodeFlags.Special | NodeFlags.Scoped) { } } public class MathElement : Element, IConstructableMathElement, IConstructableElement, IConstructableNode { public MathElement(Document owner, string name, string? prefix = null, NodeFlags flags = NodeFlags.None) : base(owner, name, prefix, NamespaceNames.MathMlUri, flags | NodeFlags.MathMember) { } public override IElement ParseSubtree(string html) { return this.ParseHtmlSubtree(html); } public override Node Clone(Document owner, bool deep) { MathElement mathElement = base.Context.GetFactory>().Create(owner, base.LocalName, base.Prefix); CloneElement(mathElement, owner, deep); return mathElement; } } internal sealed class MathIdentifierElement : MathElement { public MathIdentifierElement(Document owner, string? prefix = null) : base(owner, TagNames.Mi, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.MathTip) { } } internal sealed class MathNumberElement : MathElement { public MathNumberElement(Document owner, string? prefix = null) : base(owner, TagNames.Mn, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.MathTip) { } } internal sealed class MathOperatorElement : MathElement { public MathOperatorElement(Document owner, string? prefix = null) : base(owner, TagNames.Mo, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.MathTip) { } } internal sealed class MathStringElement : MathElement { public MathStringElement(Document owner, string? prefix = null) : base(owner, TagNames.Ms, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.MathTip) { } } internal sealed class MathTextElement : MathElement { public MathTextElement(Document owner, string? prefix = null) : base(owner, TagNames.Mtext, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.MathTip) { } } } namespace AngleSharp.Io { public abstract class BaseLoader : ILoader { private readonly IBrowsingContext _context; private readonly Predicate _filter; private readonly List _downloads; public int MaxRedirects { get; protected set; } public BaseLoader(IBrowsingContext context, Predicate? filter) { _context = context; _filter = filter ?? ((Predicate)((Request _) => true)); _downloads = new List(); MaxRedirects = 50; } protected virtual void Add(IDownload download) { lock (this) { _downloads.Add(download); } } protected virtual void Remove(IDownload download) { lock (this) { _downloads.Remove(download); } } protected virtual string GetCookie(Url url) { return _context.GetCookie(url); } protected virtual void SetCookie(Url url, string value) { _context.SetCookie(url, value); } protected virtual IDownload DownloadAsync(Request request, INode? originator) { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); if (_filter(request)) { Task task = LoadAsync(request, cancellationTokenSource.Token); Download download = new Download(task, cancellationTokenSource, request.Address, originator); Add(download); task.ContinueWith(delegate { Remove(download); }); return download; } return new Download(Task.FromResult(null), cancellationTokenSource, request.Address, originator); } public IEnumerable GetDownloads() { lock (this) { return _downloads.ToArray(); } } protected async Task LoadAsync(Request request, CancellationToken cancel) { IEnumerable requesters = _context.GetServices(); IResponse response = null; int redirectCount = 0; AppendCookieTo(request); do { if (response != null) { redirectCount++; ExtractCookieFrom(response); request = CreateNewRequest(request, response); AppendCookieTo(request); } foreach (IRequester item in requesters) { if (item.SupportsProtocol(request.Address.Scheme)) { _context.Fire(new RequestEvent(request, null)); response = await item.RequestAsync(request, cancel).ConfigureAwait(continueOnCapturedContext: false); _context.Fire(new RequestEvent(request, response)); break; } } } while (response != null && response.StatusCode.IsRedirected() && redirectCount < MaxRedirects); return response; } protected static Request CreateNewRequest(Request request, IResponse response) { HttpMethod method = request.Method; Stream stream = request.Content ?? Stream.Null; Dictionary dictionary = new Dictionary(request.Headers); string relativeAddress = response.Headers[HeaderNames.Location]; if (response.StatusCode == HttpStatusCode.Found || response.StatusCode == HttpStatusCode.SeeOther) { method = HttpMethod.Get; dictionary.Remove(HeaderNames.ContentType); stream = Stream.Null; } else if (stream.Length > 0) { stream.Position = 0L; } dictionary.Remove(HeaderNames.Cookie); return new Request { Address = new Url(request.Address, relativeAddress), Method = method, Content = stream, Headers = dictionary }; } private void AppendCookieTo(Request request) { string cookie = GetCookie(request.Address); if (cookie != null) { request.Headers[HeaderNames.Cookie] = cookie; } } private void ExtractCookieFrom(IResponse response) { string orDefault = response.Headers.GetOrDefault(HeaderNames.SetCookie, null); if (orDefault != null) { SetCookie(response.Address, orDefault); } } } public abstract class BaseRequester : EventTarget, IRequester, IEventTarget { public event DomEventHandler Requesting { add { AddEventListener(EventNames.Requesting, value); } remove { RemoveEventListener(EventNames.Requesting, value); } } public event DomEventHandler Requested { add { AddEventListener(EventNames.Requested, value); } remove { RemoveEventListener(EventNames.Requested, value); } } public async Task RequestAsync(Request request, CancellationToken cancel) { RequestEvent ev = new RequestEvent(request, null); InvokeEventListener(ev); IResponse response = await PerformRequestAsync(request, cancel).ConfigureAwait(continueOnCapturedContext: false); ev = new RequestEvent(request, response); InvokeEventListener(ev); return response; } public abstract bool SupportsProtocol(string protocol); protected abstract Task PerformRequestAsync(Request request, CancellationToken cancel); } public class CorsRequest { public ResourceRequest Request { get; } public CorsSetting Setting { get; set; } public OriginBehavior Behavior { get; set; } public IIntegrityProvider? Integrity { get; set; } public CorsRequest(ResourceRequest request) { Request = request; } } public enum CorsSetting : byte { None, Anonymous, UseCredentials } public class DefaultDocumentLoader : BaseLoader, IDocumentLoader, ILoader { public DefaultDocumentLoader(IBrowsingContext context, Predicate? filter = null) : base(context, filter) { } public virtual IDownload FetchAsync(DocumentRequest request) { Request request2 = new Request { Address = request.Target, Content = request.Body, Method = request.Method }; foreach (KeyValuePair header in request.Headers) { request2.Headers[header.Key] = header.Value; } return DownloadAsync(request2, request.Source); } } public sealed class DefaultHttpRequester : BaseRequester { private sealed class RequestState { private static MethodInfo? _serverString; private readonly CookieContainer _cookies; private readonly IDictionary _headers; private readonly HttpWebRequest _http; private readonly Request _request; private readonly byte[] _buffer; public RequestState(Request request, IDictionary headers, Action setup) { _cookies = new CookieContainer(); _headers = headers; _request = request; _http = (HttpWebRequest)WebRequest.Create(request.Address); _http.CookieContainer = _cookies; _http.Method = request.Method.ToString().ToUpperInvariant(); _buffer = new byte[4096]; SetHeaders(); SetCookies(); AllowCompression(); DisableAutoRedirect(); setup(_http); } public async Task RequestAsync(CancellationToken cancellationToken) { cancellationToken.Register(_http.Abort); if (_request.Method == HttpMethod.Post || _request.Method == HttpMethod.Put) { SendRequest(await _http.GetRequestStreamAsync().ConfigureAwait(continueOnCapturedContext: false)); } WebResponse webResponse; try { webResponse = await _http.GetResponseAsync().ConfigureAwait(continueOnCapturedContext: false); } catch (WebException ex) { webResponse = ex.Response; } RaiseConnectionLimit(_http); return GetResponse(webResponse as HttpWebResponse); } private void SendRequest(Stream target) { Stream content = _request.Content; while (content != null) { int num = content.Read(_buffer, 0, 4096); if (num != 0) { target.Write(_buffer, 0, num); continue; } break; } } [return: NotNullIfNotNull("response")] private DefaultResponse? GetResponse(HttpWebResponse? response) { if (response != null) { CookieCollection cookies = _cookies.GetCookies(_request.Address); Cookie[] array = _cookies.GetCookies(response.ResponseUri).OfType().Except(cookies.OfType()) .ToArray(); var enumerable = response.Headers.AllKeys.Select((string m) => new { Key = m, Value = response.Headers[m] }); DefaultResponse defaultResponse = new DefaultResponse { Content = response.GetResponseStream(), StatusCode = response.StatusCode, Address = Url.Convert(response.ResponseUri) }; foreach (var item in enumerable) { defaultResponse.Headers.Add(item.Key, item.Value); if (item.Key.Isi(HeaderNames.ContentEncoding)) { string value = item.Value; if ((value == null || value.Length != 0) && !(value == "gzip") && !(value == "deflate")) { throw new InvalidOperationException("The given server response is invalid. The encoding '" + item.Value + "' is not supported."); } } } if (array.Length != 0) { IEnumerable values = array.Select(Stringify); defaultResponse.Headers[HeaderNames.SetCookie] = string.Join(", ", values); } return defaultResponse; } return null; } private static string Stringify(Cookie cookie) { if ((object)_serverString == null) { MethodInfo[] methods = typeof(Cookie).GetMethods(); _serverString = methods.FirstOrDefault((MethodInfo m) => m.Name == "ToServerString") ?? methods.First((MethodInfo m) => m.Name == "ToString"); } return _serverString.Invoke(cookie, null).ToString(); } private void AddHeader(string key, string value) { if (key.Is(HeaderNames.Accept)) { _http.Accept = value; } else if (key.Is(HeaderNames.ContentType)) { _http.ContentType = value; } else if (key.Is(HeaderNames.Expect)) { _http.Expect = value; } else if (key.Is(HeaderNames.Date)) { _http.Date = DateTime.Parse(value, CultureInfo.InvariantCulture); } else if (key.Is(HeaderNames.Host)) { _http.Host = value; } else if (key.Is(HeaderNames.IfModifiedSince)) { _http.IfModifiedSince = DateTime.Parse(value, CultureInfo.InvariantCulture); } else if (key.Is(HeaderNames.Referer)) { _http.Referer = value; } else if (key.Is(HeaderNames.UserAgent)) { _http.UserAgent = value; } else if (!key.Is(HeaderNames.Connection) && !key.Is(HeaderNames.Range) && !key.Is(HeaderNames.ContentLength) && !key.Is(HeaderNames.TransferEncoding)) { _http.Headers[key] = value; } } private void SetCookies() { string orDefault = _request.Headers.GetOrDefault(HeaderNames.Cookie, string.Empty); _cookies.SetCookies(_http.RequestUri, orDefault.Replace(';', ',').Replace("$", "")); } private void SetHeaders() { foreach (KeyValuePair header in _headers) { AddHeader(header.Key, header.Value); } foreach (KeyValuePair header2 in _request.Headers) { if (!header2.Key.Is(HeaderNames.Cookie)) { AddHeader(header2.Key, header2.Value); } } } private void AllowCompression() { _http.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; } private void DisableAutoRedirect() { _http.AllowAutoRedirect = false; } } private const int BufferSize = 4096; private static readonly string? Version = typeof(DefaultHttpRequester).Assembly.GetCustomAttribute()?.Version; private static readonly string AgentName = "AngleSharp/" + Version; private TimeSpan _timeOut; private readonly Action _setup; private readonly Dictionary _headers; public IDictionary Headers => _headers; public TimeSpan Timeout { get { return _timeOut; } set { _timeOut = value; } } public DefaultHttpRequester(string? userAgent = null, Action? setup = null) { _timeOut = new TimeSpan(0, 0, 0, 45); _setup = setup ?? ((Action)delegate { }); _headers = new Dictionary { { HeaderNames.UserAgent, userAgent ?? AgentName }, { HeaderNames.AcceptEncoding, "gzip, deflate" } }; } public override bool SupportsProtocol(string protocol) { return protocol.IsOneOf(ProtocolNames.Http, ProtocolNames.Https); } protected override async Task PerformRequestAsync(Request request, CancellationToken cancellationToken) { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(_timeOut); RequestState requestState = new RequestState(request, _headers, _setup); using (cancellationToken.Register(cancellationTokenSource.Cancel)) { return await requestState.RequestAsync(cancellationTokenSource.Token).ConfigureAwait(continueOnCapturedContext: false); } } private static void RaiseConnectionLimit(HttpWebRequest http) { http.ServicePoint.ConnectionLimit = 1024; } } public class DefaultResourceLoader : BaseLoader, IResourceLoader, ILoader { public DefaultResourceLoader(IBrowsingContext context, Predicate? filter = null) : base(context, filter) { } public virtual IDownload FetchAsync(ResourceRequest request) { Request request2 = new Request { Address = request.Target, Content = Stream.Null, Method = HttpMethod.Get, Headers = new Dictionary { [HeaderNames.Referer] = request.Source?.Owner?.DocumentUri ?? string.Empty } }; string cookie = GetCookie(request.Target); if (cookie != null) { request2.Headers[HeaderNames.Cookie] = cookie; } return DownloadAsync(request2, request.Source); } } public sealed class DefaultResponse : IResponse, IDisposable { public HttpStatusCode StatusCode { get; set; } public Url Address { get; set; } public IDictionary Headers { get; set; } public Stream Content { get; set; } public DefaultResponse() { Headers = new Dictionary(StringComparer.OrdinalIgnoreCase); StatusCode = HttpStatusCode.Accepted; } void IDisposable.Dispose() { Content?.Dispose(); Headers.Clear(); } } public class DocumentRequest { public INode? Source { get; set; } public Url Target { get; } public string? Referer { get { return GetHeader(HeaderNames.Referer); } set { SetHeader(HeaderNames.Referer, value); } } public HttpMethod Method { get; set; } public Stream Body { get; set; } public string? MimeType { get { return GetHeader(HeaderNames.ContentType); } set { SetHeader(HeaderNames.ContentType, value); } } public Dictionary Headers { get; } public DocumentRequest(Url target) { Target = target ?? throw new ArgumentNullException("target"); Headers = new Dictionary(StringComparer.OrdinalIgnoreCase) { { HeaderNames.Accept, "text/html,application/xhtml+xml,application/xml" } }; Method = HttpMethod.Get; Body = Stream.Null; } public static DocumentRequest Get(Url target, INode? source = null, string? referer = null) { return new DocumentRequest(target) { Method = HttpMethod.Get, Referer = referer, Source = source }; } public static DocumentRequest Post(Url target, Stream body, string type, INode? source = null, string? referer = null) { return new DocumentRequest(target) { Method = HttpMethod.Post, Body = (body ?? throw new ArgumentNullException("body")), MimeType = (type ?? throw new ArgumentNullException("type")), Referer = referer, Source = source }; } public static DocumentRequest PostAsPlaintext(Url target, IDictionary fields) { FormDataSet formDataSet = new FormDataSet(); fields = fields ?? throw new ArgumentNullException("fields"); foreach (KeyValuePair field in fields) { formDataSet.Append(field.Key, field.Value, InputTypeNames.Text); } return Post(target, formDataSet.AsPlaintext(), MimeTypeNames.Plain); } public static DocumentRequest PostAsUrlencoded(Url target, IDictionary fields) { FormDataSet formDataSet = new FormDataSet(); fields = fields ?? throw new ArgumentNullException("fields"); foreach (KeyValuePair field in fields) { formDataSet.Append(field.Key, field.Value, InputTypeNames.Text); } return Post(target, formDataSet.AsUrlEncoded(), MimeTypeNames.UrlencodedForm); } public static DocumentRequest PostAsMultipart(Url target, FormDataSet form) { if (form == null) { throw new ArgumentNullException("form"); } return PostAsMultipart(target, form.AsMultipart(null), form.Boundary); } public static DocumentRequest PostAsMultipart(Url target, Stream formBody, string formBoundary) { if (formBody == null) { throw new ArgumentNullException("formBody"); } if (formBoundary == null) { throw new ArgumentNullException("formBoundary"); } string type = MimeTypeNames.MultipartForm + "; boundary=" + formBoundary; return Post(target, formBody, type); } private void SetHeader(string name, string value) { Headers[name] = value; } private string? GetHeader(string name) { Headers.TryGetValue(name, out string value); return value; } } internal sealed class Download : IDownload, ICancellable, ICancellable { private readonly CancellationTokenSource _cts; private readonly Task _task; private readonly Url _target; private readonly object? _source; public object? Source => _source; public Url Target => _target; public Task Task => _task; public bool IsRunning => _task.Status == TaskStatus.Running; public bool IsCompleted { get { if (_task.Status != TaskStatus.Faulted && _task.Status != TaskStatus.RanToCompletion) { return _task.Status == TaskStatus.Canceled; } return true; } } public Download(Task task, CancellationTokenSource cts, Url target, object? source) { _task = task; _cts = cts; _target = target; _source = source; } public void Cancel() { _cts.Cancel(); } } public static class HeaderNames { public static readonly string CacheControl = "Cache-Control"; public static readonly string Connection = "Connection"; public static readonly string ContentLength = "Content-Length"; public static readonly string ContentMd5 = "Content-MD5"; public static readonly string ContentType = "Content-Type"; public static readonly string Date = "Date"; public static readonly string Pragma = "Pragma"; public static readonly string Via = "Via"; public static readonly string Warning = "Warning"; public static readonly string Accept = "Accept"; public static readonly string AcceptCharset = "Accept-Charset"; public static readonly string AcceptEncoding = "Accept-Encoding"; public static readonly string AcceptLanguage = "Accept-Language"; public static readonly string AcceptDatetime = "Accept-Datetime"; public static readonly string Authorization = "Authorization"; public static readonly string Cookie = "Cookie"; public static readonly string Expect = "Expect"; public static readonly string From = "From"; public static readonly string Host = "Host"; public static readonly string IfMatch = "If-Match"; public static readonly string IfModifiedSince = "If-Modified-Since"; public static readonly string IfNoneMatch = "If-None-Match"; public static readonly string IfRange = "If-Range"; public static readonly string IfUnmodifiedSince = "If-Unmodified-Since"; public static readonly string MaxForwards = "Max-Forwards"; public static readonly string Origin = "Origin"; public static readonly string ProxyAuthorization = "Proxy-Authorization"; public static readonly string Range = "Range"; public static readonly string Referer = "Referer"; public static readonly string Te = "TE"; public static readonly string Upgrade = "Upgrade"; public static readonly string UserAgent = "User-Agent"; public static readonly string AccessControlAllowOrigin = "Access-Control-Allow-Origin"; public static readonly string AcceptRanges = "Accept-Ranges"; public static readonly string Age = "Age"; public static readonly string Allow = "Allow"; public static readonly string ContentEncoding = "Content-Encoding"; public static readonly string ContentLanguage = "Content-Language"; public static readonly string ContentLocation = "Content-Location"; public static readonly string ContentDisposition = "Content-Disposition"; public static readonly string ContentRange = "Content-Range"; public static readonly string ETag = "ETag"; public static readonly string Expires = "Expires"; public static readonly string LastModified = "Last-Modified"; public static readonly string Link = "Link"; public static readonly string Location = "Location"; public static readonly string P3p = "P3P"; public static readonly string ProxyAuthenticate = "Proxy-Authenticate"; public static readonly string Refresh = "Refresh"; public static readonly string RetryAfter = "Retry-After"; public static readonly string Server = "Server"; public static readonly string SetCookie = "Set-Cookie"; public static readonly string Status = "Status"; public static readonly string StrictTransportSecurity = "Strict-Transport-Security"; public static readonly string Trailer = "Trailer"; public static readonly string TransferEncoding = "Transfer-Encoding"; public static readonly string Vary = "Vary"; public static readonly string WwwAuthenticate = "WWW-Authenticate"; } public enum HttpMethod : byte { Get, Post, Put, Delete, Options, Head, Trace, Connect } public interface ICookieProvider { string GetCookie(Url url); void SetCookie(Url url, string value); } public interface IDocumentLoader : ILoader { IDownload FetchAsync(DocumentRequest request); } public interface IDownload : ICancellable, ICancellable { Url Target { get; } object? Source { get; } } public interface IIntegrityProvider { bool IsSatisfied(byte[] content, string integrity); } [DomNoInterfaceObject] public interface ILoadableElement { IDownload? CurrentDownload { get; } } public interface ILoader { IEnumerable GetDownloads(); } public interface IRequester : IEventTarget { event DomEventHandler Requesting; event DomEventHandler Requested; bool SupportsProtocol(string protocol); Task RequestAsync(Request request, CancellationToken cancel); } public interface IResourceLoader : ILoader { IDownload FetchAsync(ResourceRequest request); } public interface IResponse : IDisposable { HttpStatusCode StatusCode { get; } Url Address { get; } IDictionary Headers { get; } Stream Content { get; } } public sealed class LoaderOptions { public bool IsNavigationDisabled { get; set; } public bool IsResourceLoadingEnabled { get; set; } public Predicate? Filter { get; set; } } public class MemoryCookieProvider : ICookieProvider { private readonly CookieContainer _container; public CookieContainer Container => _container; public MemoryCookieProvider() { _container = new CookieContainer(); } public string GetCookie(Url url) { return _container.GetCookieHeader(url); } public void SetCookie(Url url, string value) { string cookieHeader = Sanatize(url.HostName, value); try { _container.SetCookies(url, cookieHeader); } catch (CookieException) { } } private static string Sanatize(string host, string cookie) { string text = "expires="; string oldValue = "Domain=" + host + ";"; int num = 0; while (num < cookie.Length) { int num2 = cookie.IndexOf(text, num, StringComparison.OrdinalIgnoreCase); if (num2 == -1) { break; } int num3 = num2 + text.Length; int num4 = cookie.IndexOfAny(new char[2] { ';', ',' }, num3 + 4); if (num4 == -1) { num4 = cookie.Length; } string text2 = cookie.Substring(0, num3); string text3 = cookie.Substring(num3, num4 - num3); string text4 = cookie.Substring(num4); if (DateTime.TryParse(text3.Replace("UTC", "GMT"), out var result)) { string text5 = result.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss", CultureInfo.InvariantCulture); cookie = text2 + text5 + text4; } num = num4; } return cookie.Replace(oldValue, string.Empty); } } public class MimeType : IEquatable { private readonly string _general; private readonly string _media; private readonly string _suffix; private readonly string _params; private static readonly char[] s_semicolon = new char[1] { ';' }; public string Content { get { if (_media.Length != 0 || _suffix.Length != 0) { string text = _general + "/" + _media; string text2 = ((_suffix.Length > 0) ? ("+" + _suffix) : string.Empty); return text + text2; } return _general; } } public string GeneralType => _general; public string MediaType => _media; public string Suffix => _suffix; public IEnumerable Keys { get { string[] array = _params.Split(s_semicolon); foreach (string text in array) { if (text.Length != 0) { int num = text.IndexOf('='); yield return (num >= 0) ? text.Substring(0, num) : text; } } } } public MimeType(string value) { int i; for (i = 0; i < value.Length && value[i] != '/'; i++) { } int j; for (j = i; j < value.Length && value[j] != '+'; j++) { } int k; for (k = ((j < value.Length) ? j : i); k < value.Length && value[k] != ';'; k++) { } _general = value.Substring(0, i); _media = ((i < value.Length) ? value.Substring(i + 1, Math.Min(j, k) - i - 1) : string.Empty); _suffix = ((j < value.Length) ? value.Substring(j + 1, k - j - 1) : string.Empty); _params = ((k < value.Length) ? value.Substring(k + 1).StripLeadingTrailingSpaces() : string.Empty); } public string? GetParameter(string key) { string[] array = _params.Split(s_semicolon); foreach (string text in array) { if (text.StartsWith(key, StringComparison.Ordinal) && text.Length > key.Length && text[key.Length] == '=') { return text.Substring(key.Length + 1); } } return null; } public override string ToString() { if (_media.Length != 0 || _suffix.Length != 0 || _params.Length != 0) { string text = _general + "/" + _media; string text2 = ((_suffix.Length > 0) ? ("+" + _suffix) : string.Empty); string text3 = ((_params.Length > 0) ? (";" + _params) : string.Empty); return text + text2 + text3; } return _general; } public bool Equals(MimeType? other) { if (_general.Isi(other?._general) && _media.Isi(other?._media)) { return _suffix.Isi(other?._suffix); } return false; } public override bool Equals(object? obj) { if (this != obj) { if (obj is MimeType other) { return Equals(other); } return false; } return true; } public override int GetHashCode() { return (_general.GetHashCode() << 2) ^ (_media.GetHashCode() << 1) ^ _suffix.GetHashCode(); } public static bool operator ==(MimeType a, MimeType b) { return a.Equals(b); } public static bool operator !=(MimeType a, MimeType b) { return !a.Equals(b); } } public static class MimeTypeNames { private static readonly string[] CommonJsTypes = new string[16] { "application/ecmascript", "application/javascript", "application/x-ecmascript", "application/x-javascript", "text/ecmascript", "text/javascript", "text/javascript1.0", "text/javascript1.1", "text/javascript1.2", "text/javascript1.3", "text/javascript1.4", "text/javascript1.5", "text/jscript", "text/livescript", "text/x-ecmascript", "text/x-javascript" }; private static readonly Dictionary Extensions = new Dictionary(StringComparer.OrdinalIgnoreCase) { { ".3dm", "x-world/x-3dmf" }, { ".3dmf", "x-world/x-3dmf" }, { ".a", "application/octet-stream" }, { ".aab", "application/x-authorware-bin" }, { ".aam", "application/x-authorware-map" }, { ".aas", "application/x-authorware-seg" }, { ".abc", "text/vnd.abc" }, { ".acgi", "text/html" }, { ".afl", "video/animaflex" }, { ".ai", "application/postscript" }, { ".aif", "audio/aiff" }, { ".aifc", "audio/aiff" }, { ".aiff", "audio/aiff" }, { ".aim", "application/x-aim" }, { ".aip", "text/x-audiosoft-intra" }, { ".ani", "application/x-navi-animation" }, { ".aos", "application/x-nokia-9000-communicator-add-on-software" }, { ".apng", "image/apng" }, { ".aps", "application/mime" }, { ".arc", "application/octet-stream" }, { ".arj", "application/arj" }, { ".art", "image/x-jg" }, { ".asf", "video/x-ms-asf" }, { ".asm", "text/x-asm" }, { ".asp", "text/asp" }, { ".asx", "application/x-mplayer2" }, { ".au", "audio/basic" }, { ".avi", "video/avi" }, { ".avif", "image/avif" }, { ".avifs", "image/avif-sequence" }, { ".avs", "video/avs-video" }, { ".bcpio", "application/x-bcpio" }, { ".bin", "application/octet-stream" }, { ".bm", "image/bmp" }, { ".bmp", "image/bmp" }, { ".boo", "application/book" }, { ".book", "application/book" }, { ".boz", "application/x-bzip2" }, { ".bsh", "application/x-bsh" }, { ".bz", "application/x-bzip" }, { ".bz2", "application/x-bzip2" }, { ".c", "text/plain" }, { ".cat", "application/vnd.ms-pki.seccat" }, { ".cc", "text/plain" }, { ".ccad", "application/clariscad" }, { ".cco", "application/x-cocoa" }, { ".cdf", "application/cdf" }, { ".cer", "application/x-x509-ca-cert" }, { ".cha", "application/x-chat" }, { ".chat", "application/x-chat" }, { ".class", "application/java" }, { ".com", "application/octet-stream" }, { ".conf", "text/plain" }, { ".cpio", "application/x-cpio" }, { ".cpp", "text/x-c" }, { ".cpt", "application/x-cpt" }, { ".crl", "application/pkix-crl" }, { ".crt", "application/x-x509-ca-cert" }, { ".csh", "application/x-csh" }, { ".css", "text/css" }, { ".cxx", "text/plain" }, { ".dcr", "application/x-director" }, { ".deepv", "application/x-deepv" }, { ".def", "text/plain" }, { ".der", "application/x-x509-ca-cert" }, { ".dif", "video/x-dv" }, { ".dir", "application/x-director" }, { ".dl", "video/dl" }, { ".doc", "application/msword" }, { ".dot", "application/msword" }, { ".dp", "application/commonground" }, { ".drw", "application/drafting" }, { ".dump", "application/octet-stream" }, { ".dv", "video/x-dv" }, { ".dvi", "application/x-dvi" }, { ".dwf", "model/vnd.dwf" }, { ".dwg", "application/acad" }, { ".dxf", "application/dxf" }, { ".dxr", "application/x-director" }, { ".el", "text/x-script.elisp" }, { ".elc", "application/x-elc" }, { ".env", "application/x-envoy" }, { ".eps", "application/postscript" }, { ".es", "application/x-esrehber" }, { ".etx", "text/x-setext" }, { ".evy", "application/envoy" }, { ".exe", "application/octet-stream" }, { ".f", "text/plain" }, { ".f77", "text/x-fortran" }, { ".f90", "text/plain" }, { ".fdf", "application/vnd.fdf" }, { ".fif", "image/fif" }, { ".fli", "video/fli" }, { ".flo", "image/florian" }, { ".flx", "text/vnd.fmi.flexstor" }, { ".fmf", "video/x-atomic3d-feature" }, { ".for", "text/plain" }, { ".fpx", "image/vnd.fpx" }, { ".frl", "application/freeloader" }, { ".funk", "audio/make" }, { ".g", "text/plain" }, { ".g3", "image/g3fax" }, { ".gif", "image/gif" }, { ".gl", "video/gl" }, { ".gsd", "audio/x-gsm" }, { ".gsm", "audio/x-gsm" }, { ".gsp", "application/x-gsp" }, { ".gss", "application/x-gss" }, { ".gtar", "application/x-gtar" }, { ".gz", "application/x-gzip" }, { ".gzip", "application/x-gzip" }, { ".h", "text/plain" }, { ".hdf", "application/x-hdf" }, { ".help", "application/x-helpfile" }, { ".hgl", "application/vnd.hp-hpgl" }, { ".hh", "text/plain" }, { ".hlb", "text/x-script" }, { ".hlp", "application/hlp" }, { ".hpg", "application/vnd.hp-hpgl" }, { ".hpgl", "application/vnd.hp-hpgl" }, { ".hqx", "application/binhex" }, { ".hta", "application/hta" }, { ".htc", "text/x-component" }, { ".htm", "text/html" }, { ".html", "text/html" }, { ".htmls", "text/html" }, { ".htt", "text/webviewhtml" }, { ".htx", "text/html" }, { ".ice", "x-conference/x-cooltalk" }, { ".ico", "image/x-icon" }, { ".idc", "text/plain" }, { ".ief", "image/ief" }, { ".iefs", "image/ief" }, { ".iges", "application/iges" }, { ".igs", "application/iges" }, { ".ima", "application/x-ima" }, { ".imap", "application/x-httpd-imap" }, { ".inf", "application/inf" }, { ".ins", "application/x-internett-signup" }, { ".ip", "application/x-ip2" }, { ".isu", "video/x-isvideo" }, { ".it", "audio/it" }, { ".iv", "application/x-inventor" }, { ".ivr", "i-world/i-vrml" }, { ".ivy", "application/x-livescreen" }, { ".jam", "audio/x-jam" }, { ".jav", "text/plain" }, { ".java", "text/plain" }, { ".jcm", "application/x-java-commerce" }, { ".jfif", "image/jpeg" }, { ".jpe", "image/jpeg" }, { ".jpeg", "image/jpeg" }, { ".jpg", "image/jpeg" }, { ".jps", "image/x-jps" }, { ".js", "application/javascript" }, { ".jxl", "image/jxl" }, { ".jut", "image/jutvision" }, { ".kar", "audio/midi" }, { ".ksh", "application/x-ksh" }, { ".la", "audio/nspaudio" }, { ".lam", "audio/x-liveaudio" }, { ".latex", "application/x-latex" }, { ".lha", "application/lha" }, { ".lhx", "application/octet-stream" }, { ".list", "text/plain" }, { ".lma", "audio/nspaudio" }, { ".log", "text/plain" }, { ".lsp", "application/x-lisp" }, { ".lst", "text/plain" }, { ".lsx", "text/x-la-asf" }, { ".ltx", "application/x-latex" }, { ".lzh", "application/x-lzh" }, { ".lzx", "application/lzx" }, { ".m", "text/plain" }, { ".m1v", "video/mpeg" }, { ".m2a", "audio/mpeg" }, { ".m2v", "video/mpeg" }, { ".m3u", "audio/x-mpequrl" }, { ".man", "application/x-troff-man" }, { ".map", "application/x-navimap" }, { ".mar", "text/plain" }, { ".mbd", "application/mbedlet" }, { ".mc", "\tapplication/x-magic-cap-package-1.0" }, { ".mcd", "application/mcad" }, { ".mcf", "image/vasa" }, { ".mcp", "application/netmc" }, { ".me", "application/x-troff-me" }, { ".mht", "message/rfc822" }, { ".mhtml", "message/rfc822" }, { ".mid", "audio/midi" }, { ".midi", "audio/midi" }, { ".mif", "application/x-frame" }, { ".mime", "www/mime" }, { ".mjf", "audio/x-vnd.audioexplosion.mjuicemediafile" }, { ".mjpg", "video/x-motion-jpeg" }, { ".mm", "application/x-meme" }, { ".mme", "application/base64" }, { ".mod", "audio/mod" }, { ".moov", "video/quicktime" }, { ".mov", "video/quicktime" }, { ".movie", "video/x-sgi-movie" }, { ".mp2", "audio/mpeg" }, { ".mp3", "audio/mpeg3" }, { ".mpa", "audio/mpeg" }, { ".mpc", "application/x-project" }, { ".mpe", "video/mpeg" }, { ".mpeg", "video/mpeg" }, { ".mpg", "video/mpeg" }, { ".mpga", "audio/mpeg" }, { ".mpp", "application/vnd.ms-project" }, { ".mpt", "application/x-project" }, { ".mpv", "application/x-project" }, { ".mpx", "application/x-project" }, { ".mrc", "application/marc" }, { ".ms", "application/x-troff-ms" }, { ".mv", "video/x-sgi-movie" }, { ".my", "audio/make" }, { ".mzz", "application/x-vnd.audioexplosion.mzz" }, { ".nap", "image/naplps" }, { ".naplps", "image/naplps" }, { ".nc", "application/x-netcdf" }, { ".ncm", "application/vnd.nokia.configuration-message" }, { ".nif", "image/x-niff" }, { ".niff", "image/x-niff" }, { ".nix", "application/x-mix-transfer" }, { ".nsc", "application/x-conference" }, { ".nvd", "application/x-navidoc" }, { ".o", "application/octet-stream" }, { ".oda", "application/oda" }, { ".omc", "application/x-omc" }, { ".omcd", "application/x-omcdatamaker" }, { ".omcr", "application/x-omcregerator" }, { ".p", "text/x-pascal" }, { ".p10", "application/pkcs10" }, { ".p12", "application/pkcs-12" }, { ".p7a", "application/x-pkcs7-signature" }, { ".p7c", "application/pkcs7-mime" }, { ".p7m", "application/pkcs7-mime" }, { ".p7r", "application/x-pkcs7-certreqresp" }, { ".p7s", "application/pkcs7-signature" }, { ".part", "application/pro_eng" }, { ".pas", "text/pascal" }, { ".pbm", "image/x-portable-bitmap" }, { ".pcl", "application/vnd.hp-pcl" }, { ".pct", "image/x-pict" }, { ".pcx", "image/x-pcx" }, { ".pdb", "chemical/x-pdb" }, { ".pdf", "application/pdf" }, { ".pfunk", "audio/make" }, { ".pgm", "image/x-portable-graymap" }, { ".pic", "image/pict" }, { ".pict", "image/pict" }, { ".pkg", "application/x-newton-compatible-pkg" }, { ".pko", "application/vnd.ms-pki.pko" }, { ".pl", "text/plain" }, { ".plx", "application/x-pixclscript" }, { ".pm", "image/x-xpixmap" }, { ".pm4", "application/x-pagemaker" }, { ".pm5", "application/x-pagemaker" }, { ".png", "image/png" }, { ".pnm", "application/x-portable-anymap" }, { ".pot", "application/mspowerpoint" }, { ".pov", "model/x-pov" }, { ".ppa", "application/vnd.ms-powerpoint" }, { ".ppm", "image/x-portable-pixmap" }, { ".pps", "application/mspowerpoint" }, { ".ppt", "application/powerpoint" }, { ".ppz", "application/mspowerpoint" }, { ".pre", "application/x-freelance" }, { ".prt", "application/pro_eng" }, { ".ps", "application/postscript" }, { ".psd", "application/octet-stream" }, { ".pvu", "paleovu/x-pv" }, { ".pwz", "application/vnd.ms-powerpoint" }, { ".py", "text/x-script.phyton" }, { ".pyc", "applicaiton/x-bytecode.python" }, { ".qcp", "audio/vnd.qcelp" }, { ".qd3", "x-world/x-3dmf" }, { ".qd3d", "x-world/x-3dmf" }, { ".qif", "image/x-quicktime" }, { ".qt", "video/quicktime" }, { ".qtc", "video/x-qtc" }, { ".qti", "image/x-quicktime" }, { ".qtif", "image/x-quicktime" }, { ".ra", "audio/x-realaudio" }, { ".ram", "audio/x-pn-realaudio" }, { ".ras", "image/cmu-raster" }, { ".rast", "image/cmu-raster" }, { ".rexx", "text/x-script.rexx" }, { ".rf", "image/vnd.rn-realflash" }, { ".rgb", "image/x-rgb" }, { ".rm", "audio/x-pn-realaudio" }, { ".rmi", "audio/mid" }, { ".rmm", "audio/x-pn-realaudio" }, { ".rmp", "audio/x-pn-realaudio" }, { ".rng", "application/ringing-tones" }, { ".rnx", "application/vnd.rn-realplayer" }, { ".roff", "application/x-troff" }, { ".rp", "image/vnd.rn-realpix" }, { ".rpm", "audio/x-pn-realaudio-plugin" }, { ".rt", "text/richtext" }, { ".rtf", "application/rtf" }, { ".rtx", "application/rtf" }, { ".rv", "video/vnd.rn-realvideo" }, { ".s", "text/x-asm" }, { ".s3m", "audio/s3m" }, { ".saveme", "application/octet-stream" }, { ".sbk", "application/x-tbook" }, { ".scm", "video/x-scm" }, { ".sdml", "text/plain" }, { ".sdp", "application/sdp" }, { ".sdr", "application/sounder" }, { ".sea", "application/sea" }, { ".set", "application/set" }, { ".sgm", "text/sgml" }, { ".sgml", "text/sgml" }, { ".sh", "application/x-sh" }, { ".shar", "application/x-bsh" }, { ".shtml", "text/html" }, { ".sid", "audio/x-psid" }, { ".sit", "application/x-sit" }, { ".skd", "application/x-koan" }, { ".skm", "application/x-koan" }, { ".skp", "application/x-koan" }, { ".skt", "application/x-koan" }, { ".sl", "application/x-seelogo" }, { ".smi", "application/smil" }, { ".smil", "application/smil" }, { ".snd", "audio/basic" }, { ".sol", "application/solids" }, { ".spc", "application/x-pkcs7-certificates" }, { ".spl", "application/futuresplash" }, { ".spr", "application/x-sprite" }, { ".sprite", "application/x-sprite" }, { ".src", "application/x-wais-source" }, { ".ssi", "text/x-server-parsed-html" }, { ".ssm", "application/streamingmedia" }, { ".sst", "application/vnd.ms-pki.certstore" }, { ".step", "application/step" }, { ".stl", "application/sla" }, { ".stp", "application/step" }, { ".sv4cpio", "application/x-sv4cpio" }, { ".sv4crc", "application/x-sv4crc" }, { ".svf", "image/vnd.dwg" }, { ".svg", "image/svg+xml" }, { ".swf", "application/x-shockwave-flash" }, { ".t", "application/x-troff" }, { ".talk", "text/x-speech" }, { ".tar", "application/x-tar" }, { ".tbk", "application/toolbook" }, { ".tcl", "application/x-tcl" }, { ".tcsh", "text/x-script.tcsh" }, { ".tex", "application/x-tex" }, { ".texi", "application/x-texinfo" }, { ".texinfo", "application/x-texinfo" }, { ".text", "text/plain" }, { ".tgz", "application/gnutar" }, { ".tif", "image/tiff" }, { ".tiff", "image/tiff" }, { ".tr", "application/x-troff" }, { ".tsi", "audio/tsp-audio" }, { ".tsp", "audio/tsplayer" }, { ".tsv", "text/tab-separated-values" }, { ".turbot", "image/florian" }, { ".txt", "text/plain" }, { ".uil", "text/x-uil" }, { ".uni", "text/uri-list" }, { ".unis", "text/uri-list" }, { ".unv", "application/i-deas" }, { ".uri", "text/uri-list" }, { ".uris", "text/uri-list" }, { ".ustar", "application/x-ustar" }, { ".uu", "text/x-uuencode" }, { ".uue", "text/x-uuencode" }, { ".vcd", "application/x-cdlink" }, { ".vcs", "text/x-vcalendar" }, { ".vda", "application/vda" }, { ".vdo", "video/vdo" }, { ".vew", "application/groupwise" }, { ".viv", "video/vivo" }, { ".vivo", "video/vivo" }, { ".vmd", "application/vocaltec-media-desc" }, { ".vmf", "application/vocaltec-media-file" }, { ".voc", "audio/voc" }, { ".vos", "video/vosaic" }, { ".vox", "audio/voxware" }, { ".vqe", "audio/x-twinvq-plugin" }, { ".vqf", "audio/x-twinvq" }, { ".vql", "audio/x-twinvq-plugin" }, { ".vrml", "model/vrml" }, { ".vrt", "x-world/x-vrt" }, { ".vsd", "application/x-visio" }, { ".vst", "application/x-visio" }, { ".vsw", "application/x-visio" }, { ".w60", "application/wordperfect6.0" }, { ".w61", "application/wordperfect6.1" }, { ".w6w", "application/msword" }, { ".wav", "audio/wav" }, { ".wb1", "application/x-qpro" }, { ".wbmp", "image/vnd.wap.wbmp" }, { ".web", "application/vnd.xara" }, { ".webp", "image/webp" }, { ".wiz", "application/msword" }, { ".wk1", "application/x-123" }, { ".wmf", "windows/metafile" }, { ".wml", "text/vnd.wap.wml" }, { ".wmlc", "application/vnd.wap.wmlc" }, { ".wmls", "text/vnd.wap.wmlscript" }, { ".wmlsc", "application/vnd.wap.wmlscriptc" }, { ".word", "application/msword" }, { ".wp", "application/wordperfect" }, { ".wp5", "application/wordperfect" }, { ".wp6", "application/wordperfect" }, { ".wpd", "application/wordperfect" }, { ".wq1", "application/x-lotus" }, { ".wri", "application/mswrite" }, { ".wrl", "model/vrml" }, { ".wrz", "model/vrml" }, { ".wsc", "text/scriplet" }, { ".wsrc", "application/x-wais-source" }, { ".wtk", "application/x-wintalk" }, { ".xbm", "image/xbm" }, { ".xdr", "video/x-amt-demorun" }, { ".xgz", "xgl/drawing" }, { ".xif", "image/vnd.xiff" }, { ".xl", "application/excel" }, { ".xla", "application/excel" }, { ".xlb", "application/excel" }, { ".xlc", "application/excel" }, { ".xld", "application/excel" }, { ".xlk", "application/excel" }, { ".xll", "application/excel" }, { ".xlm", "application/excel" }, { ".xls", "application/excel" }, { ".xlt", "application/excel" }, { ".xlv", "application/excel" }, { ".xlw", "application/excel" }, { ".xm", "audio/xm" }, { ".xml", "application/xml" }, { ".xmz", "xgl/movie" }, { ".xpix", "application/x-vnd.ls-xpix" }, { ".xpm", "image/xpm" }, { ".x", "image/png" }, { ".xsr", "video/x-amt-showrun" }, { ".xwd", "image/x-xwd" }, { ".xyz", "chemical/x-pdb" }, { ".z", "application/x-compressed" }, { ".zip", "application/zip" }, { ".zoo", "application/octet-stream" }, { ".zsh", "text/x-script.zsh" } }; public static readonly string Html = "text/html"; public static readonly string Png = "image/png"; public static readonly string Plain = "text/plain"; public static readonly string Xml = "text/xml"; public static readonly string Svg = "image/svg+xml"; public static readonly string Css = "text/css"; public static readonly string DefaultJavaScript = "text/javascript"; public static readonly string ApplicationJson = "application/json"; public static readonly string ApplicationXml = "application/xml"; public static readonly string ApplicationXHtml = "application/xhtml+xml"; public static readonly string Binary = "application/octet-stream"; public static readonly string UrlencodedForm = "application/x-www-form-urlencoded"; public static readonly string MultipartForm = "multipart/form-data"; public static string FromExtension(string extension) { if (Extensions.TryGetValue(extension, out string value)) { return value; } return Binary; } public static string GetExtension(string mimeType) { return Extensions.FirstOrDefault>((KeyValuePair x) => x.Value.Isi(mimeType)).Key ?? string.Empty; } public static bool IsJavaScript(string type) { string[] commonJsTypes = CommonJsTypes; foreach (string other in commonJsTypes) { if (type.Isi(other)) { return true; } } return false; } public static bool Represents(this MimeType type, string content) { MimeType other = new MimeType(content); return type.Equals(other); } } public enum OriginBehavior : byte { Taint, Fail } internal static class PortNumbers { private static readonly Dictionary Ports = new Dictionary { { ProtocolNames.Http, "80" }, { ProtocolNames.Https, "443" }, { ProtocolNames.Ftp, "21" }, { ProtocolNames.File, "" }, { ProtocolNames.Ws, "80" }, { ProtocolNames.Wss, "443" }, { ProtocolNames.Gopher, "70" }, { ProtocolNames.Telnet, "23" }, { ProtocolNames.Ssh, "22" } }; public static string? GetDefaultPort(string protocol) { Ports.TryGetValue(protocol, out string value); return value; } } public static class ProtocolNames { public static readonly string Http = "http"; public static readonly string Https = "https"; public static readonly string Ftp = "ftp"; public static readonly string JavaScript = "javascript"; public static readonly string Data = "data"; public static readonly string Mailto = "mailto"; public static readonly string File = "file"; public static readonly string Ws = "ws"; public static readonly string Wss = "wss"; public static readonly string Telnet = "telnet"; public static readonly string Ssh = "ssh"; public static readonly string Gopher = "gopher"; public static readonly string Blob = "blob"; private static readonly string[] RelativeProtocols = new string[7] { Http, Https, Ftp, File, Ws, Wss, Gopher }; private static readonly string[] OriginalableProtocols = new string[6] { Http, Https, Ftp, Ws, Wss, Gopher }; public static bool IsRelative(string protocol) { return RelativeProtocols.Contains(protocol); } public static bool IsOriginable(string protocol) { return OriginalableProtocols.Contains(protocol); } } public sealed class Request { public HttpMethod Method { get; set; } public Url Address { get; set; } public IDictionary Headers { get; set; } public Stream Content { get; set; } public Request() { Headers = new Dictionary(StringComparer.OrdinalIgnoreCase); } } public static class RequesterExtensions { public static bool IsRedirected(this HttpStatusCode status) { if (status != HttpStatusCode.Found && status != HttpStatusCode.TemporaryRedirect && status != HttpStatusCode.SeeOther && status != HttpStatusCode.TemporaryRedirect && status != HttpStatusCode.MovedPermanently) { return status == HttpStatusCode.MultipleChoices; } return true; } public static IDownload FetchWithCorsAsync(this IResourceLoader loader, CorsRequest cors) { ResourceRequest request = cors.Request; CorsSetting setting = cors.Setting; Url target = request.Target; if (request.Origin == target.Origin || target.Scheme == ProtocolNames.Data || target.Href == "about:blank") { return loader.FetchFromSameOriginAsync(target, cors); } switch (setting) { case CorsSetting.Anonymous: case CorsSetting.UseCredentials: return loader.FetchFromDifferentOriginAsync(cors); case CorsSetting.None: return loader.FetchWithoutCorsAsync(request, cors.Behavior); default: throw new DomException(DomError.Network); } } private static IDownload FetchFromSameOriginAsync(this IResourceLoader loader, Url url, CorsRequest cors) { ResourceRequest request = cors.Request; IDownload download = loader.FetchAsync(new ResourceRequest(request.Source, url) { Origin = request.Origin, IsManualRedirectDesired = true }); return download.Wrap(delegate(IResponse response) { if (response.IsRedirected()) { url.Href = response.Headers.GetOrDefault(HeaderNames.Location, url.Href); if (!request.Origin.Is(url.Origin)) { return loader.FetchFromSameOriginAsync(url, cors); } return loader.FetchWithCorsAsync(cors.RedirectTo(url)); } return cors.CheckIntegrity(download); }); } private static IDownload FetchFromDifferentOriginAsync(this IResourceLoader loader, CorsRequest cors) { ResourceRequest request = cors.Request; request.IsCredentialOmitted = cors.IsAnonymous(); IDownload download = loader.FetchAsync(request); return download.Wrap(delegate(IResponse response) { if (response == null || response.StatusCode != HttpStatusCode.OK) { response?.Dispose(); throw new DomException(DomError.Network); } return cors.CheckIntegrity(download); }); } private static IDownload FetchWithoutCorsAsync(this IResourceLoader loader, ResourceRequest request, OriginBehavior behavior) { if (behavior == OriginBehavior.Fail) { throw new DomException(DomError.Network); } return loader.FetchAsync(request); } private static bool IsAnonymous(this CorsRequest cors) { return cors.Setting == CorsSetting.Anonymous; } private static IDownload Wrap(this IDownload download, Func callback) { CancellationTokenSource cts = new CancellationTokenSource(); return new Download(download.Task.Wrap(callback), cts, download.Target, download.Source); } private static IDownload Wrap(this IDownload download, IResponse response) { CancellationTokenSource cts = new CancellationTokenSource(); return new Download(Task.FromResult(response), cts, download.Target, download.Source); } private static async Task Wrap(this Task task, Func callback) { return await callback(await task.ConfigureAwait(continueOnCapturedContext: false)).Task.ConfigureAwait(continueOnCapturedContext: false); } private static bool IsRedirected(this IResponse response) { return (response?.StatusCode ?? HttpStatusCode.NotFound).IsRedirected(); } private static CorsRequest RedirectTo(this CorsRequest cors, Url url) { ResourceRequest request = cors.Request; return new CorsRequest(new ResourceRequest(request.Source, url) { IsCookieBlocked = request.IsCookieBlocked, IsSameOriginForced = request.IsSameOriginForced, Origin = request.Origin }) { Setting = cors.Setting, Behavior = cors.Behavior, Integrity = cors.Integrity }; } private static IDownload CheckIntegrity(this CorsRequest cors, IDownload download) { IResponse result = download.Task.Result; string text = cors.Request.Source?.GetAttribute(AttributeNames.Integrity); IIntegrityProvider integrity = cors.Integrity; if (text != null && text.Length > 0 && integrity != null && result != null) { MemoryStream memoryStream = new MemoryStream(); result.Content.CopyTo(memoryStream); memoryStream.Position = 0L; if (!integrity.IsSatisfied(memoryStream.ToArray(), text)) { result.Dispose(); throw new DomException(DomError.Security); } return download.Wrap(new DefaultResponse { Address = result.Address, Content = memoryStream, Headers = result.Headers, StatusCode = result.StatusCode }); } return download; } } public class ResourceRequest { public IElement Source { get; } public Url Target { get; } public string? Origin { get; set; } public bool IsManualRedirectDesired { get; set; } public bool IsSameOriginForced { get; set; } public bool IsCredentialOmitted { get; set; } public bool IsCookieBlocked { get; set; } public ResourceRequest(IElement source, Url target) { Source = source; Target = target; Origin = source.Owner.Origin; IsManualRedirectDesired = false; IsSameOriginForced = false; IsCookieBlocked = false; IsCredentialOmitted = false; } } public static class ResponseExtensions { public static MimeType GetContentType(this IResponse response) { string path = response.Address.Path; int num = path.LastIndexOf('.'); string defaultValue = MimeTypeNames.FromExtension((num >= 0) ? path.Substring(num) : ".a"); return new MimeType(response.Headers.GetOrDefault(HeaderNames.ContentType, defaultValue)); } public static MimeType GetContentType(this IResponse response, string defaultType) { string path = response.Address.Path; int num = path.LastIndexOf('.'); if (num >= 0) { defaultType = MimeTypeNames.FromExtension(path.Substring(num)); } return new MimeType(response.Headers.GetOrDefault(HeaderNames.ContentType, defaultType)); } } public class VirtualResponse : IResponse, IDisposable { private Url _address; private HttpStatusCode _status; private Dictionary _headers; private Stream _content; private bool _dispose; Url IResponse.Address => _address; Stream IResponse.Content => _content; IDictionary IResponse.Headers => _headers; HttpStatusCode IResponse.StatusCode => _status; private VirtualResponse() { _address = Url.Create("http://localhost/"); _status = HttpStatusCode.OK; _headers = new Dictionary(StringComparer.OrdinalIgnoreCase); _content = Stream.Null; _dispose = false; } public static IResponse Create(Action request) { VirtualResponse virtualResponse = new VirtualResponse(); request(virtualResponse); return virtualResponse; } public VirtualResponse Address(Url url) { _address = url; return this; } public VirtualResponse Address(string address) { return Address(Url.Create(address ?? string.Empty)); } public VirtualResponse Address(Uri url) { return Address(Url.Convert(url)); } public VirtualResponse Cookie(string value) { return Header(HeaderNames.SetCookie, value); } public VirtualResponse Status(HttpStatusCode code) { _status = code; return this; } public VirtualResponse Status(int code) { return Status((HttpStatusCode)code); } public VirtualResponse Header(string name, string value) { _headers[name] = value; return this; } public VirtualResponse Headers(object obj) { Dictionary headers = obj.ToDictionary(); return Headers(headers); } public VirtualResponse Headers(IDictionary headers) { foreach (KeyValuePair header in headers) { Header(header.Key, header.Value); } return this; } public VirtualResponse Content(string text) { Release(); byte[] bytes = TextEncoding.Utf8.GetBytes(text); _content = new MemoryStream(bytes); _dispose = true; return this; } public VirtualResponse Content(Stream stream, bool shouldDispose = false) { Release(); _content = stream; _dispose = shouldDispose; return this; } private void Release() { if (_dispose) { _content?.Dispose(); } _dispose = false; _content = null; } void IDisposable.Dispose() { Release(); } } } namespace AngleSharp.Io.Processors { public abstract class BaseRequestProcessor : IRequestProcessor { private readonly IResourceLoader _loader; public bool IsAvailable => _loader != null; public IDownload? Download { get; protected set; } public BaseRequestProcessor(IResourceLoader loader) { _loader = loader; } public virtual Task ProcessAsync(ResourceRequest request) { if (IsAvailable && IsDifferentToCurrentDownloadUrl(request.Target)) { CancelDownload(); Download = _loader.FetchAsync(request); return FinishDownloadAsync(); } return Task.CompletedTask; } protected abstract Task ProcessResponseAsync(IResponse response); protected async Task FinishDownloadAsync() { IDownload download = Download; IResponse response = await download.Task.ConfigureAwait(continueOnCapturedContext: false); string eventName = EventNames.Error; if (response != null) { try { await ProcessResponseAsync(response).ConfigureAwait(continueOnCapturedContext: false); eventName = EventNames.Load; } catch (Exception) { } finally { response.Dispose(); } } object source = download.Source; EventTarget eventTarget = source as EventTarget; if (eventTarget == null) { return; } if (eventTarget is Element element) { element.Owner.QueueTask(delegate { eventTarget.FireSimpleEvent(eventName); }); } else { eventTarget.FireSimpleEvent(eventName); } } protected IDownload DownloadWithCors(CorsRequest request) { return _loader.FetchWithCorsAsync(request); } protected void CancelDownload() { IDownload download = Download; if (download != null && !download.IsCompleted) { download.Cancel(); } } protected bool IsDifferentToCurrentDownloadUrl(Url target) { IDownload download = Download; if (download != null) { return !target.Equals(download.Target); } return true; } } internal sealed class DocumentRequestProcessor : BaseRequestProcessor { private readonly IDocument? _parentDocument; private readonly IBrowsingContext _context; public IDocument? ChildDocument { get; private set; } public DocumentRequestProcessor(IBrowsingContext context) : base(context.GetService()) { _parentDocument = context.Active; _context = context; } protected override async Task ProcessResponseAsync(IResponse response) { BrowsingContext context = new BrowsingContext(_context, Sandboxes.None); Encoding defaultEncoding = _context.GetDefaultEncoding(); CreateDocumentOptions options = new CreateDocumentOptions(response, defaultEncoding, _parentDocument); ChildDocument = await _context.GetFactory().CreateAsync(context, options, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); } } internal sealed class FrameRequestProcessor : BaseRequestProcessor { private readonly HtmlFrameElementBase _element; public IDocument? Document { get; private set; } public FrameRequestProcessor(IBrowsingContext context, HtmlFrameElementBase element) : base(context?.GetService()) { _element = element; } public override Task ProcessAsync(ResourceRequest request) { string contentHtml = _element.GetContentHtml(); if (contentHtml != null) { string documentUri = _element.Owner.DocumentUri; return ProcessResponse(contentHtml, documentUri); } return base.ProcessAsync(request); } protected override Task ProcessResponseAsync(IResponse response) { CancellationToken none = CancellationToken.None; Task task = _element.NestedContext.OpenAsync(response, none); return WaitResponse(task); } private Task ProcessResponse(string response, string referer) { CancellationToken none = CancellationToken.None; Task task = _element.NestedContext.OpenAsync(delegate(VirtualResponse m) { m.Content(response).Address(referer); }, none); return WaitResponse(task); } private async Task WaitResponse(Task task) { Document = await task.ConfigureAwait(continueOnCapturedContext: false); } } internal sealed class ImageRequestProcessor : ResourceRequestProcessor { public int Width { get { if (!base.IsReady) { return 0; } return base.Resource.Width; } } public int Height { get { if (!base.IsReady) { return 0; } return base.Resource.Height; } } public ImageRequestProcessor(IBrowsingContext context) : base(context) { } protected override async Task ProcessResponseAsync(IResponse response) { IResourceService service = GetService(response); if (service != null) { CancellationToken none = CancellationToken.None; base.Resource = await service.CreateAsync(response, none).ConfigureAwait(continueOnCapturedContext: false); } } } public interface IRequestProcessor { IDownload? Download { get; } Task ProcessAsync(ResourceRequest request); } internal sealed class MediaRequestProcessor : ResourceRequestProcessor where TMediaInfo : IMediaInfo { public TMediaInfo? Media { get; private set; } public MediaNetworkState NetworkState { get { IDownload download = base.Download; if (download != null) { if (download.IsRunning) { return MediaNetworkState.Loading; } if (base.Resource == null) { return MediaNetworkState.NoSource; } } return MediaNetworkState.Idle; } } public MediaRequestProcessor(IBrowsingContext context) : base(context) { } protected override async Task ProcessResponseAsync(IResponse response) { IResourceService service = GetService(response); if (service != null) { CancellationToken none = CancellationToken.None; Media = await service.CreateAsync(response, none).ConfigureAwait(continueOnCapturedContext: false); } } } internal sealed class ObjectRequestProcessor : ResourceRequestProcessor { public int Width => base.Resource?.Width ?? 0; public int Height => base.Resource?.Height ?? 0; public ObjectRequestProcessor(IBrowsingContext context) : base(context) { } protected override async Task ProcessResponseAsync(IResponse response) { IResourceService service = GetService(response); if (service != null) { CancellationToken none = CancellationToken.None; base.Resource = await service.CreateAsync(response, none).ConfigureAwait(continueOnCapturedContext: false); } } } internal abstract class ResourceRequestProcessor : BaseRequestProcessor where TResource : IResourceInfo { private readonly IBrowsingContext _context; public string Source { get { TResource resource = Resource; return ((resource != null) ? resource.Source.Href : null) ?? string.Empty; } } [MemberNotNullWhen(true, "Resource")] public bool IsReady { [MemberNotNullWhen(true, "Resource")] get { return Resource != null; } } public TResource? Resource { get; protected set; } public ResourceRequestProcessor(IBrowsingContext context) : base(context?.GetService()) { _context = context; } public override Task ProcessAsync(ResourceRequest request) { if (base.IsAvailable && IsDifferentToCurrentResourceUrl(request.Target)) { return base.ProcessAsync(request); } return Task.CompletedTask; } protected IResourceService? GetService(IResponse response) { MimeType contentType = response.GetContentType(); return _context.GetResourceService(contentType.Content); } private bool IsDifferentToCurrentResourceUrl(Url target) { TResource resource = Resource; if (resource != null) { return !target.Equals(resource.Source); } return true; } } internal sealed class ScriptRequestProcessor : IRequestProcessor { private readonly IBrowsingContext _context; private readonly Document _document; private readonly HtmlScriptElement _script; private readonly IResourceLoader _loader; private IResponse? _response; private IScriptingService? _engine; public IDownload? Download { get; private set; } public IScriptingService? Engine => _engine ?? (_engine = _context.GetScripting(ScriptLanguage)); public string? AlternativeLanguage { get { string ownAttribute = _script.GetOwnAttribute(AttributeNames.Language); if (ownAttribute == null) { return null; } return "text/" + ownAttribute; } } public string ScriptLanguage { get { string text = _script.Type ?? AlternativeLanguage; if (text == null || text.Length <= 0) { return MimeTypeNames.DefaultJavaScript; } return text; } } public ScriptRequestProcessor(IBrowsingContext context, HtmlScriptElement script) { _context = context; _document = script.Owner; _script = script; _loader = context.GetService(); } public async Task RunAsync(CancellationToken cancel) { IDownload download = Download; if (download != null) { try { _response = await download.Task.ConfigureAwait(continueOnCapturedContext: false); } catch { await _document.QueueTaskAsync(FireErrorEvent).ConfigureAwait(continueOnCapturedContext: false); } } if (_response != null && !(await _document.QueueTaskAsync((Func)FireBeforeScriptExecuteEvent).ConfigureAwait(continueOnCapturedContext: false))) { ScriptOptions options = CreateOptions(); int index = _document.Source.Index; try { await _engine.EvaluateScriptAsync(_response, options, cancel).ConfigureAwait(continueOnCapturedContext: false); } catch (Exception ex) { _context.TrackError(ex); } _document.Source.Index = index; await _document.QueueTaskAsync(FireAfterScriptExecuteEvent).ConfigureAwait(continueOnCapturedContext: false); await _document.QueueTaskAsync(FireLoadEvent).ConfigureAwait(continueOnCapturedContext: false); _response.Dispose(); _response = null; } } public void Process(string content) { if (Engine != null) { _response = VirtualResponse.Create(delegate(VirtualResponse res) { res.Content(content).Address(_script.BaseUri); }); } } public Task ProcessAsync(ResourceRequest request) { if (_loader != null && Engine != null) { Download = _loader.FetchWithCorsAsync(new CorsRequest(request) { Behavior = OriginBehavior.Taint, Setting = _script.CrossOrigin.ToEnum(CorsSetting.None), Integrity = _context.GetProvider() }); return Download.Task; } return Task.CompletedTask; } private ScriptOptions CreateOptions() { return new ScriptOptions(_document, _document.Loop) { Element = _script, Encoding = TextEncoding.Resolve(_script.CharacterSet) }; } private void FireLoadEvent(CancellationToken _) { _script.FireSimpleEvent(EventNames.Load); } private void FireErrorEvent(CancellationToken _) { _script.FireSimpleEvent(EventNames.Error); } private bool FireBeforeScriptExecuteEvent(CancellationToken _) { return _script.FireSimpleEvent(EventNames.BeforeScriptExecute, bubble: false, cancelable: true); } private void FireAfterScriptExecuteEvent(CancellationToken _) { _script.FireSimpleEvent(EventNames.AfterScriptExecute, bubble: true); } } internal sealed class StyleSheetRequestProcessor : BaseRequestProcessor { private readonly IHtmlLinkElement _link; private readonly IBrowsingContext _context; private IStylingService? _engine; public IStyleSheet? Sheet { get; private set; } public IStylingService? Engine => _engine ?? (_engine = _context?.GetStyling(LinkType)); public string LinkType => _link.Type ?? MimeTypeNames.Css; public StyleSheetRequestProcessor(IBrowsingContext context, IHtmlLinkElement link) : base(context?.GetService()) { _context = context; _link = link; } public override Task ProcessAsync(ResourceRequest request) { if (base.IsAvailable && Engine != null && IsDifferentToCurrentDownloadUrl(request.Target)) { CancelDownload(); base.Download = DownloadWithCors(new CorsRequest(request) { Setting = _link.CrossOrigin.ToEnum(CorsSetting.None), Behavior = OriginBehavior.Taint, Integrity = _context.GetProvider() }); return FinishDownloadAsync(); } return Task.CompletedTask; } protected override async Task ProcessResponseAsync(IResponse response) { CancellationToken none = CancellationToken.None; StyleOptions options = new StyleOptions(_link.Owner) { Element = _link, IsDisabled = _link.IsDisabled, IsAlternate = _link.RelationList.Contains(Keywords.Alternate) }; IStyleSheet styleSheet = await _engine.ParseStylesheetAsync(response, options, none).ConfigureAwait(continueOnCapturedContext: false); styleSheet.Media.MediaText = _link.Media ?? string.Empty; Sheet = styleSheet; } } } namespace AngleSharp.Io.Dom { [DomName("Blob")] public interface IBlob : IDisposable { [DomName("size")] int Length { get; } [DomName("type")] string Type { get; } [DomName("isClosed")] bool IsClosed { get; } Stream Body { get; } [DomName("slice")] IBlob Slice(int start = 0, int end = int.MaxValue, string? contentType = null); [DomName("close")] void Close(); } [DomName("File")] public interface IFile : IBlob, IDisposable { [DomName("name")] string Name { get; } [DomName("lastModified")] DateTime LastModified { get; } } [DomName("FileList")] public interface IFileList : IEnumerable, IEnumerable { [DomName("item")] [DomAccessor(Accessors.Getter)] IFile this[int index] { get; } [DomName("length")] int Length { get; } void Add(IFile file); bool Remove(IFile file); void Clear(); } internal sealed class FileList : IFileList, IEnumerable, IEnumerable { private readonly List _entries; public IFile this[int index] => _entries[index]; public int Length => _entries.Count; internal FileList() { _entries = new List(); } public void Add(IFile item) { _entries.Add(item); } public void Clear() { _entries.Clear(); } public bool Remove(IFile item) { return _entries.Remove(item); } public IEnumerator GetEnumerator() { return _entries.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } } namespace AngleSharp.Dom { public enum AdjacentPosition : byte { [DomName("beforebegin")] BeforeBegin, [DomName("afterbegin")] AfterBegin, [DomName("beforeend")] BeforeEnd, [DomName("afterend")] AfterEnd } public static class AttrExtensions { public static bool SameAs(this INamedNodeMap sourceAttributes, INamedNodeMap targetAttributes) { if (sourceAttributes.Length == targetAttributes.Length) { foreach (IAttr sourceAttribute in sourceAttributes) { bool flag = false; foreach (IAttr targetAttribute in targetAttributes) { flag = sourceAttribute.GetHashCode() == targetAttribute.GetHashCode(); if (flag) { break; } } if (!flag) { return false; } } return true; } return false; } public static INamedNodeMap Clear(this INamedNodeMap attributes) { if (attributes == null) { throw new ArgumentNullException("attributes"); } while (attributes.Length > 0) { string name = attributes[attributes.Length - 1].Name; attributes.RemoveNamedItem(name); } return attributes; } } public static class AttributeNames { public static readonly string Name = "name"; public static readonly string HttpEquiv = "http-equiv"; public static readonly string Scheme = "scheme"; public static readonly string Content = "content"; public static readonly string Class = "class"; public static readonly string Style = "style"; public static readonly string Label = "label"; public static readonly string Action = "action"; public static readonly string Prompt = "prompt"; public static readonly string Href = "href"; public static readonly string HrefLang = "hreflang"; public static readonly string Lang = "lang"; public static readonly string Disabled = "disabled"; public static readonly string Selected = "selected"; public static readonly string Value = "value"; public static readonly string Title = "title"; public static readonly string Type = "type"; public static readonly string Rel = "rel"; public static readonly string Rev = "rev"; public static readonly string AccessKey = "accesskey"; public static readonly string Download = "download"; public static readonly string Media = "media"; public static readonly string Target = "target"; public static readonly string Charset = "charset"; public static readonly string Alt = "alt"; public static readonly string Coords = "coords"; public static readonly string Shape = "shape"; public static readonly string FormAction = "formaction"; public static readonly string FormMethod = "formmethod"; public static readonly string FormTarget = "formtarget"; public static readonly string FormEncType = "formenctype"; public static readonly string FormNoValidate = "formnovalidate"; public static readonly string DirName = "dirname"; public static readonly string Dir = "dir"; public static readonly string Nonce = "nonce"; public static readonly string NoResize = "noresize"; public static readonly string Src = "src"; public static readonly string SrcSet = "srcset"; public static readonly string SrcLang = "srclang"; public static readonly string SrcDoc = "srcdoc"; public static readonly string Scrolling = "scrolling"; public static readonly string LongDesc = "longdesc"; public static readonly string FrameBorder = "frameborder"; public static readonly string Width = "width"; public static readonly string Height = "height"; public static readonly string MarginWidth = "marginwidth"; public static readonly string MarginHeight = "marginheight"; public static readonly string Cols = "cols"; public static readonly string Rows = "rows"; public static readonly string Align = "align"; public static readonly string Encoding = "encoding"; public static readonly string Standalone = "standalone"; public static readonly string Version = "version"; public static readonly string DropZone = "dropzone"; public static readonly string Draggable = "draggable"; public static readonly string Spellcheck = "spellcheck"; public static readonly string TabIndex = "tabindex"; public static readonly string ContentEditable = "contenteditable"; public static readonly string Translate = "translate"; public static readonly string ContextMenu = "contextmenu"; public static readonly string Hidden = "hidden"; public static readonly string Id = "id"; public static readonly string Sizes = "sizes"; public static readonly string Scoped = "scoped"; public static readonly string Reversed = "reversed"; public static readonly string Start = "start"; public static readonly string Ping = "ping"; public static readonly string IsMap = "ismap"; public static readonly string UseMap = "usemap"; public static readonly string CrossOrigin = "crossorigin"; public static readonly string Sandbox = "sandbox"; public static readonly string AllowFullscreen = "allowfullscreen"; public static readonly string AllowPaymentRequest = "allowpaymentrequest"; public static readonly string Data = "data"; public static readonly string TypeMustMatch = "typemustmatch"; public static readonly string AutoFocus = "autofocus"; public static readonly string AcceptCharset = "accept-charset"; public static readonly string Enctype = "enctype"; public static readonly string AutoComplete = "autocomplete"; public static readonly string Method = "method"; public static readonly string NoValidate = "novalidate"; public static readonly string For = "for"; public static readonly string Seamless = "seamless"; public static readonly string Valign = "valign"; public static readonly string Span = "span"; public static readonly string BgColor = "bgcolor"; public static readonly string ColSpan = "colspan"; public static readonly string ReferrerPolicy = "referrerpolicy"; public static readonly string RowSpan = "rowspan"; public static readonly string NoWrap = "nowrap"; public static readonly string Abbr = "abbr"; public static readonly string Scope = "scope"; public static readonly string Headers = "headers"; public static readonly string Axis = "axis"; public static readonly string Border = "border"; public static readonly string CellPadding = "cellpadding"; public static readonly string Rules = "rules"; public static readonly string Summary = "summary"; public static readonly string CellSpacing = "cellspacing"; public static readonly string Frame = "frame"; public static readonly string Form = "form"; public static readonly string Required = "required"; public static readonly string Multiple = "multiple"; public static readonly string Min = "min"; public static readonly string Max = "max"; public static readonly string Open = "open"; public static readonly string Challenge = "challenge"; public static readonly string Keytype = "keytype"; public static readonly string Size = "size"; public static readonly string Wrap = "wrap"; public static readonly string MaxLength = "maxlength"; public static readonly string MinLength = "minlength"; public static readonly string Placeholder = "placeholder"; public static readonly string Readonly = "readonly"; public static readonly string Accept = "accept"; public static readonly string Pattern = "pattern"; public static readonly string Step = "step"; public static readonly string List = "list"; public static readonly string Checked = "checked"; public static readonly string Kind = "kind"; public static readonly string Default = "default"; public static readonly string Autoplay = "autoplay"; public static readonly string Preload = "preload"; public static readonly string Loop = "loop"; public static readonly string Controls = "controls"; public static readonly string Muted = "muted"; public static readonly string MediaGroup = "mediagroup"; public static readonly string Poster = "poster"; public static readonly string Color = "color"; public static readonly string Face = "face"; public static readonly string Command = "command"; public static readonly string Icon = "icon"; public static readonly string Radiogroup = "radiogroup"; public static readonly string Cite = "cite"; public static readonly string Async = "async"; public static readonly string Defer = "defer"; public static readonly string Language = "language"; public static readonly string Event = "event"; public static readonly string Alink = "alink"; public static readonly string Background = "background"; public static readonly string Link = "link"; public static readonly string Text = "text"; public static readonly string Vlink = "vlink"; public static readonly string Show = "show"; public static readonly string Role = "role"; public static readonly string Actuate = "actuate"; public static readonly string Arcrole = "arcrole"; public static readonly string Space = "space"; public static readonly string Window = "window"; public static readonly string Manifest = "manifest"; public static readonly string Datetime = "datetime"; public static readonly string Low = "low"; public static readonly string High = "high"; public static readonly string Optimum = "optimum"; public static readonly string Slot = "slot"; public static readonly string Body = "body"; public static readonly string Integrity = "integrity"; public static readonly string Clear = "clear"; public static readonly string Codetype = "codetype"; public static readonly string Compact = "compact"; public static readonly string Declare = "declare"; public static readonly string Direction = "direction"; public static readonly string NoHref = "nohref"; public static readonly string NoShade = "noshade"; public static readonly string ValueType = "valuetype"; } public sealed class CreateDocumentOptions { private readonly IResponse _response; private readonly MimeType _contentType; private readonly TextSource _source; private readonly IDocument? _ancestor; public IResponse Response => _response; public MimeType ContentType => _contentType; public TextSource Source => _source; public IDocument? ImportAncestor => _ancestor; public CreateDocumentOptions(IResponse response, Encoding? encoding = null, IDocument? ancestor = null) { MimeType contentType = response.GetContentType(MimeTypeNames.Html); string parameter = contentType.GetParameter(AttributeNames.Charset); Encoding encoding2 = encoding ?? Encoding.UTF8; TextSource textSource = new TextSource(response.Content ?? Stream.Null, encoding2); if (parameter != null && parameter.Length > 0 && TextEncoding.IsSupported(parameter)) { textSource.CurrentEncoding = TextEncoding.Resolve(parameter); } _source = textSource; _contentType = contentType; _response = response; _ancestor = ancestor; } } public class DefaultDocumentFactory : IDocumentFactory { public delegate Task Creator(IBrowsingContext context, CreateDocumentOptions options, CancellationToken cancellationToken); private readonly Dictionary _creators = new Dictionary { { MimeTypeNames.Html, LoadHtmlAsync }, { MimeTypeNames.ApplicationXHtml, LoadHtmlAsync }, { MimeTypeNames.Plain, LoadTextAsync }, { MimeTypeNames.ApplicationJson, LoadTextAsync }, { MimeTypeNames.DefaultJavaScript, LoadTextAsync }, { MimeTypeNames.Css, LoadTextAsync } }; public virtual void Register(string contentType, Creator creator) { _creators.Add(contentType, creator); } public virtual Creator? Unregister(string contentType) { if (_creators.TryGetValue(contentType, out Creator value)) { _creators.Remove(contentType); } return value; } protected virtual Task CreateDefaultAsync(IBrowsingContext context, CreateDocumentOptions options, CancellationToken cancellationToken) { return LoadHtmlAsync(context, options, cancellationToken); } public virtual Task CreateAsync(IBrowsingContext context, CreateDocumentOptions options, CancellationToken cancellationToken) { MimeType contentType = options.ContentType; foreach (KeyValuePair creator in _creators) { if (contentType.Represents(creator.Key)) { return creator.Value(context, options, cancellationToken); } } return CreateDefaultAsync(context, options, cancellationToken); } protected static Task LoadHtmlAsync(IBrowsingContext context, CreateDocumentOptions options, CancellationToken cancellationToken) { IHtmlParser? service = context.GetService(); HtmlDocument htmlDocument = new HtmlDocument(context, options.Source); htmlDocument.Setup(options.Response, options.ContentType, options.ImportAncestor); context.NavigateTo(htmlDocument); return service.ParseDocumentAsync(htmlDocument, cancellationToken); } protected static async Task LoadTextAsync(IBrowsingContext context, CreateDocumentOptions options, CancellationToken cancellationToken) { HtmlDocument document = new HtmlDocument(context, options.Source); document.Setup(options.Response, options.ContentType, options.ImportAncestor); context.NavigateTo(document); IElement element = document.CreateElement(TagNames.Html); IElement child = document.CreateElement(TagNames.Head); IElement element2 = document.CreateElement(TagNames.Body); IElement pre = document.CreateElement(TagNames.Pre); document.AppendChild(element); element.AppendChild(child); element.AppendChild(element2); element2.AppendChild(pre); pre.SetAttribute(AttributeNames.Style, "word-wrap: break-word; white-space: pre-wrap;"); await options.Source.PrefetchAllAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); pre.TextContent = options.Source.Text; return document; } } public enum DirectionMode : byte { Ltr, Rtl } public static class DocumentExtensions { public static TElement CreateElement(this IDocument document) where TElement : IElement { if (document == null) { throw new ArgumentNullException("document"); } Type type = typeof(BrowsingContext).Assembly.GetTypes().FirstOrDefault((Type m) => !m.IsAbstract && m.GetInterfaces().Contains(typeof(TElement))); if ((object)type != null) { foreach (ConstructorInfo item in from m in type.GetConstructors() orderby m.GetParameters().Length select m) { ParameterInfo[] parameters = item.GetParameters(); object[] array = new object[parameters.Length]; for (int num = 0; num < parameters.Length; num++) { bool flag = parameters[num].ParameterType == typeof(Document); array[num] = (flag ? document : parameters[num].DefaultValue); } object obj = item.Invoke(array); if (obj != null) { TElement val = (TElement)obj; (val as Element)?.SetupElement(); document.Adopt(val); return val; } } } throw new ArgumentException("No element could be created for the provided interface."); } public static void AdoptNode(this IDocument document, INode node) { if (node is Node node2) { node2.Parent?.RemoveChild(node2, suppressObservers: false); node2.Owner = document as Document; return; } throw new DomException(DomError.NotSupported); } internal static void QueueTask(this Document document, Action action) { document.Loop.Enqueue(action); } internal static Task QueueTaskAsync(this Document document, Action action) { return document.Loop.EnqueueAsync(delegate(CancellationToken _) { action(_); return true; }); } internal static Task QueueTaskAsync(this Document document, Func func) { return document.Loop.EnqueueAsync(func); } internal static void QueueMutation(this Document document, MutationRecord record) { MutationObserver[] array = document.Mutations.Observers.ToArray(); if (array.Length == 0) { return; } IEnumerable inclusiveAncestors = record.Target.GetInclusiveAncestors(); foreach (MutationObserver mutationObserver in array) { bool? flag = null; foreach (INode item in inclusiveAncestors) { MutationObserver.MutationOptions mutationOptions = mutationObserver.ResolveOptions(item); if (!mutationOptions.IsInvalid && (item == record.Target || mutationOptions.IsObservingSubtree) && (!record.IsAttribute || mutationOptions.IsObservingAttributes) && (!record.IsAttribute || mutationOptions.AttributeFilters == null || (mutationOptions.AttributeFilters.Contains(record.AttributeName) && record.AttributeNamespace == null)) && (!record.IsCharacterData || mutationOptions.IsObservingCharacterData) && (!record.IsChildList || mutationOptions.IsObservingChildNodes) && (!flag.HasValue || flag.Value)) { flag = (record.IsAttribute && !mutationOptions.IsExaminingOldAttributeValue) || (record.IsCharacterData && !mutationOptions.IsExaminingOldCharacterData); } } if (flag.HasValue) { mutationObserver.Enqueue(record.Copy(flag.Value)); } } document.PerformMicrotaskCheckpoint(); } internal static void AddTransientObserver(this Document document, INode node) { IEnumerable ancestors = node.GetAncestors(); IEnumerable observers = document.Mutations.Observers; foreach (INode item in ancestors) { foreach (MutationObserver item2 in observers) { item2.AddTransient(item, node); } } } internal static void ApplyManifest(this Document document) { if (document.IsInBrowsingContext && document.DocumentElement is IHtmlHtmlElement htmlHtmlElement) { string manifest = htmlHtmlElement.Manifest; Predicate predicate = (string _) => false; if (manifest != null && manifest.Length > 0) { predicate(manifest); } } } internal static void PerformMicrotaskCheckpoint(this Document document) { document.Mutations.ScheduleCallback(); } internal static void ProvideStableState(this Document document) { } public static IEnumerable GetScriptDownloads(this IDocument document) { return document.Context.GetDownloads(); } public static IEnumerable GetStyleSheetDownloads(this IDocument document) { return document.Context.GetDownloads(); } public static async Task WaitForReadyAsync(this IDocument document) { await Task.WhenAll(document.GetScriptDownloads().ToArray()).ConfigureAwait(continueOnCapturedContext: false); await Task.WhenAll(document.GetStyleSheetDownloads().ToArray()).ConfigureAwait(continueOnCapturedContext: false); } public static IEnumerable GetDownloads(this IDocument document) { if (document == null) { throw new ArgumentNullException("document"); } foreach (IElement item in document.All) { if (item is ILoadableElement loadableElement) { IDownload currentDownload = loadableElement.CurrentDownload; if (currentDownload != null) { yield return currentDownload; } } } } } [Flags] [DomName("Document")] public enum DocumentPositions : byte { Same = 0, [DomName("DOCUMENT_POSITION_DISCONNECTED")] Disconnected = 1, [DomName("DOCUMENT_POSITION_PRECEDING")] Preceding = 2, [DomName("DOCUMENT_POSITION_FOLLOWING")] Following = 4, [DomName("DOCUMENT_POSITION_CONTAINS")] Contains = 8, [DomName("DOCUMENT_POSITION_CONTAINED_BY")] ContainedBy = 0x10, [DomName("DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC")] ImplementationSpecific = 0x20 } public enum DocumentReadyState : byte { [DomName("loading")] Loading, [DomName("interactive")] Interactive, [DomName("complete")] Complete } [DomName("DOMError")] public enum DomError : byte { [DomDescription("The index is not in the allowed range.")] [DomName("INDEX_SIZE_ERR")] IndexSizeError = 1, [DomDescription("The size of the string is invalid.")] [DomName("DOMSTRING_SIZE_ERR")] [DomHistorical] DomStringSize = 2, [DomDescription("The operation would yield an incorrect node tree.")] [DomName("HIERARCHY_REQUEST_ERR")] HierarchyRequest = 3, [DomDescription("The object is in the wrong document.")] [DomName("WRONG_DOCUMENT_ERR")] WrongDocument = 4, [DomDescription("Invalid character detected.")] [DomName("INVALID_CHARACTER_ERR")] InvalidCharacter = 5, [DomDescription("The data is allowed for this object.")] [DomName("NO_DATA_ALLOWED_ERR")] [DomHistorical] NoDataAllowed = 6, [DomDescription("The object can not be modified.")] [DomName("NO_MODIFICATION_ALLOWED_ERR")] NoModificationAllowed = 7, [DomDescription("The object can not be found here.")] [DomName("NOT_FOUND_ERR")] NotFound = 8, [DomDescription("The operation is not supported.")] [DomName("NOT_SUPPORTED_ERR")] NotSupported = 9, [DomDescription("The element is already in-use.")] [DomName("INUSE_ATTRIBUTE_ERR")] [DomHistorical] InUse = 10, [DomDescription("The object is in an invalid state.")] [DomName("INVALID_STATE_ERR")] InvalidState = 11, [DomDescription("The string did not match the expected pattern.")] [DomName("SYNTAX_ERR")] Syntax = 12, [DomDescription("The object can not be modified in this way.")] [DomName("INVALID_MODIFICATION_ERR")] InvalidModification = 13, [DomDescription("The operation is not allowed by namespaces in XML.")] [DomName("NAMESPACE_ERR")] Namespace = 14, [DomDescription("The object does not support the operation or argument.")] [DomName("INVALID_ACCESS_ERR")] InvalidAccess = 15, [DomDescription("The validation failed.")] [DomName("VALIDATION_ERR")] Validation = 15, [DomDescription("The provided argument type is invalid.")] [DomName("TYPE_MISMATCH_ERR")] [DomHistorical] TypeMismatch = 17, [DomDescription("The operation is insecure.")] [DomName("SECURITY_ERR")] Security = 18, [DomDescription("A network error occurred.")] [DomName("NETWORK_ERR")] Network = 19, [DomDescription("The operation was aborted.")] [DomName("ABORT_ERR")] Abort = 20, [DomDescription("The given URL does not match another URL.")] [DomName("URL_MISMATCH_ERR")] UrlMismatch = 21, [DomDescription("The quota has been exceeded.")] [DomName("QUOTA_EXCEEDED_ERR")] QuotaExceeded = 22, [DomDescription("The operation timed out.")] [DomName("TIMEOUT_ERR")] Timeout = 23, [DomDescription("The supplied node is incorrect or has an incorrect ancestor for this operation.")] [DomName("INVALID_NODE_TYPE_ERR")] InvalidNodeType = 24, [DomDescription("The object can not be cloned.")] [DomName("DATA_CLONE_ERR")] DataClone = 25 } public delegate void DomEventHandler(object sender, Event ev); public sealed class DomException : Exception, IDomException { public string Name { get; } public int Code { get; } public DomException(DomError code) : base(code.GetMessage()) { Code = (int)code; Name = code.ToString(); } public DomException(string message) { Code = 0; Name = message; } } public static class ElementExtensions { public static string? LocatePrefixFor(this IElement element, string namespaceUri) { 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?.LocatePrefixFor(namespaceUri); } public static string? LocateNamespaceFor(this IElement element, string prefix) { string namespaceUri = element.GivenNamespaceUri; string prefix2 = element.Prefix; if ((string.IsNullOrEmpty(namespaceUri) || !prefix2.Is(prefix)) && !((prefix != null) ? element.TryLocateCustomNamespace(prefix, out namespaceUri) : element.TryLocateStandardNamespace(out namespaceUri))) { namespaceUri = element.ParentElement?.LocateNamespaceFor(prefix); } return namespaceUri; } public static string? GetNamespaceUri(this IElement element) { string prefix = element.Prefix; if ((prefix != null) ? element.TryLocateCustomNamespace(prefix, out string namespaceUri) : element.TryLocateStandardNamespace(out namespaceUri)) { return namespaceUri; } return element.ParentElement?.LocateNamespaceFor(prefix); } public static bool TryLocateCustomNamespace(this IElement element, string prefix, out string? namespaceUri) { foreach (IAttr attribute in element.Attributes) { if (attribute.NamespaceUri.Is(NamespaceNames.XmlNsUri) && attribute.Prefix.Is(NamespaceNames.XmlNsPrefix) && attribute.LocalName.Is(prefix)) { string text = attribute.Value; if (string.IsNullOrEmpty(text)) { text = null; } namespaceUri = text; return true; } } namespaceUri = null; return false; } public static bool TryLocateStandardNamespace(this IElement element, out string? namespaceUri) { foreach (IAttr attribute in element.Attributes) { if (attribute.Prefix == null && attribute.LocalName.Is(NamespaceNames.XmlNsPrefix)) { string text = attribute.Value; if (string.IsNullOrEmpty(text)) { text = null; } namespaceUri = text; return true; } } namespaceUri = null; return false; } 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 == "*")) { string current = el.GetAttribute(NamespaceNames.XmlNsPrefix) ?? el.NamespaceUri; if (prefix.Is(string.Empty)) { return current.Is(string.Empty); } return current.Is(el.GetCssNamespace(prefix)); } return true; } public static string? GetCssNamespace(this IElement el, string prefix) { return el.Owner?.StyleSheets.LocateNamespace(prefix) ?? el.LocateNamespaceFor(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) { string id = element.Id; string text = element.Owner?.Location.Hash; if (id != null && text != null) { return string.Compare(id, 0, text, (text.Length > 0) ? 1 : 0, int.MaxValue) == 0; } return false; } public static bool IsEnabled(this IElement element) { if ((element is IHtmlAnchorElement || element is IHtmlAreaElement || element is IHtmlLinkElement) ? true : false) { return !string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href)); } if (element is IHtmlButtonElement htmlButtonElement) { return !htmlButtonElement.IsDisabled; } if (element is IHtmlInputElement htmlInputElement) { return !htmlInputElement.IsDisabled; } if (element is IHtmlSelectElement htmlSelectElement) { return !htmlSelectElement.IsDisabled; } if (element is IHtmlTextAreaElement htmlTextAreaElement) { return !htmlTextAreaElement.IsDisabled; } if (element is IHtmlOptionElement htmlOptionElement) { return !htmlOptionElement.IsDisabled; } if ((element is IHtmlOptionsGroupElement || element is IHtmlMenuItemElement || element is IHtmlFieldSetElement) ? true : false) { return string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Disabled)); } return false; } public static bool IsDisabled(this IElement element) { if (element is IHtmlButtonElement htmlButtonElement) { return htmlButtonElement.IsDisabled; } if (element is IHtmlInputElement htmlInputElement) { return htmlInputElement.IsDisabled; } if (element is IHtmlSelectElement htmlSelectElement) { return htmlSelectElement.IsDisabled; } if (element is IHtmlTextAreaElement htmlTextAreaElement) { return htmlTextAreaElement.IsDisabled; } if (element is IHtmlOptionElement htmlOptionElement) { return htmlOptionElement.IsDisabled; } if ((element is IHtmlOptionsGroupElement || element is IHtmlMenuItemElement || element is IHtmlFieldSetElement) ? true : false) { return !string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Disabled)); } return false; } public static bool IsDefault(this IElement element) { if (element is IHtmlButtonElement htmlButtonElement) { if (htmlButtonElement.Form != null) { return true; } } else if (element is IHtmlInputElement htmlInputElement) { if (htmlInputElement.Type.IsOneOf(InputTypeNames.Submit, InputTypeNames.Image) && htmlInputElement.Form != null) { return true; } } else if (element is IHtmlOptionElement) { return !string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Selected)); } return false; } public static bool IsPseudo(this IElement element, string name) { return (element as IPseudoElement)?.PseudoName.Is(name) ?? false; } public static bool IsChecked(this IElement element) { if (element is IHtmlInputElement htmlInputElement) { if (htmlInputElement.Type.IsOneOf(InputTypeNames.Checkbox, InputTypeNames.Radio)) { return htmlInputElement.IsChecked; } return false; } if (element is IHtmlMenuItemElement htmlMenuItemElement) { if (htmlMenuItemElement.Type.IsOneOf(InputTypeNames.Checkbox, InputTypeNames.Radio)) { return htmlMenuItemElement.IsChecked; } return false; } if (element is IHtmlOptionElement htmlOptionElement) { return htmlOptionElement.IsSelected; } return false; } public static bool IsIndeterminate(this IElement element) { if (element is IHtmlInputElement htmlInputElement) { if (htmlInputElement.Type.Is(InputTypeNames.Checkbox)) { return htmlInputElement.IsIndeterminate; } return false; } if (element is IHtmlProgressElement) { return string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Value)); } return false; } public static bool IsPlaceholderShown(this IElement element) { if (element is IHtmlInputElement htmlInputElement) { bool flag = !string.IsNullOrEmpty(htmlInputElement.Placeholder); bool flag2 = string.IsNullOrEmpty(htmlInputElement.Value); return flag && flag2; } return false; } public static bool IsUnchecked(this IElement element) { if (element is IHtmlInputElement htmlInputElement) { if (htmlInputElement.Type.IsOneOf(InputTypeNames.Checkbox, InputTypeNames.Radio)) { return !htmlInputElement.IsChecked; } return false; } if (element is IHtmlMenuItemElement htmlMenuItemElement) { if (htmlMenuItemElement.Type.IsOneOf(InputTypeNames.Checkbox, InputTypeNames.Radio)) { return !htmlMenuItemElement.IsChecked; } return false; } if (element is IHtmlOptionElement htmlOptionElement) { return !htmlOptionElement.IsSelected; } return false; } public static bool IsActive(this IElement element) { if (element is IHtmlAnchorElement element2) { if (!string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href))) { return CheckActive(element2); } return false; } if (element is IHtmlAreaElement element3) { if (!string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href))) { return CheckActive(element3); } return false; } if (element is IHtmlLinkElement element4) { if (!string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href))) { return CheckActive(element4); } return false; } if (element is IHtmlButtonElement htmlButtonElement) { if (!htmlButtonElement.IsDisabled) { return CheckActive(htmlButtonElement); } return false; } if (element is IHtmlInputElement htmlInputElement) { if (htmlInputElement.Type.IsOneOf(InputTypeNames.Submit, InputTypeNames.Image, InputTypeNames.Reset, InputTypeNames.Button)) { return CheckActive(htmlInputElement); } return false; } if (element is HtmlMenuItemElement htmlMenuItemElement) { if (!htmlMenuItemElement.IsDisabled) { return CheckActive(htmlMenuItemElement); } return false; } return false; } public static bool IsVisited(this IElement element) { if (element is IHtmlAnchorElement element2) { if (!string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href))) { return CheckVisited(element2); } return false; } if (element is IHtmlAreaElement element3) { if (!string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href))) { return CheckVisited(element3); } return false; } if (element is IHtmlLinkElement element4) { if (!string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href))) { return CheckVisited(element4); } return false; } return false; } private static bool CheckActive(IElement element) { return false; } private static bool CheckVisited(IElement element) { return false; } public static bool IsLink(this IElement element) { if (element is IHtmlAnchorElement element2) { if (!string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href))) { return !element2.IsVisited(); } return false; } if (element is IHtmlAreaElement element3) { if (!string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href))) { return !element3.IsVisited(); } return false; } if (element is IHtmlLinkElement element4) { if (!string.IsNullOrEmpty(element.GetAttribute(null, AttributeNames.Href))) { return !element4.IsVisited(); } return false; } return false; } public static bool IsShadow(this IElement element) { return element?.ShadowRoot != null; } public static bool IsOptional(this IElement element) { if (element is IHtmlInputElement htmlInputElement) { return !htmlInputElement.IsRequired; } if (element is IHtmlSelectElement htmlSelectElement) { return !htmlSelectElement.IsRequired; } if (element is IHtmlTextAreaElement htmlTextAreaElement) { return !htmlTextAreaElement.IsRequired; } return false; } public static bool IsVisible(this IElement element) { return false; } public static bool IsRequired(this IElement element) { if (element is IHtmlInputElement htmlInputElement) { return htmlInputElement.IsRequired; } if (element is IHtmlSelectElement htmlSelectElement) { return htmlSelectElement.IsRequired; } if (element is IHtmlTextAreaElement htmlTextAreaElement) { return htmlTextAreaElement.IsRequired; } return false; } public static bool IsInvalid(this IElement element) { if (element is IValidation validation) { return !validation.CheckValidity(); } if (element is IHtmlFormElement htmlFormElement) { return !htmlFormElement.CheckValidity(); } return false; } public static bool IsValid(this IElement element) { if (element is IValidation validation) { return validation.CheckValidity(); } if (element is IHtmlFormElement htmlFormElement) { return htmlFormElement.CheckValidity(); } return false; } public static bool IsReadOnly(this IElement element) { if (element is IHtmlInputElement input) { return !input.IsMutable(); } if (element is IHtmlTextAreaElement textArea) { return !textArea.IsMutable(); } if (element is IHtmlElement htmlElement) { return !htmlElement.IsContentEditable; } return true; } public static bool IsMutable(this IHtmlInputElement input) { if (!input.IsDisabled) { return !input.IsReadOnly; } return false; } public static bool IsMutable(this IHtmlTextAreaElement textArea) { if (!textArea.IsDisabled) { return !textArea.IsReadOnly; } return false; } public static bool IsEditable(this IElement element) { if (element is IHtmlInputElement input) { return input.IsMutable(); } if (element is IHtmlTextAreaElement textArea) { return textArea.IsMutable(); } if (element is IHtmlElement htmlElement) { return htmlElement.IsContentEditable; } return false; } public static bool IsOutOfRange(this IElement element) { if (element is IValidation validation) { IValidityState validity = validation.Validity; if (!validity.IsRangeOverflow) { return validity.IsRangeUnderflow; } return true; } return false; } public static bool IsInRange(this IElement element) { if (element is IValidation validation) { 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) { return element.ParentElement?.FirstElementChild == element; } public static bool IsLastChild(this IElement element) { return element.ParentElement?.LastElementChild == element; } public static T Attr(this T elements, string attributeName, string attributeValue) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); attributeName = attributeName ?? throw new ArgumentNullException("attributeName"); foreach (IElement element in elements) { element.SetAttribute(attributeName, attributeValue); } return elements; } public static T Attr(this T elements, IEnumerable> attributes) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); attributes = attributes ?? throw new ArgumentNullException("attributes"); foreach (IElement element in elements) { foreach (KeyValuePair attribute in attributes) { element.SetAttribute(attribute.Key, attribute.Value); } } return elements; } public static T Attr(this T elements, object attributes) where T : class, IEnumerable { Dictionary attributes2 = attributes.ToDictionary(); return elements.Attr(attributes2); } public static IEnumerable Attr(this T elements, string attributeName) where T : IEnumerable { return elements.Select((IElement m) => m.GetAttribute(attributeName)); } public static IElement ClearAttr(this IElement element) { element = element ?? throw new ArgumentNullException("element"); element.Attributes.Clear(); return element; } public static T ClearAttr(this T elements) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); foreach (IElement element in elements) { element.ClearAttr(); } return elements; } public static IElement Empty(this IElement element) { element = element ?? throw new ArgumentNullException("element"); element.InnerHtml = string.Empty; return element; } public static T Empty(this T elements) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); foreach (IElement element in elements) { element.Empty(); } return elements; } public static string Html(this IElement element) { element = element ?? throw new ArgumentNullException("element"); return element.InnerHtml; } public static T Html(this T elements, string html) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); foreach (IElement element in elements) { element.InnerHtml = html; } return elements; } public static T AddClass(this T elements, string className) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); className = className ?? throw new ArgumentNullException("className"); string[] tokens = className.SplitSpaces(); foreach (IElement element in elements) { element.ClassList.Add(tokens); } return elements; } public static T RemoveClass(this T elements, string className) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); className = className ?? throw new ArgumentNullException("className"); string[] tokens = className.SplitSpaces(); foreach (IElement element in elements) { element.ClassList.Remove(tokens); } return elements; } public static T ToggleClass(this T elements, string className) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); className = className ?? throw new ArgumentNullException("className"); string[] array = className.SplitSpaces(); foreach (IElement element in elements) { string[] array2 = array; foreach (string token in array2) { element.ClassList.Toggle(token); } } return elements; } public static bool HasClass(this IEnumerable elements, string className) { elements = elements ?? throw new ArgumentNullException("elements"); className = className ?? throw new ArgumentNullException("className"); string[] array = className.SplitSpaces(); foreach (IElement element in elements) { bool flag = true; string[] array2 = array; foreach (string token in array2) { if (!element.ClassList.Contains(token)) { flag = false; break; } } if (flag) { return true; } } return false; } public static T Before(this T elements, string html) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); foreach (IElement element in elements) { IElement parentElement = element.ParentElement; if (parentElement != null) { IDocumentFragment newElement = parentElement.CreateFragment(html); parentElement.InsertBefore(newElement, element); } } return elements; } public static T After(this T elements, string html) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); foreach (IElement element in elements) { IElement parentElement = element.ParentElement; if (parentElement != null) { IDocumentFragment newElement = parentElement.CreateFragment(html); parentElement.InsertBefore(newElement, element.NextSibling); } } return elements; } public static T Append(this T elements, string html) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); foreach (IElement element in elements) { IDocumentFragment documentFragment = element.CreateFragment(html); element.Append(documentFragment); } return elements; } public static T Prepend(this T elements, string html) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); foreach (IElement element in elements) { IDocumentFragment newElement = element.CreateFragment(html); element.InsertBefore(newElement, element.FirstChild); } return elements; } public static T Wrap(this T elements, string html) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); foreach (IElement element in elements) { IDocumentFragment documentFragment = element.CreateFragment(html); IElement innerMostElement = documentFragment.GetInnerMostElement(); element.Parent?.InsertBefore(documentFragment, element); innerMostElement.AppendChild(element); } return elements; } public static T WrapInner(this T elements, string html) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); foreach (IElement element in elements) { IDocumentFragment documentFragment = element.CreateFragment(html); IElement innerMostElement = documentFragment.GetInnerMostElement(); while (element.ChildNodes.Length > 0) { INode child = element.ChildNodes[0]; innerMostElement.AppendChild(child); } element.AppendChild(documentFragment); } return elements; } public static T WrapAll(this T elements, string html) where T : class, IEnumerable { elements = elements ?? throw new ArgumentNullException("elements"); IElement element = elements.FirstOrDefault(); if (element != null) { IDocumentFragment documentFragment = element.CreateFragment(html); IElement innerMostElement = documentFragment.GetInnerMostElement(); element.Parent?.InsertBefore(documentFragment, element); foreach (IElement element2 in elements) { innerMostElement.AppendChild(element2); } } return elements; } public static IHtmlCollection ToCollection(this IEnumerable elements) where TElement : class, IElement { return new HtmlCollection(elements); } public static Task NavigateAsync(this TElement element) where TElement : class, IUrlUtilities, IElement { return element.NavigateAsync(CancellationToken.None); } public static Task NavigateAsync(this TElement element, CancellationToken cancel) where TElement : class, IUrlUtilities, IElement { element = element ?? throw new ArgumentNullException("element"); IDocument owner = element.Owner; DocumentRequest request = DocumentRequest.Get(Url.Create(element.Href), element, owner.DocumentUri); return owner.Context.NavigateToAsync(request); } internal static void Process(this Element element, IRequestProcessor processor, Url url) { ResourceRequest request = element.CreateRequestFor(url); Task task = processor?.ProcessAsync(request); element.Owner?.DelayLoad(task); } internal static Url? GetImageCandidate(this HtmlImageElement img) { SourceSet sourceSet = new SourceSet(); IBrowsingContext context = img.Context; Stack sources = img.GetSources(); while (sources.Count > 0) { IHtmlSourceElement htmlSourceElement = sources.Pop(); string type = htmlSourceElement.Type; if (!string.IsNullOrEmpty(type) && context?.GetResourceService(type) == null) { continue; } using IEnumerator enumerator = sourceSet.GetCandidates(htmlSourceElement.SourceSet, htmlSourceElement.Sizes).GetEnumerator(); if (enumerator.MoveNext()) { string current = enumerator.Current; return new Url(img.BaseUrl, current); } } using (IEnumerator enumerator = sourceSet.GetCandidates(img.SourceSet, img.Sizes).GetEnumerator()) { if (enumerator.MoveNext()) { string current2 = enumerator.Current; return new Url(img.BaseUrl, current2); } } string source = img.Source; if (source == null || source.Length <= 0) { return null; } return Url.Create(source); } internal static string? GetOwnAttribute(this Element element, string name) { return element.Attributes.GetNamedItem(null, name)?.Value; } internal static bool HasOwnAttribute(this Element element, string name) { return element.Attributes.GetNamedItem(null, name) != null; } internal 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; } internal static bool IsBooleanAttribute(this IElement element, string name) { if ((!(element is HtmlDetailsElement) || !name.Is(AttributeNames.Open)) && (!(element is HtmlDialogElement) || !name.Is(AttributeNames.Open)) && (!(element is HtmlElement) || !name.Is(AttributeNames.Hidden)) && (!(element is HtmlFormControlElement) || !name.Is(AttributeNames.AutoFocus)) && (!(element is HtmlFormControlElement) || !name.Is(AttributeNames.Disabled)) && (!(element is HtmlLinkElement) || !name.Is(AttributeNames.Disabled)) && (!(element is HtmlIFrameElement) || !name.Is(AttributeNames.SrcDoc)) && (!(element is HtmlIFrameElement) || !name.Is(AttributeNames.AllowFullscreen)) && (!(element is HtmlIFrameElement) || !name.Is(AttributeNames.AllowPaymentRequest)) && (!(element is HtmlImageElement) || !name.Is(AttributeNames.IsMap)) && (!(element is HtmlInputElement) || !name.Is(AttributeNames.Checked)) && (!(element is HtmlInputElement) || !name.Is(AttributeNames.Multiple)) && (!(element is HtmlTrackElement) || !name.Is(AttributeNames.Default)) && (!(element is HtmlTextFormControlElement) || !name.Is(AttributeNames.Required)) && (!(element is HtmlTextFormControlElement) || !name.Is(AttributeNames.Readonly)) && (!(element is HtmlStyleElement) || !name.Is(AttributeNames.Scoped)) && (!(element is HtmlStyleElement) || !name.Is(AttributeNames.Disabled)) && (!(element is HtmlSelectElement) || !name.Is(AttributeNames.Required)) && (!(element is HtmlSelectElement) || !name.Is(AttributeNames.Multiple)) && (!(element is HtmlScriptElement) || !name.Is(AttributeNames.Defer)) && (!(element is HtmlScriptElement) || !name.Is(AttributeNames.Async)) && (!(element is HtmlOrderedListElement) || !name.Is(AttributeNames.Reversed)) && (!(element is HtmlOptionsGroupElement) || !name.Is(AttributeNames.Disabled)) && (!(element is HtmlOptionElement) || !name.Is(AttributeNames.Disabled)) && (!(element is HtmlOptionElement) || !name.Is(AttributeNames.Selected)) && (!(element is HtmlObjectElement) || !name.Is(AttributeNames.TypeMustMatch)) && (!(element is HtmlMenuItemElement) || !name.Is(AttributeNames.Disabled)) && (!(element is HtmlMenuItemElement) || !name.Is(AttributeNames.Checked)) && (!(element is HtmlMenuItemElement) || !name.Is(AttributeNames.Default)) && (!(element is IHtmlMediaElement) || !name.Is(AttributeNames.Autoplay)) && (!(element is IHtmlMediaElement) || !name.Is(AttributeNames.Loop)) && (!(element is IHtmlMediaElement) || !name.Is(AttributeNames.Muted))) { if (element is IHtmlMediaElement) { return name.Is(AttributeNames.Controls); } return false; } return true; } internal static bool GetBoolAttribute(this Element element, string name) { return element.GetOwnAttribute(name) != null; } internal static void SetBoolAttribute(this Element element, string name, bool value) { if (value) { element.SetOwnAttribute(name, string.Empty); } else { element.Attributes.RemoveNamedItemOrDefault(name, suppressMutationObservers: true); } } internal static void SetOwnAttribute(this Element element, string name, string? value, bool suppressCallbacks = false) { element.Attributes.SetNamedItemWithNamespaceUri(new Attr(name, value), suppressCallbacks); } private static IDocumentFragment CreateFragment(this IElement context, string html) { Element contextElement = context as Element; string html2 = html ?? string.Empty; return new DocumentFragment(contextElement, html2); } 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; } public static string GetSelector(this IElement element) { string text = string.Empty; bool flag = false; do { int num; if (!string.IsNullOrEmpty(element.Id)) { IDocument? owner = element.Owner; num = ((owner != null && owner.QuerySelectorAll("[id='" + element.Id + "']").Length == 1) ? 1 : 0); } else { num = 0; } flag = (byte)num != 0; IElement parentElement = element.ParentElement; string text2 = element.LocalName; if (flag) { text2 = "#" + CssUtilities.Escape(element.Id); } else if (parentElement != null && !element.IsOnlyOfType()) { int num2 = parentElement.Children.Index(element); text2 += $":nth-child({num2 + 1})"; } text = (string.IsNullOrEmpty(text) ? text2 : (text2 + ">" + text)); element = parentElement; } while (element?.ParentElement != null && !flag); return text; } internal static IElement ParseHtmlSubtree(this Element element, string html) { IBrowsingContext context = element.Context; TextSource source = new TextSource(html); HtmlDocument document = new HtmlDocument(context, source); HtmlParserOptions htmlParserOptions = new HtmlParserOptions { IsEmbedded = false, IsStrictMode = false, IsScripting = context.IsScripting() }; return new HtmlDomBuilder(HtmlDomConstructionFactory.Instance, document, new HtmlTokenizerOptions(htmlParserOptions)).ParseFragment(htmlParserOptions, element).DocumentElement; } } public static class EventNames { public static readonly string Invalid = "invalid"; public static readonly string Load = "load"; public static readonly string DomContentLoaded = "DOMContentLoaded"; public static readonly string Error = "error"; public static readonly string BeforeScriptExecute = "beforescriptexecute"; public static readonly string AfterScriptExecute = "afterscriptexecute"; public static readonly string ReadyStateChanged = "readystatechanged"; public static readonly string Abort = "abort"; public static readonly string Blur = "blur"; public static readonly string Cancel = "cancel"; public static readonly string Click = "click"; public static readonly string Change = "change"; public static readonly string CanPlayThrough = "canplaythrough"; public static readonly string CanPlay = "canplay"; public static readonly string CueChange = "cuechange"; public static readonly string DblClick = "dblclick"; public static readonly string Drag = "drag"; public static readonly string DragEnd = "dragend"; public static readonly string DragEnter = "dragenter"; public static readonly string DragExit = "dragexit"; public static readonly string DragLeave = "dragleave"; public static readonly string DragOver = "dragover"; public static readonly string DragStart = "dragstart"; public static readonly string Drop = "drop"; public static readonly string DurationChange = "durationchange"; public static readonly string Emptied = "emptied"; public static readonly string Focus = "focus"; public static readonly string FullscreenChange = "fullscreenchange"; public static readonly string FullscreenError = "fullscreenerror"; public static readonly string HashChange = "hashchange"; public static readonly string Input = "input"; public static readonly string Message = "message"; public static readonly string Keydown = "keydown"; public static readonly string Keypress = "keypress"; public static readonly string Keyup = "keyup"; public static readonly string Ended = "ended"; public static readonly string LoadedData = "loadeddata"; public static readonly string LoadedMetaData = "loadedmetadata"; public static readonly string LoadEnd = "loadend"; public static readonly string LoadStart = "loadstart"; public static readonly string Wheel = "wheel"; public static readonly string Mouseup = "mouseup"; public static readonly string Mouseover = "mouseover"; public static readonly string Mouseout = "mouseout"; public static readonly string Mousemove = "mousemove"; public static readonly string Mouseleave = "mouseleave"; public static readonly string Mouseenter = "mouseenter"; public static readonly string Mousedown = "mousedown"; public static readonly string Pause = "pause"; public static readonly string Play = "play"; public static readonly string Playing = "playing"; public static readonly string Progress = "progress"; public static readonly string RateChange = "ratechange"; public static readonly string Waiting = "waiting"; public static readonly string VolumeChange = "volumechange"; public static readonly string Toggle = "toggle"; public static readonly string TimeUpdate = "timeupdate"; public static readonly string Suspend = "suspend"; public static readonly string Submit = "submit"; public static readonly string Stalled = "stalled"; public static readonly string Show = "show"; public static readonly string Select = "select"; public static readonly string Seeking = "seeking"; public static readonly string Seeked = "seeked"; public static readonly string Scroll = "scroll"; public static readonly string Resize = "resize"; public static readonly string Reset = "reset"; public static readonly string AfterPrint = "afterprint"; public static readonly string Print = "print"; public static readonly string BeforePrint = "beforeprint"; public static readonly string BeforeUnload = "beforeunload"; public static readonly string Unloading = "unloading"; public static readonly string Offline = "offline"; public static readonly string Online = "online"; public static readonly string PageHide = "pagehide"; public static readonly string PageShow = "pageshow"; public static readonly string PopState = "popstate"; public static readonly string Unload = "unload"; public static readonly string ConfirmUnload = "confirmUnload"; public static readonly string Storage = "storage"; public static readonly string Parsing = "parsing"; public static readonly string Parsed = "parsed"; public static readonly string Requesting = "requesting"; public static readonly string Requested = "requested"; } public abstract class EventTarget : IEventTarget { private readonly struct RegisteredEventListener { public readonly string Type; public readonly DomEventHandler Callback; public readonly bool IsCaptured; public RegisteredEventListener(string type, DomEventHandler callback, bool isCaptured) { Type = type; Callback = callback; IsCaptured = isCaptured; } } private List? _listeners; private List Listeners => _listeners ?? (_listeners = new List()); internal bool HasEventListeners { get { if (_listeners != null) { return _listeners.Count > 0; } return false; } } public void AddEventListener(string type, DomEventHandler? callback = null, bool capture = false) { if (callback != null) { Listeners.Add(new RegisteredEventListener(type, callback, capture)); } } public void RemoveEventListener(string type, DomEventHandler? callback = null, bool capture = false) { if (callback != null) { _listeners?.Remove(new RegisteredEventListener(type, callback, capture)); } } public void RemoveEventListeners() { if (_listeners != null) { _listeners.Clear(); } } public void InvokeEventListener(Event ev) { if (_listeners == null) { return; } string type = ev.Type; RegisteredEventListener[] array = _listeners.ToArray(); IEventTarget currentTarget = ev.CurrentTarget; EventPhase phase = ev.Phase; RegisteredEventListener[] array2 = array; for (int i = 0; i < array2.Length; i++) { RegisteredEventListener item = array2[i]; if (_listeners.Contains(item) && item.Type.Is(type)) { if ((ev.Flags & EventFlags.StopImmediatePropagation) == EventFlags.StopImmediatePropagation) { break; } if ((!item.IsCaptured || phase != EventPhase.Bubbling) && (item.IsCaptured || phase != EventPhase.Capturing)) { item.Callback(currentTarget, ev); } } } } public bool HasEventListener(string type) { if (_listeners != null) { foreach (RegisteredEventListener listener in _listeners) { if (listener.Type.Is(type)) { return true; } } } return false; } public bool Dispatch(Event ev) { if (ev == null || (ev.Flags & EventFlags.Dispatch) == EventFlags.Dispatch || (ev.Flags & EventFlags.Initialized) != EventFlags.Initialized) { throw new DomException(DomError.InvalidState); } ev.IsTrusted = false; return ev.Dispatch(this); } } public static class EventTargetExtensions { public static bool FireSimpleEvent(this IEventTarget target, string eventName, bool bubble = false, bool cancelable = false) { Event obj = new Event(); obj.IsTrusted = true; obj.Init(eventName, bubble, cancelable); return obj.Dispatch(target); } public static bool Fire(this IEventTarget target, Event eventData) { eventData.IsTrusted = true; return eventData.Dispatch(target); } public static bool Fire(this IEventTarget target, Action initializer, IEventTarget? targetOverride = null) where T : Event, new() { T val = new T { IsTrusted = true }; initializer(val); return val.Dispatch(targetOverride ?? target); } public static async Task AwaitEventAsync(this TEventTarget node, string eventName) where TEventTarget : IEventTarget { if (node == null) { throw new ArgumentNullException("node"); } if (eventName == null) { throw new ArgumentNullException("eventName"); } TaskCompletionSource completion = new TaskCompletionSource(); ref TEventTarget reference = ref node; TEventTarget val = default(TEventTarget); if (val == null) { val = reference; reference = ref val; } DomEventHandler callback = handler; reference.AddEventListener(eventName, callback); try { return await completion.Task.ConfigureAwait(continueOnCapturedContext: false); } finally { ref TEventTarget reference2 = ref node; val = default(TEventTarget); if (val == null) { val = reference2; reference2 = ref val; } DomEventHandler callback2 = handler; reference2.RemoveEventListener(eventName, callback2); } void handler(object s, Event ev) { completion.TrySetResult(ev); } } } [DomName("NodeFilter")] public enum FilterResult : byte { [DomName("FILTER_ACCEPT")] Accept = 1, [DomName("FILTER_REJECT")] Reject, [DomName("FILTER_SKIP")] Skip } [Flags] [DomName("NodeFilter")] public enum FilterSettings : ulong { [DomName("SHOW_ALL")] All = 0xFFFFFFFFuL, [DomName("SHOW_ELEMENT")] Element = 1uL, [DomName("SHOW_ATTRIBUTE")] [DomHistorical] Attribute = 2uL, [DomName("SHOW_TEXT")] Text = 4uL, [DomName("SHOW_CDATA_SECTION")] [DomHistorical] CharacterData = 8uL, [DomName("SHOW_ENTITY_REFERENCE")] [DomHistorical] EntityReference = 0x10uL, [DomName("SHOW_ENTITY")] [DomHistorical] Entity = 0x20uL, [DomName("SHOW_PROCESSING_INSTRUCTION")] ProcessingInstruction = 0x40uL, [DomName("SHOW_COMMENT")] Comment = 0x80uL, [DomName("SHOW_DOCUMENT")] Document = 0x100uL, [DomName("SHOW_DOCUMENT_TYPE")] DocumentType = 0x200uL, [DomName("SHOW_DOCUMENT_FRAGMENT")] DocumentFragment = 0x400uL, [DomName("SHOW_NOTATION")] [DomHistorical] Notation = 0x800uL } public enum HorizontalAlignment : byte { Left, Center, Right, Justify } [DomName("Attr")] public interface IAttr : INode, IEventTarget, IMarkupFormattable, IEquatable { [DomName("localName")] string LocalName { get; } [DomName("name")] string Name { get; } [DomName("value")] string Value { get; set; } [DomName("namespaceURI")] string? NamespaceUri { get; } [DomName("prefix")] string? Prefix { get; } [DomName("ownerElement")] IElement? OwnerElement { get; } [DomName("specified")] bool IsSpecified { get; } } public interface IAttributeObserver { void NotifyChange(IElement host, string name, string? value); } [DomName("CharacterData")] public interface ICharacterData : INode, IEventTarget, IMarkupFormattable, IChildNode, INonDocumentTypeChildNode { [DomName("data")] string Data { get; set; } [DomName("length")] int Length { get; } [DomName("substringData")] string Substring(int offset, int count); [DomName("appendData")] void Append(string value); [DomName("insertData")] void Insert(int offset, string value); [DomName("deleteData")] void Delete(int offset, int count); [DomName("replaceData")] void Replace(int offset, int count, string value); } [DomName("ChildNode")] [DomNoInterfaceObject] public interface IChildNode { [DomName("before")] void Before(params INode[] nodes); [DomName("after")] void After(params INode[] nodes); [DomName("replace")] void Replace(params INode[] nodes); [DomName("remove")] void Remove(); } [DomName("Comment")] public interface IComment : ICharacterData, INode, IEventTarget, IMarkupFormattable, IChildNode, INonDocumentTypeChildNode { } [DomName("Document")] public interface IDocument : INode, IEventTarget, IMarkupFormattable, IParentNode, IGlobalEventHandlers, IDocumentStyle, INonElementParentNode, IDisposable { [DomName("all")] IHtmlAllCollection All { get; } [DomName("anchors")] IHtmlCollection Anchors { get; } [DomName("implementation")] IImplementation Implementation { get; } [DomName("designMode")] string DesignMode { get; set; } [DomName("dir")] string? Direction { get; set; } [DomName("documentURI")] string DocumentUri { get; } [DomName("characterSet")] string CharacterSet { get; } [DomName("compatMode")] string CompatMode { get; } [DomName("URL")] string Url { get; } [DomName("contentType")] string ContentType { get; } [DomName("doctype")] IDocumentType Doctype { get; } [DomName("documentElement")] IElement DocumentElement { get; } [DomName("lastModified")] string? LastModified { get; } [DomLenientThis] [DomName("readyState")] DocumentReadyState ReadyState { get; } [DomName("location")] [DomPutForwards("href")] ILocation Location { get; } [DomName("forms")] IHtmlCollection Forms { get; } [DomName("images")] IHtmlCollection Images { get; } [DomName("scripts")] IHtmlCollection Scripts { get; } [DomName("embeds")] [DomName("plugins")] IHtmlCollection Plugins { get; } [DomName("commands")] IHtmlCollection Commands { get; } [DomName("links")] IHtmlCollection Links { get; } [DomName("title")] string? Title { get; set; } [DomName("head")] IHtmlHeadElement? Head { get; } [DomName("body")] IHtmlElement? Body { get; set; } [DomName("cookie")] string Cookie { get; set; } [DomName("origin")] string? Origin { get; } [DomName("domain")] string Domain { get; set; } [DomName("referrer")] string? Referrer { get; } [DomName("activeElement")] IElement? ActiveElement { get; } [DomName("currentScript")] IHtmlScriptElement? CurrentScript { get; } [DomName("defaultView")] IWindow? DefaultView { get; } IBrowsingContext Context { get; } IDocument? ImportAncestor { get; } TextSource Source { get; } HttpStatusCode StatusCode { get; } IEntityProvider Entities { get; } [DomName("onreadystatechange")] event DomEventHandler ReadyStateChanged; [DomName("open")] IDocument Open(string type = "text/html", string? replace = null); [DomName("close")] void Close(); [DomName("write")] void Write(string content); [DomName("writeln")] void WriteLine(string content); [DomName("load")] void Load(string url); [DomName("getElementsByName")] IHtmlCollection GetElementsByName(string name); [DomName("getElementsByClassName")] IHtmlCollection GetElementsByClassName(string classNames); [DomName("getElementsByTagName")] IHtmlCollection GetElementsByTagName(string tagName); [DomName("getElementsByTagNameNS")] IHtmlCollection GetElementsByTagName(string? namespaceUri, string tagName); [DomName("createEvent")] Event CreateEvent(string type); [DomName("createRange")] IRange CreateRange(); [DomName("createComment")] IComment CreateComment(string data); [DomName("createDocumentFragment")] IDocumentFragment CreateDocumentFragment(); [DomName("createElement")] IElement CreateElement(string name); [DomName("createElementNS")] IElement CreateElement(string? namespaceUri, string name); [DomName("createAttribute")] IAttr CreateAttribute(string name); [DomName("createAttributeNS")] IAttr CreateAttribute(string? namespaceUri, string name); [DomName("createProcessingInstruction")] IProcessingInstruction CreateProcessingInstruction(string target, string data); [DomName("createTextNode")] IText CreateTextNode(string data); [DomName("createNodeIterator")] INodeIterator CreateNodeIterator(INode root, FilterSettings settings = FilterSettings.All, NodeFilter? filter = null); [DomName("createTreeWalker")] ITreeWalker CreateTreeWalker(INode root, FilterSettings settings = FilterSettings.All, NodeFilter? filter = null); [DomName("importNode")] INode Import(INode externalNode, bool deep = true); [DomName("adoptNode")] INode Adopt(INode externalNode); [DomName("hasFocus")] bool HasFocus(); [DomName("execCommand")] bool ExecuteCommand(string commandId, bool showUserInterface = false, string value = ""); [DomName("queryCommandEnabled")] bool IsCommandEnabled(string commandId); [DomName("queryCommandIndeterm")] bool IsCommandIndeterminate(string commandId); [DomName("queryCommandState")] bool IsCommandExecuted(string commandId); [DomName("queryCommandSupported")] bool IsCommandSupported(string commandId); [DomName("queryCommandValue")] string? GetCommandValue(string commandId); bool AddImportUrl(Uri uri); bool HasImported(Uri uri); } public interface IDocumentFactory { Task CreateAsync(IBrowsingContext context, CreateDocumentOptions options, CancellationToken cancellationToken); } [DomName("DocumentFragment")] public interface IDocumentFragment : INode, IEventTarget, IMarkupFormattable, IParentNode, INonElementParentNode { } [DomName("DocumentStyle")] [DomNoInterfaceObject] public interface IDocumentStyle { [DomName("styleSheets")] IStyleSheetList StyleSheets { get; } [DomName("selectedStyleSheetSet")] string? SelectedStyleSheetSet { get; set; } [DomName("lastStyleSheetSet")] string? LastStyleSheetSet { get; } [DomName("preferredStyleSheetSet")] string? PreferredStyleSheetSet { get; } [DomName("styleSheetSets")] IStringList StyleSheetSets { get; } [DomName("enableStyleSheetsForSet")] void EnableStyleSheetsForSet(string name); } [DomName("DocumentType")] public interface IDocumentType : INode, IEventTarget, IMarkupFormattable, IChildNode { [DomName("name")] string Name { get; } [DomName("publicId")] string PublicIdentifier { get; } [DomName("systemId")] string SystemIdentifier { get; } } [DomName("DOMException")] public interface IDomException { [DomName("code")] int Code { get; } } [DomName("Element")] public interface IElement : INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { [DomName("prefix")] string? Prefix { get; } [DomName("localName")] string LocalName { get; } [DomName("namespaceURI")] string? NamespaceUri { get; } string? GivenNamespaceUri { get; } [DomName("attributes")] INamedNodeMap Attributes { get; } [DomName("classList")] ITokenList ClassList { get; } [DomName("className")] string? ClassName { get; set; } [DomName("id")] string? Id { get; set; } [DomName("innerHTML")] string InnerHtml { get; set; } [DomName("outerHTML")] string OuterHtml { get; set; } [DomName("tagName")] string TagName { get; } [DomName("assignedSlot")] IElement? AssignedSlot { get; } [DomName("slot")] string? Slot { get; set; } [DomName("shadowRoot")] IShadowRoot? ShadowRoot { get; } bool IsFocused { get; } ISourceReference? SourceReference { get; } [DomName("insertAdjacentHTML")] void Insert(AdjacentPosition position, string html); [DomName("hasAttribute")] bool HasAttribute(string name); [DomName("hasAttributeNS")] bool HasAttribute(string? namespaceUri, string localName); [DomName("getAttribute")] string? GetAttribute(string name); [DomName("getAttributeNS")] string? GetAttribute(string? namespaceUri, string localName); [DomName("setAttribute")] void SetAttribute(string name, string? value); [DomName("setAttributeNS")] void SetAttribute(string? namespaceUri, string name, string? value); [DomName("removeAttribute")] bool RemoveAttribute(string name); [DomName("removeAttributeNS")] bool RemoveAttribute(string? namespaceUri, string localName); [DomName("getElementsByClassName")] IHtmlCollection GetElementsByClassName(string classNames); [DomName("getElementsByTagName")] IHtmlCollection GetElementsByTagName(string tagName); [DomName("getElementsByTagNameNS")] IHtmlCollection GetElementsByTagNameNS(string? namespaceUri, string tagName); [DomName("matches")] bool Matches(string selectors); [DomName("closest")] IElement? Closest(string selectors); [DomName("attachShadow")] [DomInitDict(0, false)] IShadowRoot AttachShadow(ShadowRootMode mode = ShadowRootMode.Open); } public interface IElementFactory where TDocument : IDocument where TElement : IElement { TElement Create(TDocument document, string localName, string? prefix = null, NodeFlags flags = NodeFlags.None); } public interface IEntityProvider { string? GetSymbol(string name); } public interface IEntityProviderExtended { string? GetSymbol(StringOrMemory name); } [DomName("EventTarget")] public interface IEventTarget { [DomName("addEventListener")] void AddEventListener(string type, DomEventHandler? callback = null, bool capture = false); [DomName("removeEventListener")] void RemoveEventListener(string type, DomEventHandler? callback = null, bool capture = false); void InvokeEventListener(Event ev); [DomName("dispatchEvent")] bool Dispatch(Event ev); } [DomName("HTMLAllCollection")] public interface IHtmlAllCollection : IHtmlCollection, IEnumerable, IEnumerable { } [DomName("HTMLCollection")] public interface IHtmlCollection : IEnumerable, IEnumerable where T : IElement { [DomName("length")] int Length { get; } [DomName("item")] [DomAccessor(Accessors.Getter)] T this[int index] { get; } [DomName("namedItem")] [DomAccessor(Accessors.Getter)] T? this[string id] { get; } } [DomName("DOMImplementation")] public interface IImplementation { [DomName("createHTMLDocument")] IDocument CreateHtmlDocument(string title); [DomName("createDocumentType")] IDocumentType CreateDocumentType(string qualifiedName, string publicId, string systemId); [DomName("hasFeature")] bool HasFeature(string feature, string? version = null); } [DomName("LinkImport")] [DomNoInterfaceObject] public interface ILinkImport { [DomName("import")] IDocument? Import { get; } } [DomName("LinkStyle")] [DomNoInterfaceObject] public interface ILinkStyle { [DomName("sheet")] IStyleSheet? Sheet { get; } } [DomName("Location")] public interface ILocation : IUrlUtilities { [DomName("assign")] void Assign(string url); [DomName("replace")] void Replace(string url); [DomName("reload")] void Reload(); } [DomName("MutationRecord")] public interface IMutationRecord { [DomName("type")] string Type { get; } [DomName("target")] INode Target { get; } [DomName("addedNodes")] INodeList? Added { get; } [DomName("removedNodes")] INodeList? Removed { get; } [DomName("previousSibling")] INode? PreviousSibling { get; } [DomName("nextSibling")] INode? NextSibling { get; } [DomName("attributeName")] string? AttributeName { get; } [DomName("attributeNamespace")] string? AttributeNamespace { get; } [DomName("oldValue")] string? PreviousValue { get; } } [DomName("NamedNodeMap")] public interface INamedNodeMap : IEnumerable, IEnumerable { [DomName("item")] [DomAccessor(Accessors.Getter)] IAttr? this[int index] { get; } [DomAccessor(Accessors.Getter)] IAttr? this[string name] { get; } [DomName("length")] int Length { get; } [DomName("getNamedItem")] IAttr? GetNamedItem(string name); [DomName("setNamedItem")] IAttr? SetNamedItem(IAttr item); [DomName("removeNamedItem")] IAttr RemoveNamedItem(string name); [DomName("getNamedItemNS")] IAttr? GetNamedItem(string? namespaceUri, string localName); [DomName("setNamedItemNS")] IAttr? SetNamedItemWithNamespaceUri(IAttr item); [DomName("removeNamedItemNS")] IAttr RemoveNamedItem(string? namespaceUri, string localName); } [DomName("Node")] public interface INode : IEventTarget, IMarkupFormattable { [DomName("baseURI")] string BaseUri { get; } Url? BaseUrl { get; } [DomName("nodeName")] string NodeName { get; } [DomName("childNodes")] INodeList ChildNodes { get; } [DomName("ownerDocument")] IDocument? Owner { get; } [DomName("parentElement")] IElement? ParentElement { get; } [DomName("parentNode")] INode? Parent { get; } [DomName("firstChild")] INode? FirstChild { get; } [DomName("lastChild")] INode? LastChild { get; } [DomName("nextSibling")] INode? NextSibling { get; } [DomName("previousSibling")] INode? PreviousSibling { get; } [DomName("nodeType")] NodeType NodeType { get; } [DomName("nodeValue")] string NodeValue { get; set; } [DomName("textContent")] string TextContent { get; set; } [DomName("hasChildNodes")] [MemberNotNullWhen(true, new string[] { "ChildNodes", "FirstChild", "LastChild" })] bool HasChildNodes { [MemberNotNullWhen(true, new string[] { "ChildNodes", "FirstChild", "LastChild" })] get; } NodeFlags Flags { get; } [DomName("cloneNode")] INode Clone(bool deep = true); [DomName("isEqualNode")] bool Equals(INode otherNode); [DomName("compareDocumentPosition")] DocumentPositions CompareDocumentPosition(INode otherNode); [DomName("normalize")] void Normalize(); [DomName("contains")] bool Contains(INode otherNode); [DomName("isDefaultNamespace")] bool IsDefaultNamespace(string namespaceUri); [DomName("lookupNamespaceURI")] string? LookupNamespaceUri(string prefix); [DomName("lookupPrefix")] string? LookupPrefix(string? namespaceUri); [DomName("appendChild")] INode AppendChild(INode child); [DomName("insertBefore")] INode InsertBefore(INode newElement, INode? referenceElement); [DomName("removeChild")] INode RemoveChild(INode child); [DomName("replaceChild")] INode ReplaceChild(INode newChild, INode oldChild); } [DomName("NodeIterator")] public interface INodeIterator { [DomName("root")] INode Root { get; } [DomName("referenceNode")] INode Reference { get; } [DomName("pointerBeforeReferenceNode")] bool IsBeforeReference { get; } [DomName("whatToShow")] FilterSettings Settings { get; } [DomName("filter")] NodeFilter Filter { get; } [DomName("nextNode")] INode? Next(); [DomName("previousNode")] INode? Previous(); } [DomName("NodeList")] public interface INodeList : IEnumerable, IEnumerable, IMarkupFormattable { [DomName("item")] [DomAccessor(Accessors.Getter)] INode this[int index] { get; } [DomName("length")] int Length { get; } } [DomName("NonDocumentTypeChildNode")] [DomNoInterfaceObject] public interface INonDocumentTypeChildNode { [DomName("nextElementSibling")] IElement? NextElementSibling { get; } [DomName("previousElementSibling")] IElement? PreviousElementSibling { get; } } [DomName("NonElementParentNode")] [DomNoInterfaceObject] public interface INonElementParentNode { [DomName("getElementById")] IElement? GetElementById(string elementId); } internal sealed class AnyElement : Element { public AnyElement(Document owner, string localName, string? prefix, string? namespaceUri, NodeFlags flags = NodeFlags.None) : base(owner, localName, prefix, namespaceUri, flags) { } public override IElement ParseSubtree(string html) { return this.ParseHtmlSubtree(html); } } public sealed class Attr : IAttr, INode, IEventTarget, IMarkupFormattable, IEquatable, IConstructableAttr { private readonly string _localName; private readonly string? _prefix; private readonly string? _namespace; private string _value; internal NamedNodeMap? Container { get; set; } public bool IsSpecified => true; public IElement? OwnerElement => Container?.Owner; public string? Prefix => _prefix; public bool IsId { get { if (_prefix == null) { return _localName.Isi(AttributeNames.Id); } return false; } } public bool Specified => !string.IsNullOrEmpty(_value); public string Name { get { if (_prefix != null) { return _prefix + ":" + _localName; } return _localName; } } StringOrMemory IConstructableAttr.Value { get { return Value; } set { Value = value.ToString(); } } StringOrMemory IConstructableAttr.Name => Name; public string Value { get { return _value; } set { string value2 = _value; _value = value; Container?.RaiseChangedEvent(this, value, value2); } } public string LocalName => _localName; public string? NamespaceUri => _namespace; string INode.BaseUri => OwnerElement.BaseUri; Url? INode.BaseUrl => OwnerElement?.BaseUrl; string INode.NodeName => Name; INodeList INode.ChildNodes => NodeList.Empty; IDocument? INode.Owner => OwnerElement?.Owner; IElement? INode.ParentElement => null; INode? INode.Parent => null; INode? INode.FirstChild => null; INode? INode.LastChild => null; INode? INode.NextSibling => null; INode? INode.PreviousSibling => null; NodeType INode.NodeType => NodeType.Attribute; string INode.NodeValue { get { return Value; } set { Value = value; } } string INode.TextContent { get { return Value; } set { Value = value; } } bool INode.HasChildNodes => false; NodeFlags INode.Flags { get { throw new NotImplementedException(); } } public Attr(string localName) : this(localName, string.Empty) { } public Attr(string localName, string value) { _localName = localName; _value = value; } public Attr(string? prefix, string localName, string value, string? namespaceUri) { _prefix = prefix; _localName = localName; _value = value; _namespace = namespaceUri; } public bool Equals(IAttr? other) { if (Prefix.Is(other?.Prefix) && NamespaceUri.Is(other?.NamespaceUri)) { return Value.Is(other?.Value); } return false; } public override int GetHashCode() { return (((1 * 31 + _localName.GetHashCode()) * 31 + (_value ?? string.Empty).GetHashCode()) * 31 + (_namespace ?? string.Empty).GetHashCode()) * 31 + (_prefix ?? string.Empty).GetHashCode(); } INode INode.Clone(bool deep) { return new Attr(_prefix, _localName, _value, _namespace); } bool INode.Equals(INode otherNode) { if (otherNode is IAttr other) { return Equals(other); } return false; } DocumentPositions INode.CompareDocumentPosition(INode otherNode) { return OwnerElement?.CompareDocumentPosition(otherNode) ?? DocumentPositions.Disconnected; } void INode.Normalize() { } bool INode.Contains(INode otherNode) { return false; } bool INode.IsDefaultNamespace(string namespaceUri) { return OwnerElement?.IsDefaultNamespace(namespaceUri) ?? false; } string? INode.LookupNamespaceUri(string prefix) { return OwnerElement?.LookupNamespaceUri(prefix); } string? INode.LookupPrefix(string? namespaceUri) { return OwnerElement?.LookupPrefix(namespaceUri); } INode INode.AppendChild(INode child) { throw new DomException(DomError.NotSupported); } INode INode.InsertBefore(INode newElement, INode? referenceElement) { throw new DomException(DomError.NotSupported); } INode INode.RemoveChild(INode child) { throw new DomException(DomError.NotSupported); } INode INode.ReplaceChild(INode newChild, INode oldChild) { throw new DomException(DomError.NotSupported); } void IEventTarget.AddEventListener(string type, DomEventHandler? callback, bool capture) { throw new DomException(DomError.NotSupported); } void IEventTarget.RemoveEventListener(string type, DomEventHandler? callback, bool capture) { throw new DomException(DomError.NotSupported); } void IEventTarget.InvokeEventListener(Event ev) { throw new DomException(DomError.NotSupported); } bool IEventTarget.Dispatch(Event ev) { throw new DomException(DomError.NotSupported); } void IMarkupFormattable.ToHtml(TextWriter writer, IMarkupFormatter formatter) { } } internal abstract class CharacterData : Node, ICharacterData, INode, IEventTarget, IMarkupFormattable, IChildNode, INonDocumentTypeChildNode { private string _content; public IElement? PreviousElementSibling { get { Node parent = base.Parent; if (parent != null) { bool flag = false; for (int num = parent.ChildNodes.Length - 1; num >= 0; num--) { if (parent.ChildNodes[num] == this) { flag = true; } else if (flag && parent.ChildNodes[num] is IElement result) { return result; } } } return null; } } public IElement? NextElementSibling { get { Node parent = base.Parent; if (parent != null) { int length = parent.ChildNodes.Length; bool flag = false; for (int i = 0; i < length; i++) { if (parent.ChildNodes[i] == this) { flag = true; } else if (flag && parent.ChildNodes[i] is IElement result) { return result; } } } return null; } } internal char this[int index] { get { return _content[index]; } set { if (index >= 0) { if (index >= Length) { _content = _content.PadRight(index) + value; return; } char[] array = _content.ToCharArray(); array[index] = value; _content = new string(array); } } } public int Length => _content.Length; public sealed override string NodeValue { get { return Data; } set { Data = value; } } public sealed override string TextContent { get { return Data; } set { Data = value; } } public string Data { get { return _content; } set { Replace(0, Length, value); } } internal CharacterData(Document owner, string name, NodeType type) : this(owner, name, type, string.Empty) { } internal CharacterData(Document owner, string name, NodeType type, string content) : base(owner, name, type) { _content = content; } public string Substring(int offset, int count) { int length = _content.Length; if (offset > length) { throw new DomException(DomError.IndexSizeError); } if (offset + count > length) { return _content.Substring(offset); } return _content.Substring(offset, count); } public void Append(string value) { Replace(_content.Length, 0, value); } public void Insert(int offset, string data) { Replace(offset, 0, data); } public void Delete(int offset, int count) { Replace(offset, count, string.Empty); } public void Replace(int offset, int count, string data) { Document owner = base.Owner; int length = _content.Length; if (offset > length) { throw new DomException(DomError.IndexSizeError); } if (offset + count > length) { count = length - offset; } string content = _content; int startIndex = offset + data.Length; _content = _content.Insert(offset, data); if (count > 0) { _content = _content.Remove(startIndex, count); } owner.QueueMutation(MutationRecord.CharacterData(this, content)); foreach (Range attachedReference in owner.GetAttachedReferences()) { if (attachedReference.Head == this && attachedReference.Start > offset && attachedReference.Start <= offset + count) { attachedReference.StartWith(this, offset); } if (attachedReference.Tail == this && attachedReference.End > offset && attachedReference.End <= offset + count) { attachedReference.EndWith(this, offset); } if (attachedReference.Head == this && attachedReference.Start > offset + count) { attachedReference.StartWith(this, attachedReference.Start + data.Length - count); } if (attachedReference.Tail == this && attachedReference.End > offset + count) { attachedReference.EndWith(this, attachedReference.End + data.Length - count); } } } public void Before(params INode[] nodes) { this.InsertBefore(nodes); } public void After(params INode[] nodes) { this.InsertAfter(nodes); } public void Replace(params INode[] nodes) { this.ReplaceWith(nodes); } public void Remove() { this.RemoveFromParent(); } } public static class CollectionExtensions { public static IEnumerable GetNodes(this INode parent, bool deep = true, Func? predicate = null) where T : class, INode { if (predicate == null) { predicate = (T _) => true; } if (!deep) { return parent.GetDescendendElements(predicate); } return parent.GetAllNodes(predicate); } public static IElement? GetElementById(this INodeList children, string id) { for (int i = 0; i < children.Length; i++) { if (children[i] is IElement element) { if (element.Id.Is(id)) { return element; } IElement elementById = element.ChildNodes.GetElementById(id); if (elementById != null) { return elementById; } } } return null; } public static void GetElementsByName(this INodeList children, string name, List result) { for (int i = 0; i < children.Length; i++) { if (children[i] is IElement element) { if (element.GetAttribute(null, AttributeNames.Name).Is(name)) { result.Add(element); } element.ChildNodes.GetElementsByName(name, result); } } } public static bool Accepts(this FilterSettings filter, INode node) { return node.NodeType switch { NodeType.Attribute => (filter & FilterSettings.Attribute) == FilterSettings.Attribute, NodeType.CharacterData => (filter & FilterSettings.CharacterData) == FilterSettings.CharacterData, NodeType.Comment => (filter & FilterSettings.Comment) == FilterSettings.Comment, NodeType.Document => (filter & FilterSettings.Document) == FilterSettings.Document, NodeType.DocumentFragment => (filter & FilterSettings.DocumentFragment) == FilterSettings.DocumentFragment, NodeType.DocumentType => (filter & FilterSettings.DocumentType) == FilterSettings.DocumentType, NodeType.Element => (filter & FilterSettings.Element) == FilterSettings.Element, NodeType.Entity => (filter & FilterSettings.Entity) == FilterSettings.Entity, NodeType.EntityReference => (filter & FilterSettings.EntityReference) == FilterSettings.EntityReference, NodeType.ProcessingInstruction => (filter & FilterSettings.ProcessingInstruction) == FilterSettings.ProcessingInstruction, NodeType.Notation => (filter & FilterSettings.Notation) == FilterSettings.Notation, NodeType.Text => (filter & FilterSettings.Text) == FilterSettings.Text, _ => filter == FilterSettings.All, }; } public static T? GetElementById(this IEnumerable elements, string id) where T : class, IElement { foreach (T element in elements) { if (element.Id.Is(id)) { return element; } } foreach (T element2 in elements) { if (element2.GetAttribute(null, AttributeNames.Name).Is(id)) { return element2; } } return null; } private static IEnumerable GetAllNodes(this INode parent, Func predicate) where T : class, INode { return new NodeEnumerable(parent).OfType().Where(predicate); } private static IEnumerable GetDescendendElements(this INode parent, Func predicate) where T : class, INode { for (int i = 0; i < parent.ChildNodes.Length; i++) { if (parent.ChildNodes[i] is T val && predicate(val)) { yield return val; } } } } internal sealed class Comment : CharacterData, IComment, ICharacterData, INode, IEventTarget, IMarkupFormattable, IChildNode, INonDocumentTypeChildNode { internal Comment(Document owner) : this(owner, string.Empty) { } internal Comment(Document owner, string data) : base(owner, "#comment", NodeType.Comment, data) { } public override Node Clone(Document owner, bool deep) { Comment comment = new Comment(owner, base.Data); CloneNode(comment, owner, deep); return comment; } } internal enum ContentEditableMode : byte { False, True, Inherited } public class DefaultAttributeObserver : IAttributeObserver { private readonly List> _actions; public DefaultAttributeObserver() { _actions = new List>(); RegisterStandardObservers(); } protected virtual void RegisterStandardObservers() { RegisterObserver(AttributeNames.Class, delegate(Element element, string value) { element.UpdateClassList(value); }); RegisterObserver(AttributeNames.DropZone, delegate(HtmlElement element, string value) { element.UpdateDropZone(value); }); RegisterObserver(AttributeNames.Href, delegate(HtmlBaseElement element, string value) { element.UpdateUrl(value); }); RegisterObserver(AttributeNames.Src, delegate(HtmlEmbedElement element, string value) { element.UpdateSource(value); }); RegisterObserver(AttributeNames.Sizes, delegate(HtmlLinkElement element, string value) { element.UpdateSizes(value); }); RegisterObserver(AttributeNames.Media, delegate(HtmlLinkElement element, string value) { element.UpdateMedia(value); }); RegisterObserver(AttributeNames.Disabled, delegate(HtmlLinkElement element, string value) { element.UpdateDisabled(value); }); RegisterObserver(AttributeNames.Href, delegate(HtmlLinkElement element, string value) { element.UpdateSource(value); }); RegisterObserver(AttributeNames.Rel, delegate(HtmlUrlBaseElement element, string value) { element.UpdateRel(value); }); RegisterObserver(AttributeNames.Ping, delegate(HtmlUrlBaseElement element, string value) { element.UpdatePing(value); }); RegisterObserver(AttributeNames.Headers, delegate(HtmlTableCellElement element, string value) { element.UpdateHeaders(value); }); RegisterObserver(AttributeNames.Media, delegate(HtmlStyleElement element, string value) { element.UpdateMedia(value); }); RegisterObserver(AttributeNames.Value, delegate(HtmlSelectElement element, string value) { element.UpdateValue(value); }); RegisterObserver(AttributeNames.For, delegate(HtmlOutputElement element, string value) { element.UpdateFor(value); }); RegisterObserver(AttributeNames.Data, delegate(HtmlObjectElement element, string value) { element.UpdateSource(value); }); RegisterObserver(AttributeNames.Src, delegate(HtmlAudioElement element, string value) { element.UpdateSource(value); }); RegisterObserver(AttributeNames.Src, delegate(HtmlVideoElement element, string value) { element.UpdateSource(value); }); RegisterObserver(AttributeNames.Src, delegate(HtmlImageElement element, string _) { element.UpdateSource(); }); RegisterObserver(AttributeNames.SrcSet, delegate(HtmlImageElement element, string _) { element.UpdateSource(); }); RegisterObserver(AttributeNames.Sizes, delegate(HtmlImageElement element, string _) { element.UpdateSource(); }); RegisterObserver(AttributeNames.CrossOrigin, delegate(HtmlImageElement element, string _) { element.UpdateSource(); }); RegisterObserver(AttributeNames.Sandbox, delegate(HtmlIFrameElement element, string value) { element.UpdateSandbox(value); }); RegisterObserver(AttributeNames.SrcDoc, delegate(HtmlIFrameElement element, string _) { element.UpdateSource(); }); RegisterObserver(AttributeNames.Src, delegate(HtmlFrameElementBase element, string _) { element.UpdateSource(); }); RegisterObserver(AttributeNames.Type, delegate(HtmlInputElement element, string value) { element.UpdateType(value); }); } public void RegisterObserver(string expectedName, Action callback) where TElement : IElement { _actions.Add(delegate(IElement element, string actualName, string value) { if (element is TElement arg && actualName.Is(expectedName)) { callback(arg, value); } }); } void IAttributeObserver.NotifyChange(IElement host, string name, string? value) { foreach (Action action in _actions) { action(host, name, value); } } } public abstract class Document : Node, IDocument, INode, IEventTarget, IMarkupFormattable, IParentNode, IGlobalEventHandlers, IDocumentStyle, INonElementParentNode, IDisposable, IConstructableDocument, IConstructableNode { private readonly List _attachedReferences; private readonly Queue _loadingScripts; private readonly MutationHost _mutations; private readonly IBrowsingContext _context; private readonly IEventLoop? _loop; private readonly Window _view; private readonly IResourceLoader? _loader; private readonly Location _location; private readonly TextSource _source; private readonly object _importedUrisLock = new object(); private QuirksMode _quirksMode; private Sandboxes _sandbox; private bool _async; private bool _designMode; private bool _shown; private bool _salvageable; private bool _firedUnload; private DocumentReadyState _ready; private IElement? _focus; private HtmlAllCollection? _all; private HtmlCollection? _anchors; private HtmlCollection? _children; private DomImplementation? _implementation; private IStringList? _styleSheetSets; private HtmlCollection? _images; private HtmlCollection? _scripts; private HtmlCollection? _plugins; private HtmlCollection? _commands; private HtmlCollection? _links; private IStyleSheetList? _styleSheets; private HttpStatusCode _statusCode; private HashSet? _importedUris; public TextSource Source => _source ?? _source; public abstract IEntityProvider Entities { get; } public IDocument? ImportAncestor { get; private set; } public IEventLoop? Loop => _loop; public string DesignMode { get { if (!_designMode) { return Keywords.Off; } return Keywords.On; } set { _designMode = value.Isi(Keywords.On); } } public IHtmlAllCollection All => _all ?? (_all = new HtmlAllCollection(this)); public IHtmlCollection Anchors => _anchors ?? (_anchors = new HtmlCollection(this, deep: true, IsAnchor)); public int ChildElementCount => base.ChildNodes.OfType().Count(); public IHtmlCollection Children => _children ?? (_children = new HtmlCollection(base.ChildNodes.OfType())); public IElement? FirstElementChild { get { NodeList childNodes = base.ChildNodes; int length = childNodes.Length; for (int i = 0; i < length; i++) { if (childNodes[i] is IElement result) { return result; } } return null; } } public IElement? LastElementChild { get { NodeList childNodes = base.ChildNodes; for (int num = childNodes.Length - 1; num >= 0; num--) { if (childNodes[num] is IElement result) { return result; } } return null; } } public bool IsAsync => _async; public IHtmlScriptElement? CurrentScript { get { if (_loadingScripts.Count <= 0) { return null; } return _loadingScripts.Peek(); } } public IImplementation Implementation => _implementation ?? (_implementation = new DomImplementation(this)); public string? LastModified { get; protected set; } public IDocumentType Doctype => this.FindChild(); public string ContentType { get; protected set; } public DocumentReadyState ReadyState { get { return _ready; } protected set { _ready = value; this.FireSimpleEvent(EventNames.ReadyStateChanged); } } public IStyleSheetList StyleSheets => _styleSheets ?? (_styleSheets = this.CreateStyleSheets()); public IStringList StyleSheetSets => _styleSheetSets ?? (_styleSheetSets = this.CreateStyleSheetSets()); public string Referrer { get; protected set; } public ILocation Location => _location; public string DocumentUri { get { return _location.Href; } protected set { _location.Changed -= LocationChanged; _location.Href = value; _location.Changed += LocationChanged; } } public Url DocumentUrl => _location.Original; public IWindow DefaultView => _view; public string? Direction { get { return ((DocumentElement as IHtmlElement) ?? new HtmlHtmlElement(this)).Direction; } set { ((DocumentElement as IHtmlElement) ?? new HtmlHtmlElement(this)).Direction = value; } } public string CharacterSet => _source.CurrentEncoding.WebName; public abstract IElement DocumentElement { get; } public IElement? ActiveElement => All.FirstOrDefault((IElement m) => m.IsFocused); public string CompatMode => _quirksMode.GetCompatiblity(); public string Url => _location.Href; public IHtmlCollection Forms => new HtmlCollection(this); public IHtmlCollection Images => _images ?? (_images = new HtmlCollection(this)); public IHtmlCollection Scripts => _scripts ?? (_scripts = new HtmlCollection(this)); public IHtmlCollection Plugins => _plugins ?? (_plugins = new HtmlCollection(this)); public IHtmlCollection Commands => _commands ?? (_commands = new HtmlCollection(this, deep: true, IsCommand)); public IHtmlCollection Links => _links ?? (_links = new HtmlCollection(this, deep: true, IsLink)); public string? Title { get { return GetTitle(); } set { SetTitle(value); } } public IHtmlHeadElement? Head => DocumentElement.FindChild(); public IHtmlElement? Body { get { IElement documentElement = DocumentElement; if (documentElement != null) { foreach (INode childNode in documentElement.ChildNodes) { if (childNode is HtmlBodyElement result) { return result; } if (childNode is HtmlFrameSetElement result2) { return result2; } } } return null; } set { if (!(value is IHtmlBodyElement) && !(value is HtmlFrameSetElement)) { throw new DomException(DomError.HierarchyRequest); } IHtmlElement body = Body; if (body != value) { if (body == null) { (DocumentElement ?? throw new DomException(DomError.HierarchyRequest)).AppendChild(value); } else { ReplaceChild(value, body); } } } } public IBrowsingContext Context => _context; public HttpStatusCode StatusCode { get { return _statusCode; } private set { _statusCode = value; } } public string Cookie { get { return _context.GetCookie(_location.Original); } set { _context.SetCookie(_location.Original, value); } } public string Domain { get { if (!string.IsNullOrEmpty(DocumentUri)) { return new Uri(DocumentUri).Host; } return string.Empty; } set { if (_location != null) { _location.Host = value; } } } public string? Origin => _location.Origin; public string? SelectedStyleSheetSet { get { IEnumerable enabledStyleSheetSets = StyleSheets.GetEnabledStyleSheetSets(); string enabledName = enabledStyleSheetSets.FirstOrDefault(); IEnumerable source = StyleSheets.Where((IStyleSheet m) => !string.IsNullOrEmpty(m.Title) && !m.IsDisabled); if (enabledStyleSheetSets.Count() == 1 && !source.Any((IStyleSheet m) => !m.Title.Is(enabledName))) { return enabledName; } if (source.Any()) { return null; } return string.Empty; } set { if (value != null) { StyleSheets.EnableStyleSheetSet(value); LastStyleSheetSet = value; } } } public string? LastStyleSheetSet { get; private set; } public string? PreferredStyleSheetSet => (from m in All.OfType() where m.IsPreferred() select m.Title).FirstOrDefault(); public bool IsReady => ReadyState == DocumentReadyState.Complete; public bool IsLoading => ReadyState == DocumentReadyState.Loading; internal MutationHost Mutations => _mutations; internal QuirksMode QuirksMode { get { return _quirksMode; } set { _quirksMode = value; } } internal Sandboxes ActiveSandboxing { get { return _sandbox; } set { _sandbox = value; } } internal bool IsInBrowsingContext => _context.Active != null; internal bool IsToBePrinted => false; internal IElement? FocusElement => _focus; TextSource IConstructableDocument.Source => _source; IDisposable? IConstructableDocument.Builder { get; set; } QuirksMode IConstructableDocument.QuirksMode { get { return QuirksMode; } set { QuirksMode = value; } } IConstructableElement? IConstructableDocument.Head => DocumentElement.FindChild(); IConstructableElement IConstructableDocument.DocumentElement => this.FindChild(); bool IConstructableDocument.IsLoading => IsLoading; public event DomEventHandler ReadyStateChanged { add { AddEventListener(EventNames.ReadyStateChanged, value); } remove { RemoveEventListener(EventNames.ReadyStateChanged, value); } } public event DomEventHandler Aborted { add { AddEventListener(EventNames.Abort, value); } remove { RemoveEventListener(EventNames.Abort, value); } } public event DomEventHandler Blurred { add { AddEventListener(EventNames.Blur, value); } remove { RemoveEventListener(EventNames.Blur, value); } } public event DomEventHandler Cancelled { add { AddEventListener(EventNames.Cancel, value); } remove { RemoveEventListener(EventNames.Cancel, value); } } public event DomEventHandler CanPlay { add { AddEventListener(EventNames.CanPlay, value); } remove { RemoveEventListener(EventNames.CanPlay, value); } } public event DomEventHandler CanPlayThrough { add { AddEventListener(EventNames.CanPlayThrough, value); } remove { RemoveEventListener(EventNames.CanPlayThrough, value); } } public event DomEventHandler Changed { add { AddEventListener(EventNames.Change, value); } remove { RemoveEventListener(EventNames.Change, value); } } public event DomEventHandler Clicked { add { AddEventListener(EventNames.Click, value); } remove { RemoveEventListener(EventNames.Click, value); } } public event DomEventHandler CueChanged { add { AddEventListener(EventNames.CueChange, value); } remove { RemoveEventListener(EventNames.CueChange, value); } } public event DomEventHandler DoubleClick { add { AddEventListener(EventNames.DblClick, value); } remove { RemoveEventListener(EventNames.DblClick, value); } } public event DomEventHandler Drag { add { AddEventListener(EventNames.Drag, value); } remove { RemoveEventListener(EventNames.Drag, value); } } public event DomEventHandler DragEnd { add { AddEventListener(EventNames.DragEnd, value); } remove { RemoveEventListener(EventNames.DragEnd, value); } } public event DomEventHandler DragEnter { add { AddEventListener(EventNames.DragEnter, value); } remove { RemoveEventListener(EventNames.DragEnter, value); } } public event DomEventHandler DragExit { add { AddEventListener(EventNames.DragExit, value); } remove { RemoveEventListener(EventNames.DragExit, value); } } public event DomEventHandler DragLeave { add { AddEventListener(EventNames.DragLeave, value); } remove { RemoveEventListener(EventNames.DragLeave, value); } } public event DomEventHandler DragOver { add { AddEventListener(EventNames.DragOver, value); } remove { RemoveEventListener(EventNames.DragOver, value); } } public event DomEventHandler DragStart { add { AddEventListener(EventNames.DragStart, value); } remove { RemoveEventListener(EventNames.DragStart, value); } } public event DomEventHandler Dropped { add { AddEventListener(EventNames.Drop, value); } remove { RemoveEventListener(EventNames.Drop, value); } } public event DomEventHandler DurationChanged { add { AddEventListener(EventNames.DurationChange, value); } remove { RemoveEventListener(EventNames.DurationChange, value); } } public event DomEventHandler Emptied { add { AddEventListener(EventNames.Emptied, value); } remove { RemoveEventListener(EventNames.Emptied, value); } } public event DomEventHandler Ended { add { AddEventListener(EventNames.Ended, value); } remove { RemoveEventListener(EventNames.Ended, value); } } public event DomEventHandler Error { add { AddEventListener(EventNames.Error, value); } remove { RemoveEventListener(EventNames.Error, value); } } public event DomEventHandler Focused { add { AddEventListener(EventNames.Focus, value); } remove { RemoveEventListener(EventNames.Focus, value); } } public event DomEventHandler Input { add { AddEventListener(EventNames.Input, value); } remove { RemoveEventListener(EventNames.Input, value); } } public event DomEventHandler Invalid { add { AddEventListener(EventNames.Invalid, value); } remove { RemoveEventListener(EventNames.Invalid, value); } } public event DomEventHandler KeyDown { add { AddEventListener(EventNames.Keydown, value); } remove { RemoveEventListener(EventNames.Keydown, value); } } public event DomEventHandler KeyPress { add { AddEventListener(EventNames.Keypress, value); } remove { RemoveEventListener(EventNames.Keypress, value); } } public event DomEventHandler KeyUp { add { AddEventListener(EventNames.Keyup, value); } remove { RemoveEventListener(EventNames.Keyup, value); } } public event DomEventHandler Loaded { add { AddEventListener(EventNames.Load, value); } remove { RemoveEventListener(EventNames.Load, value); } } public event DomEventHandler LoadedData { add { AddEventListener(EventNames.LoadedData, value); } remove { RemoveEventListener(EventNames.LoadedData, value); } } public event DomEventHandler LoadedMetadata { add { AddEventListener(EventNames.LoadedMetaData, value); } remove { RemoveEventListener(EventNames.LoadedMetaData, value); } } public event DomEventHandler Loading { add { AddEventListener(EventNames.LoadStart, value); } remove { RemoveEventListener(EventNames.LoadStart, value); } } public event DomEventHandler MouseDown { add { AddEventListener(EventNames.Mousedown, value); } remove { RemoveEventListener(EventNames.Mousedown, value); } } public event DomEventHandler MouseEnter { add { AddEventListener(EventNames.Mouseenter, value); } remove { RemoveEventListener(EventNames.Mouseenter, value); } } public event DomEventHandler MouseLeave { add { AddEventListener(EventNames.Mouseleave, value); } remove { RemoveEventListener(EventNames.Mouseleave, value); } } public event DomEventHandler MouseMove { add { AddEventListener(EventNames.Mousemove, value); } remove { RemoveEventListener(EventNames.Mousemove, value); } } public event DomEventHandler MouseOut { add { AddEventListener(EventNames.Mouseout, value); } remove { RemoveEventListener(EventNames.Mouseout, value); } } public event DomEventHandler MouseOver { add { AddEventListener(EventNames.Mouseover, value); } remove { RemoveEventListener(EventNames.Mouseover, value); } } public event DomEventHandler MouseUp { add { AddEventListener(EventNames.Mouseup, value); } remove { RemoveEventListener(EventNames.Mouseup, value); } } public event DomEventHandler MouseWheel { add { AddEventListener(EventNames.Wheel, value); } remove { RemoveEventListener(EventNames.Wheel, value); } } public event DomEventHandler Paused { add { AddEventListener(EventNames.Pause, value); } remove { RemoveEventListener(EventNames.Pause, value); } } public event DomEventHandler Played { add { AddEventListener(EventNames.Play, value); } remove { RemoveEventListener(EventNames.Play, value); } } public event DomEventHandler Playing { add { AddEventListener(EventNames.Playing, value); } remove { RemoveEventListener(EventNames.Playing, value); } } public event DomEventHandler Progress { add { AddEventListener(EventNames.Progress, value); } remove { RemoveEventListener(EventNames.Progress, value); } } public event DomEventHandler RateChanged { add { AddEventListener(EventNames.RateChange, value); } remove { RemoveEventListener(EventNames.RateChange, value); } } public event DomEventHandler Resetted { add { AddEventListener(EventNames.Reset, value); } remove { RemoveEventListener(EventNames.Reset, value); } } public event DomEventHandler Resized { add { AddEventListener(EventNames.Resize, value); } remove { RemoveEventListener(EventNames.Resize, value); } } public event DomEventHandler Scrolled { add { AddEventListener(EventNames.Scroll, value); } remove { RemoveEventListener(EventNames.Scroll, value); } } public event DomEventHandler Seeked { add { AddEventListener(EventNames.Seeked, value); } remove { RemoveEventListener(EventNames.Seeked, value); } } public event DomEventHandler Seeking { add { AddEventListener(EventNames.Seeking, value); } remove { RemoveEventListener(EventNames.Seeking, value); } } public event DomEventHandler Selected { add { AddEventListener(EventNames.Select, value); } remove { RemoveEventListener(EventNames.Select, value); } } public event DomEventHandler Shown { add { AddEventListener(EventNames.Show, value); } remove { RemoveEventListener(EventNames.Show, value); } } public event DomEventHandler Stalled { add { AddEventListener(EventNames.Stalled, value); } remove { RemoveEventListener(EventNames.Stalled, value); } } public event DomEventHandler Submitted { add { AddEventListener(EventNames.Submit, value); } remove { RemoveEventListener(EventNames.Submit, value); } } public event DomEventHandler Suspended { add { AddEventListener(EventNames.Suspend, value); } remove { RemoveEventListener(EventNames.Suspend, value); } } public event DomEventHandler TimeUpdated { add { AddEventListener(EventNames.TimeUpdate, value); } remove { RemoveEventListener(EventNames.TimeUpdate, value); } } public event DomEventHandler Toggled { add { AddEventListener(EventNames.Toggle, value); } remove { RemoveEventListener(EventNames.Toggle, value); } } public event DomEventHandler VolumeChanged { add { AddEventListener(EventNames.VolumeChange, value); } remove { RemoveEventListener(EventNames.VolumeChange, value); } } public event DomEventHandler Waiting { add { AddEventListener(EventNames.Waiting, value); } remove { RemoveEventListener(EventNames.Waiting, value); } } public Document(IBrowsingContext context, TextSource source) : base(null, "#document", NodeType.Document) { Referrer = string.Empty; ContentType = MimeTypeNames.ApplicationXml; _attachedReferences = new List(); _async = true; _designMode = false; _firedUnload = false; _salvageable = true; _shown = false; _context = context; _source = source; _ready = DocumentReadyState.Loading; _sandbox = Sandboxes.None; _quirksMode = QuirksMode.Off; _loadingScripts = new Queue(); _location = new Location("about:blank"); _location.Changed += LocationChanged; _view = new Window(this); _loader = context.GetService(); _loop = context.GetService(); _mutations = new MutationHost(_loop); _statusCode = HttpStatusCode.OK; } internal void AddScript(HtmlScriptElement script) { _loadingScripts.Enqueue(script); } public void Clear() { ReplaceAll(null, suppressObservers: true); } public virtual void Dispose() { Clear(); _loop?.CancelAll(); _loadingScripts.Clear(); _source.Dispose(); _view?.Dispose(); ((IConstructableDocument)this).Builder?.Dispose(); } public void EnableStyleSheetsForSet(string name) { if (name != null) { StyleSheets.EnableStyleSheetSet(name); } } public IDocument Open(string type = "text/html", string? replace = null) { if (!ContentType.Is(MimeTypeNames.Html)) { throw new DomException(DomError.InvalidState); } if (!IsInBrowsingContext || _context.Active == this) { IDocument document = _context?.Parent.Active; if (document != null && !document.Origin.Is(Origin)) { throw new DomException(DomError.Security); } if (!_firedUnload && _loadingScripts.Count == 0) { bool num = replace.Isi(Keywords.Replace); IHistory sessionHistory = _context.SessionHistory; int num2 = type?.IndexOf(';') ?? (-1); if (!num && sessionHistory != null) { if (sessionHistory.Length == 1) { _ = sessionHistory[0].Url == "about:blank"; } else _ = 0; } _salvageable = false; if (!PromptToUnloadAsync().Result) { return this; } Unload(recycle: true).Wait(); Abort(); RemoveEventListeners(); foreach (Element item in this.Descendants()) { item.RemoveEventListeners(); } _loop?.CancelAll(); ReplaceAll(null, suppressObservers: true); _source.CurrentEncoding = TextEncoding.Utf8; _salvageable = true; _ready = DocumentReadyState.Loading; if (type.Isi(Keywords.Replace)) { type = MimeTypeNames.Html; } else if (num2 >= 0) { type = type.Substring(0, num2); } type = type.StripLeadingTrailingSpaces(); type.Isi(MimeTypeNames.Html); ContentType = type; _firedUnload = false; _source.Index = _source.Length; } return this; } return null; } public void Load(string url) { Location.Href = url; } void IDocument.Close() { if (IsLoading) { FinishLoadingAsync().Wait(); } } public void Write(string content) { if (IsReady) { string content2 = content ?? string.Empty; Open().Write(content2); } else { ((ITextSource)_source)?.InsertText(content); } } public void WriteLine(string content) { Write(content + "\n"); } public IHtmlCollection GetElementsByName(string name) { List list = new List(); base.ChildNodes.GetElementsByName(name, list); return new HtmlCollection(list); } public INode Import(INode externalNode, bool deep = true) { if (externalNode.NodeType == NodeType.Document) { throw new DomException(DomError.NotSupported); } return externalNode.Clone(deep); } public INode Adopt(INode externalNode) { if (externalNode.NodeType == NodeType.Document) { throw new DomException(DomError.NotSupported); } this.AdoptNode(externalNode); return externalNode; } public Event CreateEvent(string type) { return _context.GetFactory().Create(type) ?? throw new DomException(DomError.NotSupported); } public INodeIterator CreateNodeIterator(INode root, FilterSettings settings = FilterSettings.All, NodeFilter? filter = null) { return new NodeIterator(root, settings, filter); } public ITreeWalker CreateTreeWalker(INode root, FilterSettings settings = FilterSettings.All, NodeFilter? filter = null) { return new TreeWalker(root, settings, filter); } public IRange CreateRange() { Range range = new Range(this); AttachReference(range); return range; } public void Prepend(params INode[] nodes) { this.PrependNodes(nodes); } public void Append(params INode[] nodes) { this.AppendNodes(nodes); } public IElement CreateElement(string localName) { if (localName.IsXmlName()) { HtmlElement htmlElement = _context.GetFactory>().Create(this, localName); htmlElement.SetupElement(); return htmlElement; } throw new DomException(DomError.InvalidCharacter); } public IElement CreateElement(string? namespaceUri, string qualifiedName) { Node.GetPrefixAndLocalName(qualifiedName, ref namespaceUri, out string prefix, out string localName); if (namespaceUri.Is(NamespaceNames.HtmlUri)) { HtmlElement htmlElement = _context.GetFactory>().Create(this, localName, prefix); htmlElement.SetupElement(); return htmlElement; } if (namespaceUri.Is(NamespaceNames.SvgUri)) { SvgElement svgElement = _context.GetFactory>().Create(this, localName, prefix); svgElement.SetupElement(); return svgElement; } if (namespaceUri.Is(NamespaceNames.MathMlUri)) { MathElement mathElement = _context.GetFactory>().Create(this, localName, prefix); mathElement.SetupElement(); return mathElement; } AnyElement anyElement = new AnyElement(this, localName, prefix, namespaceUri); anyElement.SetupElement(); return anyElement; } public IComment CreateComment(string data) { return new Comment(this, data); } public IDocumentFragment CreateDocumentFragment() { return new DocumentFragment(this); } public IProcessingInstruction CreateProcessingInstruction(string target, string data) { if (!target.IsXmlName() || data.Contains("?>")) { throw new DomException(DomError.InvalidCharacter); } return new ProcessingInstruction(this, target) { Data = data }; } public IText CreateTextNode(string data) { return new TextNode(this, data); } public IElement? GetElementById(string elementId) { return base.ChildNodes.GetElementById(elementId); } public IElement? QuerySelector(string selectors) { return base.ChildNodes.QuerySelector(selectors, DocumentElement); } public IHtmlCollection QuerySelectorAll(string selectors) { return base.ChildNodes.QuerySelectorAll(selectors, DocumentElement); } public IHtmlCollection GetElementsByClassName(string classNames) { return base.ChildNodes.GetElementsByClassName(classNames); } public IHtmlCollection GetElementsByTagName(string tagName) { return base.ChildNodes.GetElementsByTagName(tagName); } public IHtmlCollection GetElementsByTagName(string? namespaceURI, string tagName) { return base.ChildNodes.GetElementsByTagName(namespaceURI, tagName); } public bool HasFocus() { return _context.Active == this; } public IAttr CreateAttribute(string localName) { if (!localName.IsXmlName()) { throw new DomException(DomError.InvalidCharacter); } return new Attr(localName); } public IAttr CreateAttribute(string? namespaceUri, string qualifiedName) { Node.GetPrefixAndLocalName(qualifiedName, ref namespaceUri, out string prefix, out string localName); return new Attr(prefix, localName, string.Empty, namespaceUri); } public void Setup(IResponse response, MimeType contentType, IDocument? importAncestor) { ContentType = contentType.Content; StatusCode = response.StatusCode; Referrer = response.Headers.GetOrDefault(HeaderNames.Referer, string.Empty); DocumentUri = response.Address.Href; Cookie = response.Headers.GetOrDefault(HeaderNames.SetCookie, string.Empty); ImportAncestor = importAncestor; ReadyState = DocumentReadyState.Loading; } public abstract Element CreateElementFrom(string name, string prefix, NodeFlags flags = NodeFlags.None); public void DelayLoad(Task? task) { if (!IsReady && task != null && !task.IsCompleted) { AttachReference(task); } } internal IEnumerable GetAttachedReferences() where T : class { foreach (WeakReference attachedReference in _attachedReferences) { if (attachedReference.IsAlive && attachedReference.Target is T val) { yield return val; } } } internal void AttachReference(object value) { _attachedReferences.Add(new WeakReference(value)); } internal void SetFocus(IElement? element) { _focus = element; } internal async Task FinishLoadingAsync() { Task[] tasks = GetAttachedReferences().ToArray(); ReadyState = DocumentReadyState.Interactive; while (_loadingScripts.Count > 0) { await this.WaitForReadyAsync().ConfigureAwait(continueOnCapturedContext: false); await _loadingScripts.Dequeue().RunAsync(CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); } this.FireSimpleEvent(EventNames.DomContentLoaded); _view.FireSimpleEvent(EventNames.DomContentLoaded); await Task.WhenAll(tasks).ConfigureAwait(continueOnCapturedContext: false); ReadyState = DocumentReadyState.Complete; Body?.FireSimpleEvent(EventNames.Load); this.FireSimpleEvent(EventNames.Load); _view.FireSimpleEvent(EventNames.Load); if (IsInBrowsingContext && !_shown) { _shown = true; this.Fire(delegate(PageTransitionEvent ev) { ev.Init(EventNames.PageShow, bubbles: false, cancelable: false, persisted: false); }, _view); } this.QueueTask(EmptyAppCache); if (IsToBePrinted) { await PrintAsync().ConfigureAwait(continueOnCapturedContext: false); } } internal async Task PromptToUnloadAsync() { IEnumerable descendants = GetAttachedReferences(); if (_view.HasEventListener(EventNames.BeforeUnload)) { Event unloadEvent = new Event(EventNames.BeforeUnload, bubbles: false, cancelable: true); bool num = await this.QueueTaskAsync((CancellationToken _) => _view.Fire(unloadEvent)).ConfigureAwait(continueOnCapturedContext: false); _salvageable = false; if (num) { var data = new { Document = this, IsCancelled = true }; await _context.InteractAsync(EventNames.ConfirmUnload, data).ConfigureAwait(continueOnCapturedContext: false); if (data.IsCancelled) { return false; } } } foreach (IBrowsingContext item in descendants) { IDocument active = item.Active; if (active is Document active2) { if (!(await active2.PromptToUnloadAsync().ConfigureAwait(continueOnCapturedContext: false))) { return false; } _salvageable = _salvageable && active2._salvageable; } } return true; } internal async Task Unload(bool recycle) { IEnumerable descendants = GetAttachedReferences(); if (_shown) { _shown = false; await this.QueueTaskAsync(delegate { this.Fire(delegate(PageTransitionEvent ev) { ev.Init(EventNames.PageHide, bubbles: false, cancelable: false, _salvageable); }, _view); }).ConfigureAwait(continueOnCapturedContext: false); } if (_view.HasEventListener(EventNames.Unload)) { if (!_firedUnload) { await this.QueueTaskAsync((CancellationToken _) => _view.FireSimpleEvent(EventNames.Unload)).ConfigureAwait(continueOnCapturedContext: false); _firedUnload = true; } _salvageable = false; } CancelTasks(); foreach (IBrowsingContext item in descendants) { IDocument active = item.Active; if (active is Document active2) { await active2.Unload(recycle: false).ConfigureAwait(continueOnCapturedContext: false); _salvageable = _salvageable && active2._salvageable; } } if (!recycle && !_salvageable && _context.Active == this) { _context.Active = null; } } bool IDocument.ExecuteCommand(string commandId, bool showUserInterface, string value) { return _context.GetCommand(commandId)?.Execute(this, showUserInterface, value) ?? false; } bool IDocument.IsCommandEnabled(string commandId) { return _context.GetCommand(commandId)?.IsEnabled(this) ?? false; } bool IDocument.IsCommandIndeterminate(string commandId) { return _context.GetCommand(commandId)?.IsIndeterminate(this) ?? false; } bool IDocument.IsCommandExecuted(string commandId) { return _context.GetCommand(commandId)?.IsExecuted(this) ?? false; } bool IDocument.IsCommandSupported(string commandId) { return _context.GetCommand(commandId)?.IsSupported(this) ?? false; } string? IDocument.GetCommandValue(string commandId) { return _context.GetCommand(commandId)?.GetValue(this); } private void Abort(bool fromUser = false) { if (fromUser && _context.Active == this) { this.QueueTaskAsync((CancellationToken _) => _view.FireSimpleEvent(EventNames.Abort)); } foreach (IBrowsingContext attachedReference in GetAttachedReferences()) { if (attachedReference.Active is Document document) { document.Abort(); _salvageable = _salvageable && document._salvageable; } } foreach (IDownload item in from m in _loader.GetDownloads() where !m.IsCompleted select m) { item.Cancel(); _salvageable = false; } } private void CancelTasks() { foreach (CancellationTokenSource attachedReference in GetAttachedReferences()) { if (!attachedReference.IsCancellationRequested) { attachedReference.Cancel(); } } } private static bool IsCommand(IElement element) { if (element is IHtmlMenuItemElement || element is IHtmlButtonElement || element is IHtmlAnchorElement) { return true; } return false; } private static bool IsLink(IElement element) { if ((element is IHtmlAnchorElement || element is IHtmlAreaElement) ? true : false) { return element.Attributes.Any((IAttr m) => m.Name.Is(AttributeNames.Href)); } return false; } private static bool IsAnchor(IHtmlAnchorElement element) { return element.Attributes.Any((IAttr m) => m.Name.Is(AttributeNames.Name)); } private void EmptyAppCache() { } private async Task PrintAsync() { await this.QueueTaskAsync((CancellationToken _) => this.FireSimpleEvent(EventNames.BeforePrint)).ConfigureAwait(continueOnCapturedContext: false); await _context.InteractAsync(EventNames.Print, new { Document = this }).ConfigureAwait(continueOnCapturedContext: false); await this.QueueTaskAsync((CancellationToken _) => this.FireSimpleEvent(EventNames.AfterPrint)).ConfigureAwait(continueOnCapturedContext: false); } private async void LocationChanged(object? sender, Location.ChangedEventArgs e) { if (e.IsHashChanged) { HashChangedEvent ev = new HashChangedEvent(); ev.Init(EventNames.HashChange, bubbles: false, cancelable: false, e.PreviousLocation, e.CurrentLocation); ev.IsTrusted = true; this.QueueTask(delegate { ev.Dispatch(_view); }); } else if (!e.IsReloaded) { DocumentRequest request = DocumentRequest.Get(new Url(e.CurrentLocation), this, DocumentUri); await _context.OpenAsync(request, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); } else { DocumentRequest request2 = DocumentRequest.Get(_location.Original, this, Referrer); await _context.OpenAsync(request2, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); } } protected sealed override string? LocateNamespace(string prefix) { return DocumentElement?.LocateNamespaceFor(prefix); } protected sealed override string? LocatePrefix(string namespaceUri) { return DocumentElement?.LocatePrefixFor(namespaceUri); } protected void CloneDocument(Document document, bool deep) { CloneNode(document, document, deep); document._ready = _ready; document.Referrer = Referrer; document._location.Href = _location.Href; document._quirksMode = _quirksMode; document._sandbox = _sandbox; document._async = _async; document.ContentType = ContentType; } protected virtual string GetTitle() { return string.Empty; } protected abstract void SetTitle(string? value); public bool AddImportUrl(Uri uri) { if ((object)uri == null) { return false; } for (IDocument document = this; document != null; document = document.ImportAncestor) { if (document.HasImported(uri)) { return false; } } if (_importedUris == null) { lock (_importedUrisLock) { _importedUris = _importedUris ?? new HashSet(); } } return _importedUris.Add(uri); } public bool HasImported(Uri uri) { return _importedUris?.Contains(uri) ?? false; } void IConstructableDocument.PerformMicrotaskCheckpoint() { this.PerformMicrotaskCheckpoint(); } void IConstructableDocument.ProvideStableState() { this.ProvideStableState(); } void IConstructableDocument.AddComment(ref StructHtmlToken token) { this.AddComment(ref token); } void IConstructableDocument.TrackError(Exception exception) { Context.TrackError(exception); } Task IConstructableDocument.WaitForReadyAsync(CancellationToken cancelToken) { return this.WaitForReadyAsync(); } void IConstructableDocument.ApplyManifest() { this.ApplyManifest(); } Task IConstructableDocument.FinishLoadingAsync() { return FinishLoadingAsync(); } } internal sealed class DocumentFragment : Node, IDocumentFragment, INode, IEventTarget, IMarkupFormattable, IParentNode, INonElementParentNode { private HtmlCollection? _elements; public int ChildElementCount => base.ChildNodes.OfType().Count(); public IHtmlCollection Children => _elements ?? (_elements = new HtmlCollection(this, deep: false)); public IElement? FirstElementChild { get { NodeList childNodes = base.ChildNodes; int length = childNodes.Length; for (int i = 0; i < length; i++) { if (childNodes[i] is IElement result) { return result; } } return null; } } public IElement? LastElementChild { get { NodeList childNodes = base.ChildNodes; for (int num = childNodes.Length - 1; num >= 0; num--) { if (childNodes[num] is IElement result) { return result; } } return null; } } public override string TextContent { get { StringBuilder stringBuilder = StringBuilderPool.Obtain(); foreach (IText item in this.GetDescendants().OfType()) { stringBuilder.Append(item.Data); } return stringBuilder.ToPool(); } set { TextNode node = ((!string.IsNullOrEmpty(value)) ? new TextNode(base.Owner, value) : null); ReplaceAll(node, suppressObservers: false); } } internal DocumentFragment(Document owner) : base(owner, "#document-fragment", NodeType.DocumentFragment) { } internal DocumentFragment(Element contextElement, string html) : this(contextElement.Owner) { IElement element = contextElement.ParseSubtree(html); while (element.HasChildNodes) { INode firstChild = element.FirstChild; element.RemoveChild(firstChild); if (firstChild is Node newElement) { base.Owner.AdoptNode(firstChild); InsertBefore(newElement, null, suppressObservers: false); } } } public void Prepend(params INode[] nodes) { this.PrependNodes(nodes); } public void Append(params INode[] nodes) { this.AppendNodes(nodes); } public IElement? QuerySelector(string selectors) { return base.ChildNodes.QuerySelector(selectors); } public IHtmlCollection QuerySelectorAll(string selectors) { return base.ChildNodes.QuerySelectorAll(selectors); } public IHtmlCollection GetElementsByClassName(string classNames) { return base.ChildNodes.GetElementsByClassName(classNames); } public IHtmlCollection GetElementsByTagName(string tagName) { return base.ChildNodes.GetElementsByTagName(tagName); } public IHtmlCollection GetElementsByTagNameNS(string? namespaceURI, string tagName) { return base.ChildNodes.GetElementsByTagName(namespaceURI, tagName); } public IElement? GetElementById(string elementId) { return base.ChildNodes.GetElementById(elementId); } public override Node Clone(Document owner, bool deep) { DocumentFragment documentFragment = new DocumentFragment(owner); CloneNode(documentFragment, owner, deep); return documentFragment; } } internal sealed class DocumentType : Node, IDocumentType, INode, IEventTarget, IMarkupFormattable, IChildNode { public IElement? PreviousElementSibling { get { Node parent = base.Parent; if (parent != null) { bool flag = false; for (int num = parent.ChildNodes.Length - 1; num >= 0; num--) { if (parent.ChildNodes[num] == this) { flag = true; } else if (flag && parent.ChildNodes[num] is IElement result) { return result; } } } return null; } } public IElement? NextElementSibling { get { Node parent = base.Parent; if (parent != null) { int length = parent.ChildNodes.Length; bool flag = false; for (int i = 0; i < length; i++) { if (parent.ChildNodes[i] == this) { flag = true; } else if (flag && parent.ChildNodes[i] is IElement result) { return result; } } } return null; } } public IEnumerable Entities => Array.Empty(); public IEnumerable Notations => Array.Empty(); public string Name => base.NodeName; public string PublicIdentifier { get; set; } public string SystemIdentifier { get; set; } public string? InternalSubset { get; set; } internal DocumentType(Document owner, string name) : base(owner, name, NodeType.DocumentType) { PublicIdentifier = string.Empty; SystemIdentifier = string.Empty; } public void Before(params INode[] nodes) { this.InsertBefore(nodes); } public void After(params INode[] nodes) { this.InsertAfter(nodes); } public void Replace(params INode[] nodes) { this.ReplaceWith(nodes); } public void Remove() { this.RemoveFromParent(); } public override Node Clone(Document owner, bool deep) { DocumentType documentType = new DocumentType(owner, Name) { PublicIdentifier = PublicIdentifier, SystemIdentifier = SystemIdentifier, InternalSubset = InternalSubset }; CloneNode(documentType, owner, deep); return documentType; } protected override string? LocateNamespace(string prefix) { return null; } protected override string? LocatePrefix(string namespaceUri) { return null; } } internal sealed class DomImplementation : IImplementation { private static readonly Dictionary features = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "XML", new string[2] { "1.0", "2.0" } }, { "HTML", new string[2] { "1.0", "2.0" } }, { "Core", new string[1] { "2.0" } }, { "Views", new string[1] { "2.0" } }, { "StyleSheets", new string[1] { "2.0" } }, { "CSS", new string[1] { "2.0" } }, { "CSS2", new string[1] { "2.0" } }, { "Traversal", new string[1] { "2.0" } }, { "Events", new string[1] { "2.0" } }, { "UIEvents", new string[1] { "2.0" } }, { "HTMLEvents", new string[1] { "2.0" } }, { "Range", new string[1] { "2.0" } }, { "MutationEvents", new string[1] { "2.0" } } }; private readonly Document _owner; public DomImplementation(Document owner) { _owner = owner; } public IDocumentType CreateDocumentType(string qualifiedName, string publicId, string systemId) { if (qualifiedName == null) { throw new ArgumentNullException("qualifiedName"); } if (!qualifiedName.IsXmlName()) { throw new DomException(DomError.InvalidCharacter); } if (!qualifiedName.IsQualifiedName()) { throw new DomException(DomError.Namespace); } return new DocumentType(_owner, qualifiedName) { PublicIdentifier = publicId, SystemIdentifier = systemId }; } public IDocument CreateHtmlDocument(string title) { HtmlDocument htmlDocument = new HtmlDocument(); htmlDocument.AppendChild(new DocumentType(htmlDocument, TagNames.Html)); htmlDocument.AppendChild(htmlDocument.CreateElement(TagNames.Html)); htmlDocument.DocumentElement.AppendChild(htmlDocument.CreateElement(TagNames.Head)); if (!string.IsNullOrEmpty(title)) { IElement element = htmlDocument.CreateElement(TagNames.Title); element.AppendChild(htmlDocument.CreateTextNode(title)); htmlDocument.Head.AppendChild(element); } htmlDocument.DocumentElement.AppendChild(htmlDocument.CreateElement(TagNames.Body)); htmlDocument.BaseUrl = _owner.BaseUrl; return htmlDocument; } public bool HasFeature(string feature, string? version = null) { if (feature == null) { throw new ArgumentNullException("feature"); } if (features.TryGetValue(feature, out string[] value)) { return value.Contains(version ?? string.Empty, StringComparison.OrdinalIgnoreCase); } return false; } } public abstract class Element : Node, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IConstructableElement, IConstructableNode { private readonly NamedNodeMap _attributes; private readonly string _namespace; private readonly string? _prefix; private readonly string _localName; private HtmlCollection? _elements; private TokenList? _classList; private IShadowRoot? _shadowRoot; internal IBrowsingContext Context => base.Owner?.Context; internal NamedNodeMap Attributes => _attributes; public IElement? AssignedSlot => base.ParentElement?.ShadowRoot?.GetAssignedSlot(Slot); public string? Slot { get { return this.GetOwnAttribute(AttributeNames.Slot); } set { this.SetOwnAttribute(AttributeNames.Slot, value); } } public IShadowRoot? ShadowRoot => _shadowRoot; public string? Prefix => _prefix; public string LocalName => _localName; public string? NamespaceUri => _namespace ?? this.GetNamespaceUri(); public string? GivenNamespaceUri => _namespace; public override string TextContent { get { StringBuilder stringBuilder = StringBuilderPool.Obtain(); foreach (IText item in this.GetDescendants().OfType()) { stringBuilder.Append(item.Data); } return stringBuilder.ToPool(); } set { TextNode node = ((!string.IsNullOrEmpty(value)) ? new TextNode(base.Owner, value) : null); ReplaceAll(node, suppressObservers: false); } } public ITokenList ClassList { get { if (_classList == null) { _classList = new TokenList(this.GetOwnAttribute(AttributeNames.Class)); _classList.Changed += delegate(string value) { UpdateAttribute(AttributeNames.Class, value); }; } return _classList; } } public string? ClassName { get { return this.GetOwnAttribute(AttributeNames.Class); } set { this.SetOwnAttribute(AttributeNames.Class, value); } } public string? Id { get { return this.GetOwnAttribute(AttributeNames.Id); } set { this.SetOwnAttribute(AttributeNames.Id, value); } } public string TagName => base.NodeName; public ISourceReference? SourceReference { get; set; } public IElement? PreviousElementSibling { get { Node parent = base.Parent; if (parent != null) { bool flag = false; for (int num = parent.ChildNodes.Length - 1; num >= 0; num--) { if (parent.ChildNodes[num] == this) { flag = true; } else if (flag && parent.ChildNodes[num] is IElement result) { return result; } } } return null; } } public IElement? NextElementSibling { get { Node parent = base.Parent; if (parent != null) { int length = parent.ChildNodes.Length; bool flag = false; for (int i = 0; i < length; i++) { if (parent.ChildNodes[i] == this) { flag = true; } else if (flag && parent.ChildNodes[i] is IElement result) { return result; } } } return null; } } public int ChildElementCount { get { NodeList childNodes = base.ChildNodes; int length = childNodes.Length; int num = 0; for (int i = 0; i < length; i++) { if (childNodes[i].NodeType == NodeType.Element) { num++; } } return num; } } public IHtmlCollection Children => _elements ?? (_elements = new HtmlCollection(this, deep: false)); public IElement? FirstElementChild { get { NodeList childNodes = base.ChildNodes; int length = childNodes.Length; for (int i = 0; i < length; i++) { if (childNodes[i] is IElement result) { return result; } } return null; } } public IElement? LastElementChild { get { NodeList childNodes = base.ChildNodes; for (int num = childNodes.Length - 1; num >= 0; num--) { if (childNodes[num] is IElement result) { return result; } } return null; } } public string InnerHtml { get { return base.ChildNodes.ToHtml(); } set { ReplaceAll(new DocumentFragment(this, value), suppressObservers: false); } } public string OuterHtml { get { return this.ToHtml(); } set { Node node = base.Parent; if (node != null) { switch (node.NodeType) { case NodeType.Document: throw new DomException(DomError.NoModificationAllowed); case NodeType.DocumentFragment: node = new HtmlBodyElement(base.Owner); break; } } Element element = (node as Element) ?? throw new DomException(DomError.NotSupported); element.InsertChild(element.IndexOf(this), new DocumentFragment(element, value)); element.RemoveChild(this); } } INamedNodeMap IElement.Attributes => _attributes; public bool IsFocused { get { return base.Owner?.FocusElement == this; } protected set { Document document = base.Owner; document?.QueueTask(delegate { if (value) { document.SetFocus(this); this.Fire(delegate(FocusEvent m) { m.Init(EventNames.Focus, bubbles: false, cancelable: false); }); } else { document.SetFocus(null); this.Fire(delegate(FocusEvent m) { m.Init(EventNames.Blur, bubbles: false, cancelable: false); }); } }); } } StringOrMemory IConstructableElement.LocalName => _localName; IConstructableNamedNodeMap IConstructableElement.Attributes => _attributes; StringOrMemory IConstructableElement.NamespaceUri => NamespaceUri ?? ""; StringOrMemory IConstructableElement.Prefix { get { string prefix = Prefix; if (prefix == null) { return StringOrMemory.Empty; } return prefix; } } public Element(Document owner, string localName, string? prefix, string? namespaceUri, NodeFlags flags = NodeFlags.None) : this(owner, (prefix != null) ? (prefix + ":" + localName) : localName, localName, prefix, namespaceUri, flags) { } public Element(Document owner, string name, string localName, string? prefix, string namespaceUri, NodeFlags flags = NodeFlags.None) : base(owner, name, NodeType.Element, flags) { _localName = localName; _prefix = prefix; _namespace = namespaceUri; _attributes = new NamedNodeMap(this); } public abstract IElement ParseSubtree(string source); public IShadowRoot AttachShadow(ShadowRootMode mode = ShadowRootMode.Open) { if (TagNames.AllNoShadowRoot.Contains(_localName)) { throw new DomException(DomError.NotSupported); } if (ShadowRoot != null) { throw new DomException(DomError.InvalidState); } _shadowRoot = new ShadowRoot(this, mode); return _shadowRoot; } public IElement? QuerySelector(string selectors) { return base.ChildNodes.QuerySelector(selectors, this); } public IHtmlCollection QuerySelectorAll(string selectors) { return base.ChildNodes.QuerySelectorAll(selectors, this); } public IHtmlCollection GetElementsByClassName(string classNames) { return base.ChildNodes.GetElementsByClassName(classNames); } public IHtmlCollection GetElementsByTagName(string tagName) { return base.ChildNodes.GetElementsByTagName(tagName); } public IHtmlCollection GetElementsByTagNameNS(string? namespaceURI, string tagName) { return base.ChildNodes.GetElementsByTagName(namespaceURI, tagName); } public bool Matches(string selectorText) { return (Context.GetService().ParseSelector(selectorText) ?? throw new DomException(DomError.Syntax)).Match(this, this); } public IElement? Closest(string selectorText) { ISelector selector = Context.GetService().ParseSelector(selectorText) ?? throw new DomException(DomError.Syntax); for (IElement element = this; element != null; element = element.ParentElement) { if (selector.Match(element, element)) { return element; } } return null; } public bool HasAttribute(string name) { if (_namespace.Is(NamespaceNames.HtmlUri)) { name = name.HtmlLower(); } return _attributes.GetNamedItem(name) != null; } public bool HasAttribute(StringOrMemory name) { if (_namespace.Is(NamespaceNames.HtmlUri)) { name = name.HtmlLower(); } return _attributes.GetNamedItem(name) != null; } public bool HasAttribute(string? namespaceUri, string localName) { if (string.IsNullOrEmpty(namespaceUri)) { namespaceUri = null; } return _attributes.GetNamedItem(namespaceUri, localName) != null; } public string? GetAttribute(string name) { if (_namespace.Is(NamespaceNames.HtmlUri)) { name = name.HtmlLower(); } return _attributes.GetNamedItem(name)?.Value; } public string? GetAttribute(string? namespaceUri, string localName) { if (string.IsNullOrEmpty(namespaceUri)) { namespaceUri = null; } return _attributes.GetNamedItem(namespaceUri, localName)?.Value; } public void SetAttribute(string name, string? value) { if (value != null) { if (!name.IsXmlName()) { throw new DomException(DomError.InvalidCharacter); } if (_namespace.Is(NamespaceNames.HtmlUri)) { name = name.HtmlLower(); } this.SetOwnAttribute(name, value); } else { RemoveAttribute(name); } } public void SetAttribute(string? namespaceUri, string name, string? value) { if (value != null) { Node.GetPrefixAndLocalName(name, ref namespaceUri, out string prefix, out string localName); _attributes.SetNamedItem(new Attr(prefix, localName, value, namespaceUri)); } else { RemoveAttribute(namespaceUri, name); } } public void AddAttribute(Attr attr) { attr.Container = _attributes; _attributes.FastAddItem(attr); } public bool RemoveAttribute(string name) { if (_namespace.Is(NamespaceNames.HtmlUri)) { name = name.HtmlLower(); } return _attributes.RemoveNamedItemOrDefault(name) != null; } public bool RemoveAttribute(string? namespaceUri, string localName) { if (string.IsNullOrEmpty(namespaceUri)) { namespaceUri = null; } return _attributes.RemoveNamedItemOrDefault(namespaceUri, localName) != null; } public void Prepend(params INode[] nodes) { this.PrependNodes(nodes); } public void Append(params INode[] nodes) { this.AppendNodes(nodes); } public override bool Equals(INode? otherNode) { if (otherNode is IElement element) { if (NamespaceUri.Is(element.NamespaceUri) && _attributes.SameAs(element.Attributes)) { return base.Equals(otherNode); } return false; } return false; } public void Before(params INode[] nodes) { this.InsertBefore(nodes); } public void After(params INode[] nodes) { this.InsertAfter(nodes); } public void Replace(params INode[] nodes) { this.ReplaceWith(nodes); } public void Remove() { this.RemoveFromParent(); } public void Insert(AdjacentPosition position, string html) { DocumentFragment documentFragment = new DocumentFragment((position == AdjacentPosition.AfterBegin || position == AdjacentPosition.BeforeEnd) ? this : ((base.Parent as Element) ?? throw new DomException("The element has no parent.")), html); switch (position) { case AdjacentPosition.BeforeBegin: base.Parent.InsertBefore(documentFragment, this); break; case AdjacentPosition.AfterEnd: base.Parent.InsertChild(base.Parent.IndexOf(this) + 1, documentFragment); break; case AdjacentPosition.AfterBegin: InsertChild(0, documentFragment); break; case AdjacentPosition.BeforeEnd: AppendChild(documentFragment); break; } } public override Node Clone(Document owner, bool deep) { AnyElement anyElement = new AnyElement(owner, LocalName, _prefix, _namespace, base.Flags); CloneElement(anyElement, owner, deep); return anyElement; } internal virtual void SetupElement() { NamedNodeMap attributes = _attributes; if (attributes.Length <= 0) { return; } IEnumerable services = Context.GetServices(); foreach (IAttr item in attributes) { string localName = item.LocalName; string value = item.Value; foreach (IAttributeObserver item2 in services) { item2.NotifyChange(this, localName, value); } } } internal void AttributeChanged(string localName, string? namespaceUri, string? oldValue, string? newValue) { if (namespaceUri == null) { foreach (IAttributeObserver service in Context.GetServices()) { service.NotifyChange(this, localName, newValue); } } base.Owner.QueueMutation(MutationRecord.Attributes(this, localName, namespaceUri, oldValue)); } internal void UpdateClassList(string value) { _classList?.Update(value); } protected void UpdateAttribute(string name, string value) { this.SetOwnAttribute(name, value, suppressCallbacks: true); } protected sealed override string? LocateNamespace(string prefix) { return this.LocateNamespaceFor(prefix); } protected sealed override string? LocatePrefix(string namespaceUri) { return this.LocatePrefixFor(namespaceUri); } protected void CloneElement(Element element, Document owner, bool deep) { CloneNode(element, owner, deep); foreach (IAttr attribute in _attributes) { Attr attr = new Attr(attribute.Prefix, attribute.LocalName, attribute.Value, attribute.NamespaceUri); attr.Container = element._attributes; element._attributes.FastAddItem(attr); } element.SetupElement(); } void IConstructableElement.SetAttribute(string? ns, StringOrMemory name, StringOrMemory value) { SetAttribute(ns, name.ToString(), value.ToString()); } void IConstructableElement.SetOwnAttribute(StringOrMemory name, StringOrMemory value) { this.SetOwnAttribute(name.ToString(), value.ToString()); } StringOrMemory IConstructableElement.GetAttribute(StringOrMemory @namespace, StringOrMemory name) { string attribute = GetAttribute(@namespace.ToString(), name.ToString()); if (attribute == null) { return StringOrMemory.Empty; } return attribute; } void IConstructableElement.SetAttributes(StructAttributes tagAttributes) { NamedNodeMap attributes = Attributes; for (int i = 0; i < tagAttributes.Count; i++) { MemoryHtmlAttributeToken memoryHtmlAttributeToken = tagAttributes[i]; Attr attr = new Attr(memoryHtmlAttributeToken.Name.ToString(), memoryHtmlAttributeToken.Value.ToString()); attr.Container = attributes; attributes.FastAddItem(attr); } } void IConstructableElement.SetupElement() { SetupElement(); } void IConstructableElement.AddComment(ref StructHtmlToken token) { this.AddComment(ref token); } IConstructableNode IConstructableElement.ShallowCopy() { return Clone(base.Owner, deep: false); } } [DomName("Entity")] public sealed class Entity : Node { private string? _publicId; private string? _systemId; private string? _notationName; private string? _inputEncoding; private string? _xmlVersion; private string? _xmlEncoding; private string? _value; [DomName("publicId")] public string? PublicId => _publicId; [DomName("systemId")] public string? SystemId => _systemId; [DomName("notationName")] public string? NotationName { get { return _notationName; } set { _notationName = value; } } [DomName("inputEncoding")] public string? InputEncoding => _inputEncoding; [DomName("xmlEncoding")] public string? XmlEncoding => _xmlEncoding; [DomName("xmlVersion")] public string? XmlVersion => _xmlVersion; [DomName("textContent")] public override string TextContent { get { return NodeValue; } set { NodeValue = value; } } [DomName("nodeValue")] public override string NodeValue { get { return _value; } set { _value = value; } } public Entity(Document owner) : this(owner, string.Empty) { } public Entity(Document owner, string name) : base(owner, name, NodeType.Entity) { } public override Node Clone(Document newOwner, bool deep) { Entity entity = new Entity(newOwner, base.NodeName); CloneNode(entity, newOwner, deep); entity._xmlEncoding = _xmlEncoding; entity._xmlVersion = _xmlVersion; entity._systemId = _systemId; entity._publicId = _publicId; entity._inputEncoding = _inputEncoding; entity._notationName = _notationName; return entity; } } internal sealed class EntityReference : Node { internal EntityReference(Document owner) : this(owner, string.Empty) { } internal EntityReference(Document owner, string name) : base(owner, name, NodeType.EntityReference) { } public override Node Clone(Document owner, bool deep) { EntityReference entityReference = new EntityReference(owner, base.NodeName); CloneNode(entityReference, owner, deep); return entityReference; } } internal sealed class HtmlAllCollection : IHtmlAllCollection, IHtmlCollection, IEnumerable, IEnumerable { private readonly IEnumerable _elements; public IElement this[int index] => _elements.GetItemByIndex(index); public IElement? this[string id] => _elements.GetElementById(id); public int Length => _elements.Count(); public HtmlAllCollection(IDocument document) { _elements = document.GetNodes(); } public IEnumerator GetEnumerator() { return _elements.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _elements.GetEnumerator(); } } internal sealed class HtmlCollection : IHtmlCollection, IEnumerable, IEnumerable where T : class, IElement { private readonly IEnumerable _elements; public T this[int index] => _elements.GetItemByIndex(index); public T? this[string id] => _elements.GetElementById(id); public int Length => _elements.Count(); public HtmlCollection(IEnumerable elements) { _elements = elements; } public HtmlCollection(INode parent, bool deep = true, Func? predicate = null) { _elements = parent.GetNodes(deep, predicate); } public IEnumerator GetEnumerator() { return _elements.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _elements.GetEnumerator(); } } internal sealed class HtmlFormControlsCollection : IHtmlFormControlsCollection, IHtmlCollection, IEnumerable, IEnumerable { private readonly IEnumerable _elements; public int Length => _elements.Count(); public HtmlFormControlElement this[int index] => _elements.GetItemByIndex(index); public HtmlFormControlElement? this[string id] => _elements.GetElementById(id); IHtmlElement IHtmlCollection.this[int index] => this[index]; IHtmlElement? IHtmlCollection.this[string id] => this[id]; public HtmlFormControlsCollection(IElement form, IElement? root = null) { if (root == null) { root = form.Owner.DocumentElement; } _elements = from m in root.GetNodes() where (m.Form == form && (!(m is IHtmlInputElement htmlInputElement) || !htmlInputElement.Type.Is(InputTypeNames.Image))) ? true : false select m; } public IEnumerator GetEnumerator() { return _elements.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _elements.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _elements.GetEnumerator(); } } internal sealed class Location : ILocation, IUrlUtilities { public sealed class ChangedEventArgs : EventArgs { public bool IsReloaded => PreviousLocation.Is(CurrentLocation); public bool IsHashChanged { get; } public string PreviousLocation { get; } public string CurrentLocation { get; } public ChangedEventArgs(bool hashChanged, string previousLocation, string currentLocation) { IsHashChanged = hashChanged; PreviousLocation = previousLocation; CurrentLocation = currentLocation; } } private readonly Url _url; public Url Original => _url; public string? Origin => _url.Origin; public bool IsRelative => _url.IsRelative; public string? UserName { get { return _url.UserName; } set { _url.UserName = value; } } public string? Password { get { return _url.Password; } set { _url.Password = value; } } public string Hash { get { return NonEmptyPrefix(_url.Fragment, "#"); } [param: AllowNull] set { string href = _url.Href; if (value != null) { if (value.Has('#')) { value = value.Substring(1); } else if (value.Length == 0) { value = null; } } if (!value.Is(_url.Fragment)) { _url.Fragment = value; RaiseHashChanged(href); } } } public string Host { get { return _url.Host; } set { string href = _url.Href; if (!value.Isi(_url.Host)) { _url.Host = value; RaiseLocationChanged(href); } } } public string HostName { get { return _url.HostName; } set { string href = _url.Href; if (!value.Isi(_url.HostName)) { _url.HostName = value; RaiseLocationChanged(href); } } } public string Href { get { return _url.Href; } set { string href = _url.Href; if (!value.Is(_url.Href)) { _url.Href = value; RaiseLocationChanged(href); } } } public string PathName { get { string data = _url.Data; if (!string.IsNullOrEmpty(data)) { return data; } return "/" + _url.Path; } set { string href = _url.Href; if (!value.Is(_url.Path)) { _url.Path = value; RaiseLocationChanged(href); } } } public string Port { get { return _url.Port; } set { string href = _url.Href; if (!value.Isi(_url.Port)) { _url.Port = value; RaiseLocationChanged(href); } } } public string Protocol { get { return NonEmptyPostfix(_url.Scheme, ":"); } set { string href = _url.Href; if (!value.Isi(_url.Scheme)) { _url.Scheme = value; RaiseLocationChanged(href); } } } public string Search { get { return NonEmptyPrefix(_url.Query, "?"); } set { string href = _url.Href; if (!value.Is(_url.Query)) { _url.Query = value; RaiseLocationChanged(href); } } } public event EventHandler? Changed; internal Location(string url) : this(new Url(url)) { } internal Location(Url url) { _url = url ?? new Url(string.Empty); } public void Assign(string url) { string href = _url.Href; if (!href.Is(url)) { _url.Href = url; RaiseLocationChanged(href); } } public void Replace(string url) { string href = _url.Href; if (!href.Is(url)) { _url.Href = url; RaiseLocationChanged(href); } } public void Reload() { this.Changed?.Invoke(this, new ChangedEventArgs(hashChanged: false, _url.Href, _url.Href)); } public override string ToString() { return _url.Href; } private void RaiseHashChanged(string oldAddress) { this.Changed?.Invoke(this, new ChangedEventArgs(hashChanged: true, oldAddress, _url.Href)); } private void RaiseLocationChanged(string oldAddress) { this.Changed?.Invoke(this, new ChangedEventArgs(hashChanged: false, oldAddress, _url.Href)); } private static string NonEmptyPrefix(string? check, string prefix) { if (!string.IsNullOrEmpty(check)) { return prefix + check; } return string.Empty; } private static string NonEmptyPostfix(string? check, string postfix) { if (!string.IsNullOrEmpty(check)) { return check + postfix; } return string.Empty; } } internal sealed class MutationHost { private readonly List _observers; private readonly IEventLoop _loop; private bool _queued; public IEnumerable Observers => _observers; public MutationHost(IEventLoop loop) { _observers = new List(); _queued = false; _loop = loop; } public void Register(MutationObserver observer) { if (!_observers.Contains(observer)) { _observers.Add(observer); } } public void Unregister(MutationObserver observer) { if (_observers.Contains(observer)) { _observers.Remove(observer); } } public void ScheduleCallback() { if (!_queued) { _queued = true; _loop.Enqueue(DispatchCallback); } } private void DispatchCallback() { MutationObserver[] array = _observers.ToArray(); _queued = false; MutationObserver[] array2 = array; foreach (MutationObserver mutationObserver in array2) { _loop.Enqueue(mutationObserver.Trigger, TaskPriority.Microtask); } } } internal sealed class MutationRecord : IMutationRecord { private static readonly string CharacterDataType = "characterData"; private static readonly string AttributesType = "attributes"; private static readonly string ChildListType = "childList"; public bool IsAttribute => Type.Is(AttributesType); public bool IsCharacterData => Type.Is(CharacterDataType); public bool IsChildList => Type.Is(ChildListType); public string Type { get; private set; } public INode Target { get; private set; } public INodeList? Added { get; private set; } public INodeList? Removed { get; private set; } public INode? PreviousSibling { get; private set; } public INode? NextSibling { get; private set; } public string? AttributeName { get; private set; } public string? AttributeNamespace { get; private set; } public string? PreviousValue { get; private set; } private MutationRecord() { } public static MutationRecord CharacterData(INode target, string? previousValue = null) { return new MutationRecord { Type = CharacterDataType, Target = target, PreviousValue = previousValue }; } public static MutationRecord ChildList(INode target, INodeList? addedNodes = null, INodeList? removedNodes = null, INode? previousSibling = null, INode? nextSibling = null) { return new MutationRecord { Type = ChildListType, Target = target, Added = addedNodes, Removed = removedNodes, PreviousSibling = previousSibling, NextSibling = nextSibling }; } public static MutationRecord Attributes(INode target, string? attributeName = null, string? attributeNamespace = null, string? previousValue = null) { return new MutationRecord { Type = AttributesType, Target = target, AttributeName = attributeName, AttributeNamespace = attributeNamespace, PreviousValue = previousValue }; } public MutationRecord Copy(bool clearPreviousValue) { return new MutationRecord { Type = Type, Target = Target, PreviousSibling = PreviousSibling, NextSibling = NextSibling, AttributeName = AttributeName, AttributeNamespace = AttributeNamespace, PreviousValue = (clearPreviousValue ? null : PreviousValue), Added = Added, Removed = Removed }; } } internal sealed class NamedNodeMap : INamedNodeMap, IEnumerable, IEnumerable, IConstructableNamedNodeMap { private readonly List _items; private readonly WeakReference _owner; public IAttr? this[string name] => GetNamedItem(name); public IAttr? this[int index] { get { if (index < 0 || index >= _items.Count) { return null; } return _items[index]; } } public int Length => _items.Count; public Element? Owner { get { if (!_owner.TryGetTarget(out Element target)) { return null; } return target; } } IConstructableAttr? IConstructableNamedNodeMap.this[StringOrMemory name] { get { for (int i = 0; i < _items.Count; i++) { if (name.Is(_items[i].Name)) { return _items[i]; } } return null; } } public NamedNodeMap(Element owner) { _items = new List(); _owner = new WeakReference(owner); } internal void FastAddItem(Attr attr) { _items.Add(attr); } internal void RaiseChangedEvent(Attr attr, string? newValue, string? oldValue) { if (_owner.TryGetTarget(out Element target)) { target.AttributeChanged(attr.LocalName, attr.NamespaceUri, oldValue, newValue); } } internal IAttr? RemoveNamedItemOrDefault(string name, bool suppressMutationObservers) { for (int i = 0; i < _items.Count; i++) { if (name.Is(_items[i].Name)) { Attr attr = _items[i]; _items.RemoveAt(i); attr.Container = null; if (!suppressMutationObservers) { RaiseChangedEvent(attr, null, attr.Value); } return attr; } } return null; } internal IAttr? RemoveNamedItemOrDefault(string name) { return RemoveNamedItemOrDefault(name, suppressMutationObservers: false); } internal IAttr? RemoveNamedItemOrDefault(string? namespaceUri, string localName, bool suppressMutationObservers) { for (int i = 0; i < _items.Count; i++) { if (localName.Is(_items[i].LocalName) && namespaceUri.Is(_items[i].NamespaceUri)) { Attr attr = _items[i]; _items.RemoveAt(i); attr.Container = null; if (!suppressMutationObservers) { RaiseChangedEvent(attr, null, attr.Value); } return attr; } } return null; } internal IAttr? RemoveNamedItemOrDefault(string? namespaceUri, string localName) { return RemoveNamedItemOrDefault(namespaceUri, localName, suppressMutationObservers: false); } public IAttr? GetNamedItem(string name) { for (int i = 0; i < _items.Count; i++) { if (name.Is(_items[i].Name)) { return _items[i]; } } return null; } public IAttr? GetNamedItem(StringOrMemory name) { for (int i = 0; i < _items.Count; i++) { if (name.Is(_items[i].Name)) { return _items[i]; } } return null; } public IAttr? GetNamedItem(string? namespaceUri, string localName) { for (int i = 0; i < _items.Count; i++) { if (localName.Is(_items[i].LocalName) && namespaceUri.Is(_items[i].NamespaceUri)) { return _items[i]; } } return null; } public IAttr? SetNamedItem(IAttr item) { Attr attr = Prepare(item); if (attr != null) { string name = item.Name; for (int i = 0; i < _items.Count; i++) { if (name.Is(_items[i].Name)) { Attr attr2 = _items[i]; _items[i] = attr; RaiseChangedEvent(attr, attr.Value, attr2.Value); return attr2; } } _items.Add(attr); RaiseChangedEvent(attr, attr.Value, null); } return null; } public IAttr? SetNamedItemWithNamespaceUri(IAttr item, bool suppressMutationObservers) { Attr attr = Prepare(item); if (attr != null) { string localName = item.LocalName; string namespaceUri = item.NamespaceUri; for (int i = 0; i < _items.Count; i++) { if (localName.Is(_items[i].LocalName) && namespaceUri.Is(_items[i].NamespaceUri)) { Attr attr2 = _items[i]; _items[i] = attr; if (!suppressMutationObservers) { RaiseChangedEvent(attr, attr.Value, attr2.Value); } return attr2; } } _items.Add(attr); if (!suppressMutationObservers) { RaiseChangedEvent(attr, attr.Value, null); } } return null; } public IAttr? SetNamedItemWithNamespaceUri(IAttr item) { return SetNamedItemWithNamespaceUri(item, suppressMutationObservers: false); } public IAttr RemoveNamedItem(string name) { return RemoveNamedItemOrDefault(name) ?? throw new DomException(DomError.NotFound); } public IAttr RemoveNamedItem(string? namespaceUri, string localName) { return RemoveNamedItemOrDefault(namespaceUri, localName) ?? throw new DomException(DomError.NotFound); } public IEnumerator GetEnumerator() { return _items.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _items.GetEnumerator(); } private Attr? Prepare(IAttr item) { Attr attr = item as Attr; if (attr != null) { if (attr.Container == this) { return null; } if (attr.Container != null) { throw new DomException(DomError.InUse); } attr.Container = this; } return attr; } bool IConstructableNamedNodeMap.SameAs(IConstructableNamedNodeMap? attributes) { if (attributes == null || attributes.Length != Length) { return false; } for (int i = 0; i < Length; i++) { Attr attr = _items[i]; IConstructableAttr constructableAttr = attributes[attr.Name]; if (constructableAttr == null || !attr.Value.Is(constructableAttr.Value)) { return false; } } return true; } } public abstract class Node : EventTarget, INode, IEventTarget, IMarkupFormattable, IEquatable, IConstructableNode { private readonly NodeType _type; private readonly string _name; private readonly NodeFlags _flags; private Url? _baseUri; private Node? _parent; private NodeList _children; private Document? _owner; public bool HasChildNodes => _children.Length != 0; public string BaseUri => BaseUrl?.Href ?? string.Empty; public Url? BaseUrl { get { if (_baseUri != null) { return _baseUri; } if (_parent != null) { foreach (Node item in this.Ancestors()) { if (item._baseUri != null) { return item._baseUri; } } } Document owner = Owner; if (owner != null) { return owner._baseUri ?? owner.DocumentUrl; } if (_type == NodeType.Document) { owner = (Document)this; return owner.DocumentUrl; } return null; } set { _baseUri = value; } } public NodeType NodeType => _type; public NodeFlags Flags => _flags; public virtual string NodeValue { get { return null; } set { } } public virtual string TextContent { get { return null; } set { } } INode? INode.PreviousSibling => PreviousSibling; INode? INode.NextSibling => NextSibling; INode? INode.FirstChild => FirstChild; INode? INode.LastChild => LastChild; IDocument INode.Owner => Owner; INode? INode.Parent => _parent; public IElement? ParentElement => _parent as IElement; INodeList INode.ChildNodes => _children; public string NodeName => _name; internal Node? PreviousSibling { get { if (_parent != null) { int length = _parent._children.Length; for (int i = 1; i < length; i++) { if (_parent._children[i] == this) { return _parent._children[i - 1]; } } } return null; } } internal Node? NextSibling { get { if (_parent != null) { int num = _parent._children.Length - 1; for (int i = 0; i < num; i++) { if (_parent._children[i] == this) { return _parent._children[i + 1]; } } } return null; } } internal Node? FirstChild { get { if (_children.Length <= 0) { return null; } return _children[0]; } } internal Node? LastChild { get { if (_children.Length <= 0) { return null; } return _children[_children.Length - 1]; } } internal NodeList ChildNodes { get { return _children; } set { _children = value; } } internal Node? Parent { get { return _parent; } set { _parent = value; } } internal Document Owner { get { if (_type == NodeType.Document) { return null; } return _owner; } set { if (Owner == value) { return; } foreach (Node item in this.DescendantsAndSelf()) { Document owner = item.Owner; item._owner = value; if (owner != null) { NodeIsAdopted(owner); } } } } StringOrMemory IConstructableNode.NodeName => NodeName; NodeFlags IConstructableNode.Flags => _flags; IConstructableNode? IConstructableNode.Parent { get { return Parent; } set { if (value != null) { Parent = (Node)value; } } } IConstructableNodeList IConstructableNode.ChildNodes => ChildNodes; private static ReadOnlySpan WhiteSpace => " \t\r\n".AsSpan(); public Node(Document? owner, string name, NodeType type = NodeType.Element, NodeFlags flags = NodeFlags.None) { _owner = owner; _name = name ?? string.Empty; _type = type; _children = (this.IsEndPoint() ? NodeList.Empty : new NodeList()); _flags = flags; } internal void ReplaceAll(Node? node, bool suppressObservers) { Document owner = Owner; if (node != null) { owner.AdoptNode(node); } NodeList nodeList = new NodeList(); NodeList nodeList2 = new NodeList(); nodeList.AddRange(_children); if (node != null) { if (node.NodeType == NodeType.DocumentFragment) { nodeList2.AddRange(node._children); } else { nodeList2.Add(node); } } for (int i = 0; i < nodeList.Length; i++) { RemoveChild(nodeList[i], suppressObservers: true); } for (int j = 0; j < nodeList2.Length; j++) { InsertBefore(nodeList2[j], null, suppressObservers: true); } if (!suppressObservers) { owner.QueueMutation(MutationRecord.ChildList(this, nodeList2, nodeList)); } ReplacedAll(); } internal INode InsertBefore(Node newElement, Node? referenceElement, bool suppressObservers) { Document owner = Owner; int num = ((newElement.NodeType != NodeType.DocumentFragment) ? 1 : newElement.ChildNodes.Length); if (referenceElement != null && owner != null) { int num2 = referenceElement.Index(); foreach (Range attachedReference in owner.GetAttachedReferences()) { if (attachedReference.Head == this && attachedReference.Start > num2) { attachedReference.StartWith(this, attachedReference.Start + num); } if (attachedReference.Tail == this && attachedReference.End > num2) { attachedReference.EndWith(this, attachedReference.End + num); } } } if (newElement.NodeType == NodeType.Document || newElement.Contains(this)) { throw new DomException(DomError.HierarchyRequest); } NodeList nodeList = new NodeList(); int num3 = _children.Index(referenceElement); if (num3 == -1) { num3 = _children.Length; } if (newElement._type == NodeType.DocumentFragment) { int num4 = num3; int i = num3; while (newElement.HasChildNodes) { Node node = newElement.ChildNodes[0]; newElement.RemoveChild(node, suppressObservers: true); InsertNode(num4, node); num4++; } for (; i < num4; i++) { Node node2 = _children[i]; nodeList.Add(node2); NodeIsInserted(node2); } } else { nodeList.Add(newElement); InsertNode(num3, newElement); NodeIsInserted(newElement); } if (!suppressObservers) { owner?.QueueMutation(MutationRecord.ChildList(this, nodeList, null, (num3 > 0) ? _children[num3 - 1] : null, referenceElement)); } return newElement; } internal void RemoveChild(Node node, bool suppressObservers) { Document owner = Owner; int num = _children.Index(node); if (owner != null) { foreach (Range attachedReference in owner.GetAttachedReferences()) { if (attachedReference.Head.IsInclusiveDescendantOf(node)) { attachedReference.StartWith(this, num); } if (attachedReference.Tail.IsInclusiveDescendantOf(node)) { attachedReference.EndWith(this, num); } if (attachedReference.Head == this && attachedReference.Start > num) { attachedReference.StartWith(this, attachedReference.Start - 1); } if (attachedReference.Tail == this && attachedReference.End > num) { attachedReference.EndWith(this, attachedReference.End - 1); } } } Node node2 = ((num > 0) ? _children[num - 1] : null); if (!suppressObservers && owner != null) { NodeList removedNodes = new NodeList { node }; owner.QueueMutation(MutationRecord.ChildList(this, null, removedNodes, node2, node.NextSibling)); owner.AddTransientObserver(node); } RemoveNode(num, node); NodeIsRemoved(node, node2); } internal Node ReplaceChild(Node node, Node child, bool suppressObservers) { if (this.IsEndPoint() || node.IsHostIncludingInclusiveAncestor(this)) { throw new DomException(DomError.HierarchyRequest); } if (child.Parent != this) { throw new DomException(DomError.NotFound); } if (node.IsInsertable()) { Node nextSibling = child.NextSibling; Document owner = Owner; NodeList nodeList = new NodeList(); NodeList nodeList2 = new NodeList(); if (this is IDocument parent && IsChangeForbidden(node, parent, child)) { throw new DomException(DomError.HierarchyRequest); } if (nextSibling == node) { nextSibling = node.NextSibling; } owner?.AdoptNode(node); RemoveChild(child, suppressObservers: true); InsertBefore(node, nextSibling, suppressObservers: true); nodeList2.Add(child); if (node._type == NodeType.DocumentFragment) { nodeList.AddRange(node._children); } else { nodeList.Add(node); } if (!suppressObservers) { owner?.QueueMutation(MutationRecord.ChildList(this, nodeList, nodeList2, child.PreviousSibling, nextSibling)); } return child; } throw new DomException(DomError.HierarchyRequest); } protected virtual void ReplacedAll() { } public abstract Node Clone(Document newOwner, bool deep); public void AppendText(string s) { if (LastChild is TextNode textNode) { textNode.Append(s); } else { AddNode(new TextNode(Owner, s)); } } public void InsertText(int index, string s) { if (index > 0 && index <= _children.Length && _children[index - 1] is IText text) { text.Append(s); } else if (index >= 0 && index < _children.Length && _children[index] is IText text2) { text2.Insert(0, s); } else { InsertNode(index, new TextNode(Owner, s)); } } public void InsertNode(int index, Node node) { node.Parent = this; _children.Insert(index, node); } public void AddNode(Node node) { node.Parent = this; _children.Add(node); } public void RemoveNode(int index, Node node) { node.Parent = null; _children.RemoveAt(index); } public void ToHtml(TextWriter writer, IMarkupFormatter formatter) { IElement parentElement = ParentElement; foreach (INode item in this.GetDescendantsAndSelf()) { if (item is IComment comment) { writer.Write(formatter.Comment(comment)); } else if (item is IProcessingInstruction processing) { writer.Write(formatter.Processing(processing)); } else if (item is ICharacterData characterData) { INode? parent = characterData.Parent; if (parent != null && parent.Flags.HasFlag(NodeFlags.LiteralText)) { writer.Write(formatter.LiteralText(characterData)); } else { writer.Write(formatter.Text(characterData)); } } else if (item is IDocumentType doctype) { writer.Write(formatter.Doctype(doctype)); } else if (item is IElement { Flags: var flags } element) { bool flag = flags.HasFlag(NodeFlags.SelfClosing); writer.Write(formatter.OpenTag(element, flag)); if (!flag && flags.HasFlag(NodeFlags.LineTolerance) && element.FirstChild is IText text && text.Data.Has('\n')) { writer.Write('\n'); } if (element is IHtmlTemplateElement htmlTemplateElement) { htmlTemplateElement.Content.ToHtml(writer, formatter); } if (!item.HasChildNodes) { writer.Write(formatter.CloseTag(element, flag)); } } if (!item.HasChildNodes && item.NextSibling == null) { for (IElement element2 = item.ParentElement; element2 != parentElement; element2 = ((element2.NextSibling == null) ? element2.ParentElement : parentElement)) { writer.Write(formatter.CloseTag(element2, element2.Flags.HasFlag(NodeFlags.SelfClosing))); } } } } public INode AppendChild(INode child) { return this.PreInsert(child, null); } public INode InsertChild(int index, INode child) { Node child2 = ((index < _children.Length) ? _children[index] : null); return this.PreInsert(child, child2); } public INode InsertBefore(INode newElement, INode? referenceElement) { return this.PreInsert(newElement, referenceElement); } public INode ReplaceChild(INode newChild, INode oldChild) { return ReplaceChild((Node)newChild, (Node)oldChild, suppressObservers: false); } public INode RemoveChild(INode child) { return this.PreRemove(child); } public INode Clone(bool deep = true) { return Clone(Owner, deep); } public DocumentPositions CompareDocumentPosition(INode otherNode) { if (this == otherNode) { return DocumentPositions.Same; } if (Owner != otherNode.Owner) { DocumentPositions documentPositions = ((otherNode.GetHashCode() > GetHashCode()) ? DocumentPositions.Following : DocumentPositions.Preceding); return DocumentPositions.Disconnected | DocumentPositions.ImplementationSpecific | documentPositions; } if (otherNode.IsAncestorOf(this)) { return DocumentPositions.Preceding | DocumentPositions.Contains; } if (otherNode.IsDescendantOf(this)) { return DocumentPositions.Following | DocumentPositions.ContainedBy; } if (otherNode.IsPreceding(this)) { return DocumentPositions.Preceding; } return DocumentPositions.Following; } public bool Contains(INode otherNode) { return this.IsInclusiveAncestorOf(otherNode); } public void Normalize() { for (int i = 0; i < _children.Length; i++) { if (_children[i] is TextNode { Length: var num } textNode) { if (num == 0) { RemoveChild(textNode, suppressObservers: false); i--; continue; } StringBuilder stringBuilder = StringBuilderPool.Obtain(); TextNode textNode2 = textNode; int num2 = i; Document owner = Owner; while ((textNode2 = textNode2.NextSibling as TextNode) != null) { stringBuilder.Append(textNode2.Data); num2++; foreach (Range attachedReference in owner.GetAttachedReferences()) { if (attachedReference.Head == textNode2) { attachedReference.StartWith(textNode, num); } if (attachedReference.Tail == textNode2) { attachedReference.EndWith(textNode, num); } if (attachedReference.Head == textNode2.Parent && attachedReference.Start == num2) { attachedReference.StartWith(textNode, num); } if (attachedReference.Tail == textNode2.Parent && attachedReference.End == num2) { attachedReference.EndWith(textNode, num); } } num += textNode2.Length; } textNode.Replace(textNode.Length, 0, stringBuilder.ToPool()); for (int num3 = num2; num3 > i; num3--) { RemoveChild(_children[num3], suppressObservers: false); } } else if (_children[i].HasChildNodes) { _children[i].Normalize(); } } } public string? LookupNamespaceUri(string? prefix) { if (string.IsNullOrEmpty(prefix)) { prefix = null; } return LocateNamespace(prefix); } public string? LookupPrefix(string? namespaceUri) { if (string.IsNullOrEmpty(namespaceUri)) { return null; } return LocatePrefix(namespaceUri); } public bool IsDefaultNamespace(string? namespaceUri) { if (string.IsNullOrEmpty(namespaceUri)) { namespaceUri = null; } string other = LocateNamespace(null); return namespaceUri.Is(other); } public virtual bool Equals(INode? otherNode) { if (BaseUri.Is(otherNode?.BaseUri) && NodeName.Is(otherNode?.NodeName) && ChildNodes.Length == otherNode?.ChildNodes.Length) { for (int i = 0; i < _children.Length; i++) { if (!_children[i].Equals(otherNode.ChildNodes[i])) { return false; } } return true; } return false; } private static bool IsChangeForbidden(Node node, IDocument parent, Node child) { switch (node._type) { case NodeType.DocumentType: if (parent.Doctype == child) { return child.IsPrecededByElement(); } return true; case NodeType.Element: if (parent.DocumentElement == child) { return child.IsFollowedByDoctype(); } return true; case NodeType.DocumentFragment: { int elementCount = node.GetElementCount(); if (elementCount <= 1 && !node.HasTextNodes()) { if (elementCount == 1) { if (parent.DocumentElement == child) { return child.IsFollowedByDoctype(); } return true; } return false; } return true; } default: return false; } } protected static void GetPrefixAndLocalName(string qualifiedName, ref string? namespaceUri, out string? prefix, out string localName) { if (!qualifiedName.IsXmlName()) { throw new DomException(DomError.InvalidCharacter); } if (!qualifiedName.IsQualifiedName()) { throw new DomException(DomError.Namespace); } if (string.IsNullOrEmpty(namespaceUri)) { namespaceUri = null; } int num = qualifiedName.IndexOf(':'); if (num > 0) { prefix = qualifiedName.Substring(0, num); localName = qualifiedName.Substring(num + 1); } else { prefix = null; localName = qualifiedName; } if (IsNamespaceError(prefix, namespaceUri, qualifiedName)) { throw new DomException(DomError.Namespace); } } protected static bool IsNamespaceError(string? prefix, string? namespaceUri, string qualifiedName) { if ((prefix == null || namespaceUri != null) && (!prefix.Is(NamespaceNames.XmlPrefix) || namespaceUri.Is(NamespaceNames.XmlUri)) && ((!qualifiedName.Is(NamespaceNames.XmlNsPrefix) && !prefix.Is(NamespaceNames.XmlNsPrefix)) || namespaceUri.Is(NamespaceNames.XmlNsUri))) { if (namespaceUri.Is(NamespaceNames.XmlNsUri)) { if (!qualifiedName.Is(NamespaceNames.XmlNsPrefix)) { return !prefix.Is(NamespaceNames.XmlNsPrefix); } return false; } return false; } return true; } protected virtual string? LocateNamespace(string prefix) { return _parent?.LocateNamespace(prefix); } protected virtual string? LocatePrefix(string namespaceUri) { return _parent?.LocatePrefix(namespaceUri); } protected virtual void NodeIsAdopted(Document oldDocument) { } protected virtual void NodeIsInserted(Node newNode) { newNode.OnParentChanged(); } protected virtual void NodeIsRemoved(Node removedNode, Node? oldPreviousSibling) { removedNode.OnParentChanged(); } protected virtual void OnParentChanged() { } protected void CloneNode(Node target, Document owner, bool deep) { target._baseUri = _baseUri; if (!deep) { return; } foreach (Node child in _children) { if (child != null) { Node node = child; Node node2 = node.Clone(owner, deep: true); target.AddNode(node2); } } } void IConstructableNode.RemoveFromParent() { Parent?.RemoveChild(this); } void IConstructableNode.RemoveChild(IConstructableNode childNode) { RemoveChild((Node)childNode, suppressObservers: false); } void IConstructableNode.RemoveNode(int idx, IConstructableNode childNode) { RemoveNode(idx, (Node)childNode); } void IConstructableNode.InsertNode(int idx, IConstructableNode childNode) { InsertNode(idx, (Node)childNode); } void IConstructableNode.AddNode(IConstructableNode node) { AddNode((Node)node); } void IConstructableNode.AppendText(StringOrMemory text, bool emitWhiteSpaceOnly) { if (emitWhiteSpaceOnly || text.Memory.Span.Trim(WhiteSpace).Length != 0) { AppendText(text.ToString()); } } void IConstructableNode.InsertText(int idx, StringOrMemory text, bool emitWhiteSpaceOnly) { if (emitWhiteSpaceOnly || text.Memory.Span.Trim(WhiteSpace).Length != 0) { InsertText(idx, text.ToString()); } } } internal sealed class NodeEnumerable : IEnumerable, IEnumerable { private class NodeEnumerator : IEnumerator, IEnumerator, IDisposable { private readonly struct EnumerationFrame { public readonly INode Parent; public readonly int ChildIndex; public EnumerationFrame(INode parent, int childIndex) { Parent = parent; ChildIndex = childIndex; } } private readonly Stack _frameStack; public INode Current { get; private set; } object IEnumerator.Current => Current; public NodeEnumerator(INode startingNode) { _frameStack = new Stack(); TryPushFrame(startingNode, 0); } public bool MoveNext() { if (_frameStack.Count > 0) { EnumerationFrame enumerationFrame = _frameStack.Pop(); Current = enumerationFrame.Parent.ChildNodes[enumerationFrame.ChildIndex]; TryPushFrame(enumerationFrame.Parent, enumerationFrame.ChildIndex + 1); TryPushFrame(Current, 0); return true; } return false; } private void TryPushFrame(INode parent, int childIndex) { if (childIndex < parent.ChildNodes.Length) { _frameStack.Push(new EnumerationFrame(parent, childIndex)); } } public void Dispose() { } public void Reset() { throw new NotSupportedException(); } } private readonly INode _startingNode; public NodeEnumerable(INode startingNode) { _startingNode = startingNode; } public IEnumerator GetEnumerator() { return new NodeEnumerator(_startingNode); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [Flags] public enum NodeFlags : uint { None = 0u, SelfClosing = 1u, Special = 2u, LiteralText = 4u, LineTolerance = 8u, ImplicitlyClosed = 0x10u, ImpliedEnd = 0x20u, Scoped = 0x40u, HtmlMember = 0x100u, HtmlTip = 0x200u, HtmlFormatting = 0x800u, HtmlListScoped = 0x1000u, HtmlSelectScoped = 0x2000u, HtmlTableSectionScoped = 0x4000u, HtmlTableScoped = 0x8000u, MathMember = 0x10000u, MathTip = 0x20000u, SvgMember = 0x1000000u, SvgTip = 0x2000000u } internal sealed class NodeIterator : INodeIterator { private readonly INode _root; private readonly FilterSettings _settings; private readonly NodeFilter _filter; private readonly IEnumerable _iterator; private INode _reference; private bool _beforeNode; public INode Root => _root; public FilterSettings Settings => _settings; public NodeFilter Filter => _filter; public INode Reference => _reference; public bool IsBeforeReference => _beforeNode; public NodeIterator(INode root, FilterSettings settings, NodeFilter? filter) { _root = root; _settings = settings; _filter = filter ?? ((NodeFilter)((INode _) => FilterResult.Accept)); _beforeNode = true; _iterator = GetNodes(root); _reference = root; } public INode? Next() { INode node = _reference; bool flag = _beforeNode; do { if (!flag) { node = _iterator.SkipWhile((INode m) => m != node).Skip(1).FirstOrDefault(); } if (node == null) { return null; } flag = false; } while (!_settings.Accepts(node) || _filter(node) != FilterResult.Accept); _beforeNode = false; _reference = node; return node; } public INode? Previous() { INode node = _reference; bool flag = _beforeNode; do { if (flag) { node = _iterator.TakeWhile((INode m) => m != node).LastOrDefault(); } if (node == null) { return null; } flag = true; } while (!_settings.Accepts(node) || _filter(node) != FilterResult.Accept); _beforeNode = true; _reference = node; return node; } private static IEnumerable GetNodes(INode root) { yield return root; IEnumerable nodes = root.GetNodes(); foreach (INode item in nodes) { yield return item; } } } internal sealed class NodeList : INodeList, IEnumerable, IEnumerable, IMarkupFormattable, IConstructableNodeList, IEnumerable { internal readonly List _entries; internal static readonly NodeList Empty = new NodeList(); public Node this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _entries[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { _entries[index] = value; } } INode INodeList.this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return this[index]; } } public int Length => _entries.Count; IConstructableNode IConstructableNodeList.this[int index] => _entries[index]; internal NodeList() { _entries = new List(); } internal void Add(Node node) { _entries.Add(node); } internal void AddRange(NodeList nodeList) { _entries.AddRange(nodeList._entries); } internal void Insert(int index, Node node) { _entries.Insert(index, node); } internal void Remove(Node node) { _entries.Remove(node); } internal void RemoveAt(int index) { _entries.RemoveAt(index); } internal bool Contains(Node node) { return _entries.Contains(node); } public void ToHtml(TextWriter writer, IMarkupFormatter formatter) { for (int i = 0; i < _entries.Count; i++) { _entries[i].ToHtml(writer, formatter); } } public List.Enumerator GetEnumerator() { return _entries.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _entries.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _entries.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } void IConstructableNodeList.Clear() { _entries.Clear(); } } internal interface INodeListAccessor { int Length { get; } INode this[int index] { get; } } internal readonly struct ConcreteNodeListAccessor : INodeListAccessor { private readonly List _nodeList; public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _nodeList.Count; } } public INode this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _nodeList[index]; } } public ConcreteNodeListAccessor(NodeList nodeList) { _nodeList = nodeList._entries; } } internal readonly struct InterfaceNodeListAccessor : INodeListAccessor { private readonly INodeList _nodeList; public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _nodeList.Length; } } public INode this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _nodeList[index]; } } public InterfaceNodeListAccessor(INodeList nodeList) { _nodeList = nodeList; } } [DomName("Notation")] public sealed class Notation : Node { [DomName("publicId")] public string? PublicId { get; set; } [DomName("systemId")] public string? SystemId { get; set; } public Notation(Document owner, string name) : base(owner, name, NodeType.Notation) { } public override Node Clone(Document newOwner, bool deep) { Notation notation = new Notation(newOwner, base.NodeName); CloneNode(notation, newOwner, deep); return notation; } } internal sealed class OptionsCollection : IHtmlOptionsCollection, IHtmlCollection, IEnumerable, IEnumerable { private readonly IElement _parent; private readonly IEnumerable _options; public IHtmlOptionElement this[int index] => GetOptionAt(index); public IHtmlOptionElement? this[string name] { get { if (name != null && name.Length > 0) { foreach (IHtmlOptionElement option in _options) { if (option.Id.Is(name)) { return option; } } return _parent.Children[name] as IHtmlOptionElement; } return null; } } public int SelectedIndex { get { int num = 0; foreach (IHtmlOptionElement option in _options) { if (option.IsSelected) { return num; } num++; } return -1; } set { int num = 0; foreach (IHtmlOptionElement option in _options) { option.IsSelected = num++ == value; } } } public int Length => _options.Count(); public OptionsCollection(IElement parent) { _parent = parent; _options = GetOptions(); } public IHtmlOptionElement GetOptionAt(int index) { return _options.GetItemByIndex(index); } public void SetOptionAt(int index, IHtmlOptionElement value) { IHtmlOptionElement optionAt = GetOptionAt(index); if (optionAt != null) { _parent.ReplaceChild(value, optionAt); } else { _parent.AppendChild(value); } } public void Add(IHtmlOptionElement element, IHtmlElement? before = null) { _parent.InsertBefore(element, before); } public void Add(IHtmlOptionsGroupElement element, IHtmlElement? before = null) { _parent.InsertBefore(element, before); } public void Remove(int index) { if (index >= 0 && index < Length) { IHtmlOptionElement optionAt = GetOptionAt(index); _parent.RemoveChild(optionAt); } } private IEnumerable GetOptions() { foreach (INode childNode in _parent.ChildNodes) { if (childNode is IHtmlOptionsGroupElement htmlOptionsGroupElement) { foreach (INode childNode2 in htmlOptionsGroupElement.ChildNodes) { if (childNode2 is IHtmlOptionElement htmlOptionElement) { yield return htmlOptionElement; } } } else if (childNode is IHtmlOptionElement) { yield return (IHtmlOptionElement)childNode; } } } public IEnumerator GetEnumerator() { return _options.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal sealed class ProcessingInstruction : CharacterData, IProcessingInstruction, ICharacterData, INode, IEventTarget, IMarkupFormattable, IChildNode, INonDocumentTypeChildNode { public string Target => base.NodeName; internal ProcessingInstruction(Document owner, string name) : base(owner, name, NodeType.ProcessingInstruction) { } public override Node Clone(Document owner, bool deep) { ProcessingInstruction processingInstruction = new ProcessingInstruction(owner, Target); CloneNode(processingInstruction, owner, deep); return processingInstruction; } internal static ProcessingInstruction Create(Document owner, string data) { int num = data.IndexOf(' '); ProcessingInstruction processingInstruction = new ProcessingInstruction(owner, (num <= 0) ? data : data.Substring(0, num)); if (num > 0) { processingInstruction.Data = data.Substring(num); } return processingInstruction; } } public enum QuirksMode : byte { Off, Limited, [DomDescription("BackCompat")] On } internal sealed class Range : IRange { private readonly struct Boundary : IEquatable { public readonly INode Node; public readonly int Offset; public readonly bool IsExplicit; public INode? ChildAtOffset { get { if (Node.ChildNodes.Length <= Offset) { return null; } return Node.ChildNodes[Offset]; } } public Boundary(INode node, int offset, bool given = true) { Node = node; Offset = offset; IsExplicit = given; } public static bool operator >(Boundary a, Boundary b) { return a.CompareTo(b) == RangePosition.After; } public static bool operator <(Boundary a, Boundary b) { return a.CompareTo(b) == RangePosition.Before; } public static bool operator ==(Boundary a, Boundary b) { return a.CompareTo(b) == RangePosition.Equal; } public static bool operator !=(Boundary a, Boundary b) { return a.CompareTo(b) != RangePosition.Equal; } public static bool operator <=(Boundary a, Boundary b) { return a.CompareTo(b) switch { RangePosition.Before => true, RangePosition.Equal => true, _ => false, }; } public static bool operator >=(Boundary a, Boundary b) { return a.CompareTo(b) switch { RangePosition.After => true, RangePosition.Equal => true, _ => false, }; } public bool Equals(Boundary other) { return CompareTo(other) == RangePosition.Equal; } public RangePosition CompareTo(Boundary other) { if (Node.GetRoot() != other.Node.GetRoot()) { throw new DomException(DomError.InvalidAccess); } if (Node == other.Node) { if (Offset < other.Offset) { return RangePosition.Before; } if (Offset == other.Offset) { return RangePosition.Equal; } if (Offset > other.Offset) { return RangePosition.After; } } if (Node.IsFollowing(other.Node)) { switch (other.CompareTo(this)) { case RangePosition.Before: return RangePosition.After; case RangePosition.After: return RangePosition.Before; } } if (Node.IsAncestorOf(other.Node)) { INode node = other.Node; while (node != null && node.Parent != Node) { node = node.Parent; } if (node != null && node.Index() < Offset) { return RangePosition.After; } } return RangePosition.Before; } public override bool Equals(object? obj) { if (obj is Boundary) { return Equals((Boundary)obj); } return false; } public override int GetHashCode() { return ((17 * 23 + Node.GetHashCode()) * 23 + Offset.GetHashCode()) * 23 + IsExplicit.GetHashCode(); } } private Boundary _start; private Boundary _end; public INode Root => _start.Node.GetRoot(); public IEnumerable Nodes => CommonAncestor.GetNodes(deep: true, Intersects); public INode Head => _start.Node; public int Start => _start.Offset; public INode Tail => _end.Node; public int End => _end.Offset; public bool IsCollapsed => _start.Node == _end.Node; public INode CommonAncestor { get { INode node = Head; while (node != null && !node.IsInclusiveAncestorOf(Tail)) { node = node.Parent; } return node; } } public Range(IDocument document) { _start = new Boundary(document, 0, given: false); _end = new Boundary(document, 0, given: false); } private Range(Boundary start, Boundary end) { _start = start; _end = end; } public void StartWith(INode refNode, int offset) { if (refNode == null) { throw new ArgumentNullException("refNode"); } if (refNode.NodeType == NodeType.DocumentType) { throw new DomException(DomError.InvalidNodeType); } if (offset < 0) { throw new DomException(DomError.IndexSizeError); } int nodeLength = GetNodeLength(refNode); if (offset > nodeLength) { throw new DomException(DomError.IndexSizeError); } Boundary boundary = new Boundary(refNode, offset); if (!_end.IsExplicit || Root != refNode.GetRoot() || boundary > _end) { _end = boundary; } _start = boundary; } public void EndWith(INode refNode, int offset) { if (refNode == null) { throw new ArgumentNullException("refNode"); } if (refNode.NodeType == NodeType.DocumentType) { throw new DomException(DomError.InvalidNodeType); } if (offset < 0) { throw new DomException(DomError.IndexSizeError); } int nodeLength = GetNodeLength(refNode); if (offset > nodeLength) { throw new DomException(DomError.IndexSizeError); } Boundary boundary = new Boundary(refNode, offset); if (!_start.IsExplicit || Root != refNode.GetRoot() || boundary < _start) { _start = boundary; } _end = boundary; } public void StartBefore(INode refNode) { if (refNode == null) { throw new ArgumentNullException("refNode"); } INode parent = refNode.Parent; if (parent == null) { throw new DomException(DomError.InvalidNodeType); } _start = new Boundary(parent, parent.ChildNodes.Index(refNode)); if (!_end.IsExplicit) { _end = _start; } } public void EndBefore(INode refNode) { if (refNode == null) { throw new ArgumentNullException("refNode"); } INode parent = refNode.Parent; if (parent == null) { throw new DomException(DomError.InvalidNodeType); } _end = new Boundary(parent, parent.ChildNodes.Index(refNode)); if (!_start.IsExplicit) { _start = _end; } } public void StartAfter(INode refNode) { if (refNode == null) { throw new ArgumentNullException("refNode"); } INode parent = refNode.Parent; if (parent == null) { throw new DomException(DomError.InvalidNodeType); } _start = new Boundary(parent, parent.ChildNodes.Index(refNode) + 1); if (!_end.IsExplicit) { _end = _start; } } public void EndAfter(INode refNode) { if (refNode == null) { throw new ArgumentNullException("refNode"); } INode parent = refNode.Parent; if (parent == null) { throw new DomException(DomError.InvalidNodeType); } _end = new Boundary(parent, parent.ChildNodes.Index(refNode) + 1); if (!_start.IsExplicit) { _start = _end; } } public void Collapse(bool toStart) { if (toStart) { _end = _start; } else { _start = _end; } } public void Select(INode refNode) { if (refNode == null) { throw new ArgumentNullException("refNode"); } INode parent = refNode.Parent; if (parent == null) { throw new DomException(DomError.InvalidNodeType); } int num = parent.ChildNodes.Index(refNode); _start = new Boundary(parent, num); _end = new Boundary(parent, num + 1); } public void SelectContent(INode refNode) { if (refNode == null) { throw new ArgumentNullException("refNode"); } if (refNode.NodeType == NodeType.DocumentType) { throw new DomException(DomError.InvalidNodeType); } int length = refNode.ChildNodes.Length; _start = new Boundary(refNode, 0); _end = new Boundary(refNode, length); } public void ClearContent() { if (_start.Equals(_end)) { return; } Boundary boundary = default(Boundary); Boundary start = _start; Boundary end = _end; if (end.Node == start.Node && start.Node is ICharacterData) { int offset = start.Offset; ICharacterData obj = (ICharacterData)start.Node; int count = end.Offset - start.Offset; obj.Replace(offset, count, string.Empty); return; } INode[] array = (from m in CommonAncestor.GetNodes(deep: true, (INode node3) => Contains(node3, 0)) where !Contains(m.Parent, 0) select m).ToArray(); if (!start.Node.IsInclusiveAncestorOf(end.Node)) { INode node = start.Node; while (node.Parent != null && !node.Parent.IsInclusiveAncestorOf(end.Node)) { node = node.Parent; } boundary = new Boundary(node.Parent, node.Index() + 1); } else { boundary = start; } if (start.Node is ICharacterData) { int offset2 = start.Offset; ICharacterData obj2 = (ICharacterData)start.Node; int count2 = obj2.Data.Length - start.Offset; obj2.Replace(offset2, count2, string.Empty); } INode[] array2 = array; foreach (INode node2 in array2) { node2.Parent.RemoveChild(node2); } if (end.Node is ICharacterData) { int offset3 = 0; ICharacterData obj3 = (ICharacterData)end.Node; int offset4 = end.Offset; obj3.Replace(offset3, offset4, string.Empty); } _start = boundary; _end = boundary; } public IDocumentFragment ExtractContent() { IDocumentFragment documentFragment = _start.Node.Owner.CreateDocumentFragment(); if (!_start.Equals(_end)) { Boundary boundary = _start; Boundary start = _start; Boundary end = _end; if (start.Node == end.Node && _start.Node is ICharacterData) { ICharacterData characterData = (ICharacterData)start.Node; int offset = start.Offset; int count = end.Offset - start.Offset; ICharacterData characterData2 = (ICharacterData)characterData.Clone(); characterData2.Data = characterData.Substring(offset, count); documentFragment.AppendChild(characterData2); characterData.Replace(offset, count, string.Empty); } else { INode node = start.Node; while (!node.IsInclusiveAncestorOf(end.Node)) { node = node.Parent; } INode node2 = ((!start.Node.IsInclusiveAncestorOf(end.Node)) ? node.GetNodes(deep: true, IsPartiallyContained).FirstOrDefault() : null); INode node3 = ((!end.Node.IsInclusiveAncestorOf(start.Node)) ? node.GetNodes(deep: true, IsPartiallyContained).LastOrDefault() : null); List list = node.GetNodes(deep: true, Intersects).ToList(); if (list.OfType().Any()) { throw new DomException(DomError.HierarchyRequest); } if (!start.Node.IsInclusiveAncestorOf(end.Node)) { INode node4 = start.Node; while (node4.Parent != null && !node4.IsInclusiveAncestorOf(end.Node)) { node4 = node4.Parent; } boundary = new Boundary(node4, node4.Parent.ChildNodes.Index(node4) + 1); } if (node2 is ICharacterData) { ICharacterData characterData3 = (ICharacterData)start.Node; int offset2 = start.Offset; int count2 = characterData3.Length - start.Offset; ICharacterData characterData4 = (ICharacterData)characterData3.Clone(); characterData4.Data = characterData3.Substring(offset2, count2); documentFragment.AppendChild(characterData4); characterData3.Replace(offset2, count2, string.Empty); } else if (node2 != null) { INode child = node2.Clone(); documentFragment.AppendChild(child); IDocumentFragment child2 = new Range(start, new Boundary(node2, node2.ChildNodes.Length)).ExtractContent(); documentFragment.AppendChild(child2); } foreach (INode item in list) { documentFragment.AppendChild(item); } if (node3 is ICharacterData) { ICharacterData characterData5 = (ICharacterData)end.Node; ICharacterData characterData6 = (ICharacterData)characterData5.Clone(); characterData6.Data = characterData5.Substring(0, end.Offset); documentFragment.AppendChild(characterData6); characterData5.Replace(0, end.Offset, string.Empty); } else if (node3 != null) { INode child3 = node3.Clone(); documentFragment.AppendChild(child3); IDocumentFragment child4 = new Range(new Boundary(node3, 0), end).ExtractContent(); documentFragment.AppendChild(child4); } _start = boundary; _end = boundary; } } return documentFragment; } public IDocumentFragment CopyContent() { IDocumentFragment documentFragment = _start.Node.Owner.CreateDocumentFragment(); if (!_start.Equals(_end)) { Boundary start = _start; Boundary end = _end; if (start.Node == end.Node && _start.Node is ICharacterData) { ICharacterData characterData = (ICharacterData)start.Node; int offset = start.Offset; int count = end.Offset - start.Offset; ICharacterData characterData2 = (ICharacterData)characterData.Clone(); characterData2.Data = characterData.Substring(offset, count); documentFragment.AppendChild(characterData2); } else { INode node = start.Node; while (!node.IsInclusiveAncestorOf(end.Node)) { node = node.Parent; } INode node2 = ((!start.Node.IsInclusiveAncestorOf(end.Node)) ? node.GetNodes(deep: true, IsPartiallyContained).FirstOrDefault() : null); INode node3 = ((!end.Node.IsInclusiveAncestorOf(start.Node)) ? node.GetNodes(deep: true, IsPartiallyContained).LastOrDefault() : null); List list = node.GetNodes(deep: true, Intersects).ToList(); if (list.OfType().Any()) { throw new DomException(DomError.HierarchyRequest); } if (node2 is ICharacterData) { ICharacterData characterData3 = (ICharacterData)start.Node; int offset2 = start.Offset; int count2 = characterData3.Length - start.Offset; ICharacterData characterData4 = (ICharacterData)characterData3.Clone(); characterData4.Data = characterData3.Substring(offset2, count2); documentFragment.AppendChild(characterData4); } else if (node2 != null) { INode child = node2.Clone(); documentFragment.AppendChild(child); IDocumentFragment child2 = new Range(start, new Boundary(node2, node2.ChildNodes.Length)).CopyContent(); documentFragment.AppendChild(child2); } foreach (INode item in list) { documentFragment.AppendChild(item.Clone()); } if (node3 is ICharacterData) { ICharacterData characterData5 = (ICharacterData)end.Node; ICharacterData characterData6 = (ICharacterData)characterData5.Clone(); characterData6.Data = characterData5.Substring(0, end.Offset); documentFragment.AppendChild(characterData6); } else if (node3 != null) { INode child3 = node3.Clone(); documentFragment.AppendChild(child3); IDocumentFragment child4 = new Range(new Boundary(node3, 0), end).CopyContent(); documentFragment.AppendChild(child4); } } } return documentFragment; } public void Insert(INode node) { if (node == null) { throw new ArgumentNullException("node"); } INode node2 = _start.Node; NodeType nodeType = node2.NodeType; bool flag = nodeType == NodeType.Text; if (nodeType == NodeType.ProcessingInstruction || nodeType == NodeType.Comment || (flag && node2.Parent == null)) { throw new DomException(DomError.HierarchyRequest); } INode node3 = (flag ? node2 : _start.ChildAtOffset); INode node4 = ((node3 == null) ? node2 : node3.Parent); node4.EnsurePreInsertionValidity(node, node3); if (flag) { node3 = ((IText)node2).Split(_start.Offset); node4 = node3.Parent; } if (node == node3) { node3 = node3.NextSibling; } node.Parent?.RemoveChild(node); int num = ((node3 == null) ? node4.ChildNodes.Length : node4.ChildNodes.Index(node3)); num += ((node.NodeType != NodeType.DocumentFragment) ? 1 : node.ChildNodes.Length); node4.PreInsert(node, node3); if (_start.Equals(_end)) { _end = new Boundary(node4, num); } } public void Surround(INode newParent) { if (newParent == null) { throw new ArgumentNullException("newParent"); } if (Nodes.Any((INode m) => m.NodeType != NodeType.Text && IsPartiallyContained(m))) { throw new DomException(DomError.InvalidState); } NodeType nodeType = newParent.NodeType; if (nodeType == NodeType.Document || nodeType == NodeType.DocumentType || nodeType == NodeType.DocumentFragment) { throw new DomException(DomError.InvalidNodeType); } IDocumentFragment node = ExtractContent(); while (newParent.HasChildNodes) { newParent.RemoveChild(newParent.FirstChild); } Insert(newParent); newParent.PreInsert(node, null); Select(newParent); } public IRange Clone() { return new Range(_start, _end); } public void Detach() { } public bool Contains(INode node, int offset) { if (node == null) { throw new ArgumentNullException("node"); } if (node.GetRoot() == Root) { if (node.NodeType == NodeType.DocumentType) { throw new DomException(DomError.InvalidNodeType); } if (offset > node.ChildNodes.Length) { throw new DomException(DomError.IndexSizeError); } int offset2 = ((!(node is IDocumentType) && !(node is IAttr)) ? ((node is ICharacterData characterData) ? characterData.Data.Length : node.ChildNodes.Length) : 0); if (new Boundary(node, offset) > _start) { return new Boundary(node, offset2) < _end; } return false; } return false; } public RangePosition CompareBoundaryTo(RangeType how, IRange sourceRange) { if (sourceRange == null) { throw new ArgumentNullException("sourceRange"); } if (Root != sourceRange.Head.GetRoot()) { throw new DomException(DomError.WrongDocument); } Boundary boundary = default(Boundary); Boundary boundary2 = default(Boundary); switch (how) { case RangeType.StartToStart: boundary = _start; boundary2 = new Boundary(sourceRange.Head, sourceRange.Start); break; case RangeType.StartToEnd: boundary = _end; boundary2 = new Boundary(sourceRange.Head, sourceRange.Start); break; case RangeType.EndToEnd: boundary = _start; boundary2 = new Boundary(sourceRange.Tail, sourceRange.End); break; case RangeType.EndToStart: boundary = _end; boundary2 = new Boundary(sourceRange.Tail, sourceRange.End); break; default: throw new DomException(DomError.NotSupported); } return boundary.CompareTo(boundary2); } public RangePosition CompareTo(INode node, int offset) { if (node == null) { throw new ArgumentNullException("node"); } if (Root != _start.Node.GetRoot()) { throw new DomException(DomError.WrongDocument); } if (node.NodeType == NodeType.DocumentType) { throw new DomException(DomError.InvalidNodeType); } if (offset > node.ChildNodes.Length) { throw new DomException(DomError.IndexSizeError); } if (IsStartAfter(node, offset)) { return RangePosition.Before; } if (IsEndBefore(node, offset)) { return RangePosition.After; } return RangePosition.Equal; } public bool Intersects(INode node) { if (node == null) { throw new ArgumentNullException("node"); } if (Root == node.GetRoot()) { INode parent = node.Parent; if (parent != null) { int num = parent.ChildNodes.Index(node); if (new Boundary(parent, num) < _end) { return new Boundary(parent, num + 1) > _start; } return false; } return true; } return false; } public override string ToString() { StringBuilder stringBuilder = null; int start = Start; int end = End; if (Head is IText text) { if (Head == Tail) { return text.Substring(start, end - start); } if (stringBuilder == null) { stringBuilder = StringBuilderPool.Obtain(); } stringBuilder.Append(text.Substring(start, text.Length - start)); } if (stringBuilder == null) { stringBuilder = StringBuilderPool.Obtain(); } foreach (IText item in CommonAncestor.Descendants()) { if (IsStartBefore(item, 0) && IsEndAfter(item, item.Length)) { stringBuilder.Append(item.Text); } } if (Tail is IText text2) { stringBuilder.Append(text2.Substring(0, end)); } return stringBuilder.ToPool(); } private static int GetNodeLength(INode node) { if (node is IDocumentType || node is IAttr) { return 0; } if (node is ICharacterData characterData) { return characterData.Data.Length; } return node.ChildNodes.Length; } private bool IsStartBefore(INode node, int offset) { return _start < new Boundary(node, offset); } private bool IsStartAfter(INode node, int offset) { return _start > new Boundary(node, offset); } private bool IsEndBefore(INode node, int offset) { return _end < new Boundary(node, offset); } private bool IsEndAfter(INode node, int offset) { return _end > new Boundary(node, offset); } private bool IsPartiallyContained(INode node) { bool flag = node.IsInclusiveAncestorOf(_start.Node); bool flag2 = node.IsInclusiveAncestorOf(_end.Node); if (!flag || flag2) { return !flag && flag2; } return true; } } internal sealed class SettableTokenList : TokenList, ISettableTokenList, ITokenList, IEnumerable, IEnumerable { public string Value { get { return ToString(); } set { Update(value); } } internal SettableTokenList(string? value) : base(value) { } } internal sealed class ShadowRoot : Node, IShadowRoot, IDocumentFragment, INode, IEventTarget, IMarkupFormattable, IParentNode, INonElementParentNode { private readonly Element _host; private readonly IStyleSheetList _styleSheets; private readonly ShadowRootMode _mode; private HtmlCollection? _elements; public IElement? ActiveElement => this.GetDescendants().OfType().FirstOrDefault((Element m) => m.IsFocused); public ShadowRootMode Mode => _mode; public IElement Host => _host; public string InnerHtml { get { return base.ChildNodes.ToHtml(HtmlMarkupFormatter.Instance); } set { ReplaceAll(new DocumentFragment(_host, value), suppressObservers: false); } } public IStyleSheetList StyleSheets => _styleSheets; public int ChildElementCount => base.ChildNodes.OfType().Count(); public IHtmlCollection Children => _elements ?? (_elements = new HtmlCollection(this, deep: false)); public IElement? FirstElementChild { get { NodeList childNodes = base.ChildNodes; int length = childNodes.Length; for (int i = 0; i < length; i++) { if (childNodes[i] is IElement result) { return result; } } return null; } } public IElement? LastElementChild { get { NodeList childNodes = base.ChildNodes; for (int num = childNodes.Length - 1; num >= 0; num--) { if (childNodes[num] is IElement result) { return result; } } return null; } } public override string TextContent { get { StringBuilder stringBuilder = StringBuilderPool.Obtain(); foreach (IText item in this.GetDescendants().OfType()) { stringBuilder.Append(item.Data); } return stringBuilder.ToPool(); } set { TextNode node = ((!string.IsNullOrEmpty(value)) ? new TextNode(base.Owner, value) : null); ReplaceAll(node, suppressObservers: false); } } internal ShadowRoot(Element host, ShadowRootMode mode) : base(host.Owner, "#shadow-root", NodeType.DocumentFragment) { _host = host; _styleSheets = this.CreateStyleSheets(); _mode = mode; } public void Prepend(params INode[] nodes) { this.PrependNodes(nodes); } public void Append(params INode[] nodes) { this.AppendNodes(nodes); } public IElement? QuerySelector(string selectors) { return base.ChildNodes.QuerySelector(selectors, _host); } public IHtmlCollection QuerySelectorAll(string selectors) { return base.ChildNodes.QuerySelectorAll(selectors, _host); } public IHtmlCollection GetElementsByClassName(string classNames) { return base.ChildNodes.GetElementsByClassName(classNames); } public IHtmlCollection GetElementsByTagName(string tagName) { return base.ChildNodes.GetElementsByTagName(tagName); } public IHtmlCollection GetElementsByTagNameNS(string? namespaceURI, string tagName) { return base.ChildNodes.GetElementsByTagName(namespaceURI, tagName); } public IElement? GetElementById(string elementId) { return base.ChildNodes.GetElementById(elementId); } public override Node Clone(Document owner, bool deep) { ShadowRoot shadowRoot = new ShadowRoot(_host, _mode); CloneNode(shadowRoot, owner, deep); return shadowRoot; } } internal enum SimpleChoice : byte { Yes, No } internal sealed class StringList : IStringList, IEnumerable, IEnumerable { private readonly IEnumerable _list; public string this[int index] => _list.GetItemByIndex(index); public int Length => _list.Count(); internal StringList(IEnumerable list) { _list = list; } public bool Contains(string entry) { return _list.Contains(entry); } public IEnumerator GetEnumerator() { return _list.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _list.GetEnumerator(); } } internal sealed class StringMap : IStringMap, IEnumerable>, IEnumerable { private readonly string _prefix; private readonly Element _parent; public string? this[string name] { get { return _parent.GetOwnAttribute(_prefix + Check(name)); } set { _parent.SetOwnAttribute(_prefix + Check(name), value); } } internal StringMap(string prefix, Element parent) { _prefix = prefix; _parent = parent; } public void Remove(string name) { if (Contains(name)) { this[name] = null; } } public bool Contains(string name) { return _parent.HasOwnAttribute(_prefix + Check(name)); } private static string Check(string name) { if (name.StartsWith(TagNames.Xml, StringComparison.OrdinalIgnoreCase)) { throw new DomException(DomError.Syntax); } if (name.IndexOf(';') >= 0) { throw new DomException(DomError.Syntax); } for (int i = 0; i < name.Length; i++) { if (name[i].IsUppercaseAscii()) { throw new DomException(DomError.Syntax); } } return name; } public IEnumerator> GetEnumerator() { foreach (IAttr attribute in _parent.Attributes) { if (attribute.NamespaceUri == null && attribute.Name.StartsWith(_prefix, StringComparison.OrdinalIgnoreCase)) { string key = attribute.Name.Remove(0, _prefix.Length); string value = attribute.Value; yield return new KeyValuePair(key, value); } } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal sealed class StyleSheetList : IStyleSheetList, IEnumerable, IEnumerable { private readonly IEnumerable _sheets; public IStyleSheet? this[int index] => _sheets.Skip(index).FirstOrDefault(); public int Length => _sheets.Count(); internal StyleSheetList(IEnumerable sheets) { _sheets = sheets; } public IEnumerator GetEnumerator() { return _sheets.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal sealed class TextNode : CharacterData, IText, ICharacterData, INode, IEventTarget, IMarkupFormattable, IChildNode, INonDocumentTypeChildNode { internal bool IsEmpty { get { for (int i = 0; i < base.Length; i++) { if (!base[i].IsSpaceCharacter()) { return false; } } return true; } } public string Text { get { Node previousSibling = base.PreviousSibling; TextNode textNode = this; StringBuilder stringBuilder = StringBuilderPool.Obtain(); while (previousSibling is TextNode) { textNode = (TextNode)previousSibling; previousSibling = textNode.PreviousSibling; } do { stringBuilder.Append(textNode.Data); textNode = textNode.NextSibling as TextNode; } while (textNode != null); return stringBuilder.ToPool(); } } public IElement? AssignedSlot { get { IElement parentElement = base.ParentElement; if (parentElement.IsShadow()) { return parentElement.ShadowRoot?.GetAssignedSlot(null); } return null; } } internal TextNode(Document owner) : this(owner, string.Empty) { } internal TextNode(Document owner, string text) : base(owner, "#text", NodeType.Text, text) { } public IText Split(int offset) { int length = base.Length; if (offset > length) { throw new DomException(DomError.IndexSizeError); } int count = length - offset; string text = Substring(offset, count); TextNode textNode = new TextNode(base.Owner, text); Node parent = base.Parent; Document owner = base.Owner; if (parent != null) { int num = this.Index(); parent.InsertBefore(textNode, base.NextSibling); foreach (Range attachedReference in owner.GetAttachedReferences()) { if (attachedReference.Head == this && attachedReference.Start > offset) { attachedReference.StartWith(textNode, attachedReference.Start - offset); } if (attachedReference.Tail == this && attachedReference.End > offset) { attachedReference.EndWith(textNode, attachedReference.End - offset); } if (attachedReference.Head == parent && attachedReference.Start == num + 1) { attachedReference.StartWith(parent, attachedReference.Start + 1); } if (attachedReference.Tail == parent && attachedReference.End == num + 1) { attachedReference.StartWith(parent, attachedReference.End + 1); } } } Replace(offset, count, string.Empty); if (parent != null) { foreach (Range attachedReference2 in owner.GetAttachedReferences()) { if (attachedReference2.Head == this && attachedReference2.Start > offset) { attachedReference2.StartWith(this, offset); } if (attachedReference2.Tail == this && attachedReference2.End > offset) { attachedReference2.EndWith(this, offset); } } } return textNode; } public override Node Clone(Document owner, bool deep) { TextNode textNode = new TextNode(owner, base.Data); CloneNode(textNode, owner, deep); return textNode; } } internal class TokenList : ITokenList, IEnumerable, IEnumerable, IBindable { private readonly List _tokens; public string this[int index] => _tokens[index]; public int Length => _tokens.Count; public event Action? Changed; internal TokenList(string? value) { _tokens = new List(); Update(value); } public void Update(string? value) { _tokens.Clear(); if (value == null || value.Length <= 0) { return; } string[] array = value.SplitSpaces(); for (int i = 0; i < array.Length; i++) { if (!_tokens.Contains(array[i])) { _tokens.Add(array[i]); } } } public bool Contains(string token) { return _tokens.Contains(token); } public void Remove(params string[] tokens) { bool flag = false; foreach (string item in tokens) { if (_tokens.Contains(item)) { _tokens.Remove(item); flag = true; } } if (flag) { RaiseChanged(); } } public void Add(params string[] tokens) { bool flag = false; foreach (string item in tokens) { if (!_tokens.Contains(item)) { _tokens.Add(item); flag = true; } } if (flag) { RaiseChanged(); } } public bool Toggle(string token, bool force = false) { bool flag = _tokens.Contains(token); if (flag && force) { return true; } if (flag) { _tokens.Remove(token); } else { _tokens.Add(token); } RaiseChanged(); return !flag; } private void RaiseChanged() { this.Changed?.Invoke(ToString()); } public IEnumerator GetEnumerator() { return _tokens.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public override string ToString() { return string.Join(" ", _tokens); } } internal sealed class TreeWalker : ITreeWalker { private readonly INode _root; private readonly FilterSettings _settings; private readonly NodeFilter _filter; private INode _current; public INode Root => _root; public FilterSettings Settings => _settings; public NodeFilter Filter => _filter; public INode Current { get { return _current; } set { _current = value; } } public TreeWalker(INode root, FilterSettings settings, NodeFilter? filter) { _root = root; _settings = settings; _filter = filter ?? ((NodeFilter)((INode _) => FilterResult.Accept)); _current = _root; } public INode? ToNext() { INode node = _current; FilterResult filterResult = FilterResult.Accept; while (node != null) { while (filterResult != FilterResult.Reject && node.HasChildNodes) { node = node.FirstChild; filterResult = Check(node); if (filterResult == FilterResult.Accept) { _current = node; return node; } } while (node != null && node != _root) { INode nextSibling = node.NextSibling; if (nextSibling != null) { node = nextSibling; break; } node = node.Parent; } if (node == null || node == _root) { break; } filterResult = Check(node); if (filterResult == FilterResult.Accept) { _current = node; return node; } } return null; } public INode? ToPrevious() { INode node = _current; while (node != null && node != _root) { INode previousSibling = node.PreviousSibling; while (previousSibling != null) { node = previousSibling; FilterResult filterResult = Check(node); while (filterResult != FilterResult.Reject && node.HasChildNodes) { node = node.LastChild; filterResult = Check(node); if (filterResult == FilterResult.Accept) { _current = node; return node; } } } if (node == _root || node.Parent == null) { break; } if (Check(node) == FilterResult.Accept) { _current = node; return node; } } return null; } public INode? ToParent() { INode node = _current; while (node != null && node != _root) { node = node.Parent; if (node != null && Check(node) == FilterResult.Accept) { _current = node; return node; } } return null; } public INode? ToFirst() { INode node = _current?.FirstChild; while (node != null) { switch (Check(node)) { case FilterResult.Accept: _current = node; return node; case FilterResult.Skip: { INode firstChild = node.FirstChild; if (firstChild != null) { node = firstChild; continue; } break; } } while (node != null) { INode nextSibling = node.NextSibling; if (nextSibling != null) { node = nextSibling; break; } INode parent = node.Parent; if (parent == null || parent == _root || parent == _current) { node = null; break; } node = parent; } } return null; } public INode? ToLast() { INode node = _current?.LastChild; while (node != null) { switch (Check(node)) { case FilterResult.Accept: _current = node; return node; case FilterResult.Skip: { INode lastChild = node.LastChild; if (lastChild != null) { node = lastChild; continue; } break; } } while (node != null) { INode previousSibling = node.PreviousSibling; if (previousSibling != null) { node = previousSibling; break; } INode parent = node.Parent; if (parent == null || parent == _root || parent == _current) { node = null; break; } node = parent; } } return null; } public INode? ToPreviousSibling() { INode node = _current; if (node != _root) { while (node != null) { INode node2 = node.PreviousSibling; while (node2 != null) { node = node2; FilterResult filterResult = Check(node); if (filterResult == FilterResult.Accept) { _current = node; return node; } node2 = node.LastChild; if (filterResult == FilterResult.Reject || node2 == null) { node2 = node.PreviousSibling; } } node = node.Parent; if (node == null || node == _root || Check(node) == FilterResult.Accept) { break; } } } return null; } public INode? ToNextSibling() { INode node = _current; if (node != _root) { while (node != null) { INode node2 = node.NextSibling; while (node2 != null) { node = node2; FilterResult filterResult = Check(node); if (filterResult == FilterResult.Accept) { _current = node; return node; } node2 = node.FirstChild; if (filterResult == FilterResult.Reject || node2 == null) { node2 = node.NextSibling; } } node = node.Parent; if (node == null || node == _root || Check(node) == FilterResult.Accept) { break; } } } return null; } private FilterResult Check(INode node) { if (!_settings.Accepts(node)) { return FilterResult.Skip; } return _filter(node); } } internal sealed class Window : EventTarget, IWindow, IEventTarget, IGlobalEventHandlers, IWindowEventHandlers, IWindowTimers, IDisposable { private readonly Document _document; private string? _name; private int _outerHeight; private int _outerWidth; private int _screenX; private int _screenY; private string? _status; private bool _closed; private INavigator? _navigator; public IWindow? Proxy => _document.Context.Current; public INavigator? Navigator => _navigator ?? (_navigator = _document.Context.GetService()); public IDocument Document => _document; public string? Name { get { return _name; } set { _name = value; } } public int OuterHeight { get { return _outerHeight; } set { _outerHeight = value; } } public int OuterWidth { get { return _outerWidth; } set { _outerWidth = value; } } public int ScreenX { get { return _screenX; } set { _screenX = value; } } public int ScreenY { get { return _screenY; } set { _screenY = value; } } public ILocation Location => Document.Location; public string? Status { get { return _status; } set { _status = value; } } public bool IsClosed => _closed; IHistory? IWindow.History => _document.Context.SessionHistory; event DomEventHandler IGlobalEventHandlers.Aborted { add { AddEventListener(EventNames.Abort, value); } remove { RemoveEventListener(EventNames.Abort, value); } } event DomEventHandler IGlobalEventHandlers.Blurred { add { AddEventListener(EventNames.Blur, value); } remove { RemoveEventListener(EventNames.Blur, value); } } event DomEventHandler IGlobalEventHandlers.Cancelled { add { AddEventListener(EventNames.Cancel, value); } remove { RemoveEventListener(EventNames.Cancel, value); } } event DomEventHandler IGlobalEventHandlers.CanPlay { add { AddEventListener(EventNames.CanPlay, value); } remove { RemoveEventListener(EventNames.CanPlay, value); } } event DomEventHandler IGlobalEventHandlers.CanPlayThrough { add { AddEventListener(EventNames.CanPlayThrough, value); } remove { RemoveEventListener(EventNames.CanPlayThrough, value); } } event DomEventHandler IGlobalEventHandlers.Changed { add { AddEventListener(EventNames.Change, value); } remove { RemoveEventListener(EventNames.Change, value); } } event DomEventHandler IGlobalEventHandlers.Clicked { add { AddEventListener(EventNames.Click, value); } remove { RemoveEventListener(EventNames.Click, value); } } event DomEventHandler IGlobalEventHandlers.CueChanged { add { AddEventListener(EventNames.CueChange, value); } remove { RemoveEventListener(EventNames.CueChange, value); } } event DomEventHandler IGlobalEventHandlers.DoubleClick { add { AddEventListener(EventNames.DblClick, value); } remove { RemoveEventListener(EventNames.DblClick, value); } } event DomEventHandler IGlobalEventHandlers.Drag { add { AddEventListener(EventNames.Drag, value); } remove { RemoveEventListener(EventNames.Drag, value); } } event DomEventHandler IGlobalEventHandlers.DragEnd { add { AddEventListener(EventNames.DragEnd, value); } remove { RemoveEventListener(EventNames.DragEnd, value); } } event DomEventHandler IGlobalEventHandlers.DragEnter { add { AddEventListener(EventNames.DragEnter, value); } remove { RemoveEventListener(EventNames.DragEnter, value); } } event DomEventHandler IGlobalEventHandlers.DragExit { add { AddEventListener(EventNames.DragExit, value); } remove { RemoveEventListener(EventNames.DragExit, value); } } event DomEventHandler IGlobalEventHandlers.DragLeave { add { AddEventListener(EventNames.DragLeave, value); } remove { RemoveEventListener(EventNames.DragLeave, value); } } event DomEventHandler IGlobalEventHandlers.DragOver { add { AddEventListener(EventNames.DragOver, value); } remove { RemoveEventListener(EventNames.DragOver, value); } } event DomEventHandler IGlobalEventHandlers.DragStart { add { AddEventListener(EventNames.DragStart, value); } remove { RemoveEventListener(EventNames.DragStart, value); } } event DomEventHandler IGlobalEventHandlers.Dropped { add { AddEventListener(EventNames.Drop, value); } remove { RemoveEventListener(EventNames.Drop, value); } } event DomEventHandler IGlobalEventHandlers.DurationChanged { add { AddEventListener(EventNames.DurationChange, value); } remove { RemoveEventListener(EventNames.DurationChange, value); } } event DomEventHandler IGlobalEventHandlers.Emptied { add { AddEventListener(EventNames.Emptied, value); } remove { RemoveEventListener(EventNames.Emptied, value); } } event DomEventHandler IGlobalEventHandlers.Ended { add { AddEventListener(EventNames.Ended, value); } remove { RemoveEventListener(EventNames.Ended, value); } } event DomEventHandler IGlobalEventHandlers.Error { add { AddEventListener(EventNames.Error, value); } remove { RemoveEventListener(EventNames.Error, value); } } event DomEventHandler IGlobalEventHandlers.Focused { add { AddEventListener(EventNames.Focus, value); } remove { RemoveEventListener(EventNames.Focus, value); } } event DomEventHandler IGlobalEventHandlers.Input { add { AddEventListener(EventNames.Input, value); } remove { RemoveEventListener(EventNames.Input, value); } } event DomEventHandler IGlobalEventHandlers.Invalid { add { AddEventListener(EventNames.Invalid, value); } remove { RemoveEventListener(EventNames.Invalid, value); } } event DomEventHandler IGlobalEventHandlers.KeyDown { add { AddEventListener(EventNames.Keydown, value); } remove { RemoveEventListener(EventNames.Keydown, value); } } event DomEventHandler IGlobalEventHandlers.KeyPress { add { AddEventListener(EventNames.Keypress, value); } remove { RemoveEventListener(EventNames.Keypress, value); } } event DomEventHandler IGlobalEventHandlers.KeyUp { add { AddEventListener(EventNames.Keyup, value); } remove { RemoveEventListener(EventNames.Keyup, value); } } event DomEventHandler IGlobalEventHandlers.Loaded { add { AddEventListener(EventNames.Load, value); } remove { RemoveEventListener(EventNames.Load, value); } } event DomEventHandler IGlobalEventHandlers.LoadedData { add { AddEventListener(EventNames.LoadedData, value); } remove { RemoveEventListener(EventNames.LoadedData, value); } } event DomEventHandler IGlobalEventHandlers.LoadedMetadata { add { AddEventListener(EventNames.LoadedMetaData, value); } remove { RemoveEventListener(EventNames.LoadedMetaData, value); } } event DomEventHandler IGlobalEventHandlers.Loading { add { AddEventListener(EventNames.LoadStart, value); } remove { RemoveEventListener(EventNames.LoadStart, value); } } event DomEventHandler IGlobalEventHandlers.MouseDown { add { AddEventListener(EventNames.Mousedown, value); } remove { RemoveEventListener(EventNames.Mousedown, value); } } event DomEventHandler IGlobalEventHandlers.MouseEnter { add { AddEventListener(EventNames.Mouseenter, value); } remove { RemoveEventListener(EventNames.Mouseenter, value); } } event DomEventHandler IGlobalEventHandlers.MouseLeave { add { AddEventListener(EventNames.Mouseleave, value); } remove { RemoveEventListener(EventNames.Mouseleave, value); } } event DomEventHandler IGlobalEventHandlers.MouseMove { add { AddEventListener(EventNames.Mousemove, value); } remove { RemoveEventListener(EventNames.Mousemove, value); } } event DomEventHandler IGlobalEventHandlers.MouseOut { add { AddEventListener(EventNames.Mouseout, value); } remove { RemoveEventListener(EventNames.Mouseout, value); } } event DomEventHandler IGlobalEventHandlers.MouseOver { add { AddEventListener(EventNames.Mouseover, value); } remove { RemoveEventListener(EventNames.Mouseover, value); } } event DomEventHandler IGlobalEventHandlers.MouseUp { add { AddEventListener(EventNames.Mouseup, value); } remove { RemoveEventListener(EventNames.Mouseup, value); } } event DomEventHandler IGlobalEventHandlers.MouseWheel { add { AddEventListener(EventNames.Wheel, value); } remove { RemoveEventListener(EventNames.Wheel, value); } } event DomEventHandler IGlobalEventHandlers.Paused { add { AddEventListener(EventNames.Pause, value); } remove { RemoveEventListener(EventNames.Pause, value); } } event DomEventHandler IGlobalEventHandlers.Played { add { AddEventListener(EventNames.Play, value); } remove { RemoveEventListener(EventNames.Play, value); } } event DomEventHandler IGlobalEventHandlers.Playing { add { AddEventListener(EventNames.Playing, value); } remove { RemoveEventListener(EventNames.Playing, value); } } event DomEventHandler IGlobalEventHandlers.Progress { add { AddEventListener(EventNames.Progress, value); } remove { RemoveEventListener(EventNames.Progress, value); } } event DomEventHandler IGlobalEventHandlers.RateChanged { add { AddEventListener(EventNames.RateChange, value); } remove { RemoveEventListener(EventNames.RateChange, value); } } event DomEventHandler IGlobalEventHandlers.Resetted { add { AddEventListener(EventNames.Reset, value); } remove { RemoveEventListener(EventNames.Reset, value); } } event DomEventHandler IGlobalEventHandlers.Resized { add { AddEventListener(EventNames.Resize, value); } remove { RemoveEventListener(EventNames.Resize, value); } } event DomEventHandler IGlobalEventHandlers.Scrolled { add { AddEventListener(EventNames.Scroll, value); } remove { RemoveEventListener(EventNames.Scroll, value); } } event DomEventHandler IGlobalEventHandlers.Seeked { add { AddEventListener(EventNames.Seeked, value); } remove { RemoveEventListener(EventNames.Seeked, value); } } event DomEventHandler IGlobalEventHandlers.Seeking { add { AddEventListener(EventNames.Seeking, value); } remove { RemoveEventListener(EventNames.Seeking, value); } } event DomEventHandler IGlobalEventHandlers.Selected { add { AddEventListener(EventNames.Select, value); } remove { RemoveEventListener(EventNames.Select, value); } } event DomEventHandler IGlobalEventHandlers.Shown { add { AddEventListener(EventNames.Show, value); } remove { RemoveEventListener(EventNames.Show, value); } } event DomEventHandler IGlobalEventHandlers.Stalled { add { AddEventListener(EventNames.Stalled, value); } remove { RemoveEventListener(EventNames.Stalled, value); } } event DomEventHandler IGlobalEventHandlers.Submitted { add { AddEventListener(EventNames.Submit, value); } remove { RemoveEventListener(EventNames.Submit, value); } } event DomEventHandler IGlobalEventHandlers.Suspended { add { AddEventListener(EventNames.Suspend, value); } remove { RemoveEventListener(EventNames.Suspend, value); } } event DomEventHandler IGlobalEventHandlers.TimeUpdated { add { AddEventListener(EventNames.TimeUpdate, value); } remove { RemoveEventListener(EventNames.TimeUpdate, value); } } event DomEventHandler IGlobalEventHandlers.Toggled { add { AddEventListener(EventNames.Toggle, value); } remove { RemoveEventListener(EventNames.Toggle, value); } } event DomEventHandler IGlobalEventHandlers.VolumeChanged { add { AddEventListener(EventNames.VolumeChange, value); } remove { RemoveEventListener(EventNames.VolumeChange, value); } } event DomEventHandler IGlobalEventHandlers.Waiting { add { AddEventListener(EventNames.Waiting, value); } remove { RemoveEventListener(EventNames.Waiting, value); } } event DomEventHandler IWindowEventHandlers.Printed { add { AddEventListener(EventNames.AfterPrint, value); } remove { RemoveEventListener(EventNames.AfterPrint, value); } } event DomEventHandler IWindowEventHandlers.Printing { add { AddEventListener(EventNames.BeforePrint, value); } remove { RemoveEventListener(EventNames.BeforePrint, value); } } event DomEventHandler IWindowEventHandlers.Unloading { add { AddEventListener(EventNames.Unloading, value); } remove { RemoveEventListener(EventNames.Unloading, value); } } event DomEventHandler IWindowEventHandlers.HashChanged { add { AddEventListener(EventNames.HashChange, value); } remove { RemoveEventListener(EventNames.HashChange, value); } } event DomEventHandler IWindowEventHandlers.MessageReceived { add { AddEventListener(EventNames.Message, value); } remove { RemoveEventListener(EventNames.Message, value); } } event DomEventHandler IWindowEventHandlers.WentOffline { add { AddEventListener(EventNames.Offline, value); } remove { RemoveEventListener(EventNames.Offline, value); } } event DomEventHandler IWindowEventHandlers.WentOnline { add { AddEventListener(EventNames.Online, value); } remove { RemoveEventListener(EventNames.Online, value); } } event DomEventHandler IWindowEventHandlers.PageHidden { add { AddEventListener(EventNames.PageHide, value); } remove { RemoveEventListener(EventNames.PageHide, value); } } event DomEventHandler IWindowEventHandlers.PageShown { add { AddEventListener(EventNames.PageShow, value); } remove { RemoveEventListener(EventNames.PageShow, value); } } event DomEventHandler IWindowEventHandlers.PopState { add { AddEventListener(EventNames.PopState, value); } remove { RemoveEventListener(EventNames.PopState, value); } } event DomEventHandler IWindowEventHandlers.Storage { add { AddEventListener(EventNames.Storage, value); } remove { RemoveEventListener(EventNames.Storage, value); } } event DomEventHandler IWindowEventHandlers.Unloaded { add { AddEventListener(EventNames.Unload, value); } remove { RemoveEventListener(EventNames.Unload, value); } } public Window(Document document) { _document = document; } IWindow IWindow.Open(string url, string? name, string? features, string? replace) { HtmlDocument htmlDocument = new HtmlDocument(_document.Context.CreateChild(name, Sandboxes.None)); htmlDocument.Location.Href = url; return new Window(htmlDocument) { Name = name }; } void IWindow.Close() { _closed = true; } void IWindow.Stop() { } void IWindow.Focus() { } void IWindow.Blur() { } void IWindow.Alert(string message) { } bool IWindow.Confirm(string message) { return false; } void IWindow.Print() { } int IWindowTimers.SetTimeout(Action handler, int timeout) { return QueueTask(DoTimeoutAsync, handler, timeout); } void IWindowTimers.ClearTimeout(int handle) { Clear(handle); } void IWindowTimers.ClearInterval(int handle) { Clear(handle); } int IWindowTimers.SetInterval(Action handler, int timeout) { return QueueTask(DoIntervalAsync, handler, timeout); } private async Task DoTimeoutAsync(Action callback, int timeout, CancellationTokenSource cts) { CancellationToken token = cts.Token; await Task.Delay(timeout, token).ConfigureAwait(continueOnCapturedContext: false); if (!token.IsCancellationRequested) { _document.QueueTask(delegate { callback(this); }); } } private async Task DoIntervalAsync(Action callback, int timeout, CancellationTokenSource cts) { CancellationToken token = cts.Token; while (!token.IsCancellationRequested) { await DoTimeoutAsync(callback, timeout, cts).ConfigureAwait(continueOnCapturedContext: false); } } private int QueueTask(Func, int, CancellationTokenSource, Task> taskCreator, Action callback, int timeout) { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); taskCreator(callback, timeout, cancellationTokenSource); _document.AttachReference(cancellationTokenSource); return cancellationTokenSource.GetHashCode(); } private void Clear(int handle) { CancellationTokenSource cancellationTokenSource = _document.GetAttachedReferences().FirstOrDefault((CancellationTokenSource m) => m.GetHashCode() == handle); if (cancellationTokenSource != null && !cancellationTokenSource.IsCancellationRequested) { cancellationTokenSource.Cancel(); } } public void Dispose() { foreach (CancellationTokenSource attachedReference in _document.GetAttachedReferences()) { attachedReference.Cancel(); } } } [DomName("ParentNode")] [DomNoInterfaceObject] public interface IParentNode { [DomName("children")] IHtmlCollection Children { get; } [DomName("firstElementChild")] IElement? FirstElementChild { get; } [DomName("lastElementChild")] IElement? LastElementChild { get; } [DomName("childElementCount")] int ChildElementCount { get; } [DomName("append")] void Append(params INode[] nodes); [DomName("prepend")] void Prepend(params INode[] nodes); [DomName("querySelector")] IElement? QuerySelector(string selectors); [DomName("querySelectorAll")] IHtmlCollection QuerySelectorAll(string selectors); } [DomName("ProcessingInstruction")] public interface IProcessingInstruction : ICharacterData, INode, IEventTarget, IMarkupFormattable, IChildNode, INonDocumentTypeChildNode { [DomName("target")] string Target { get; } } [DomName("PseudoElement")] [DomNoInterfaceObject] public interface IPseudoElement : IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode { string PseudoName { get; } } [DomName("Range")] public interface IRange { [DomName("startContainer")] INode Head { get; } [DomName("startOffset")] int Start { get; } [DomName("endContainer")] INode Tail { get; } [DomName("endOffset")] int End { get; } [DomName("collapsed")] bool IsCollapsed { get; } [DomName("commonAncestorContainer")] INode CommonAncestor { get; } [DomName("setStart")] void StartWith(INode refNode, int offset); [DomName("setEnd")] void EndWith(INode refNode, int offset); [DomName("setStartBefore")] void StartBefore(INode refNode); [DomName("setEndBefore")] void EndBefore(INode refNode); [DomName("setStartAfter")] void StartAfter(INode refNode); [DomName("setEndAfter")] void EndAfter(INode refNode); [DomName("collapse")] void Collapse(bool toStart); [DomName("selectNode")] void Select(INode refNode); [DomName("selectNodeContents")] void SelectContent(INode refNode); [DomName("deleteContents")] void ClearContent(); [DomName("extractContents")] IDocumentFragment ExtractContent(); [DomName("cloneContents")] IDocumentFragment CopyContent(); [DomName("insertNode")] void Insert(INode node); [DomName("surroundContents")] void Surround(INode newParent); [DomName("cloneRange")] IRange Clone(); [DomName("detach")] void Detach(); [DomName("isPointInRange")] bool Contains(INode node, int offset); [DomName("compareBoundaryPoints")] RangePosition CompareBoundaryTo(RangeType how, IRange sourceRange); [DomName("comparePoint")] RangePosition CompareTo(INode node, int offset); [DomName("intersectsNode")] bool Intersects(INode node); } public interface IReverseEntityProvider { string? GetName(string symbol); } [DomName("DOMSettableTokenList")] public interface ISettableTokenList : ITokenList, IEnumerable, IEnumerable { [DomName("value")] string Value { get; set; } } [DomName("ShadowRoot")] public interface IShadowRoot : IDocumentFragment, INode, IEventTarget, IMarkupFormattable, IParentNode, INonElementParentNode { [DomName("activeElement")] IElement? ActiveElement { get; } [DomName("host")] IElement Host { get; } [DomName("innerHTML")] string InnerHtml { get; set; } ShadowRootMode Mode { get; } [DomName("styleSheets")] IStyleSheetList StyleSheets { get; } } public interface ISourceReference { TextPosition Position { get; } } [DomName("DOMStringList")] public interface IStringList : IEnumerable, IEnumerable { [DomName("item")] [DomAccessor(Accessors.Getter)] string this[int index] { get; } [DomName("length")] int Length { get; } [DomName("contains")] bool Contains(string entry); } [DomName("DOMStringMap")] public interface IStringMap : IEnumerable>, IEnumerable { [DomAccessor(Accessors.Getter | Accessors.Setter)] string? this[string name] { get; set; } [DomAccessor(Accessors.Deleter)] void Remove(string name); } [DomName("StyleSheet")] public interface IStyleSheet : IStyleFormattable { [DomName("type")] string Type { get; } [DomName("href")] string Href { get; } [DomName("ownerNode")] IElement OwnerNode { get; } [DomName("title")] string Title { get; } [DomName("media")] [DomPutForwards("mediaText")] IMediaList Media { get; } [DomName("disabled")] bool IsDisabled { get; set; } IBrowsingContext Context { get; } TextSource Source { get; } void SetOwner(IElement element); string LocateNamespace(string prefix); } [DomName("StyleSheetList")] public interface IStyleSheetList : IEnumerable, IEnumerable { [DomName("item")] [DomAccessor(Accessors.Getter)] IStyleSheet? this[int index] { get; } [DomName("length")] int Length { get; } } [DomName("Text")] public interface IText : ICharacterData, INode, IEventTarget, IMarkupFormattable, IChildNode, INonDocumentTypeChildNode { [DomName("wholeText")] string Text { get; } [DomName("assignedSlot")] IElement? AssignedSlot { get; } [DomName("splitText")] IText Split(int offset); } [DomName("DOMTokenList")] public interface ITokenList : IEnumerable, IEnumerable { [DomName("length")] int Length { get; } [DomName("item")] [DomAccessor(Accessors.Getter)] string this[int index] { get; } [DomName("contains")] bool Contains(string token); [DomName("add")] void Add(params string[] tokens); [DomName("remove")] void Remove(params string[] tokens); [DomName("toggle")] bool Toggle(string token, bool force = false); } [DomName("TreeWalker")] public interface ITreeWalker { [DomName("root")] INode Root { get; } [DomName("currentNode")] INode Current { get; set; } [DomName("whatToShow")] FilterSettings Settings { get; } [DomName("filter")] NodeFilter Filter { get; } [DomName("nextNode")] INode? ToNext(); [DomName("previousNode")] INode? ToPrevious(); [DomName("parentNode")] INode? ToParent(); [DomName("firstChild")] INode? ToFirst(); [DomName("lastChild")] INode? ToLast(); [DomName("previousSibling")] INode? ToPreviousSibling(); [DomName("nextSibling")] INode? ToNextSibling(); } [DomName("URLUtils")] [DomNoInterfaceObject] public interface IUrlUtilities { [DomName("href")] string Href { get; set; } [DomName("protocol")] string Protocol { get; set; } [DomName("host")] string Host { get; set; } [DomName("hostname")] string HostName { get; set; } [DomName("port")] string Port { get; set; } [DomName("pathname")] string PathName { get; set; } [DomName("search")] string Search { get; set; } [DomName("hash")] string Hash { get; set; } [DomName("username")] string? UserName { get; set; } [DomName("password")] string? Password { get; set; } [DomName("origin")] string? Origin { get; } } [DomName("Window")] public interface IWindow : IEventTarget, IGlobalEventHandlers, IWindowEventHandlers, IWindowTimers, IDisposable { [DomName("document")] IDocument Document { get; } [DomName("location")] [DomPutForwards("href")] ILocation Location { get; } [DomName("closed")] bool IsClosed { get; } [DomName("status")] string? Status { get; set; } [DomName("name")] string? Name { get; set; } [DomName("outerHeight")] int OuterHeight { get; } [DomName("outerWidth")] int OuterWidth { get; } [DomName("screenX")] int ScreenX { get; } [DomName("screenY")] int ScreenY { get; } [DomName("window")] [DomName("frames")] [DomName("self")] IWindow? Proxy { get; } [DomName("navigator")] INavigator? Navigator { get; } [DomName("history")] IHistory? History { get; } [DomName("close")] void Close(); IWindow Open(string url = "about:blank", string? name = null, string? features = null, string? replace = null); [DomName("stop")] void Stop(); [DomName("focus")] void Focus(); [DomName("blur")] void Blur(); [DomName("alert")] void Alert(string message); [DomName("confirm")] bool Confirm(string message); [DomName("print")] void Print(); } [DomName("WindowTimers")] [DomNoInterfaceObject] public interface IWindowTimers { [DomName("setTimeout")] int SetTimeout(Action handler, int timeout = 0); [DomName("clearTimeout")] void ClearTimeout(int handle = 0); [DomName("setInterval")] int SetInterval(Action handler, int timeout = 0); [DomName("clearInterval")] void ClearInterval(int handle = 0); } public delegate void MutationCallback(IMutationRecord[] mutations, MutationObserver observer); [DomName("MutationObserver")] public sealed class MutationObserver { internal struct MutationOptions { public bool IsObservingChildNodes; public bool IsObservingSubtree; public bool IsObservingCharacterData; public bool IsObservingAttributes; public bool IsExaminingOldCharacterData; public bool IsExaminingOldAttributeValue; public IEnumerable? AttributeFilters; public readonly bool IsInvalid { get { if (!IsObservingAttributes && !IsObservingCharacterData) { return !IsObservingChildNodes; } return false; } } } private sealed class MutationObserving(INode target, MutationOptions options) { private readonly INode _target = target; private readonly MutationOptions _options = options; private readonly List _transientNodes = new List(); public INode Target => target; public MutationOptions Options => options; public List TransientNodes => _transientNodes; } private readonly Queue _records; private readonly MutationCallback _callback; private readonly List _observing; private MutationObserving? this[INode node] { get { foreach (MutationObserving item in _observing) { if (item.Target == node) { return item; } } return null; } } [DomConstructor] public MutationObserver(MutationCallback callback) { _records = new Queue(); _callback = callback ?? throw new ArgumentNullException("callback"); _observing = new List(); } internal void Enqueue(MutationRecord record) { _ = _records.Count; _ = 0; _records.Enqueue(record); } internal void Trigger() { IMutationRecord[] array = _records.ToArray(); _records.Clear(); ClearTransients(); if (array.Length != 0) { _callback(array, this); } } internal MutationOptions ResolveOptions(INode node) { foreach (MutationObserving item in _observing) { if (item.Target == node || item.TransientNodes.Contains(node)) { return item.Options; } } return default(MutationOptions); } internal void AddTransient(INode ancestor, INode node) { MutationObserving mutationObserving = this[ancestor]; if (mutationObserving != null && mutationObserving.Options.IsObservingSubtree) { mutationObserving.TransientNodes.Add(node); } } internal void ClearTransients() { foreach (MutationObserving item in _observing) { item.TransientNodes.Clear(); } } [DomName("disconnect")] public void Disconnect() { foreach (MutationObserving item in _observing) { ((Node)item.Target).Owner.Mutations.Unregister(this); } _records.Clear(); } [DomName("observe")] [DomInitDict(1, false)] public void Connect(INode target, bool childList = false, bool subtree = false, bool? attributes = null, bool? characterData = null, bool? attributeOldValue = null, bool? characterDataOldValue = null, IEnumerable? attributeFilter = null) { Node node = target as Node; if (node != null) { bool valueOrDefault = characterDataOldValue == true; bool valueOrDefault2 = attributeOldValue == true; MutationOptions options = new MutationOptions { IsObservingChildNodes = childList, IsObservingSubtree = subtree, IsExaminingOldCharacterData = valueOrDefault, IsExaminingOldAttributeValue = valueOrDefault2, IsObservingCharacterData = (characterData ?? valueOrDefault), IsObservingAttributes = (attributes ?? (valueOrDefault2 || attributeFilter != null)), AttributeFilters = attributeFilter }; if (options.IsExaminingOldAttributeValue && !options.IsObservingAttributes) { throw new DomException(DomError.TypeMismatch); } if (options.AttributeFilters != null && !options.IsObservingAttributes) { throw new DomException(DomError.TypeMismatch); } if (options.IsExaminingOldCharacterData && !options.IsObservingCharacterData) { throw new DomException(DomError.TypeMismatch); } if (options.IsInvalid) { throw new DomException(DomError.Syntax); } if (node is Document { DocumentElement: Node documentElement }) { node = documentElement; target = documentElement; } if (node.Owner == null) { throw new DomException(DomError.HierarchyRequest); } node.Owner.Mutations.Register(this); MutationObserving mutationObserving = this[target]; if (mutationObserving != null) { mutationObserving.TransientNodes.Clear(); _observing.Remove(mutationObserving); } _observing.Add(new MutationObserving(target, options)); } } [DomName("takeRecords")] public IEnumerable Flush() { while (_records.Count > 0) { yield return _records.Dequeue(); } } } public static class NamespaceNames { public static readonly string HtmlUri = "http://www.w3.org/1999/xhtml"; public static readonly string XmlNsUri = "http://www.w3.org/2000/xmlns/"; public static readonly string XLinkUri = "http://www.w3.org/1999/xlink"; public static readonly string XmlUri = "http://www.w3.org/XML/1998/namespace"; public static readonly string SvgUri = "http://www.w3.org/2000/svg"; public static readonly string MathMlUri = "http://www.w3.org/1998/Math/MathML"; public static readonly string XmlNsPrefix = "xmlns"; public static readonly string XLinkPrefix = "xlink"; public static readonly string XmlPrefix = "xml"; } public static class NodeExtensions { public static INode GetRoot(this INode node) { while (node.Parent != null) { node = node.Parent; } return node; } public static bool IsEndPoint(this INode node) { NodeType nodeType = node.NodeType; if (nodeType != NodeType.Document && nodeType != NodeType.DocumentFragment) { return nodeType != NodeType.Element; } return false; } public static bool IsEndPoint(this NodeType type) { if (type != NodeType.Document && type != NodeType.DocumentFragment) { return type != NodeType.Element; } return false; } public static bool IsInsertable(this INode node) { NodeType nodeType = node.NodeType; if (nodeType != NodeType.Element && nodeType != NodeType.Comment && nodeType != NodeType.Text && nodeType != NodeType.ProcessingInstruction && nodeType != NodeType.DocumentFragment) { return nodeType == NodeType.DocumentType; } return true; } [return: NotNullIfNotNull("url")] public static Url? HyperReference(this INode node, string url) { if (url != null) { return new Url(node.BaseUrl, url); } return null; } public static bool IsDescendantOf(this INode node, INode parent) { while (node.Parent != null) { if (node.Parent == parent) { return true; } node = node.Parent; } return false; } public static IEnumerable GetDescendants(this INode parent) { return parent.GetDescendantsAndSelf().Skip(1); } public static IEnumerable GetDescendantsAndSelf(this INode parent) { return parent.GetDescendantsAndSelf(new Stack()); } internal static IEnumerable GetDescendantsAndSelf(this INode parent, Stack stack, Func? filter = null, TState? state = default(TState?)) { stack.Push(parent); while (stack.Count > 0) { INode next = stack.Pop(); if (filter == null || filter(next, state)) { yield return next; } INodeList childNodes = next.ChildNodes; if (childNodes is NodeList { Length: var num } nodeList) { while (num > 0) { int num2 = num - 1; num = num2; stack.Push(nodeList[num2]); } } else { int num3 = childNodes.Length; while (num3 > 0) { stack.Push(childNodes[--num3]); } } } } public static bool IsInclusiveDescendantOf(this INode node, INode parent) { if (node != parent) { return node.IsDescendantOf(parent); } return true; } public static bool IsAncestorOf(this INode parent, INode node) { return node.IsDescendantOf(parent); } public static IEnumerable GetAncestors(this INode node) { while (true) { INode parent; node = (parent = node.Parent); if (parent != null) { yield return node; continue; } break; } } public static IEnumerable GetInclusiveAncestors(this INode node) { INode parent; do { yield return node; node = (parent = node.Parent); } while (parent != null); } public static bool IsInclusiveAncestorOf(this INode parent, INode node) { if (node != parent) { return node.IsDescendantOf(parent); } return true; } public static T? GetAncestor(this INode node) where T : INode { while ((node = node.Parent) != null) { if (node is T) { return (T)node; } } return default(T); } public static bool HasDataListAncestor(this INode child) { return child.Ancestors().Any(); } public static bool IsSiblingOf(this INode node, INode element) { return node?.Parent == element.Parent; } public static int Index(this INode node) { return node.Parent.IndexOf(node); } public static int IndexOf(this INode parent, INode node) { int num = 0; if (parent != null) { foreach (INode childNode in parent.ChildNodes) { if (childNode == node) { return num; } num++; } } return -1; } public static bool IsPreceding(this INode before, INode after) { Queue queue = new Queue(before.GetInclusiveAncestors()); Queue queue2 = new Queue(after.GetInclusiveAncestors()); int num = queue2.Count - queue.Count; if (num != 0) { while (queue.Count > queue2.Count) { queue.Dequeue(); } while (queue2.Count > queue.Count) { queue2.Dequeue(); } if (IsCurrentlySame(queue2, queue)) { return num > 0; } } while (queue.Count > 0) { before = queue.Dequeue(); after = queue2.Dequeue(); if (IsCurrentlySame(queue2, queue)) { return before.Index() < after.Index(); } } return false; } public static bool IsFollowing(this INode after, INode before) { return before.IsPreceding(after); } public static INode? GetAssociatedHost(this INode node) { if (node is IDocumentFragment) { return node.Owner?.All.OfType().FirstOrDefault((IHtmlTemplateElement m) => m.Content == node); } return null; } public static bool IsHostIncludingInclusiveAncestor(this INode parent, INode node) { if (!parent.IsInclusiveAncestorOf(node)) { INode associatedHost = node.GetRoot().GetAssociatedHost(); if (associatedHost != null) { return parent.IsInclusiveAncestorOf(associatedHost); } return false; } return true; } public static void EnsurePreInsertionValidity(this INode parent, INode node, INode? child) { if (parent.IsEndPoint() || node.IsHostIncludingInclusiveAncestor(parent)) { throw new DomException(DomError.HierarchyRequest); } if (child != null && child.Parent != parent) { throw new DomException(DomError.NotFound); } if (!(node is IElement) && !(node is ICharacterData) && !(node is IDocumentType) && !(node is IDocumentFragment)) { throw new DomException(DomError.HierarchyRequest); } if (parent is IDocument document) { bool flag = false; switch (node.NodeType) { case NodeType.Element: flag = document.DocumentElement != null || child is IDocumentType || child.IsFollowedByDoctype(); break; case NodeType.DocumentFragment: { int elementCount = node.GetElementCount(); flag = elementCount > 1 || node.HasTextNodes() || (elementCount == 1 && document.DocumentElement != null) || child is IDocumentType || child.IsFollowedByDoctype(); break; } case NodeType.DocumentType: flag = document.Doctype != null || (child != null && child.IsPrecededByElement()) || (child == null && document.DocumentElement != null); break; case NodeType.Text: flag = true; break; } if (flag) { throw new DomException(DomError.HierarchyRequest); } } else if (node is IDocumentType) { throw new DomException(DomError.HierarchyRequest); } } public static INode PreInsert(this INode parent, INode node, INode? child) { Node node2 = (Node)node; if (parent is Node node3) { parent.EnsurePreInsertionValidity(node, child); Node node4 = child as Node; if (node4 == node) { node4 = node2.NextSibling; } (parent.Owner ?? (parent as IDocument)).AdoptNode(node); node3.InsertBefore(node2, node4, suppressObservers: false); return node; } throw new DomException(DomError.NotSupported); } public static INode PreRemove(this INode parent, INode child) { if (parent is Node node) { if (child == null || child.Parent != parent) { throw new DomException(DomError.NotFound); } node.RemoveChild((Node)child, suppressObservers: false); return child; } throw new DomException(DomError.NotSupported); } public static bool HasTextNodes(this INode node) { return node.ChildNodes.OfType().Any(); } public static bool IsFollowedByDoctype(this INode? child) { if (child != null) { bool flag = true; foreach (INode childNode in child.Parent.ChildNodes) { if (flag) { flag = childNode != child; } else if (childNode.NodeType == NodeType.DocumentType) { return true; } } } return false; } public static bool IsPrecededByElement(this INode child) { foreach (INode childNode in child.Parent.ChildNodes) { if (childNode == child) { break; } if (childNode.NodeType == NodeType.Element) { return true; } } return false; } public static int GetElementCount(this INode parent) { int num = 0; foreach (INode childNode in parent.ChildNodes) { if (childNode.NodeType == NodeType.Element) { num++; } } return num; } public static TNode? FindChild(this INode parent) where TNode : class, INode { if (parent != null) { for (int i = 0; i < parent.ChildNodes.Length; i++) { if (parent.ChildNodes[i] is TNode result) { return result; } } } return null; } public static TNode? FindDescendant(this INode parent, int maxDepth = 1024) where TNode : class, INode { if (parent != null && maxDepth > -1) { for (int i = 0; i < parent.ChildNodes.Length; i++) { INode node = parent.ChildNodes[i]; TNode val = (node as TNode) ?? node.FindDescendant(maxDepth - 1); if (val != null) { return val; } } } return null; } public static IElement? GetAssignedSlot(this IShadowRoot root, string? name) { return root.GetDescendants().OfType().FirstOrDefault((IHtmlSlotElement m) => m.Name.Is(name)); } public static string Text(this INode node) { if (node == null) { throw new ArgumentNullException("node"); } return node.TextContent; } public static T Text(this T nodes, string text) where T : IEnumerable { if (nodes == null) { throw new ArgumentNullException("nodes"); } foreach (INode item in nodes) { item.TextContent = text; } return nodes; } public static int Index(this IEnumerable nodes, INode item) { if (nodes == null) { throw new ArgumentNullException("nodes"); } if (item != null) { int num = 0; foreach (INode node in nodes) { if (node == item) { return num; } num++; } } return -1; } private static bool IsCurrentlySame(Queue after, Queue before) { if (after.Count > 0 && before.Count > 0) { return after.Peek() == before.Peek(); } return false; } } public delegate FilterResult NodeFilter(INode node); [DomName("Document")] public enum NodeType : byte { [DomName("ELEMENT_NODE")] Element = 1, [DomName("ATTRIBUTE_NODE")] [DomHistorical] Attribute, [DomName("TEXT_NODE")] Text, [DomName("CDATA_SECTION_NODE")] [DomHistorical] CharacterData, [DomName("ENTITY_REFERENCE_NODE")] [DomHistorical] EntityReference, [DomName("ENTITY_NODE")] [DomHistorical] Entity, [DomName("PROCESSING_INSTRUCTION_NODE")] [DomHistorical] ProcessingInstruction, [DomName("COMMENT_NODE")] Comment, [DomName("DOCUMENT_NODE")] Document, [DomName("DOCUMENT_TYPE_NODE")] DocumentType, [DomName("DOCUMENT_FRAGMENT_NODE")] DocumentFragment, [DomName("NOTATION_NODE")] [DomHistorical] Notation } public static class ParentNodeExtensions { internal static INode MutationMacro(this INode parent, INode[] nodes) { if (nodes.Length > 1) { IDocumentFragment documentFragment = parent.Owner.CreateDocumentFragment(); for (int i = 0; i < nodes.Length; i++) { documentFragment.AppendChild(nodes[i]); } return documentFragment; } return nodes[0]; } public static void PrependNodes(this INode parent, params INode[] nodes) { if (nodes.Length != 0) { INode node = parent.MutationMacro(nodes); parent.PreInsert(node, parent.FirstChild); } } public static void AppendNodes(this INode parent, params INode[] nodes) { if (nodes.Length != 0) { INode node = parent.MutationMacro(nodes); parent.PreInsert(node, null); } } public static void InsertBefore(this INode child, params INode[] nodes) { INode parent = child.Parent; if (parent != null && nodes.Length != 0) { INode node = parent.MutationMacro(nodes); parent.PreInsert(node, child); } } public static void InsertAfter(this INode child, params INode[] nodes) { INode parent = child.Parent; if (parent != null && nodes.Length != 0) { INode node = parent.MutationMacro(nodes); parent.PreInsert(node, child.NextSibling); } } public static void ReplaceWith(this INode child, params INode[] nodes) { INode parent = child.Parent; if (parent != null) { if (nodes.Length != 0) { INode newChild = parent.MutationMacro(nodes); parent.ReplaceChild(newChild, child); } else { parent.RemoveChild(child); } } } public static void RemoveFromParent(this INode child) { child.Parent?.PreRemove(child); } public static TElement AppendElement(this INode parent, TElement element) where TElement : class, IElement { if (parent == null) { throw new ArgumentNullException("parent"); } return (TElement)parent.AppendChild(element); } public static TElement InsertElement(this INode parent, TElement newElement, INode referenceElement) where TElement : class, IElement { if (parent == null) { throw new ArgumentNullException("parent"); } return (TElement)parent.InsertBefore(newElement, referenceElement); } public static TElement RemoveElement(this INode parent, TElement element) where TElement : class, IElement { if (parent == null) { throw new ArgumentNullException("parent"); } return (TElement)parent.RemoveChild(element); } public static TElement? QuerySelector(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 QuerySelectorAll(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(); } [Obsolete("Use Descendants")] public static IEnumerable Descendents(this INode parent) { return parent.Descendants(); } public static IEnumerable Descendants(this INode parent) { return parent.Descendants().OfType(); } [Obsolete("Use Descendants")] public static IEnumerable Descendents(this INode parent) { return parent.Descendants(); } public static IEnumerable Descendants(this INode parent) { if (parent == null) { throw new ArgumentNullException("parent"); } return parent.GetDescendants(); } [Obsolete("Use DescendantsAndSelf")] public static IEnumerable DescendentsAndSelf(this INode parent) { return parent.DescendantsAndSelf(); } public static IEnumerable DescendantsAndSelf(this INode parent) { return parent.DescendantsAndSelf().OfType(); } [Obsolete("Use DescendantsAndSelf")] public static IEnumerable DescendentsAndSelf(this INode parent) { return parent.DescendantsAndSelf(); } public static IEnumerable DescendantsAndSelf(this INode parent) { if (parent == null) { throw new ArgumentNullException("parent"); } return parent.GetDescendantsAndSelf(); } public static IEnumerable Ancestors(this INode child) { return child.Ancestors().OfType(); } public static IEnumerable Ancestors(this INode child) { if (child == null) { throw new ArgumentNullException("child"); } return child.GetAncestors(); } } public static class QueryExtensions { public static IElement? QuerySelector(this INodeList nodes, string selectorText, INode? scopeNode = null) { return nodes.QuerySelector(selectorText, scopeNode); } public static IElement? QuerySelector(this T nodes, string selectorText, INode? scopeNode = null) where T : class, INodeList { IElement scope = GetScope(scopeNode); return CreateSelector(nodes, scope, selectorText)?.MatchAny(nodes.OfType(), scope); } public static IHtmlCollection QuerySelectorAll(this INodeList nodes, string selectorText, INode? scopeNode = null) { return nodes.QuerySelectorAll(selectorText, scopeNode); } public static IHtmlCollection QuerySelectorAll(this T nodes, string selectorText, INode? scopeNode = null) where T : class, INodeList { IElement scope = GetScope(scopeNode); ISelector selector = CreateSelector(nodes, scope, selectorText); if (selector != null) { return selector.MatchAll(nodes.OfType(), scope); } return new HtmlCollection(Array.Empty()); } public static IHtmlCollection GetElementsByClassName(this INodeList elements, string classNames) { return elements.GetElementsByClassName(classNames); } public static IHtmlCollection GetElementsByClassName(this T elements, string classNames) where T : class, INodeList { List list = new List(); string[] array = classNames.SplitSpaces(); if (array.Length != 0) { elements.GetElementsByClassName(array, list); } return new HtmlCollection(list); } public static IHtmlCollection GetElementsByTagName(this INodeList elements, string tagName) { return elements.GetElementsByTagName(tagName); } public static IHtmlCollection GetElementsByTagName(this T elements, string tagName) where T : class, INodeList { List list = new List(); elements.GetElementsByTagName((tagName == "*") ? null : tagName, list); return new HtmlCollection(list); } public static IHtmlCollection GetElementsByTagName(this INodeList elements, string? namespaceUri, string localName) { return elements.GetElementsByTagName(namespaceUri, localName); } public static IHtmlCollection GetElementsByTagName(this T elements, string? namespaceUri, string localName) where T : class, INodeList { List list = new List(); elements.GetElementsByTagName(namespaceUri, (localName == "*") ? null : localName, list); return new HtmlCollection(list); } public static T? QuerySelector(this INodeList elements, ISelector selectors) where T : class { return elements.QuerySelector(selectors); } public static T? QuerySelector(this TNodeList elements, ISelector selectors) where TNodeList : class, INodeList where T : class { return elements.QuerySelector(selectors) as T; } public static IElement? QuerySelector(this INodeList elements, ISelector selector) { for (int i = 0; i < elements.Length; i++) { if (!(elements[i] is IElement element)) { continue; } if (selector.Match(element)) { return element; } if (element.HasChildNodes) { IElement element2 = element.ChildNodes.QuerySelector(selector); if (element2 != null) { return element2; } } } return null; } public static IElement? QuerySelector(this T elements, ISelector selector) where T : INodeList { for (int i = 0; i < elements.Length; i++) { if (!(elements[i] is IElement element)) { continue; } if (selector.Match(element)) { return element; } if (element.HasChildNodes) { IElement element2 = element.ChildNodes.QuerySelector(selector); if (element2 != null) { return element2; } } } return null; } public static IHtmlCollection QuerySelectorAll(this INodeList elements, ISelector selector) { return elements.QuerySelectorAll(selector); } public static IHtmlCollection QuerySelectorAll(this T elements, ISelector selector) where T : class, INodeList { List list = new List(); elements.QuerySelectorAll(selector, list); return new HtmlCollection(list); } public static void QuerySelectorAll(this INodeList elements, ISelector selector, List result) { elements.QuerySelectorAll(selector, result); } public static void QuerySelectorAll(this T elements, ISelector selector, List result) where T : class, INodeList { for (int i = 0; i < elements.Length; i++) { if (!(elements[i] is IElement parent)) { continue; } foreach (IElement item in parent.DescendantsAndSelf()) { if (selector.Match(item)) { result.Add(item); } } } } public static bool Contains(this ITokenList list, string[] tokens) { return list.Contains(tokens); } public static bool Contains(this T list, string[] tokens) where T : class, ITokenList { for (int i = 0; i < tokens.Length; i++) { if (!list.Contains(tokens[i])) { return false; } } return true; } private static void GetElementsByClassName(this T elements, string[] classNames, List result) where T : class, INodeList { for (int i = 0; i < elements.Length; i++) { if (elements[i] is IElement element) { if (element.ClassList.Contains(classNames)) { result.Add(element); } if (element.ChildElementCount != 0) { element.ChildNodes.GetElementsByClassName(classNames, result); } } } } private static void GetElementsByTagName(this T elements, string? tagName, List result) where T : class, INodeList { for (int i = 0; i < elements.Length; i++) { if (elements[i] is IElement element) { if (tagName == null || tagName.Isi(element.LocalName)) { result.Add(element); } if (element.ChildElementCount != 0) { element.ChildNodes.GetElementsByTagName(tagName, result); } } } } private static void GetElementsByTagName(this T elements, string? namespaceUri, string? localName, List result) where T : class, INodeList { for (int i = 0; i < elements.Length; i++) { if (elements[i] is IElement element) { if (element.NamespaceUri.Is(namespaceUri) && (localName == null || localName.Isi(element.LocalName))) { result.Add(element); } if (element.ChildElementCount != 0) { element.ChildNodes.GetElementsByTagName(namespaceUri, localName, result); } } } } private static IElement? GetScope(INode? scopeNode) { object obj = scopeNode as IElement; if (obj == null) { obj = (scopeNode as IDocument)?.DocumentElement; if (obj == null) { IShadowRoot obj2 = scopeNode as IShadowRoot; if (obj2 == null) { return null; } obj = obj2.Host; } } return (IElement?)obj; } private static ISelector? CreateSelector(T nodes, INode? scope, string selectorText) where T : class, INodeList { INode node = ((nodes.Length > 0) ? nodes[0] : scope); ISelector result = null; if (node != null) { result = node.Owner.Context.GetService().ParseSelector(selectorText) ?? throw new DomException(DomError.Syntax); } return result; } } public enum RangePosition : short { Before = -1, Equal, After } [DomName("Range")] public enum RangeType : byte { [DomName("START_TO_START")] StartToStart, [DomName("START_TO_END")] StartToEnd, [DomName("END_TO_END")] EndToEnd, [DomName("END_TO_START")] EndToStart } public static class SelectorExtensions { public static T? Eq(this IEnumerable elements, int index) where T : notnull, IElement { if (elements == null) { throw new ArgumentNullException("elements"); } return elements.Skip(index).FirstOrDefault(); } public static IEnumerable Gt(this IEnumerable elements, int index) where T : IElement { if (elements == null) { throw new ArgumentNullException("elements"); } return elements.Skip(index + 1); } public static IEnumerable Lt(this IEnumerable elements, int index) where T : IElement { if (elements == null) { throw new ArgumentNullException("elements"); } return elements.Take(index); } public static IEnumerable Even(this IEnumerable elements) where T : IElement { if (elements == null) { throw new ArgumentNullException("elements"); } bool even = true; foreach (T element in elements) { if (even) { yield return element; } even = !even; } } public static IEnumerable Odd(this IEnumerable elements) where T : IElement { if (elements == null) { throw new ArgumentNullException("elements"); } bool odd = false; foreach (T element in elements) { if (odd) { yield return element; } odd = !odd; } } public static IEnumerable Filter(this IEnumerable elements, string selectorText) where T : IElement { return elements.Filter(selectorText, result: true); } public static IEnumerable Not(this IEnumerable elements, string selectorText) where T : IElement { return elements.Filter(selectorText, result: false); } public static IEnumerable Children(this IEnumerable elements, string? selectorText = null) { return elements.GetMany((IElement m) => m.Children, selectorText); } public static IEnumerable Siblings(this IEnumerable elements, string? selectorText = null) { return elements.GetMany((IElement m) => m.Parent.ChildNodes.OfType().Except(m), selectorText); } public static IEnumerable Parent(this IEnumerable elements, string? selectorText = null) { return elements.Get((IElement m) => m.ParentElement, selectorText); } public static IEnumerable Next(this IEnumerable elements, string? selectorText = null) { return elements.Get((IElement m) => m.NextElementSibling, selectorText); } public static IEnumerable Previous(this IEnumerable elements, string? selectorText = null) { return elements.Get((IElement m) => m.PreviousElementSibling, selectorText); } public static IEnumerable Is(this IEnumerable elements, ISelector selector) where T : IElement { return elements.Filter(selector, result: true); } public static IEnumerable Not(this IEnumerable elements, ISelector selector) where T : IElement { return elements.Filter(selector, result: false); } public static IEnumerable Children(this IEnumerable elements, ISelector? selector = null) { return elements.GetMany((IElement m) => m.Children, selector); } public static IEnumerable Siblings(this IEnumerable elements, ISelector? selector = null) { return elements.GetMany((IElement m) => m.Parent.ChildNodes.OfType().Except(m), selector); } public static IEnumerable Parent(this IEnumerable elements, ISelector? selector = null) { return elements.Get((IElement m) => m.ParentElement, selector); } public static IEnumerable Next(this IEnumerable elements, ISelector? selector = null) { return elements.Get((IElement m) => m.NextElementSibling, selector); } public static IEnumerable Previous(this IEnumerable elements, ISelector? selector = null) { return elements.Get((IElement m) => m.PreviousElementSibling, selector); } private static IEnumerable GetMany(this IEnumerable elements, Func> getter, ISelector? selector) { if (selector == null) { selector = AllSelector.Instance; } foreach (IElement element in elements) { IEnumerable enumerable = getter(element); foreach (IElement item in enumerable) { if (selector.Match(item)) { yield return item; } } } } private static IEnumerable GetMany(this IEnumerable elements, Func> getter, string? selectorText) { ISelector selector = CreateSelector(elements, selectorText); return elements.GetMany(getter, selector); } private static IEnumerable Get(this IEnumerable elements, Func getter, ISelector? selector) { if (selector == null) { selector = AllSelector.Instance; } foreach (IElement element2 in elements) { for (IElement element = getter(element2); element != null; element = getter(element)) { if (selector.Match(element)) { yield return element; break; } } } } private static IEnumerable Get(this IEnumerable elements, Func getter, string? selectorText) { ISelector selector = CreateSelector(elements, selectorText); return elements.Get(getter, selector); } private static IEnumerable Except(this IEnumerable elements, IElement excluded) { foreach (IElement element in elements) { if (element != excluded) { yield return element; } } } private static IEnumerable Filter(this IEnumerable elements, ISelector? selector, bool result) where T : IElement { if (selector == null) { selector = AllSelector.Instance; } foreach (T element in elements) { if (selector.Match(element) == result) { yield return element; } } } private static IEnumerable Filter(this IEnumerable elements, string selectorText, bool result) where T : IElement { ISelector selector = CreateSelector(elements, selectorText); return elements.Filter(selector, result); } private static ISelector? CreateSelector(IEnumerable elements, string? selector) where T : IElement { if (selector != null) { T val = elements.FirstOrDefault(); if (val != null) { return val.Owner.Context.GetService().ParseSelector(selector); } } return AllSelector.Instance; } } [DomName("ShadowRootMode")] [DomLiterals] public enum ShadowRootMode : byte { [DomName("open")] Open, [DomName("closed")] Closed } public static class TagNames { public static readonly string Doctype = "DOCTYPE"; public static readonly string Html = "html"; public static readonly string Body = "body"; public static readonly string Head = "head"; public static readonly string Meta = "meta"; public static readonly string Title = "title"; public static readonly string Bgsound = "bgsound"; public static readonly string Script = "script"; public static readonly string Style = "style"; public static readonly string NoEmbed = "noembed"; public static readonly string NoScript = "noscript"; public static readonly string NoFrames = "noframes"; public static readonly string Menu = "menu"; public static readonly string MenuItem = "menuitem"; public static readonly string Var = "var"; public static readonly string Ruby = "ruby"; public static readonly string Sub = "sub"; public static readonly string Sup = "sup"; public static readonly string Rp = "rp"; public static readonly string Rt = "rt"; public static readonly string Rb = "rb"; public static readonly string Rtc = "rtc"; public static readonly string Applet = "applet"; public static readonly string Embed = "embed"; public static readonly string Marquee = "marquee"; public static readonly string Param = "param"; public static readonly string Object = "object"; public static readonly string Canvas = "canvas"; public static readonly string Font = "font"; public static readonly string Ins = "ins"; public static readonly string Del = "del"; public static readonly string Template = "template"; public static readonly string Slot = "slot"; public static readonly string Caption = "caption"; public static readonly string Col = "col"; public static readonly string Colgroup = "colgroup"; public static readonly string Table = "table"; public static readonly string Thead = "thead"; public static readonly string Tbody = "tbody"; public static readonly string Tfoot = "tfoot"; public static readonly string Th = "th"; public static readonly string Td = "td"; public static readonly string Tr = "tr"; public static readonly string Input = "input"; public static readonly string Keygen = "keygen"; public static readonly string Textarea = "textarea"; public static readonly string P = "p"; public static readonly string Span = "span"; public static readonly string Dialog = "dialog"; public static readonly string Fieldset = "fieldset"; public static readonly string Legend = "legend"; public static readonly string Label = "label"; public static readonly string Details = "details"; public static readonly string Form = "form"; public static readonly string IsIndex = "isindex"; public static readonly string Pre = "pre"; public static readonly string Data = "data"; public static readonly string Datalist = "datalist"; public static readonly string Ol = "ol"; public static readonly string Ul = "ul"; public static readonly string Dl = "dl"; public static readonly string Li = "li"; public static readonly string Dd = "dd"; public static readonly string Dt = "dt"; public static readonly string B = "b"; public static readonly string Big = "big"; public static readonly string Strike = "strike"; public static readonly string Code = "code"; public static readonly string Em = "em"; public static readonly string I = "i"; public static readonly string S = "s"; public static readonly string Small = "small"; public static readonly string Strong = "strong"; public static readonly string U = "u"; public static readonly string Tt = "tt"; public static readonly string NoBr = "nobr"; public static readonly string Select = "select"; public static readonly string Option = "option"; public static readonly string Optgroup = "optgroup"; public static readonly string Link = "link"; public static readonly string Frameset = "frameset"; public static readonly string Frame = "frame"; public static readonly string Iframe = "iframe"; public static readonly string Audio = "audio"; public static readonly string Video = "video"; public static readonly string Source = "source"; public static readonly string Track = "track"; public static readonly string H1 = "h1"; public static readonly string H2 = "h2"; public static readonly string H3 = "h3"; public static readonly string H4 = "h4"; public static readonly string H5 = "h5"; public static readonly string H6 = "h6"; public static readonly string Div = "div"; public static readonly string Quote = "quote"; public static readonly string BlockQuote = "blockquote"; public static readonly string Q = "q"; public static readonly string Base = "base"; public static readonly string BaseFont = "basefont"; public static readonly string A = "a"; public static readonly string Area = "area"; public static readonly string Button = "button"; public static readonly string Cite = "cite"; public static readonly string Main = "main"; public static readonly string Summary = "summary"; public static readonly string Xmp = "xmp"; public static readonly string Br = "br"; public static readonly string Wbr = "wbr"; public static readonly string Hr = "hr"; public static readonly string Dir = "dir"; public static readonly string Center = "center"; public static readonly string Listing = "listing"; public static readonly string Img = "img"; public static readonly string Image = "image"; public static readonly string Nav = "nav"; public static readonly string Address = "address"; public static readonly string Article = "article"; public static readonly string Aside = "aside"; public static readonly string Figcaption = "figcaption"; public static readonly string Figure = "figure"; public static readonly string Section = "section"; public static readonly string Footer = "footer"; public static readonly string Header = "header"; public static readonly string Hgroup = "hgroup"; public static readonly string Plaintext = "plaintext"; public static readonly string Time = "time"; public static readonly string Progress = "progress"; public static readonly string Meter = "meter"; public static readonly string Output = "output"; public static readonly string Map = "map"; public static readonly string Picture = "picture"; public static readonly string Mark = "mark"; public static readonly string Dfn = "dfn"; public static readonly string Kbd = "kbd"; public static readonly string Samp = "samp"; public static readonly string Abbr = "abbr"; public static readonly string Bdi = "bdi"; public static readonly string Bdo = "bdo"; public static readonly string Math = "math"; public static readonly string Mi = "mi"; public static readonly string Mo = "mo"; public static readonly string Mn = "mn"; public static readonly string Ms = "ms"; public static readonly string Mtext = "mtext"; public static readonly string AnnotationXml = "annotation-xml"; public static readonly string Svg = "svg"; public static readonly string ForeignObject = "foreignObject"; public static readonly string Desc = "desc"; public static readonly string Circle = "circle"; public static readonly string Xml = "xml"; internal static readonly HashSet AllForeignExceptions = new HashSet(OrdinalStringOrMemoryComparer.Instance) { B, Big, BlockQuote, Body, Br, Center, Code, Dd, Div, Dl, Dt, Em, Embed, Head, Hr, I, Img, Li, Ul, H3, H2, H4, H1, H6, H5, Listing, Menu, Meta, NoBr, Ol, P, Pre, Ruby, S, Small, Span, Strike, Strong, Sub, Sup, Table, Tt, U, Var }; internal static readonly HashSet AllBeforeHead = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Html, Body, Br, Head }; internal static readonly HashSet AllNoShadowRoot = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Button, Details, Input, Marquee, Meter, Progress, Select, Textarea, Keygen }; internal static readonly HashSet AllHead = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Style, Link, Meta, Title, NoFrames, Template, Base, BaseFont, Bgsound }; internal static readonly HashSet AllHeadNoTemplate = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Link, Meta, Script, Style, Title, Base, BaseFont, Bgsound, NoFrames }; internal static readonly HashSet AllHeadBase = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Link, Base, BaseFont, Bgsound }; internal static readonly HashSet AllBodyBreakrow = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Br, Area, Embed, Keygen, Wbr }; internal static readonly HashSet AllBodyClosed = new HashSet(OrdinalStringOrMemoryComparer.Instance) { MenuItem, Param, Source, Track }; internal static readonly HashSet AllNoScript = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Style, Link, BaseFont, Meta, NoFrames, Bgsound }; internal static readonly HashSet AllHeadings = new HashSet(OrdinalStringOrMemoryComparer.Instance) { H3, H2, H4, H1, H6, H5 }; internal static readonly HashSet AllBlocks = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Ol, Ul, Dl, Fieldset, Button, Figcaption, Figure, Article, Aside, BlockQuote, Center, Address, Dialog, Dir, Summary, Details, Listing, Footer, Header, Nav, Section, Menu, Hgroup, Main, Pre }; internal static readonly HashSet AllBody = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Ol, Dl, Fieldset, Figcaption, Figure, Article, Aside, BlockQuote, Center, Address, Dialog, Dir, Summary, Details, Main, Footer, Header, Nav, Section, Menu, Hgroup }; internal static readonly HashSet AllBodyObsolete = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Applet, Marquee, Object }; internal static readonly HashSet AllInput = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Input, Keygen, Textarea }; internal static readonly HashSet AllBasicBlocks = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Address, Div, P }; internal static readonly HashSet AllSemanticFormatting = new HashSet(OrdinalStringOrMemoryComparer.Instance) { B, Strong, Code, Em, U, I }; internal static readonly HashSet AllClassicFormatting = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Font, S, Small, Strike, Big, Tt }; internal static readonly HashSet AllFormatting = new HashSet(OrdinalStringOrMemoryComparer.Instance) { B, Strong, Code, Em, U, I, NoBr, Font, S, Small, Strike, Big, Tt }; internal static readonly HashSet AllNested = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tbody, Td, Tfoot, Th, Thead, Tr, Caption, Col, Colgroup, Frame, Head }; internal static readonly HashSet AllCaptionEnd = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tbody, Col, Tfoot, Td, Thead, Caption, Th, Colgroup, Tr }; internal static readonly HashSet AllCaptionStart = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tbody, Col, Tfoot, Td, Thead, Tr, Body, Th, Colgroup, Html }; internal static readonly HashSet AllTable = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tbody, Col, Tfoot, Td, Thead, Tr }; internal static readonly HashSet AllTableRoot = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Caption, Colgroup, Tbody, Tfoot, Thead }; internal static readonly HashSet AllTableGeneral = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Caption, Colgroup, Col, Tbody, Tfoot, Thead }; internal static readonly HashSet AllTableSections = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tbody, Tfoot, Thead }; internal static readonly HashSet AllTableMajor = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tbody, Tfoot, Thead, Table, Tr }; internal static readonly HashSet AllTableSpecial = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Td, Th, Body, Caption, Col, Colgroup, Html }; internal static readonly HashSet AllTableCore = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tr, Table, Tbody, Tfoot, Thead }; internal static readonly HashSet AllTableInner = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tbody, Tr, Thead, Th, Tfoot, Td }; internal static readonly HashSet AllTableSelects = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tr, Table, Tbody, Tfoot, Thead, Td, Th, Caption }; internal static readonly HashSet AllTableCells = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Td, Th }; internal static readonly HashSet AllTableCellsRows = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Tr, Td, Th }; internal static readonly HashSet AllTableHead = new HashSet(OrdinalStringOrMemoryComparer.Instance) { Script, Style, Template }; internal static readonly HashSet DisallowedCustomElementNames = new HashSet(OrdinalStringOrMemoryComparer.Instance) { "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" }; } [DomName("URL")] [DomExposed("Window")] [DomExposed("Worker")] public sealed class Url : IEquatable { private static readonly string CurrentDirectory = "."; private static readonly string CurrentDirectoryAlternative = "%2e"; private static readonly string UpperDirectory = ".."; private static readonly string[] UpperDirectoryAlternatives = new string[3] { "%2e%2e", ".%2e", "%2e." }; private static readonly Url DefaultBase = new Url(string.Empty, string.Empty, string.Empty); private static readonly char[] C0ControlAndSpace = (from c in Enumerable.Range(0, 33) select (char)c).ToArray(); private static readonly IdnMapping DefaultIdnMapping = new IdnMapping { AllowUnassigned = false, UseStd3AsciiRules = false }; private string? _fragment; private string? _query; private string _path; private string _scheme; private string _port; private string _host; private string? _username; private string? _password; private bool _relative; private string _schemeData; private UrlSearchParams? _params; private bool _error; [DomName("origin")] public string? Origin { get { if (_scheme.Is(ProtocolNames.Blob)) { Url url = new Url(_schemeData); if (!url.IsInvalid) { return url.Origin; } } else if (ProtocolNames.IsOriginable(_scheme)) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); if (!string.IsNullOrEmpty(_host)) { if (!string.IsNullOrEmpty(_scheme)) { stringBuilder.Append(_scheme).Append(':'); } stringBuilder.Append('/').Append('/').Append(_host); if (!string.IsNullOrEmpty(_port)) { stringBuilder.Append(':').Append(_port); } } return stringBuilder.ToPool(); } return null; } } public bool IsInvalid => _error; public bool IsRelative { get { if (_relative) { return string.IsNullOrEmpty(_scheme); } return false; } } public bool IsAbsolute => !IsRelative; [DomName("username")] public string? UserName { get { return _username ?? string.Empty; } set { _username = value; } } [DomName("password")] public string? Password { get { return _password ?? string.Empty; } set { _password = value; } } public string Data => _schemeData; public string? Fragment { get { return _fragment; } set { if (value == null) { _fragment = null; } else { ParseFragment(value, 0, value.Length); } } } [DomName("hash")] public string Hash { get { if (!string.IsNullOrEmpty(_fragment)) { return "#" + _fragment; } return string.Empty; } set { if (string.IsNullOrEmpty(value)) { Fragment = null; } else if (value[0] == '#') { Fragment = value.Substring(1); } else { Fragment = value; } } } [DomName("host")] public string Host { get { return HostName + (string.IsNullOrEmpty(_port) ? string.Empty : (":" + _port)); } set { string text = value ?? string.Empty; ParseHostName(text, 0, text.Length, onlyHost: false, onlyPort: true); } } [DomName("hostname")] public string HostName { get { return _host; } set { string text = value ?? string.Empty; ParseHostName(text, 0, text.Length, onlyHost: true); } } [DomName("href")] public string Href { get { return Serialize(); } set { _error = ParseUrl(value ?? string.Empty, this); } } public string Path { get { return _path; } set { string text = value ?? string.Empty; ParsePath(text, 0, text.Length, onlyPath: true); } } [DomName("pathname")] public string PathName { get { return "/" + _path; } set { Path = value; } } [DomName("port")] public string Port { get { return _port; } set { string text = value ?? string.Empty; ParsePort(text, 0, text.Length, onlyPort: true); } } public string Scheme { get { return _scheme; } set { string text = value ?? string.Empty; ParseScheme(text, text.Length, onlyScheme: true); } } [DomName("protocol")] public string Protocol { get { return _scheme + ":"; } set { Scheme = value; } } public string? Query { get { return _query; } set { if (value == null) { _query = null; _params?.Reset(); } else { ParseQuery(value, 0, value.Length, onlyQuery: true); } } } [DomName("search")] public string Search { get { if (!string.IsNullOrEmpty(_query)) { return "?" + _query; } return string.Empty; } set { if (string.IsNullOrEmpty(value)) { Query = null; } else if (value[0] == '?') { Query = value.Substring(1); } else { Query = value; } } } [DomName("searchParams")] public UrlSearchParams SearchParams => _params ?? (_params = new UrlSearchParams(this)); private Url(string scheme, string host, string port) { _schemeData = string.Empty; _path = string.Empty; _scheme = scheme; _host = host; _port = port; _relative = ProtocolNames.IsRelative(_scheme); } [DomConstructor] public Url(string url, string baseAddress = null) { if (baseAddress != null) { Url baseUrl = new Url(baseAddress); _error = ParseUrl(url, baseUrl); } else { _error = ParseUrl(url); } } public Url(string address) { _error = ParseUrl(address); } public Url(Url baseAddress, string relativeAddress) { _error = ParseUrl(relativeAddress, baseAddress); } public Url(Url address) { _fragment = address._fragment; _query = address._query; _path = address._path; _scheme = address._scheme; _port = address._port; _host = address._host; _username = address._username; _password = address._password; _relative = address._relative; _schemeData = address._schemeData; } public static Url Create(string address) { return new Url(address); } public static Url Convert(Uri uri) { return new Url(uri.OriginalString); } public override int GetHashCode() { return (((((((((((((((((_fragment != null) ? StringComparer.Ordinal.GetHashCode(_fragment) : 0) * 397) ^ ((_query != null) ? StringComparer.Ordinal.GetHashCode(_query) : 0)) * 397) ^ ((_path != null) ? StringComparer.Ordinal.GetHashCode(_path) : 0)) * 397) ^ ((_scheme != null) ? StringComparer.OrdinalIgnoreCase.GetHashCode(_scheme) : 0)) * 397) ^ ((_port != null) ? StringComparer.Ordinal.GetHashCode(_port) : 0)) * 397) ^ ((_host != null) ? StringComparer.OrdinalIgnoreCase.GetHashCode(_host) : 0)) * 397) ^ ((_username != null) ? StringComparer.Ordinal.GetHashCode(_username) : 0)) * 397) ^ ((_password != null) ? StringComparer.Ordinal.GetHashCode(_password) : 0)) * 397) ^ ((_schemeData != null) ? StringComparer.Ordinal.GetHashCode(_schemeData) : 0); } public override bool Equals(object? obj) { if (this != obj) { if (obj is Url other) { return Equals(other); } return false; } return true; } public bool Equals(Url? other) { if (other != null && _fragment.Is(other._fragment) && _query.Is(other._query) && _path.Is(other._path) && _scheme.Isi(other._scheme) && _port.Is(other._port) && _host.Isi(other._host) && _username.Is(other._username) && _password.Is(other._password)) { return _schemeData.Is(other._schemeData); } return false; } public static implicit operator Uri(Url value) { return new Uri(value.Serialize(), (!value.IsRelative) ? UriKind.Absolute : UriKind.Relative); } [DomName("toJSON")] public string ToJson() { return Serialize(); } public override string ToString() { return Serialize(); } private string Serialize() { StringBuilder stringBuilder = StringBuilderPool.Obtain(); if (!string.IsNullOrEmpty(_scheme)) { stringBuilder.Append(_scheme).Append(':'); } if (_relative) { if (!string.IsNullOrEmpty(_host) || !string.IsNullOrEmpty(_scheme)) { stringBuilder.Append('/').Append('/'); if (!string.IsNullOrEmpty(_username) || _password != null) { stringBuilder.Append(_username); if (_password != null) { stringBuilder.Append(':').Append(_password); } stringBuilder.Append('@'); } stringBuilder.Append(_host); if (!string.IsNullOrEmpty(_port)) { stringBuilder.Append(':').Append(_port); } stringBuilder.Append('/'); } stringBuilder.Append(_path); } else { stringBuilder.Append(_schemeData); } if (_query != null) { stringBuilder.Append('?').Append(_query); } if (_fragment != null) { stringBuilder.Append('#').Append(_fragment); } return stringBuilder.ToPool(); } private bool ParseUrl(string input, Url? baseUrl = null) { Reset(baseUrl ?? DefaultBase); string text = NormalizeInput(input); int length = text.Length; return !ParseScheme(text, length); } private void Reset(Url baseUrl) { _schemeData = string.Empty; _scheme = baseUrl._scheme; _host = baseUrl._host; _path = baseUrl._path; _query = baseUrl._query; _port = baseUrl._port; _relative = ProtocolNames.IsRelative(_scheme); } private bool ParseScheme(string input, int length, bool onlyScheme = false) { if (length > 0 && input[0].IsLetter()) { for (int i = 1; i < length; i++) { char c = input[i]; if (c.IsAlphanumericAscii()) { continue; } switch (c) { case '+': case '-': case '.': continue; case ':': { string scheme = _scheme; _scheme = input.Substring(0, i).ToLowerInvariant(); if (!onlyScheme) { _relative = ProtocolNames.IsRelative(_scheme); if (_scheme.Is(ProtocolNames.File)) { _host = string.Empty; _port = string.Empty; _query = null; return RelativeState(input, i + 1, length); } if (!_relative) { _host = string.Empty; _port = string.Empty; _path = string.Empty; _query = null; return ParseSchemeData(input, i + 1, length); } if (_scheme.Is(scheme)) { if (++i < length) { c = input[i]; if (c == '/' && i + 2 < length && input[i + 1] == '/') { return IgnoreSlashesState(input, i + 2, length); } return RelativeState(input, i, length); } return false; } if (i + 1 < length && input[++i] == '/' && ++i < length && input[i] == '/') { i++; } return IgnoreSlashesState(input, i, length); } return true; } } break; } } if (!onlyScheme) { return RelativeState(input, 0, length); } return false; } private bool ParseSchemeData(string input, int index, int length) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); for (; index < length; index++) { char c = input[index]; switch (c) { case '?': _schemeData = stringBuilder.ToPool(); return ParseQuery(input, index + 1, length); case '#': _schemeData = stringBuilder.ToPool(); return ParseFragment(input, index + 1, length); case '%': if (index + 2 < length && input[index + 1].IsHex() && input[index + 2].IsHex()) { stringBuilder.Append(input[index++]); stringBuilder.Append(input[index++]); stringBuilder.Append(input[index]); continue; } break; } if (c.IsInRange(32, 126)) { stringBuilder.Append(c); } } _schemeData = stringBuilder.ToPool(); return true; } private bool RelativeState(string input, int index, int length) { _relative = true; if (index != length) { switch (input[index]) { case '?': return ParseQuery(input, index + 1, length); case '#': return ParseFragment(input, index + 1, length); case '/': case '\\': if (index != length - 1) { char c2 = input[++index]; if ((c2 == '/' || c2 == '\\') ? true : false) { if (_scheme.Is(ProtocolNames.File)) { return ParseFileHost(input, index + 1, length); } return IgnoreSlashesState(input, index + 1, length); } if (_scheme.Is(ProtocolNames.File)) { _host = string.Empty; _port = string.Empty; } return ParsePath(input, index - 1, length); } return ParsePath(input, index, length); default: { bool flag = input[index].IsLetter() && _scheme.Is(ProtocolNames.File) && index + 1 < length; if (flag) { char c = input[index + 1]; bool flag2 = ((c == '/' || c == ':') ? true : false); flag = flag2; } bool flag3 = flag; if (flag3) { bool flag2 = index + 2 == length; if (!flag2) { bool flag4; switch (input[index + 2]) { case '#': case '/': case '?': case '\\': flag4 = true; break; default: flag4 = false; break; } flag2 = flag4; } flag3 = flag2; } if (flag3) { _host = string.Empty; _path = string.Empty; _port = string.Empty; } return ParsePath(input, index, length); } } } return true; } private bool IgnoreSlashesState(string input, int index, int length) { while (index < length) { char c = input[index]; if ((c != '/' && c != '\\') || 1 == 0) { return ParseAuthority(input, index, length); } index++; } return false; } private bool ParseAuthority(string input, int index, int length) { int index2 = index; StringBuilder stringBuilder = StringBuilderPool.Obtain(); string text = null; string password = null; for (; index < length; index++) { char c = input[index]; switch (c) { case '@': if (text == null) { text = stringBuilder.ToString(); } else { password = stringBuilder.ToString(); } _username = text; _password = password; stringBuilder.Append("%40"); index2 = index + 1; continue; case ':': if (text == null) { text = stringBuilder.ToString(); password = string.Empty; stringBuilder.Clear(); continue; } goto default; default: { if (c == '%' && index + 2 < length && input[index + 1].IsHex() && input[index + 2].IsHex()) { stringBuilder.Append(input[index++]).Append(input[index++]).Append(input[index]); continue; } bool flag; switch (c) { case '#': case '/': case '?': case '\\': flag = true; break; default: flag = false; break; } if (!flag) { if (c != ':' && (c == '#' || c == '?' || c.IsNormalPathCharacter())) { stringBuilder.Append(c); } else { index += Utf8PercentEncode(stringBuilder, input, index); } continue; } break; } } break; } stringBuilder.ReturnToPool(); return ParseHostName(input, index2, length); } private bool ParseFileHost(string input, int index, int length) { int num = index; _path = string.Empty; bool flag; while (index < length) { switch (input[index]) { case '#': case '/': case '?': case '\\': flag = true; break; default: flag = false; break; } if (flag) { break; } index++; } int num2 = index - num; flag = num2 == 2 && input[num].IsLetter(); if (flag) { char c = input[num + 1]; bool flag2 = ((c == ':' || c == '|') ? true : false); flag = flag2; } if (flag) { return ParsePath(input, index - 2, length); } if (num2 != 0 && !TrySanatizeHost(input, num, num2, out _host)) { return false; } return ParsePath(input, index, length); } private bool ParseHostName(string input, int index, int length, bool onlyHost = false, bool onlyPort = false) { bool flag = false; int num = index; while (index < length) { switch (input[index]) { case ']': flag = false; break; case '[': flag = true; break; case ':': if (!flag) { if (!TrySanatizeHost(input, num, index - num, out _host)) { return false; } if (!onlyHost) { return ParsePort(input, index + 1, length, onlyPort); } return true; } break; case '#': case '/': case '?': case '\\': { if (!TrySanatizeHost(input, num, index - num, out _host)) { return false; } bool flag2 = string.IsNullOrEmpty(_host); if (!onlyHost) { _port = string.Empty; if (ParsePath(input, index, length)) { return !flag2; } return false; } return !flag2; } } index++; } if (!TrySanatizeHost(input, num, index - num, out _host)) { return false; } if (!onlyHost) { _path = string.Empty; _port = string.Empty; _query = null; _fragment = null; _params?.Reset(); } return true; } private bool ParsePort(string input, int index, int length, bool onlyPort = false) { int num = index; while (index < length) { char c = input[index]; if (c == '?' || c == '/' || c == '\\' || c == '#') { break; } if (c.IsDigit()) { index++; continue; } return false; } _port = SanatizePort(input, num, index - num); if (PortNumbers.GetDefaultPort(_scheme) == _port) { _port = string.Empty; } if (!onlyPort) { _path = string.Empty; return ParsePath(input, index, length); } return true; } private bool ParsePath(string input, int index, int length, bool onlyPath = false) { int num = index; if (index < length && (input[index] == '/' || input[index] == '\\')) { index++; } List list = new List(); if (!onlyPath && !string.IsNullOrEmpty(_path) && index - num == 0) { string[] array = _path.Split('/'); if (array.Length > 1) { list.AddRange(array); list.RemoveAt(array.Length - 1); } } int count = list.Count; StringBuilder stringBuilder = StringBuilderPool.Obtain(); while (index <= length) { char c = ((index == length) ? '\uffff' : input[index]); bool flag = !onlyPath && (c == '#' || c == '?'); if (c == '\uffff' || c == '/' || c == '\\' || flag) { string text = stringBuilder.ToString(); bool flag2 = false; stringBuilder.Clear(); if (text.Isi(CurrentDirectoryAlternative)) { text = CurrentDirectory; } else if (text.Isi(UpperDirectoryAlternatives[0]) || text.Isi(UpperDirectoryAlternatives[1]) || text.Isi(UpperDirectoryAlternatives[2])) { text = UpperDirectory; } if (text.Is(UpperDirectory)) { if (list.Count > 0) { list.RemoveAt(list.Count - 1); } flag2 = true; } else if (!text.Is(CurrentDirectory)) { if (_scheme.Is(ProtocolNames.File) && list.Count == count && text.Length == 2 && text[0].IsLetter() && text[1] == '|') { text = text.Replace('|', ':'); list.Clear(); } list.Add(text); } else { flag2 = true; } if (flag2 && c != '/' && c != '\\') { list.Add(string.Empty); } if (flag) { break; } } else if (c == '%' && index + 2 < length && input[index + 1].IsHex() && input[index + 2].IsHex()) { stringBuilder.Append(input[index++]); stringBuilder.Append(input[index++]); stringBuilder.Append(input[index]); } else if (c.IsNormalPathCharacter()) { stringBuilder.Append(c); } else { index += Utf8PercentEncode(stringBuilder, input, index); } index++; } stringBuilder.ReturnToPool(); _path = string.Join("/", list); _query = null; if (index < length) { if (input[index] == '?') { return ParseQuery(input, index + 1, length); } return ParseFragment(input, index + 1, length); } return true; } internal bool ParseQuery(string input, int index, int length, bool onlyQuery = false, bool fromParams = false) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); bool flag = false; while (index < length) { char c = input[index]; flag = !onlyQuery && input[index] == '#'; if (flag) { break; } if (c.IsNormalQueryCharacter()) { stringBuilder.Append(c); } else { index += Utf8PercentEncode(stringBuilder, input, index); } index++; } _query = stringBuilder.ToPool(); if (!fromParams) { _params?.ChangeTo(_query, fromParent: true); } if (!flag) { return true; } return ParseFragment(input, index + 1, length); } private bool ParseFragment(string input, int index, int length) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); while (index < length) { char c = input[index]; if (c != 0 && c != '\uffff') { stringBuilder.Append(c); } index++; } _fragment = stringBuilder.ToPool(); return true; } private static string NormalizeInput(string input) { string text = input.Trim(C0ControlAndSpace); StringBuilder stringBuilder = StringBuilderPool.Obtain(); string text2 = text; foreach (char c in text2) { switch (c) { case '\t': case '\n': case '\r': continue; } stringBuilder.Append(c); } return stringBuilder.ToPool(); } private static string Utf8PercentDecode(string source) { byte[] bytes = TextEncoding.Utf8.GetBytes(source); int num = bytes.Length; int num2 = 0; int num3 = 0; while (num2 < bytes.Length) { char c = (char)bytes[num2]; if (c == '%' && num2 + 2 < bytes.Length && ((char)bytes[num2 + 1]).IsHex() && ((char)bytes[num2 + 2]).IsHex()) { c = (char)(((char)bytes[num2 + 1]).FromHex() * 16 + ((char)bytes[num2 + 2]).FromHex()); num2 += 2; num -= 2; } bytes[num3] = (byte)c; num2++; num3++; } return TextEncoding.Utf8.GetString(bytes, 0, num); } private static int Utf8PercentEncode(StringBuilder buffer, string source, int index) { int num = ((!char.IsSurrogatePair(source, index)) ? 1 : 2); byte[] bytes = TextEncoding.Utf8.GetBytes(source.Substring(index, num)); for (int i = 0; i < bytes.Length; i++) { buffer.Append('%').Append(bytes[i].ToString("X2")); } return num - 1; } private static bool TrySanatizeHost(string hostName, int start, int length, out string sanatizedHostName) { if (length == 0) { sanatizedHostName = string.Empty; return true; } if (length > 1 && hostName[start] == '[' && hostName[start + length - 1] == ']') { sanatizedHostName = hostName.Substring(start, length); return true; } string unicode = Utf8PercentDecode(hostName.Substring(start, length)); string ascii; try { ascii = DefaultIdnMapping.GetAscii(unicode); } catch (ArgumentException) { sanatizedHostName = hostName.Substring(start, length); return false; } StringBuilder stringBuilder = StringBuilderPool.Obtain(); string text = ascii; foreach (char c in text) { switch (c) { case '\0': case '\t': case '\n': case '\r': case ' ': case '#': case '%': case '/': case ':': case '?': case '@': case '[': case '\\': case ']': stringBuilder.ReturnToPool(); sanatizedHostName = hostName.Substring(start, length); return false; } stringBuilder.Append(char.ToLowerInvariant(c)); } sanatizedHostName = stringBuilder.ToPool(); return true; } private static string SanatizePort(string port, int start, int length) { if (length < 128) { return Go(stackalloc char[length]); } return Go(new char[length]); string Go(Span chars) { int num = 0; int num2 = start + length; for (int i = start; i < num2; i++) { if (num == 1 && chars[0] == '0') { chars[0] = port[i]; } else { chars[num++] = port[i]; } } return chars.Slice(0, num).ToString(); } } } [DomName("URLSearchParams")] [DomExposed("Window")] [DomExposed("Worker")] public class UrlSearchParams { private readonly List> _values; private readonly Url? _parent; [DomConstructor] public UrlSearchParams() { _values = new List>(); } internal UrlSearchParams(Url parent) : this(parent.Query ?? string.Empty) { _parent = parent; } [DomConstructor] public UrlSearchParams(string init) : this() { ChangeTo(init, fromParent: false); } internal void Reset() { _values.Clear(); } internal void ChangeTo(string query, bool fromParent) { Reset(); if (query == "") { return; } string[] array = query.Split('&'); foreach (string text in array) { string[] array2 = text.Split('='); if (array2.Length > 1) { AppendCore(Decode(array2[0]), Decode(array2[1])); } else { AppendCore(Decode(text), string.Empty); } } RaiseChanged(fromParent); } [DomName("append")] public void Append(string name, string value) { AppendCore(name, value); RaiseChanged(fromParent: false); } private void AppendCore(string name, string value) { _values.Add(new KeyValuePair(name, value)); } [DomName("delete")] public void Delete(string name) { DeleteCore(name); RaiseChanged(fromParent: false); } private void DeleteCore(string name) { _values.RemoveAll((KeyValuePair p) => p.Key == name); } [DomName("get")] public string? Get(string name) { return _values.Find((KeyValuePair p) => p.Key == name).Value; } [DomName("getAll")] public string[] GetAll(string name) { return (from m in _values.FindAll((KeyValuePair p) => p.Key == name) select m.Value).ToArray(); } [DomName("has")] public bool Has(string name) { return _values.Any>((KeyValuePair p) => p.Key == name); } [DomName("set")] public void Set(string name, string value) { if (Has(name)) { int index = _values.FindIndex((KeyValuePair p) => p.Key == name); DeleteCore(name); _values.Insert(index, new KeyValuePair(name, value)); } else { AppendCore(name, value); } RaiseChanged(fromParent: false); } [DomName("sort")] public void Sort() { _values.Sort((KeyValuePair a, KeyValuePair b) => a.Key.CompareTo(b.Key)); RaiseChanged(fromParent: false); } public override string ToString() { return string.Join("&", _values.Select, string>((KeyValuePair p) => Encode(p.Key) + "=" + Encode(p.Value))); } private static string Encode(string value) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); foreach (char c in value) { bool flag = c.IsAlphanumericAscii(); if (!flag) { bool flag2; switch (c) { case '!': case '(': case ')': case '*': case '-': case '\\': case '_': case '~': flag2 = true; break; default: flag2 = false; break; } flag = flag2; } if (flag) { stringBuilder.Append(c); continue; } stringBuilder.Append('%'); int num = c; stringBuilder.Append(num.ToString("X2")); } return stringBuilder.ToPool(); } private static string Decode(string value) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); for (int i = 0; i < value.Length; i++) { char c = value[i]; if (c == '%' && i + 2 < value.Length) { int num = value.Substring(i + 1, 2).FromHex(); stringBuilder.Append((char)num); i += 2; } else { stringBuilder.Append(c); } } return stringBuilder.ToPool(); } private void RaiseChanged(bool fromParent) { if (!fromParent) { string text = ToString(); _parent?.ParseQuery(text, 0, text.Length, onlyQuery: true, fromParams: true); } } } public enum VerticalAlignment : byte { Baseline, Sub, Super, TextTop, TextBottom, Middle, Top, Bottom } public enum Visibility : byte { Visible, Hidden, Collapse } public enum WordBreak : byte { Normal, BreakAll, KeepAll } } namespace AngleSharp.Dom.Events { [DomName("CustomEvent")] public class CustomEvent : Event { [DomName("detail")] public object? Details { get; private set; } public CustomEvent() { } [DomConstructor] [DomInitDict(1, true)] public CustomEvent(string type, bool bubbles = false, bool cancelable = false, object? details = null) { Init(type, bubbles, cancelable, details); } [DomName("initCustomEvent")] public void Init(string type, bool bubbles, bool cancelable, object? details) { Init(type, bubbles, cancelable); Details = details; } } public class DefaultEventFactory : IEventFactory { public delegate Event Creator(); private readonly Dictionary _creators = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "event", () => new Event() }, { "uievent", () => new UiEvent() }, { "focusevent", () => new FocusEvent() }, { "keyboardevent", () => new KeyboardEvent() }, { "mouseevent", () => new MouseEvent() }, { "wheelevent", () => new WheelEvent() }, { "customevent", () => new CustomEvent() } }; public DefaultEventFactory() { AddEventAlias("events", "event"); AddEventAlias("htmlevents", "event"); AddEventAlias("uievents", "uievent"); AddEventAlias("keyevents", "keyboardevent"); AddEventAlias("mouseevents", "mouseevent"); } public void Register(string name, Creator creator) { _creators.Add(name, creator); } public Creator? Unregister(string name) { if (_creators.TryGetValue(name, out Creator value)) { _creators.Remove(name); } return value; } protected virtual Event? CreateDefault(string name) { return null; } public Event? Create(string name) { if (name != null && _creators.TryGetValue(name, out Creator value)) { return value(); } return CreateDefault(name); } private void AddEventAlias(string aliasName, string aliasFor) { _creators.Add(aliasName, _creators[aliasFor]); } } [DomName("ErrorEvent")] public class ErrorEvent : Event { [DomName("message")] public string Message => Error.Message; [DomName("filename")] public string FileName { get; private set; } [DomName("lineno")] public int Line { get; private set; } [DomName("colno")] public int Column { get; private set; } [DomName("error")] public Exception Error { get; private set; } public void Init(string filename, int line, int column, Exception error) { FileName = filename; Line = line; Column = column; Error = error; } } [DomName("Event")] public class Event : EventArgs { private struct EventPathItem { public EventTarget InvocationTarget; public bool IsInvocationTargetInShadowTree; public bool IsRootOfClosedTree; public bool IsSlotInClosedTree; public EventTarget? ShadowAdjustedTarget; public EventTarget? RelatedTarget; } private EventFlags _flags; private EventPhase _phase; private IEventTarget? _current; private IEventTarget? _target; private bool _bubbles; private bool _cancelable; private bool _composed; private string? _type; private DateTime _time; private List? _currentPath; internal EventFlags Flags => _flags; [DomName("type")] public string Type => _type; [DomName("target")] public IEventTarget? OriginalTarget => _target; [DomName("currentTarget")] public IEventTarget? CurrentTarget => _current; [DomName("eventPhase")] public EventPhase Phase => _phase; [DomName("composed")] public bool IsComposed => _composed; [DomName("bubbles")] public bool IsBubbling => _bubbles; [DomName("cancelable")] public bool IsCancelable => _cancelable; [DomName("defaultPrevented")] public bool IsDefaultPrevented => (_flags & EventFlags.Canceled) == EventFlags.Canceled; [DomName("isTrusted")] public bool IsTrusted { get; internal set; } [DomName("timeStamp")] public DateTime Time => _time; public Event() { _flags = EventFlags.None; _phase = EventPhase.None; _time = DateTime.Now; _composed = false; } public Event(string type) : this(type, bubbles: false, cancelable: false) { } public Event(string type, bool bubbles = false, bool cancelable = false) : this(type, bubbles, cancelable, composed: false) { } [DomConstructor] [DomInitDict(1, true)] public Event(string type, bool bubbles = false, bool cancelable = false, bool composed = false) : this() { Init(type, bubbles, cancelable); _composed = composed; } [DomName("composedPath")] public IEnumerable GetComposedPath() { List list = new List(); if (_currentPath != null && _currentPath.Count > 0) { list.Add(_current); int num = 0; int num2 = 0; int count = _currentPath.Count; for (int num3 = count - 1; num3 >= 0; num3--) { EventPathItem eventPathItem = _currentPath[num3]; if (eventPathItem.IsRootOfClosedTree) { num2++; } if (eventPathItem.InvocationTarget == _current) { num = num3; break; } if (eventPathItem.IsSlotInClosedTree) { num2--; } } int num4 = num2; int num5 = num2; for (int num6 = num - 1; num6 >= 0; num6--) { EventPathItem eventPathItem2 = _currentPath[num6]; if (eventPathItem2.IsRootOfClosedTree) { num4++; } if (num4 <= num5) { list.Insert(0, eventPathItem2.InvocationTarget); } if (eventPathItem2.IsSlotInClosedTree) { num4--; if (num4 < num5) { num5 = num4; } } } num4 = num2; num5 = num2; for (int i = num + 1; i < count; i++) { EventPathItem eventPathItem3 = _currentPath[i]; if (eventPathItem3.IsRootOfClosedTree) { num4++; } if (num4 <= num5) { list.Add(eventPathItem3.InvocationTarget); } if (eventPathItem3.IsSlotInClosedTree) { num4--; if (num4 < num5) { num5 = num4; } } } } return list; } [DomName("stopPropagation")] public void Stop() { _flags |= EventFlags.StopPropagation; } [DomName("stopImmediatePropagation")] public void StopImmediately() { _flags |= EventFlags.StopImmediatePropagation; } [DomName("preventDefault")] public void Cancel() { if (_cancelable) { _flags |= EventFlags.Canceled; } } [DomName("initEvent")] public void Init(string type, bool bubbles, bool cancelable) { _flags |= EventFlags.Initialized; if ((_flags & EventFlags.Dispatch) != EventFlags.Dispatch) { _flags &= ~(EventFlags.StopPropagation | EventFlags.StopImmediatePropagation | EventFlags.Canceled); IsTrusted = false; _target = null; _type = type; _bubbles = bubbles; _cancelable = cancelable; } } internal bool Dispatch(IEventTarget target) { _flags |= EventFlags.Dispatch; _target = target; List list = new List(); Node node = target as Node; if (node != null) { while ((node = node.Parent) != null) { bool isRootOfClosedTree = false; bool isSlotInClosedTree = false; bool isInvocationTargetInShadowTree = false; if (node is IElement element && element.GetRoot() is IShadowRoot shadowRoot) { isInvocationTargetInShadowTree = true; if (element.AssignedSlot != null && shadowRoot.Mode == ShadowRootMode.Closed) { isSlotInClosedTree = true; } } if (node is IShadowRoot { Mode: ShadowRootMode.Closed }) { isRootOfClosedTree = true; } list.Add(new EventPathItem { InvocationTarget = node, IsInvocationTargetInShadowTree = isInvocationTargetInShadowTree, IsSlotInClosedTree = isSlotInClosedTree, IsRootOfClosedTree = isRootOfClosedTree, RelatedTarget = null, ShadowAdjustedTarget = null }); } } _currentPath = list; _phase = EventPhase.Capturing; DispatchAt(Enumerable.Reverse(list)); _phase = EventPhase.AtTarget; if ((_flags & EventFlags.StopPropagation) != EventFlags.StopPropagation) { CallListeners(target); } if (_bubbles) { _phase = EventPhase.Bubbling; DispatchAt(list); } _flags &= ~EventFlags.Dispatch; _phase = EventPhase.None; _current = null; return (_flags & EventFlags.Canceled) == EventFlags.Canceled; } private void CallListeners(IEventTarget target) { _current = target; target.InvokeEventListener(this); } private void DispatchAt(IEnumerable path) { foreach (EventPathItem item in path) { CallListeners(item.InvocationTarget); if ((_flags & EventFlags.StopPropagation) == EventFlags.StopPropagation) { break; } } } } [DomName("Event")] public enum EventPhase : byte { [DomName("NONE")] None, [DomName("CAPTURING_PHASE")] Capturing, [DomName("AT_TARGET")] AtTarget, [DomName("BUBBLING_PHASE")] Bubbling } [DomName("FocusEvent")] public class FocusEvent : UiEvent { [DomName("relatedTarget")] public IEventTarget? Target { get; private set; } public FocusEvent() { } [DomConstructor] [DomInitDict(1, true)] public FocusEvent(string type, bool bubbles = false, bool cancelable = false, IWindow? view = null, int detail = 0, IEventTarget? target = null) { Init(type, bubbles, cancelable, view, detail, target); } [DomName("initFocusEvent")] public void Init(string type, bool bubbles, bool cancelable, IWindow? view, int detail, IEventTarget? target) { Init(type, bubbles, cancelable, view, detail); Target = target; } } [DomName("HashChangeEvent")] public class HashChangedEvent : Event { [DomName("oldURL")] public string PreviousUrl { get; private set; } [DomName("newURL")] public string CurrentUrl { get; private set; } public HashChangedEvent() { } [DomConstructor] [DomInitDict(1, true)] public HashChangedEvent(string type, bool bubbles = false, bool cancelable = false, string? oldURL = null, string? newURL = null) { Init(type, bubbles, cancelable, oldURL ?? string.Empty, newURL ?? string.Empty); } [DomName("initHashChangedEvent")] [MemberNotNull(new string[] { "PreviousUrl", "CurrentUrl" })] public void Init(string type, bool bubbles, bool cancelable, string previousUrl, string currentUrl) { Init(type, bubbles, cancelable); Stop(); PreviousUrl = previousUrl; CurrentUrl = currentUrl; } } public interface IEventFactory { Event? Create(string name); } [DomName("GlobalEventHandlers")] [DomNoInterfaceObject] public interface IGlobalEventHandlers { [DomName("onabort")] event DomEventHandler Aborted; [DomName("onblur")] event DomEventHandler Blurred; [DomName("oncancel")] event DomEventHandler Cancelled; [DomName("oncanplay")] event DomEventHandler CanPlay; [DomName("oncanplaythrough")] event DomEventHandler CanPlayThrough; [DomName("onchange")] event DomEventHandler Changed; [DomName("onclick")] event DomEventHandler Clicked; [DomName("oncuechange")] event DomEventHandler CueChanged; [DomName("ondblclick")] event DomEventHandler DoubleClick; [DomName("ondrag")] event DomEventHandler Drag; [DomName("ondragend")] event DomEventHandler DragEnd; [DomName("ondragenter")] event DomEventHandler DragEnter; [DomName("ondragexit")] event DomEventHandler DragExit; [DomName("ondragleave")] event DomEventHandler DragLeave; [DomName("ondragover")] event DomEventHandler DragOver; [DomName("ondragstart")] event DomEventHandler DragStart; [DomName("ondrop")] event DomEventHandler Dropped; [DomName("ondurationchange")] event DomEventHandler DurationChanged; [DomName("onemptied")] event DomEventHandler Emptied; [DomName("onended")] event DomEventHandler Ended; [DomName("onerror")] event DomEventHandler Error; [DomName("onfocus")] event DomEventHandler Focused; [DomName("oninput")] event DomEventHandler Input; [DomName("oninvalid")] event DomEventHandler Invalid; [DomName("onkeydown")] event DomEventHandler KeyDown; [DomName("onkeypress")] event DomEventHandler KeyPress; [DomName("onkeyup")] event DomEventHandler KeyUp; [DomName("onload")] event DomEventHandler Loaded; [DomName("onloadeddata")] event DomEventHandler LoadedData; [DomName("onloadedmetadata")] event DomEventHandler LoadedMetadata; [DomName("onloadstart")] event DomEventHandler Loading; [DomName("onmousedown")] event DomEventHandler MouseDown; [DomLenientThis] [DomName("onmouseenter")] event DomEventHandler MouseEnter; [DomLenientThis] [DomName("onmouseleave")] event DomEventHandler MouseLeave; [DomName("onmousemove")] event DomEventHandler MouseMove; [DomName("onmouseout")] event DomEventHandler MouseOut; [DomName("onmouseover")] event DomEventHandler MouseOver; [DomName("onmouseup")] event DomEventHandler MouseUp; [DomName("onmousewheel")] event DomEventHandler MouseWheel; [DomName("onpause")] event DomEventHandler Paused; [DomName("onplay")] event DomEventHandler Played; [DomName("onplaying")] event DomEventHandler Playing; [DomName("onprogress")] event DomEventHandler Progress; [DomName("onratechange")] event DomEventHandler RateChanged; [DomName("onreset")] event DomEventHandler Resetted; [DomName("onresize")] event DomEventHandler Resized; [DomName("onscroll")] event DomEventHandler Scrolled; [DomName("onseeked")] event DomEventHandler Seeked; [DomName("onseeking")] event DomEventHandler Seeking; [DomName("onselect")] event DomEventHandler Selected; [DomName("onshow")] event DomEventHandler Shown; [DomName("onstalled")] event DomEventHandler Stalled; [DomName("onsubmit")] event DomEventHandler Submitted; [DomName("onsuspend")] event DomEventHandler Suspended; [DomName("ontimeupdate")] event DomEventHandler TimeUpdated; [DomName("ontoggle")] event DomEventHandler Toggled; [DomName("onvolumechange")] event DomEventHandler VolumeChanged; [DomName("onwaiting")] event DomEventHandler Waiting; } [DomName("MessagePort")] public interface IMessagePort : IEventTarget { [DomName("onmessage")] event DomEventHandler MessageReceived; [DomName("postMessage")] void Send(object message); [DomName("start")] void Open(); [DomName("close")] void Close(); } [DomName("WindowEventHandlers")] [DomNoInterfaceObject] public interface IWindowEventHandlers { [DomName("onafterprint")] event DomEventHandler Printed; [DomName("onbeforeprint")] event DomEventHandler Printing; [DomName("onbeforeunload")] event DomEventHandler Unloading; [DomName("onhashchange")] event DomEventHandler HashChanged; [DomName("onmessage")] event DomEventHandler MessageReceived; [DomName("onoffline")] event DomEventHandler WentOffline; [DomName("ononline")] event DomEventHandler WentOnline; [DomName("onpagehide")] event DomEventHandler PageHidden; [DomName("onpageshow")] event DomEventHandler PageShown; [DomName("onpopstate")] event DomEventHandler PopState; [DomName("onstorage")] event DomEventHandler Storage; [DomName("onunload")] event DomEventHandler Unloaded; } [DomName("MessageEvent")] public class MessageEvent : Event { [DomName("data")] public object? Data { get; private set; } [DomName("origin")] public string Origin { get; private set; } [DomName("lastEventId")] public string LastEventId { get; private set; } [DomName("source")] public IWindow? Source { get; private set; } [DomName("ports")] public IMessagePort[] Ports { get; private set; } public MessageEvent() { } [DomConstructor] [DomInitDict(1, true)] public MessageEvent(string type, bool bubbles = false, bool cancelable = false, object? data = null, string? origin = null, string? lastEventId = null, IWindow? source = null, params IMessagePort[] ports) { Init(type, bubbles, cancelable, data, origin ?? string.Empty, lastEventId ?? string.Empty, source, ports); } [DomName("initMessageEvent")] [MemberNotNull(new string[] { "Origin", "LastEventId", "Ports" })] public void Init(string type, bool bubbles, bool cancelable, object? data, string origin, string lastEventId, IWindow? source, params IMessagePort[] ports) { Init(type, bubbles, cancelable); Data = data; Origin = origin; LastEventId = lastEventId; Source = source; Ports = ports; } } [DomName("PageTransitionEvent")] public class PageTransitionEvent : Event { [DomName("persisted")] public bool IsPersisted { get; private set; } public PageTransitionEvent() { } [DomConstructor] [DomInitDict(1, true)] public PageTransitionEvent(string type, bool bubbles = false, bool cancelable = false, bool persisted = false) { Init(type, bubbles, cancelable, persisted); } [DomName("initPageTransitionEvent")] public void Init(string type, bool bubbles, bool cancelable, bool persisted) { Init(type, bubbles, cancelable); IsPersisted = persisted; } } public class RequestEvent : Event { public Request Request { get; } public IResponse? Response { get; } public RequestEvent(Request request, IResponse? response) : base((response != null) ? EventNames.Requested : EventNames.Requesting) { Response = response; Request = request; } } [DomName("UIEvent")] public class UiEvent : Event { [DomName("view")] public IWindow? View { get; private set; } [DomName("detail")] public int Detail { get; private set; } public UiEvent() { } [DomConstructor] [DomInitDict(1, true)] public UiEvent(string type, bool bubbles = false, bool cancelable = false, IWindow? view = null, int detail = 0) { Init(type, bubbles, cancelable, view, detail); } [DomName("initUIEvent")] public void Init(string type, bool bubbles, bool cancelable, IWindow? view, int detail) { Init(type, bubbles, cancelable); View = view; Detail = detail; } } } namespace AngleSharp.Css { public static class CombinatorSymbols { public static readonly string Exactly = "="; public static readonly string Unlike = "!="; public static readonly string InList = "~="; public static readonly string InToken = "|="; public static readonly string Begins = "^="; public static readonly string Ends = "$="; public static readonly string InText = "*="; public static readonly string Column = "||"; public static readonly string Pipe = "|"; public static readonly string Adjacent = "+"; [Obsolete("Use CombinatorSymbols.Descendant")] public static readonly string Descendent = " "; public static readonly string Descendant = " "; public static readonly string Deep = ">>>"; public static readonly string Child = ">"; public static readonly string Sibling = "~"; } public sealed class CssStyleFormatter : IStyleFormatter { public static readonly IStyleFormatter Instance = new CssStyleFormatter(); string IStyleFormatter.Sheet(IEnumerable rules) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); string newLine = Environment.NewLine; using (StringWriter stringWriter = new StringWriter(stringBuilder)) { foreach (IStyleFormattable rule in rules) { rule.ToCss(stringWriter, this); stringWriter.Write(newLine); } if (stringBuilder.Length > 0) { stringBuilder.Remove(stringBuilder.Length - newLine.Length, newLine.Length); } } return stringBuilder.ToPool(); } string IStyleFormatter.BlockRules(IEnumerable rules) { StringBuilder stringBuilder = StringBuilderPool.Obtain().Append('{'); using (StringWriter stringWriter = new StringWriter(stringBuilder)) { foreach (IStyleFormattable rule in rules) { stringWriter.Write(' '); rule.ToCss(stringWriter, this); } } return stringBuilder.Append(' ').Append('}').ToPool(); } string IStyleFormatter.Declaration(string name, string value, bool important) { return string.Concat(name, ": ", value + (important ? " !important" : string.Empty)); } string IStyleFormatter.BlockDeclarations(IEnumerable declarations) { StringBuilder stringBuilder = StringBuilderPool.Obtain().Append('{'); using (StringWriter stringWriter = new StringWriter(stringBuilder)) { foreach (IStyleFormattable declaration in declarations) { stringWriter.Write(' '); declaration.ToCss(stringWriter, this); stringWriter.Write(';'); } if (stringBuilder.Length > 1) { stringBuilder.Remove(stringBuilder.Length - 1, 1); } } return stringBuilder.Append(' ').Append('}').ToPool(); } string IStyleFormatter.Rule(string name, string value) { return name + " " + value + ";"; } string IStyleFormatter.Rule(string name, string prelude, string rules) { return name + " " + (string.IsNullOrEmpty(prelude) ? string.Empty : (prelude + " ")) + rules; } string IStyleFormatter.Comment(string data) { return string.Join("/*", data, "*/"); } } public static class CssUtilities { public static string Escape(string text) { if (!string.IsNullOrEmpty(text)) { int length = text.Length; int num = -1; StringBuilder stringBuilder = StringBuilderPool.Obtain(); int num2 = text[0]; while (++num < length) { int num3 = text[num]; switch (num3) { case 0: stringBuilder.Append('\ufffd'); continue; default: if (num3 != 127 && (num != 0 || num3 < 48 || num3 > 57) && (num != 1 || num3 < 48 || num3 > 57 || num2 != 45)) { break; } goto case 1; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: stringBuilder.Append('\\').Append(num3.ToString("X")).Append(' '); continue; } if (num == 0 && length == 1 && num3 == 45) { stringBuilder.Append('\\').Append(text[num]); continue; } if (num3 < 128) { switch (num3) { default: if ((num3 < 65 || num3 > 90) && (num3 < 97 || num3 > 122)) { stringBuilder.Append('\\').Append(char.ConvertFromUtf32(text[num])); continue; } break; case 45: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 95: break; } } stringBuilder.Append(text[num]); } return stringBuilder.ToPool(); } return text; } } public class DefaultAttributeSelectorFactory : IAttributeSelectorFactory { public delegate ISelector Creator(string name, string value, string? prefix, bool insensitive); private static readonly HashSet insensitiveAttributes = new HashSet { AttributeNames.Accept, AttributeNames.AcceptCharset, AttributeNames.Align, AttributeNames.Alink, AttributeNames.Axis, AttributeNames.BgColor, AttributeNames.Charset, AttributeNames.Checked, AttributeNames.Clear, AttributeNames.Codetype, AttributeNames.Color, AttributeNames.Compact, AttributeNames.Declare, AttributeNames.Defer, AttributeNames.Dir, AttributeNames.Direction, AttributeNames.Disabled, AttributeNames.Enctype, AttributeNames.Face, AttributeNames.Frame, AttributeNames.HrefLang, AttributeNames.HttpEquiv, AttributeNames.Lang, AttributeNames.Language, AttributeNames.Link, AttributeNames.Media, AttributeNames.Method, AttributeNames.Multiple, AttributeNames.NoHref, AttributeNames.NoResize, AttributeNames.NoShade, AttributeNames.NoWrap, AttributeNames.Readonly, AttributeNames.Rel, AttributeNames.Rev, AttributeNames.Rules, AttributeNames.Scope, AttributeNames.Scrolling, AttributeNames.Selected, AttributeNames.Shape, AttributeNames.Target, AttributeNames.Text, AttributeNames.Type, AttributeNames.Valign, AttributeNames.ValueType, AttributeNames.Vlink }; private readonly Dictionary _creators = new Dictionary { { CombinatorSymbols.Exactly, (string name, string value, string? prefix, bool mode) => new AttrMatchSelector(name, value, prefix, mode) }, { CombinatorSymbols.InList, (string name, string value, string? prefix, bool mode) => new AttrInListSelector(name, value, prefix, mode) }, { CombinatorSymbols.InToken, (string name, string value, string? prefix, bool mode) => new AttrInTokenSelector(name, value, prefix, mode) }, { CombinatorSymbols.Begins, (string name, string value, string? prefix, bool mode) => new AttrStartsWithSelector(name, value, prefix, mode) }, { CombinatorSymbols.Ends, (string name, string value, string? prefix, bool mode) => new AttrEndsWithSelector(name, value, prefix, mode) }, { CombinatorSymbols.InText, (string name, string value, string? prefix, bool mode) => new AttrContainsSelector(name, value, prefix, mode) }, { CombinatorSymbols.Unlike, (string name, string value, string? prefix, bool mode) => new AttrNotMatchSelector(name, value, prefix, mode) } }; public void Register(string combinator, Creator creator) { _creators.Add(combinator, creator); } public Creator? Unregister(string combinator) { if (_creators.TryGetValue(combinator, out Creator value)) { _creators.Remove(combinator); } return value; } protected virtual ISelector CreateDefault(string name, string value, string? prefix, bool insensitive) { return new AttrAvailableSelector(name, prefix); } public ISelector Create(string combinator, string name, string value, string? prefix, bool insensitive) { if (!insensitive && insensitiveAttributes.Contains(name)) { insensitive = true; } if (_creators.TryGetValue(combinator, out Creator value2)) { return value2(name, value, prefix, insensitive); } if (combinator == "&") { return NestedSelector.Instance; } return CreateDefault(name, value, prefix, insensitive); } } public class DefaultPseudoClassSelectorFactory : IPseudoClassSelectorFactory { private readonly Dictionary _selectors = new Dictionary(StringComparer.OrdinalIgnoreCase) { { PseudoClassNames.Root, new PseudoClassSelector((IElement el) => el.Owner.DocumentElement == el, PseudoClassNames.Root) }, { PseudoClassNames.Scope, ScopePseudoClassSelector.Instance }, { PseudoClassNames.OnlyType, new PseudoClassSelector((IElement el) => el.IsOnlyOfType(), PseudoClassNames.OnlyType) }, { PseudoClassNames.FirstOfType, new PseudoClassSelector((IElement el) => el.IsFirstOfType(), PseudoClassNames.FirstOfType) }, { PseudoClassNames.LastOfType, new PseudoClassSelector((IElement el) => el.IsLastOfType(), PseudoClassNames.LastOfType) }, { PseudoClassNames.OnlyChild, new PseudoClassSelector((IElement el) => el.IsOnlyChild(), PseudoClassNames.OnlyChild) }, { PseudoClassNames.FirstChild, new PseudoClassSelector((IElement el) => el.IsFirstChild(), PseudoClassNames.FirstChild) }, { PseudoClassNames.LastChild, new PseudoClassSelector((IElement el) => el.IsLastChild(), PseudoClassNames.LastChild) }, { PseudoClassNames.Empty, new PseudoClassSelector((IElement el) => el.ChildElementCount == 0 && el.TextContent.Is(string.Empty), PseudoClassNames.Empty) }, { PseudoClassNames.AnyLink, new PseudoClassSelector((IElement el) => el.IsLink() || el.IsVisited(), PseudoClassNames.AnyLink) }, { PseudoClassNames.Link, new PseudoClassSelector((IElement el) => el.IsLink(), PseudoClassNames.Link) }, { PseudoClassNames.Visited, new PseudoClassSelector((IElement el) => el.IsVisited(), PseudoClassNames.Visited) }, { PseudoClassNames.Active, new PseudoClassSelector((IElement el) => el.IsActive(), PseudoClassNames.Active) }, { PseudoClassNames.Hover, new PseudoClassSelector((IElement el) => el.IsHovered(), PseudoClassNames.Hover) }, { PseudoClassNames.Focus, new PseudoClassSelector((IElement el) => el.IsFocused, PseudoClassNames.Focus) }, { PseudoClassNames.Target, new PseudoClassSelector((IElement el) => el.IsTarget(), PseudoClassNames.Target) }, { PseudoClassNames.Enabled, new PseudoClassSelector((IElement el) => el.IsEnabled(), PseudoClassNames.Enabled) }, { PseudoClassNames.Disabled, new PseudoClassSelector((IElement el) => el.IsDisabled(), PseudoClassNames.Disabled) }, { PseudoClassNames.Default, new PseudoClassSelector((IElement el) => el.IsDefault(), PseudoClassNames.Default) }, { PseudoClassNames.Checked, new PseudoClassSelector((IElement el) => el.IsChecked(), PseudoClassNames.Checked) }, { PseudoClassNames.Indeterminate, new PseudoClassSelector((IElement el) => el.IsIndeterminate(), PseudoClassNames.Indeterminate) }, { PseudoClassNames.PlaceholderShown, new PseudoClassSelector((IElement el) => el.IsPlaceholderShown(), PseudoClassNames.PlaceholderShown) }, { PseudoClassNames.Unchecked, new PseudoClassSelector((IElement el) => el.IsUnchecked(), PseudoClassNames.Unchecked) }, { PseudoClassNames.Valid, new PseudoClassSelector((IElement el) => el.IsValid(), PseudoClassNames.Valid) }, { PseudoClassNames.Invalid, new PseudoClassSelector((IElement el) => el.IsInvalid(), PseudoClassNames.Invalid) }, { PseudoClassNames.Required, new PseudoClassSelector((IElement el) => el.IsRequired(), PseudoClassNames.Required) }, { PseudoClassNames.ReadOnly, new PseudoClassSelector((IElement el) => el.IsReadOnly(), PseudoClassNames.ReadOnly) }, { PseudoClassNames.ReadWrite, new PseudoClassSelector((IElement el) => el.IsEditable(), PseudoClassNames.ReadWrite) }, { PseudoClassNames.InRange, new PseudoClassSelector((IElement el) => el.IsInRange(), PseudoClassNames.InRange) }, { PseudoClassNames.OutOfRange, new PseudoClassSelector((IElement el) => el.IsOutOfRange(), PseudoClassNames.OutOfRange) }, { PseudoClassNames.Optional, new PseudoClassSelector((IElement el) => el.IsOptional(), PseudoClassNames.Optional) }, { PseudoClassNames.FocusVisible, new PseudoClassSelector((IElement el) => el.IsFocused && el.IsVisible(), PseudoClassNames.FocusVisible) }, { PseudoClassNames.FocusWithin, new PseudoClassSelector((IElement el) => el.GetDescendantsAndSelf().OfType().Any((IElement m) => m.IsFocused), PseudoClassNames.FocusWithin) }, { PseudoClassNames.Shadow, new PseudoClassSelector((IElement el) => el.IsShadow(), PseudoClassNames.Shadow) }, { PseudoElementNames.Before, new PseudoClassSelector((IElement el) => el.IsPseudo(PseudoElementNames.Before), PseudoElementNames.Before) }, { PseudoElementNames.After, new PseudoClassSelector((IElement el) => el.IsPseudo(PseudoElementNames.After), PseudoElementNames.After) }, { PseudoElementNames.FirstLine, new PseudoClassSelector((IElement el) => el.HasChildNodes && el.ChildNodes[0].NodeType == NodeType.Text, PseudoElementNames.FirstLine) }, { PseudoElementNames.FirstLetter, new PseudoClassSelector((IElement el) => el.HasChildNodes && el.ChildNodes[0].NodeType == NodeType.Text && el.ChildNodes[0].TextContent.Length > 0, PseudoElementNames.FirstLetter) } }; public void Register(string name, ISelector selector) { _selectors.Add(name, selector); } public ISelector? Unregister(string name) { if (_selectors.TryGetValue(name, out ISelector value)) { _selectors.Remove(name); } return value; } protected virtual ISelector? CreateDefault(string name) { return null; } public ISelector? Create(string name) { if (_selectors.TryGetValue(name, out ISelector value)) { return value; } return CreateDefault(name); } } public class DefaultPseudoElementSelectorFactory : IPseudoElementSelectorFactory { private readonly Dictionary _selectors = new Dictionary(StringComparer.OrdinalIgnoreCase) { { PseudoElementNames.Before, new PseudoElementSelector((IElement el) => el.IsPseudo(PseudoElementNames.Before), PseudoElementNames.Before) }, { PseudoElementNames.After, new PseudoElementSelector((IElement el) => el.IsPseudo(PseudoElementNames.After), PseudoElementNames.After) }, { PseudoElementNames.Selection, new PseudoElementSelector((IElement _) => false, PseudoElementNames.Selection) }, { PseudoElementNames.FootnoteCall, new PseudoElementSelector((IElement _) => false, PseudoElementNames.FootnoteCall) }, { PseudoElementNames.FootnoteMarker, new PseudoElementSelector((IElement _) => false, PseudoElementNames.FootnoteMarker) }, { PseudoElementNames.FirstLine, new PseudoElementSelector((IElement el) => el.HasChildNodes && el.ChildNodes[0].NodeType == NodeType.Text, PseudoElementNames.FirstLine) }, { PseudoElementNames.FirstLetter, new PseudoElementSelector((IElement el) => el.HasChildNodes && el.ChildNodes[0].NodeType == NodeType.Text && el.ChildNodes[0].TextContent.Length > 0, PseudoElementNames.FirstLetter) }, { PseudoElementNames.Content, new PseudoElementSelector((IElement _) => false, PseudoElementNames.Content) } }; public void Register(string name, ISelector selector) { _selectors.Add(name, selector); } public ISelector? Unregister(string name) { if (_selectors.TryGetValue(name, out ISelector value)) { _selectors.Remove(name); } return value; } protected virtual ISelector CreateDefault(string name) { return null; } public ISelector Create(string name) { if (_selectors.TryGetValue(name, out ISelector value)) { return value; } return CreateDefault(name); } } public interface IAttributeSelectorFactory { ISelector Create(string combinator, string name, string value, string? prefix, bool insensitive); } public interface IPseudoClassSelectorFactory { ISelector? Create(string name); } public interface IPseudoElementSelectorFactory { ISelector Create(string name); } public interface ISelectorVisitor { void Attribute(string name, string op, string? value); void Type(string name); void Id(string value); void Child(string name, int step, int offset, ISelector selector); void Class(string name); void PseudoClass(string name); void PseudoElement(string name); void List(IEnumerable selectors); void Combinator(IEnumerable selectors, IEnumerable symbols); void Many(IEnumerable selectors); } public interface IStylingService { bool SupportsType(string mimeType); Task ParseStylesheetAsync(IResponse response, StyleOptions options, CancellationToken cancel); } [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 1)] public readonly struct Priority : IEquatable, IComparable { [FieldOffset(0)] private readonly byte _tags; [FieldOffset(1)] private readonly byte _classes; [FieldOffset(2)] private readonly byte _ids; [FieldOffset(3)] private readonly byte _inlines; [FieldOffset(0)] private readonly uint _priority; public static readonly Priority Zero = new Priority(0u); public static readonly Priority OneTag = new Priority(0, 0, 0, 1); public static readonly Priority OneClass = new Priority(0, 0, 1, 0); public static readonly Priority OneId = new Priority(0, 1, 0, 0); public static readonly Priority Inline = new Priority(1, 0, 0, 0); public byte Tags => _tags; public byte Classes => _classes; public byte Ids => _ids; public byte Inlines => _inlines; public Priority(uint priority) { _inlines = (_ids = (_classes = (_tags = 0))); _priority = priority; } public Priority(byte inlines, byte ids, byte classes, byte tags) { _priority = 0u; _inlines = inlines; _ids = ids; _classes = classes; _tags = tags; } public static Priority operator +(Priority a, Priority b) { return new Priority(a._priority + b._priority); } public static bool operator ==(Priority a, Priority b) { return a._priority == b._priority; } public static bool operator >(Priority a, Priority b) { return a._priority > b._priority; } public static bool operator >=(Priority a, Priority b) { return a._priority >= b._priority; } public static bool operator <(Priority a, Priority b) { return a._priority < b._priority; } public static bool operator <=(Priority a, Priority b) { return a._priority <= b._priority; } public static bool operator !=(Priority a, Priority b) { return a._priority != b._priority; } public bool Equals(Priority other) { return _priority == other._priority; } public override bool Equals(object? obj) { if (obj is Priority other) { return Equals(other); } return false; } public override int GetHashCode() { return (int)_priority; } public int CompareTo(Priority other) { if (!(this == other)) { if (!(this > other)) { return -1; } return 1; } return 0; } public override string ToString() { return $"({_inlines}, {_ids}, {_classes}, {_tags})"; } } public static class PseudoClassNames { public static readonly string Root = "root"; public static readonly string Scope = "scope"; public static readonly string OnlyType = "only-of-type"; public static readonly string FirstOfType = "first-of-type"; public static readonly string LastOfType = "last-of-type"; public static readonly string OnlyChild = "only-child"; public static readonly string FirstChild = "first-child"; public static readonly string LastChild = "last-child"; public static readonly string Empty = "empty"; public static readonly string AnyLink = "any-link"; public static readonly string Link = "link"; public static readonly string Visited = "visited"; public static readonly string Active = "active"; public static readonly string Hover = "hover"; public static readonly string Focus = "focus"; public static readonly string Target = "target"; public static readonly string Enabled = "enabled"; public static readonly string Disabled = "disabled"; public static readonly string Checked = "checked"; public static readonly string Unchecked = "unchecked"; public static readonly string Indeterminate = "indeterminate"; public static readonly string PlaceholderShown = "placeholder-shown"; public static readonly string Default = "default"; public static readonly string Valid = "valid"; public static readonly string Invalid = "invalid"; public static readonly string Required = "required"; public static readonly string InRange = "in-range"; public static readonly string OutOfRange = "out-of-range"; public static readonly string Optional = "optional"; public static readonly string ReadOnly = "read-only"; public static readonly string ReadWrite = "read-write"; public static readonly string Shadow = "shadow"; public static readonly string Dir = "dir"; public static readonly string Has = "has"; public static readonly string Is = "is"; public static readonly string Matches = "matches"; public static readonly string NthChild = "nth-child"; public static readonly string NthLastChild = "nth-last-child"; public static readonly string NthOfType = "nth-of-type"; public static readonly string NthLastOfType = "nth-last-of-type"; public static readonly string NthColumn = "nth-column"; public static readonly string NthLastColumn = "nth-last-column"; public static readonly string Not = "not"; public static readonly string Lang = "lang"; public static readonly string Contains = "contains"; public static readonly string Where = "where"; public static readonly string HostContext = "host-context"; public static readonly string FocusVisible = "focus-visible"; public static readonly string FocusWithin = "focus-within"; public static readonly string Separator = ":"; } public static class PseudoElementNames { public static readonly string Before = "before"; public static readonly string After = "after"; public static readonly string Slotted = "slotted"; public static readonly string Selection = "selection"; public static readonly string FirstLine = "first-line"; public static readonly string FirstLetter = "first-letter"; public static readonly string FootnoteCall = "footnote-call"; public static readonly string FootnoteMarker = "footnote-marker"; public static readonly string Content = "content"; public static readonly string Separator = "::"; } public sealed class StyleOptions { public IDocument Document { get; } public IElement? Element { get; set; } public bool IsDisabled { get; set; } public bool IsAlternate { get; set; } public StyleOptions(IDocument document) { Document = document; } } } namespace AngleSharp.Css.Parser { internal abstract class CssCombinator { private sealed class ChildCombinator : CssCombinator { public ChildCombinator() { base.Delimiter = CombinatorSymbols.Child; base.Transform = (IElement el) => Single(el.ParentElement); } } private sealed class DeepCombinator : CssCombinator { public DeepCombinator() { base.Delimiter = CombinatorSymbols.Deep; base.Transform = (IElement el) => Single((el.Parent is IShadowRoot shadowRoot) ? shadowRoot.Host : null); } } private sealed class DescendantCombinator : CssCombinator { public DescendantCombinator() { base.Delimiter = CombinatorSymbols.Descendant; base.Transform = delegate(IElement el) { List list = new List(); for (IElement parentElement = el.ParentElement; parentElement != null; parentElement = parentElement.ParentElement) { list.Add(parentElement); } return list; }; } } private sealed class AdjacentSiblingCombinator : CssCombinator { public AdjacentSiblingCombinator() { base.Delimiter = CombinatorSymbols.Adjacent; base.Transform = (IElement el) => Single(el.PreviousElementSibling); } } private sealed class SiblingCombinator : CssCombinator { public SiblingCombinator() { base.Delimiter = CombinatorSymbols.Sibling; base.Transform = delegate(IElement el) { IElement parentElement = el.ParentElement; if (parentElement != null) { List list = new List(); foreach (INode childNode in parentElement.ChildNodes) { if (childNode is IElement element) { if (element == el) { break; } list.Add(element); } } return list; } return Array.Empty(); }; } } private sealed class NamespaceCombinator : CssCombinator { public NamespaceCombinator() { base.Delimiter = CombinatorSymbols.Pipe; base.Transform = Single; } public override ISelector Change(ISelector selector) { string prefix = ((!(selector is TypeSelector typeSelector)) ? selector.Text : typeSelector.TypeName); return new NamespaceSelector(prefix); } } private sealed class ColumnCombinator : CssCombinator { public ColumnCombinator() { base.Delimiter = CombinatorSymbols.Column; } } public static readonly CssCombinator Child = new ChildCombinator(); public static readonly CssCombinator Deep = new DeepCombinator(); public static readonly CssCombinator Descendant = new DescendantCombinator(); public static readonly CssCombinator AdjacentSibling = new AdjacentSiblingCombinator(); public static readonly CssCombinator Sibling = new SiblingCombinator(); public static readonly CssCombinator Namespace = new NamespaceCombinator(); public static readonly CssCombinator Column = new ColumnCombinator(); public Func>? Transform { get; protected set; } public string? Delimiter { get; protected set; } public virtual ISelector Change(ISelector selector) { return selector; } protected static IEnumerable Single(IElement? element) { if (element != null) { yield return element; } } } internal sealed class CssSelectorConstructor { private enum State : byte { Data, Function, Attribute, AttributeOperator, AttributeValue, AttributeEnd, PseudoClass, PseudoElement } private abstract class FunctionState { public bool Finished(CssSelectorToken token) { return OnToken(token); } public abstract ISelector? Produce(); protected abstract bool OnToken(CssSelectorToken token); protected Priority ResolveMostSpecificParameter(ISelector parameter) { if (!(parameter is ListSelector source)) { return parameter.Specificity; } return source.Max((ISelector x) => x.Specificity); } } private sealed class NotFunctionState : FunctionState { private readonly CssSelectorConstructor _selector; public NotFunctionState(CssSelectorConstructor parent) { _selector = parent.CreateChild(forgiving: false); _selector._nested = true; } protected override bool OnToken(CssSelectorToken token) { if (token.Type != CssTokenType.RoundBracketClose || _selector._state != State.Data) { _selector.Apply(token); return false; } return true; } public override ISelector? Produce() { bool isValid = _selector.IsValid; ISelector sel = _selector.GetResult(); if (isValid) { string pseudoClass = PseudoClassNames.Not.CssFunction(sel.Text); Priority specificity = ResolveMostSpecificParameter(sel); return new PseudoClassSelector((IElement el) => !sel.Match(el), pseudoClass, specificity); } return null; } } private sealed class HasFunctionState : FunctionState { private readonly CssSelectorConstructor _nested = parent.CreateChild(forgiving: false); private bool _firstToken = true; private bool _matchSiblings; public HasFunctionState(CssSelectorConstructor parent) { } protected override bool OnToken(CssSelectorToken token) { if (token.Type != CssTokenType.RoundBracketClose || _nested._state != State.Data) { if (_firstToken && token.Type == CssTokenType.Delim) { _nested.Insert(ScopePseudoClassSelector.Instance); _nested.Apply(CssSelectorToken.Whitespace); _matchSiblings = true; } _firstToken = false; _nested.Apply(token); return false; } return true; } public override ISelector? Produce() { bool isValid = _nested.IsValid; ISelector sel = _nested.GetResult(); string text = sel.Text; bool matchSiblings = _matchSiblings || text.Contains(":" + PseudoClassNames.Scope); if (isValid) { string pseudoClass = PseudoClassNames.Has.CssFunction(text); Priority specificity = ResolveMostSpecificParameter(sel); return new PseudoClassSelector(delegate(IElement el) { IEnumerable enumerable = null; enumerable = ((!matchSiblings) ? el.Children : el.ParentElement?.Children); if (enumerable == null) { enumerable = Array.Empty(); } return sel.MatchAny(enumerable, el) != null; }, pseudoClass, specificity); } return null; } } private abstract class BaseMatchingFunctionState : FunctionState { private readonly CssSelectorConstructor _selector = parent.CreateChild(forgiving: true); protected abstract string Name { get; } protected BaseMatchingFunctionState(CssSelectorConstructor parent) { } protected override bool OnToken(CssSelectorToken token) { if (token.Type != CssTokenType.RoundBracketClose || _selector._state != State.Data) { _selector.Apply(token); return false; } return true; } protected abstract Priority DecideSpecificity(ISelector innerSelector); public override ISelector? Produce() { bool isValid = _selector.IsValid; ISelector result = _selector.GetResult(); if (isValid) { string pseudoClass = Name.CssFunction(result.Text); Priority specificity = DecideSpecificity(result); return new PseudoClassSelector(result.Match, pseudoClass, specificity); } return null; } } private sealed class MatchesFunctionState : BaseMatchingFunctionState { protected override string Name => PseudoClassNames.Matches; public MatchesFunctionState(CssSelectorConstructor parent) : base(parent) { } protected override Priority DecideSpecificity(ISelector innerSelector) { return ResolveMostSpecificParameter(innerSelector); } } private sealed class IsFunctionState : BaseMatchingFunctionState { protected override string Name => PseudoClassNames.Is; public IsFunctionState(CssSelectorConstructor parent) : base(parent) { } protected override Priority DecideSpecificity(ISelector innerSelector) { return ResolveMostSpecificParameter(innerSelector); } } private sealed class WhereFunctionState : BaseMatchingFunctionState { protected override string Name => PseudoClassNames.Where; public WhereFunctionState(CssSelectorConstructor parent) : base(parent) { } protected override Priority DecideSpecificity(ISelector innerSelector) { return Priority.Zero; } } private sealed class DirFunctionState : FunctionState { private bool _valid; private string? _value; public DirFunctionState() { _valid = true; _value = null; } protected override bool OnToken(CssSelectorToken token) { if (token.Type == CssTokenType.Ident) { _value = token.Data; } else { if (token.Type == CssTokenType.RoundBracketClose) { return true; } if (token.Type != CssTokenType.Whitespace) { _valid = false; } } return false; } public override ISelector? Produce() { if (_valid && _value != null) { string pseudoClass = PseudoClassNames.Dir.CssFunction(_value); return new PseudoClassSelector((IElement el) => el is IHtmlElement htmlElement && _value.Isi(htmlElement.Direction), pseudoClass); } return null; } } private sealed class LangFunctionState : FunctionState { private bool valid; private string? value; public LangFunctionState() { valid = true; value = null; } protected override bool OnToken(CssSelectorToken token) { if (token.Type == CssTokenType.Ident) { value = token.Data; } else { if (token.Type == CssTokenType.RoundBracketClose) { return true; } if (token.Type != CssTokenType.Whitespace) { valid = false; } } return false; } public override ISelector? Produce() { if (valid && value != null) { string pseudoClass = PseudoClassNames.Lang.CssFunction(value); return new PseudoClassSelector((IElement el) => el is IHtmlElement htmlElement && htmlElement.Language.StartsWith(value, StringComparison.OrdinalIgnoreCase), pseudoClass); } return null; } } private sealed class ContainsFunctionState : FunctionState { private bool _valid; private string? _value; public ContainsFunctionState() { _valid = true; _value = null; } protected override bool OnToken(CssSelectorToken token) { if (token.Type == CssTokenType.Ident || token.Type == CssTokenType.String) { _value = token.Data; } else { if (token.Type == CssTokenType.RoundBracketClose) { return true; } if (token.Type != CssTokenType.Whitespace) { _valid = false; } } return false; } public override ISelector? Produce() { if (_valid && _value != null) { string pseudoClass = PseudoClassNames.Contains.CssFunction(_value); return new PseudoClassSelector((IElement el) => el.TextContent.Contains(_value), pseudoClass); } return null; } } private sealed class HostContextFunctionState : FunctionState { private readonly CssSelectorConstructor _selector = parent.CreateChild(forgiving: false); public HostContextFunctionState(CssSelectorConstructor parent) { } protected override bool OnToken(CssSelectorToken token) { if (token.Type != CssTokenType.RoundBracketClose || _selector._state != State.Data) { _selector.Apply(token); return false; } return true; } public override ISelector? Produce() { bool isValid = _selector.IsValid; ISelector sel = _selector.GetResult(); if (isValid) { string pseudoClass = PseudoClassNames.HostContext.CssFunction(sel.Text); return new PseudoClassSelector(delegate(IElement el) { for (IElement element = (el.Parent as IShadowRoot)?.Host; element != null; element = element.ParentElement) { if (sel.Match(element)) { return true; } } return false; }, pseudoClass); } return null; } } private sealed class ChildFunctionState : FunctionState { private enum ParseState : byte { Initial, AfterInitialSign, Offset, BeforeOf, AfterOf } private readonly CssSelectorConstructor _parent; private bool _valid; private int _step; private int _offset; private int _sign; private ParseState _state; private CssSelectorConstructor? _nested; private readonly bool _allowOf; private readonly Func _creator; public ChildFunctionState(Func creator, CssSelectorConstructor parent, bool withOptionalSelector = true) { _parent = parent; _valid = true; _sign = 1; _allowOf = withOptionalSelector; _creator = creator; base..ctor(); } public override ISelector? Produce() { if (_valid && (_nested == null || _nested.IsValid)) { ISelector arg = _nested?.GetResult() ?? AllSelector.Instance; return _creator(_step, _offset, arg); } return null; } protected override bool OnToken(CssSelectorToken token) { return _state switch { ParseState.Initial => OnInitial(token), ParseState.AfterInitialSign => OnAfterInitialSign(token), ParseState.Offset => OnOffset(token), ParseState.BeforeOf => OnBeforeOf(token), _ => OnAfter(token), }; } private bool OnAfterInitialSign(CssSelectorToken token) { if (token.Type == CssTokenType.Number) { return OnOffset(token); } if (token.Type == CssTokenType.Dimension) { string s = token.Data.Remove(token.Data.Length - 1); _valid = _valid && token.Data.EndsWith("n", StringComparison.OrdinalIgnoreCase) && int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out _step); _step *= _sign; _sign = 1; _state = ParseState.Offset; return false; } if (token.Type == CssTokenType.Ident && token.Data.Isi("n")) { _step = _sign; _sign = 1; _state = ParseState.Offset; return false; } if (_state == ParseState.Initial && token.Type == CssTokenType.Ident && token.Data.Isi("-n")) { _step = -1; _state = ParseState.Offset; return false; } _valid = false; return token.Type == CssTokenType.RoundBracketClose; } private bool OnAfter(CssSelectorToken token) { if (token.Type != CssTokenType.RoundBracketClose || _nested._state != State.Data) { _nested.Apply(token); return false; } return true; } private bool OnBeforeOf(CssSelectorToken token) { if (token.Type == CssTokenType.Whitespace) { return false; } if (token.Data.Isi(Keywords.Of)) { _valid = _allowOf; _state = ParseState.AfterOf; _nested = _parent.CreateChild(forgiving: false); return false; } if (token.Type == CssTokenType.RoundBracketClose) { return true; } _valid = false; return false; } private bool OnOffset(CssSelectorToken token) { if (token.Type == CssTokenType.Whitespace) { return false; } if (token.Type == CssTokenType.Number) { _valid = _valid && int.TryParse(token.Data, NumberStyles.Integer, CultureInfo.InvariantCulture, out _offset); _offset *= _sign; _state = ParseState.BeforeOf; return false; } return OnBeforeOf(token); } private bool OnInitial(CssSelectorToken token) { if (token.Type == CssTokenType.Whitespace) { return false; } if (token.Data.Isi(Keywords.Odd)) { _state = ParseState.BeforeOf; _step = 2; _offset = 1; return false; } if (token.Data.Isi(Keywords.Even)) { _state = ParseState.BeforeOf; _step = 2; _offset = 0; return false; } if (token.Type == CssTokenType.Delim && token.Data.IsOneOf("+", "-")) { _sign = ((!(token.Data == "-")) ? 1 : (-1)); _state = ParseState.AfterInitialSign; return false; } return OnAfterInitialSign(token); } } private static readonly Dictionary> pseudoClassFunctions = new Dictionary>(StringComparer.OrdinalIgnoreCase) { { PseudoClassNames.NthChild, (CssSelectorConstructor ctx) => new ChildFunctionState((int step, int offset, ISelector kind) => new FirstChildSelector(step, offset, kind), ctx) }, { PseudoClassNames.NthLastChild, (CssSelectorConstructor ctx) => new ChildFunctionState((int step, int offset, ISelector kind) => new LastChildSelector(step, offset, kind), ctx) }, { PseudoClassNames.NthOfType, (CssSelectorConstructor ctx) => new ChildFunctionState((int step, int offset, ISelector kind) => new FirstTypeSelector(step, offset, kind), ctx, withOptionalSelector: false) }, { PseudoClassNames.NthLastOfType, (CssSelectorConstructor ctx) => new ChildFunctionState((int step, int offset, ISelector kind) => new LastTypeSelector(step, offset, kind), ctx, withOptionalSelector: false) }, { PseudoClassNames.NthColumn, (CssSelectorConstructor ctx) => new ChildFunctionState((int step, int offset, ISelector kind) => new FirstColumnSelector(step, offset, kind), ctx, withOptionalSelector: false) }, { PseudoClassNames.NthLastColumn, (CssSelectorConstructor ctx) => new ChildFunctionState((int step, int offset, ISelector kind) => new LastColumnSelector(step, offset, kind), ctx, withOptionalSelector: false) }, { PseudoClassNames.Not, (CssSelectorConstructor ctx) => new NotFunctionState(ctx) }, { PseudoClassNames.Dir, (CssSelectorConstructor _) => new DirFunctionState() }, { PseudoClassNames.Lang, (CssSelectorConstructor _) => new LangFunctionState() }, { PseudoClassNames.Contains, (CssSelectorConstructor _) => new ContainsFunctionState() }, { PseudoClassNames.Has, (CssSelectorConstructor ctx) => new HasFunctionState(ctx) }, { PseudoClassNames.Is, (CssSelectorConstructor ctx) => new IsFunctionState(ctx) }, { PseudoClassNames.Matches, (CssSelectorConstructor ctx) => new MatchesFunctionState(ctx) }, { PseudoClassNames.Where, (CssSelectorConstructor ctx) => new WhereFunctionState(ctx) }, { PseudoClassNames.HostContext, (CssSelectorConstructor ctx) => new HostContextFunctionState(ctx) } }; private readonly CssTokenizer _tokenizer; private readonly Stack _combinators; private readonly IAttributeSelectorFactory _attributeSelector; private readonly IPseudoElementSelectorFactory _pseudoElementSelector; private readonly IPseudoClassSelectorFactory _pseudoClassSelector; private State _state; private ISelector? _temp; private ListSelector? _group; private ComplexSelector? _complex; private string? _attrName; private string? _attrValue; private bool _attrInsensitive; private string _attrOp; private string? _attrNs; private bool _valid; private bool _nested; private bool _ready; private FunctionState? _function; private bool _invoked; private bool _forgiving; public bool IsValid { get { if (_invoked && _valid) { return _ready; } return false; } } public bool IsNested => _nested; public CssSelectorConstructor(CssTokenizer tokenizer, IAttributeSelectorFactory attributeSelector, IPseudoClassSelectorFactory pseudoClassSelector, IPseudoElementSelectorFactory pseudoElementSelector, bool invoked = false, bool forgiving = false) { _tokenizer = tokenizer; _combinators = new Stack(); _attributeSelector = attributeSelector; _pseudoElementSelector = pseudoElementSelector; _pseudoClassSelector = pseudoClassSelector; _attrOp = string.Empty; _valid = true; _ready = true; _invoked = invoked; _forgiving = forgiving; base..ctor(); } public ISelector? Parse() { CssSelectorToken token = _tokenizer.Get(); while (token.Type != CssTokenType.EndOfFile) { Apply(token); token = _tokenizer.Get(); } return GetResult(); } private ISelector? GetResult() { if (IsValid) { if (_complex != null) { _complex.ConcludeSelector(_temp); _temp = _complex; _complex = null; } if (_group == null || _group.Length == 0) { return _temp ?? AllSelector.Instance; } if (_temp == null && _group.Length == 1) { return _group[0]; } if (_temp != null) { _group.Add(_temp); _temp = null; } return _group; } return null; } private void Apply(CssSelectorToken token) { _invoked = true; switch (_state) { case State.Data: OnData(token); break; case State.Attribute: OnAttribute(token); break; case State.AttributeOperator: OnAttributeOperator(token); break; case State.AttributeValue: OnAttributeValue(token); break; case State.AttributeEnd: OnAttributeEnd(token); break; case State.PseudoClass: OnPseudoClass(token); break; case State.PseudoElement: OnPseudoElement(token); break; case State.Function: OnFunctionState(token); break; default: _valid = false; break; } } private void OnData(CssSelectorToken token) { switch (token.Type) { case CssTokenType.SquareBracketOpen: _attrName = null; _attrValue = null; _attrOp = string.Empty; _attrNs = null; _state = State.Attribute; _ready = false; break; case CssTokenType.Colon: _state = State.PseudoClass; _ready = false; break; case CssTokenType.Hash: Insert(new IdSelector(token.Data)); _ready = true; break; case CssTokenType.Class: Insert(new ClassSelector(token.Data)); _ready = true; break; case CssTokenType.Ident: Insert(new TypeSelector(token.Data)); _ready = true; break; case CssTokenType.Whitespace: Insert(CssCombinator.Descendant); break; case CssTokenType.Delim: OnDelim(token); break; case CssTokenType.Comma: InsertOr(); _ready = false; break; case CssTokenType.Column: Insert(CssCombinator.Column); _ready = false; break; case CssTokenType.Descendant: Insert(CssCombinator.Descendant); _ready = false; break; case CssTokenType.Deep: Insert(CssCombinator.Deep); _ready = false; break; default: _valid = false; break; } } private void OnAttribute(CssSelectorToken token) { if (token.Type != CssTokenType.Whitespace) { if (token.Type == CssTokenType.Ident || token.Type == CssTokenType.String) { _state = State.AttributeOperator; _attrName = token.Data; } else if (token.Type == CssTokenType.Delim && token.Data.Is(CombinatorSymbols.Pipe)) { _state = State.Attribute; _attrNs = string.Empty; } else if (token.Type == CssTokenType.Delim && token.Data == "*") { _state = State.AttributeOperator; _attrName = "*"; } else { _state = State.Data; _valid = false; } } } private void OnAttributeOperator(CssSelectorToken token) { if (token.Type == CssTokenType.Whitespace) { return; } if (token.Type == CssTokenType.SquareBracketClose) { _state = State.AttributeValue; OnAttributeEnd(token); } else if (token.Type == CssTokenType.Match || token.Type == CssTokenType.Delim) { _state = State.AttributeValue; _attrOp = token.Data; if (_attrOp == CombinatorSymbols.Pipe) { _attrNs = _attrName; _attrName = null; _attrOp = string.Empty; _state = State.Attribute; } } else { _state = State.AttributeEnd; _valid = false; } } private void OnAttributeValue(CssSelectorToken token) { if (token.Type != CssTokenType.Whitespace) { CssTokenType type = token.Type; if ((type == CssTokenType.String || type == CssTokenType.Ident || type == CssTokenType.Number) ? true : false) { _state = State.AttributeEnd; _attrValue = token.Data; } else { _state = State.Data; _valid = false; } } } private void OnAttributeEnd(CssSelectorToken token) { if (!_attrInsensitive && token.Type == CssTokenType.Ident && token.Data == "i") { _attrInsensitive = true; } else if (token.Type != CssTokenType.Whitespace) { _state = State.Data; _ready = true; if (token.Type == CssTokenType.SquareBracketClose) { ISelector selector = _attributeSelector.Create(_attrOp, _attrName, _attrValue, _attrNs, _attrInsensitive); _attrInsensitive = false; Insert(selector); } else { _valid = false; } } } private void OnPseudoClass(CssSelectorToken token) { _state = State.Data; _ready = true; if (token.Type == CssTokenType.Colon) { _state = State.PseudoElement; return; } if (token.Type == CssTokenType.Function) { if (pseudoClassFunctions.TryGetValue(token.Data, out Func value)) { _state = State.Function; _function = value(this); _ready = false; return; } if (_forgiving) { return; } } else if (token.Type == CssTokenType.Ident) { ISelector selector = _pseudoClassSelector.Create(token.Data); if (selector != null) { Insert(selector); return; } if (_forgiving) { return; } } _valid = false; } private void OnPseudoElement(CssSelectorToken token) { _state = State.Data; _ready = true; if (token.Type == CssTokenType.Ident) { ISelector selector = _pseudoElementSelector.Create(token.Data); if (selector != null) { _valid = _valid && !_nested; Insert(selector); return; } } _valid = false; } private void InsertOr() { if (_temp != null) { if (_group == null) { _group = new ListSelector(); } if (_complex != null) { _complex.ConcludeSelector(_temp); _group.Add(_complex); _complex = null; } else { _group.Add(_temp); } _temp = null; } } private void Insert(ISelector selector) { if (_temp != null) { if (_combinators.Count == 0) { CompoundSelector compoundSelector = _temp as CompoundSelector; if (compoundSelector == null) { compoundSelector = new CompoundSelector { _temp }; } compoundSelector.Add(selector); _temp = compoundSelector; } else { if (_complex == null) { _complex = new ComplexSelector(); } CssCombinator combinator = GetCombinator(); _complex.AppendSelector(_temp, combinator); _temp = selector; } } else { _combinators.Clear(); _temp = selector; } } private CssCombinator GetCombinator() { while (_combinators.Count > 1 && _combinators.Peek() == CssCombinator.Descendant) { _combinators.Pop(); } if (_combinators.Count > 1) { CssCombinator result = _combinators.Pop(); while (_combinators.Count > 0) { _valid = _combinators.Pop() == CssCombinator.Descendant && _valid; } return result; } return _combinators.Pop(); } private void Insert(CssCombinator cssCombinator) { _combinators.Push(cssCombinator); } private void OnDelim(CssSelectorToken token) { switch (token.Data[0]) { case ',': InsertOr(); _ready = false; break; case '>': Insert(CssCombinator.Child); _ready = false; break; case '+': Insert(CssCombinator.AdjacentSibling); _ready = false; break; case '~': Insert(CssCombinator.Sibling); _ready = false; break; case '*': Insert(AllSelector.Instance); _ready = true; break; case '|': if (_combinators.Count > 0 && _combinators.Peek() == CssCombinator.Descendant) { Insert(new TypeSelector(string.Empty)); } Insert(CssCombinator.Namespace); _ready = false; break; case '&': Insert(_attributeSelector.Create("&", string.Empty, string.Empty, null, insensitive: true)); _ready = true; break; default: _valid = false; break; } } private void OnFunctionState(CssSelectorToken token) { if (_function.Finished(token)) { ISelector selector = _function.Produce(); if (_nested && _function is NotFunctionState) { selector = null; } _function = null; _state = State.Data; _ready = true; if (selector != null) { Insert(selector); } else { _valid = false; } } } private CssSelectorConstructor CreateChild(bool forgiving) { return new CssSelectorConstructor(_tokenizer, _attributeSelector, _pseudoClassSelector, _pseudoElementSelector, invoked: true, forgiving); } } public class CssSelectorParser : ICssSelectorParser { private readonly IAttributeSelectorFactory _attribute; private readonly IPseudoClassSelectorFactory _pseudoClass; private readonly IPseudoElementSelectorFactory _pseudoElement; public CssSelectorParser() : this(null) { } internal CssSelectorParser(IBrowsingContext? context) { if (context == null) { context = BrowsingContext.NewFrom((ICssSelectorParser)this); } _attribute = context.GetFactory(); _pseudoClass = context.GetFactory(); _pseudoElement = context.GetFactory(); } public ISelector? ParseSelector(string selectorText) { return new CssSelectorConstructor(new CssTokenizer(new StringSource(selectorText)), _attribute, _pseudoClass, _pseudoElement).Parse(); } } internal readonly struct CssSelectorToken { private readonly CssTokenType _type; private readonly string _data; public static readonly CssSelectorToken Whitespace = new CssSelectorToken(CssTokenType.Whitespace, " "); public CssTokenType Type => _type; public string Data => _data; public CssSelectorToken(CssTokenType type, string data) { _type = type; _data = data; } } public static class CssStringSourceExtensions { public static char SkipCssComment(this StringSource source) { char c = source.Next(); while (true) { switch (c) { case '*': c = source.Next(); if (c == '/') { return source.Next(); } break; default: c = source.Next(); break; case '\uffff': return c; } } } public static string ConsumeEscape(this StringSource source) { char c = source.Next(); if (c.IsHex()) { bool flag = true; Span span = stackalloc char[6]; int num = 0; while (flag && num < span.Length) { span[num++] = c; c = source.Next(); flag = c.IsHex(); } if (!c.IsSpaceCharacter()) { source.Back(); } int num2 = 0; int num3 = 1; for (int num4 = num - 1; num4 >= 0; num4--) { num2 += span[num4].FromHex() * num3; num3 *= 16; } if (!num2.IsInvalid()) { return char.ConvertFromUtf32(num2); } c = '\ufffd'; } return c.ToString(); } public static bool IsValidEscape(this StringSource source) { char current = source.Current; if (current == '\\') { current = source.Peek(); if (current != '\uffff') { return !current.IsLineBreak(); } return false; } return false; } } internal sealed class CssTokenizer { private readonly StringSource _source; public CssTokenizer(StringSource source) { _source = source; } public CssSelectorToken Get() { return Data(_source.Current); } private CssSelectorToken Data(char current) { switch (current) { case '\t': case '\n': case '\f': case '\r': case ' ': _source.SkipSpaces(); return new CssSelectorToken(CssTokenType.Whitespace, " "); case '#': return HashStart(); case '.': { current = _source.Next(); if (current.IsDigit()) { return NumberStart(_source.Back()); } CssSelectorToken cssSelectorToken = Data(current); if (cssSelectorToken.Type == CssTokenType.Ident) { return new CssSelectorToken(CssTokenType.Class, cssSelectorToken.Data); } return NewInvalid(); } case '*': current = _source.Next(); if (current == '=') { _source.Next(); return NewMatch(CombinatorSymbols.InText); } return NewDelimiter('*'); case ',': _source.Next(); return new CssSelectorToken(CssTokenType.Comma, ","); case '>': current = _source.Next(); if (current == '>') { current = _source.Next(); if (current == '>') { _source.Next(); return new CssSelectorToken(CssTokenType.Deep, ">>>"); } return new CssSelectorToken(CssTokenType.Descendant, ">>"); } return NewDelimiter('>'); case '-': { char c3 = _source.Next(); if (c3 != '\uffff') { char c4 = _source.Next(); _source.Back(2); if (c3.IsDigit() || (c3 == '.' && c4.IsDigit())) { return NumberStart(current); } if (c3.IsNameStart()) { return IdentStart(current); } if (c3 == '\\' && !c4.IsLineBreak() && c4 != '\uffff') { return IdentStart(current); } if (c3 == '-' && c4 == '>') { _source.Next(2); return NewInvalid(); } _source.Next(); } return NewDelimiter('-'); } case '+': { char c = _source.Next(); if (c != '\uffff') { char c2 = _source.Next(); _source.Back(); if (c.IsDigit() || (c == '.' && c2.IsDigit())) { _source.Back(); return NumberStart(current); } } return NewDelimiter('+'); } case ':': _source.Next(); return new CssSelectorToken(CssTokenType.Colon, ":"); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return NumberStart(current); case '"': return StringDQ(); case '\'': return StringSQ(); case 'U': case 'u': current = _source.Next(); if (current == '+') { current = _source.Next(); if (current.IsHex() || current == '?') { return UnicodeRange(current); } current = _source.Back(); } return IdentStart(_source.Back()); case '[': _source.Next(); return new CssSelectorToken(CssTokenType.SquareBracketOpen, "["); case ']': _source.Next(); return new CssSelectorToken(CssTokenType.SquareBracketClose, "]"); case ')': _source.Next(); return new CssSelectorToken(CssTokenType.RoundBracketClose, ")"); case '/': current = _source.Next(); if (current == '*') { return Data(_source.SkipCssComment()); } return NewDelimiter('/'); case '\\': current = _source.Next(); if (current.IsLineBreak() || current == '\uffff') { return NewDelimiter('\\'); } return IdentStart(_source.Back()); case '<': current = _source.Next(); if (current == '!') { current = _source.Next(); if (current == '-') { current = _source.Next(); if (current == '-') { _source.Next(); return NewInvalid(); } current = _source.Back(); } current = _source.Back(); } return NewDelimiter('<'); case '^': current = _source.Next(); if (current == '=') { _source.Next(); return NewMatch(CombinatorSymbols.Begins); } return NewDelimiter('^'); case '\uffff': return new CssSelectorToken(CssTokenType.EndOfFile, string.Empty); case '|': current = _source.Next(); switch (current) { case '=': _source.Next(); return NewMatch(CombinatorSymbols.InToken); case '|': _source.Next(); return new CssSelectorToken(CssTokenType.Column, CombinatorSymbols.Column); default: return NewDelimiter('|'); } case '$': current = _source.Next(); if (current == '=') { _source.Next(); return NewMatch(CombinatorSymbols.Ends); } return NewDelimiter('$'); case '~': current = _source.Next(); if (current == '=') { _source.Next(); return NewMatch(CombinatorSymbols.InList); } return NewDelimiter('~'); case '!': current = _source.Next(); if (current == '=') { _source.Next(); return NewMatch(CombinatorSymbols.Unlike); } return NewDelimiter('!'); case '@': return AtKeywordStart(); case '(': case ';': case '{': case '}': _source.Next(); return NewInvalid(); default: if (current.IsNameStart()) { return IdentStart(current); } _source.Next(); return NewDelimiter(current); } } private CssSelectorToken StringDQ() { StringBuilder stringBuilder = StringBuilderPool.Obtain(); while (true) { char c = _source.Next(); switch (c) { case '"': case '\uffff': _source.Next(); return NewString(stringBuilder.ToPool()); case '\n': case '\f': return NewString(stringBuilder.ToPool()); case '\\': c = _source.Next(); if (c.IsLineBreak()) { stringBuilder.AppendLine(); break; } if (c != '\uffff') { _source.Back(); stringBuilder.Append(_source.ConsumeEscape()); break; } return NewString(stringBuilder.ToPool()); default: stringBuilder.Append(c); break; } } } private CssSelectorToken StringSQ() { StringBuilder stringBuilder = StringBuilderPool.Obtain(); while (true) { char c = _source.Next(); switch (c) { case '\'': case '\uffff': _source.Next(); return NewString(stringBuilder.ToPool()); case '\n': case '\f': return NewString(stringBuilder.ToPool()); case '\\': c = _source.Next(); if (c.IsLineBreak()) { stringBuilder.AppendLine(); break; } if (c != '\uffff') { _source.Back(); stringBuilder.Append(_source.ConsumeEscape()); break; } return NewString(stringBuilder.ToPool()); default: stringBuilder.Append(c); break; } } } private CssSelectorToken HashStart() { char c = _source.Next(); if (c.IsNameStart() || c == '-') { StringBuilder stringBuilder = StringBuilderPool.Obtain(); stringBuilder.Append(c); return HashRest(stringBuilder); } if (_source.IsValidEscape()) { StringBuilder stringBuilder2 = StringBuilderPool.Obtain(); stringBuilder2.Append(_source.ConsumeEscape()); return HashRest(stringBuilder2); } return NewDelimiter('#'); } private CssSelectorToken HashRest(StringBuilder buffer) { while (true) { char c = _source.Next(); if (c.IsName()) { buffer.Append(c); continue; } if (!_source.IsValidEscape()) { break; } buffer.Append(_source.ConsumeEscape()); } return new CssSelectorToken(CssTokenType.Hash, buffer.ToPool()); } private CssSelectorToken AtKeywordStart() { char c = _source.Next(); if (c == '-') { c = _source.Next(); if (c.IsNameStart() || _source.IsValidEscape()) { return AtKeywordRest(c); } _source.Back(); return NewDelimiter('@'); } if (c.IsNameStart()) { return AtKeywordRest(_source.Next()); } if (_source.IsValidEscape()) { _source.ConsumeEscape(); return AtKeywordRest(_source.Next()); } return NewDelimiter('@'); } private CssSelectorToken AtKeywordRest(char current) { while (true) { if (!current.IsName()) { if (!_source.IsValidEscape()) { break; } _source.ConsumeEscape(); } current = _source.Next(); } return NewInvalid(); } private CssSelectorToken IdentStart(char current) { if (current == '-') { current = _source.Next(); if (current.IsNameStart() || _source.IsValidEscape()) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); stringBuilder.Append('-'); return IdentRest(current, stringBuilder); } return NewDelimiter('-'); } if (current.IsNameStart()) { StringBuilder stringBuilder2 = StringBuilderPool.Obtain(); stringBuilder2.Append(current); return IdentRest(_source.Next(), stringBuilder2); } if (current == '\\' && _source.IsValidEscape()) { StringBuilder stringBuilder3 = StringBuilderPool.Obtain(); stringBuilder3.Append(_source.ConsumeEscape()); return IdentRest(_source.Next(), stringBuilder3); } return Data(current); } private CssSelectorToken IdentRest(char current, StringBuilder buffer) { while (true) { if (current.IsName()) { buffer.Append(current); } else { if (!_source.IsValidEscape()) { break; } buffer.Append(_source.ConsumeEscape()); } current = _source.Next(); } if (current == '(') { string text = buffer.ToPool(); if (text.Isi(Keywords.Url)) { return UrlStart(); } _source.Next(); return new CssSelectorToken(CssTokenType.Function, text); } return new CssSelectorToken(CssTokenType.Ident, buffer.ToPool()); } private CssSelectorToken NumberStart(char current) { while (true) { if ((current == '+' || current == '-') ? true : false) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); stringBuilder.Append(current); current = _source.Next(); if (current == '.') { stringBuilder.Append(current).Append(_source.Next()); return NumberFraction(stringBuilder); } stringBuilder.Append(current); return NumberRest(stringBuilder); } if (current == '.') { StringBuilder stringBuilder2 = StringBuilderPool.Obtain(); stringBuilder2.Append(current).Append(_source.Next()); return NumberFraction(stringBuilder2); } if (current.IsDigit()) { break; } current = _source.Next(); } StringBuilder stringBuilder3 = StringBuilderPool.Obtain(); stringBuilder3.Append(current); return NumberRest(stringBuilder3); } private CssSelectorToken NumberRest(StringBuilder buffer) { char c = _source.Next(); while (c.IsDigit()) { buffer.Append(c); c = _source.Next(); } if (c.IsNameStart()) { buffer.Append(c); return Dimension(buffer); } if (_source.IsValidEscape()) { buffer.Append(_source.ConsumeEscape()); return Dimension(buffer); } switch (c) { case '.': c = _source.Next(); if (c.IsDigit()) { buffer.Append('.').Append(c); return NumberFraction(buffer); } return NewNumber(buffer.ToPool()); case '%': _source.Next(); return NewDimension(buffer.Append('%').ToPool()); case 'E': case 'e': return NumberExponential(c, buffer); case '-': return NumberDash(buffer); default: return NewNumber(buffer.ToPool()); } } private CssSelectorToken NumberFraction(StringBuilder buffer) { char c = _source.Next(); while (c.IsDigit()) { buffer.Append(c); c = _source.Next(); } if (c.IsNameStart()) { buffer.Append(c); return Dimension(buffer); } if (_source.IsValidEscape()) { buffer.Append(_source.ConsumeEscape()); return Dimension(buffer); } switch (c) { case 'E': case 'e': return NumberExponential(c, buffer); case '%': _source.Next(); return NewDimension(buffer.Append('%').ToPool()); case '-': return NumberDash(buffer); default: return NewNumber(buffer.ToPool()); } } private CssSelectorToken Dimension(StringBuilder buffer) { while (true) { char c = _source.Next(); if (c.IsLetter()) { buffer.Append(c); continue; } if (!_source.IsValidEscape()) { break; } buffer.Append(_source.ConsumeEscape()); } return NewDimension(buffer.ToPool()); } private CssSelectorToken SciNotation(StringBuilder buffer) { while (true) { char c = _source.Next(); if (!c.IsDigit()) { break; } buffer.Append(c); } return NewNumber(buffer.ToPool()); } private CssSelectorToken UrlStart() { char c = _source.SkipSpaces(); switch (c) { case '\uffff': return NewInvalid(); case '"': return UrlDQ(); case '\'': return UrlSQ(); case ')': _source.Next(); return NewInvalid(); default: return UrlUQ(c); } } private CssSelectorToken UrlDQ() { while (true) { char c = _source.Next(); if (c.IsLineBreak()) { return UrlBad(); } if ('\uffff' == c) { break; } switch (c) { case '"': return UrlEnd(); case '\\': c = _source.Next(); if (c == '\uffff') { return NewInvalid(); } if (!c.IsLineBreak()) { _source.Back(); _source.ConsumeEscape(); } break; } } return NewInvalid(); } private CssSelectorToken UrlSQ() { while (true) { char c = _source.Next(); if (c.IsLineBreak()) { break; } switch (c) { case '\uffff': return NewInvalid(); case '\'': return UrlEnd(); case '\\': c = _source.Next(); if (c == '\uffff') { return NewInvalid(); } if (!c.IsLineBreak()) { _source.Back(); _source.ConsumeEscape(); } break; } } return UrlBad(); } private CssSelectorToken UrlUQ(char current) { while (true) { if (current.IsSpaceCharacter()) { return UrlEnd(); } if ((current == ')' || current == '\uffff') ? true : false) { _source.Next(); return NewInvalid(); } bool flag = ((current == '"' || current == '\'' || current == '(') ? true : false); if (flag || current.IsNonPrintable()) { return UrlBad(); } if (current != '\\' || !_source.IsValidEscape()) { break; } _source.ConsumeEscape(); current = _source.Next(); } return UrlBad(); } private CssSelectorToken UrlEnd() { char c; do { c = _source.Next(); if (c == ')') { _source.Next(); return NewInvalid(); } } while (c.IsSpaceCharacter()); _source.Back(); return UrlBad(); } private CssSelectorToken UrlBad() { char c = _source.Current; int num = 0; int num2 = 1; while (c != '\uffff') { switch (c) { case ';': return NewInvalid(); case '}': if (--num == -1) { return NewInvalid(); } break; } if (c == ')' && --num2 == 0) { return NewInvalid(); } if (_source.IsValidEscape()) { _source.ConsumeEscape(); } else if (c == '(') { num2++; } else if (num == 123) { num++; } c = _source.Next(); } return NewInvalid(); } private CssSelectorToken UnicodeRange(char current) { int num = 0; for (int i = 0; i < 6; i++) { if (!current.IsHex()) { break; } num++; current = _source.Next(); } if (num != 6) { for (int j = 0; j < 6 - num; j++) { if (current != '?') { current = _source.Back(); break; } current = _source.Next(); } return NewInvalid(); } if (current == '-') { current = _source.Next(); if (current.IsHex()) { for (int k = 0; k < 6; k++) { if (!current.IsHex()) { current = _source.Back(); break; } current = _source.Next(); } return new CssSelectorToken(CssTokenType.Invalid, string.Empty); } _source.Back(); return NewInvalid(); } return NewInvalid(); } private CssSelectorToken NewMatch(string match) { return new CssSelectorToken(CssTokenType.Match, match); } private CssSelectorToken NewInvalid() { return new CssSelectorToken(CssTokenType.Invalid, string.Empty); } private CssSelectorToken NewString(string value) { return new CssSelectorToken(CssTokenType.String, value); } private CssSelectorToken NewDimension(string value) { return new CssSelectorToken(CssTokenType.Dimension, value); } private CssSelectorToken NewNumber(string number) { return new CssSelectorToken(CssTokenType.Number, number); } private CssSelectorToken NewDelimiter(char c) { return new CssSelectorToken(CssTokenType.Delim, c.ToString()); } private CssSelectorToken NumberExponential(char letter, StringBuilder buffer) { char c = _source.Next(); if (c.IsDigit()) { buffer.Append(letter).Append(c); return SciNotation(buffer); } if (c == '+' || c == '-') { char value = c; c = _source.Next(); if (c.IsDigit()) { buffer.Append(letter).Append(value).Append(c); return SciNotation(buffer); } _source.Back(); } buffer.Append(letter); _source.Back(); return Dimension(buffer); } private CssSelectorToken NumberDash(StringBuilder buffer) { char c = _source.Next(); if (c.IsNameStart()) { buffer.Append('-').Append(c); return Dimension(buffer); } if (_source.IsValidEscape()) { buffer.Append('-').Append(_source.ConsumeEscape()); return Dimension(buffer); } _source.Back(); return NewNumber(buffer.ToPool()); } } internal enum CssTokenType : byte { String, Hash, Class, Ident, Function, Number, Dimension, Column, Descendant, Deep, Delim, Match, RoundBracketClose, SquareBracketOpen, SquareBracketClose, Colon, Comma, Whitespace, Invalid, EndOfFile } public interface ICssSelectorParser { ISelector? ParseSelector(string selectorText); } } namespace AngleSharp.Css.Dom { public interface ICssMedium : IStyleFormattable { string Type { get; } bool IsExclusive { get; } bool IsInverse { get; } string Constraints { get; } IEnumerable Features { get; } } public interface IMediaFeature : IStyleFormattable { string Name { get; } bool IsMinimum { get; } bool IsMaximum { get; } string Value { get; } bool HasValue { get; } } [DomName("MediaList")] public interface IMediaList : IEnumerable, IEnumerable, IStyleFormattable { [DomName("mediaText")] string MediaText { get; set; } [DomName("length")] int Length { get; } [DomAccessor(Accessors.Getter)] [DomName("item")] string this[int index] { get; } [DomName("appendMedium")] void Add(string medium); [DomName("removeMedium")] void Remove(string medium); } public interface IMultiSelector { ISelector? GetMatchingSelector(IElement element, IElement? scope = null); } public interface INestedSelector : ISelector { ISelector ParentSelector { get; set; } } internal sealed class AllSelector : ISelector { public static readonly ISelector Instance = new AllSelector(); public Priority Specificity => Priority.Zero; public string Text => "*"; private AllSelector() { } public void Accept(ISelectorVisitor visitor) { visitor.Type(Text); } public bool Match(IElement element, IElement? scope) { return true; } } internal sealed class AttrAvailableSelector : BaseAttrSelector, ISelector { public string Text => "[" + base.Attribute + "]"; public AttrAvailableSelector(string name, string? prefix) : base(name, prefix) { } public void Accept(ISelectorVisitor visitor) { visitor.Attribute(base.Attribute, string.Empty, null); } public bool Match(IElement element, IElement? scope) { return element.HasAttribute(base.Name); } } internal sealed class AttrContainsSelector : BaseAttrSelector, ISelector { private readonly string _value; private readonly StringComparison _comparison; public string Text => "[" + base.Attribute + "*=" + _value.CssString() + "]"; public AttrContainsSelector(string name, string value, string? prefix = null, bool insensitive = false) : base(name, prefix) { _value = value; _comparison = (insensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); } public void Accept(ISelectorVisitor visitor) { visitor.Attribute(base.Attribute, "*=", _value); } public bool Match(IElement element, IElement? scope) { if (!string.IsNullOrEmpty(_value)) { return (element.GetAttribute(base.Name) ?? string.Empty).IndexOf(_value, _comparison) != -1; } return false; } } internal sealed class AttrEndsWithSelector : BaseAttrSelector, ISelector { private readonly string _value; private readonly StringComparison _comparison; public string Text => "[" + base.Attribute + "$=" + _value.CssString() + "]"; public AttrEndsWithSelector(string name, string value, string? prefix = null, bool insensitive = false) : base(name, prefix) { _value = value; _comparison = (insensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); } public void Accept(ISelectorVisitor visitor) { visitor.Attribute(base.Attribute, "$=", _value); } public bool Match(IElement element, IElement? scope) { if (!string.IsNullOrEmpty(_value)) { return (element.GetAttribute(base.Name) ?? string.Empty).EndsWith(_value, _comparison); } return false; } } internal sealed class AttrInListSelector : BaseAttrSelector, ISelector { private readonly string _value; private readonly StringComparison _comparison; public string Text => "[" + base.Attribute + "~=" + _value.CssString() + "]"; public AttrInListSelector(string name, string value, string? prefix = null, bool insensitive = false) : base(name, prefix) { _value = value; _comparison = (insensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); } public void Accept(ISelectorVisitor visitor) { visitor.Attribute(base.Attribute, "~=", _value); } public bool Match(IElement element, IElement? scope) { if (!string.IsNullOrEmpty(_value)) { return (element.GetAttribute(base.Name) ?? string.Empty).SplitSpaces().Contains(_value, _comparison); } return false; } } internal sealed class AttrInTokenSelector : BaseAttrSelector, ISelector { private readonly string _value; private readonly StringComparison _comparison; public string Text => "[" + base.Attribute + "|=" + _value.CssString() + "]"; public AttrInTokenSelector(string name, string value, string? prefix = null, bool insensitive = false) : base(name, prefix) { _value = value; _comparison = (insensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); } public void Accept(ISelectorVisitor visitor) { visitor.Attribute(base.Attribute, "|=", _value); } public bool Match(IElement element, IElement? scope) { if (!string.IsNullOrEmpty(_value)) { return (element.GetAttribute(base.Name) ?? string.Empty).HasHyphen(_value, _comparison); } return false; } } internal sealed class AttrMatchSelector : BaseAttrSelector, ISelector { private readonly string _value; private readonly StringComparison _comparison; public string Text => "[" + base.Attribute + "=" + _value.CssString() + "]"; public AttrMatchSelector(string name, string value, string? prefix = null, bool insensitive = false) : base(name, prefix) { _value = value; _comparison = (insensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); } public void Accept(ISelectorVisitor visitor) { visitor.Attribute(base.Attribute, "=", _value); } public bool Match(IElement element, IElement? scope) { return string.Equals(element.GetAttribute(base.Name), _value, _comparison); } } internal sealed class AttrNotMatchSelector : BaseAttrSelector, ISelector { private readonly string _value; private readonly StringComparison _comparison; public string Text => "[" + base.Attribute + "!=" + _value.CssString() + "]"; public AttrNotMatchSelector(string name, string value, string? prefix = null, bool insensitive = false) : base(name, prefix) { _value = value; _comparison = (insensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); } public void Accept(ISelectorVisitor visitor) { visitor.Attribute(base.Attribute, "!=", _value); } public bool Match(IElement element, IElement? scope) { return !string.Equals(element.GetAttribute(base.Name), _value, _comparison); } } internal sealed class AttrStartsWithSelector : BaseAttrSelector, ISelector { private readonly string _value; private readonly StringComparison _comparison; public string Text => "[" + base.Attribute + "^=" + _value.CssString() + "]"; public AttrStartsWithSelector(string name, string value, string? prefix = null, bool insensitive = false) : base(name, prefix) { _value = value; _comparison = (insensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); } public void Accept(ISelectorVisitor visitor) { visitor.Attribute(base.Attribute, "^=", _value); } public bool Match(IElement element, IElement? scope) { if (!string.IsNullOrEmpty(_value)) { return (element.GetAttribute(base.Name) ?? string.Empty).StartsWith(_value, _comparison); } return false; } } internal abstract class BaseAttrSelector { private readonly string _name; private readonly string? _prefix; private readonly string _attr; public Priority Specificity => Priority.OneClass; protected string Attribute { get { if (string.IsNullOrEmpty(_prefix)) { return CssUtilities.Escape(_name); } return CssUtilities.Escape(_prefix) + "|" + CssUtilities.Escape(_name); } } protected string Name => _attr; public BaseAttrSelector(string name, string? prefix) { _name = name; _prefix = prefix; if (!string.IsNullOrEmpty(prefix) && !(prefix == "*")) { _attr = prefix + ":" + name; } else { _attr = name; } } } internal abstract class ChildSelector { private readonly string _name; private readonly int _step; private readonly int _offset; private readonly ISelector _kind; public Priority Specificity { get { Priority oneClass = Priority.OneClass; if (IncludeParameterInSpecificity) { oneClass += ((Kind is ListSelector source) ? source.Max((ISelector x) => x.Specificity) : Kind.Specificity); } return oneClass; } } protected virtual bool IncludeParameterInSpecificity => false; public string Text { get { string text = _step.ToString(); string text2 = string.Empty; string text3 = string.Empty; if (_offset > 0) { text2 = "+"; int offset = _offset; text3 = offset.ToString(); } else if (_offset < 0) { text2 = "-"; text3 = (-_offset).ToString(); } return $":{_name}({text}n{text2}{text3})"; } } public string Name => _name; public int Step => _step; public int Offset => _offset; public ISelector Kind => _kind; public ChildSelector(string name, int step, int offset, ISelector kind) { _name = name; _step = step; _offset = offset; _kind = kind; } public void Accept(ISelectorVisitor visitor) { visitor.Child(_name, _step, _offset, _kind); } } internal sealed class ClassSelector : ISelector { private readonly string _cls; public Priority Specificity => Priority.OneClass; public string Text => "." + CssUtilities.Escape(_cls); public ClassSelector(string cls) { _cls = cls; } public void Accept(ISelectorVisitor visitor) { visitor.Class(_cls); } public bool Match(IElement element, IElement? scope) { return element.ClassList.Contains(_cls); } } internal sealed class ComplexSelector : ISelector { private struct CombinatorSelector { public string? Delimiter; public Func>? Transform; public ISelector Selector; } private readonly List _combinators; public Priority Specificity { get { Priority result = default(Priority); int count = _combinators.Count; for (int i = 0; i < count; i++) { result += _combinators[i].Selector.Specificity; } return result; } } public string Text { get { string[] array = new string[2 * _combinators.Count + 1]; if (_combinators.Count > 0) { int num = 0; int num2 = _combinators.Count - 1; for (int i = 0; i < num2; i++) { array[num++] = _combinators[i].Selector.Text; array[num++] = _combinators[i].Delimiter; } array[num] = _combinators[num2].Selector.Text; } return string.Concat(array); } } public int Length => _combinators.Count; public bool IsReady { get; private set; } public ComplexSelector() { _combinators = new List(); } public void Accept(ISelectorVisitor visitor) { IEnumerable selectors = _combinators.Select((CombinatorSelector m) => m.Selector); IEnumerable symbols = from m in _combinators.Take(_combinators.Count - 1) select m.Delimiter; visitor.Combinator(selectors, symbols); } public bool Match(IElement element, IElement? scope) { int num = _combinators.Count - 1; if (_combinators[num].Selector.Match(element, scope)) { if (num <= 0) { return true; } return MatchCascade(num - 1, element, scope); } return false; } public void ConcludeSelector(ISelector selector) { if (!IsReady) { _combinators.Add(new CombinatorSelector { Selector = selector, Transform = null, Delimiter = null }); IsReady = true; } } public void AppendSelector(ISelector selector, CssCombinator combinator) { if (!IsReady) { _combinators.Add(new CombinatorSelector { Selector = combinator.Change(selector), Transform = combinator.Transform, Delimiter = combinator.Delimiter }); } } private bool MatchCascade(int pos, IElement element, IElement? scope) { CombinatorSelector combinatorSelector = _combinators[pos]; foreach (IElement item in combinatorSelector.Transform(element)) { if (combinatorSelector.Selector.Match(item, scope) && (pos == 0 || MatchCascade(pos - 1, item, scope))) { return true; } } return false; } } internal sealed class CompoundSelector : Selectors, ISelector { public bool Match(IElement element, IElement? scope) { for (int i = 0; i < _selectors.Count; i++) { if (!_selectors[i].Match(element, scope)) { return false; } } return true; } public void Accept(ISelectorVisitor visitor) { visitor.Many(_selectors); } protected override string Stringify() { string[] array = new string[_selectors.Count]; for (int i = 0; i < _selectors.Count; i++) { array[i] = _selectors[i].Text; } return string.Concat(array); } protected override Priority ComputeSpecificity() { Priority result = default(Priority); for (int i = 0; i < _selectors.Count; i++) { result += _selectors[i].Specificity; } return result; } } internal sealed class FirstChildSelector : ChildSelector, ISelector { protected override bool IncludeParameterInSpecificity => true; public FirstChildSelector(int step, int offset, ISelector kind) : base(PseudoClassNames.NthChild, step, offset, kind) { } public bool Match(IElement element, IElement? scope) { IElement parentElement = element.ParentElement; if (parentElement != null) { if (parentElement.ChildNodes is NodeList nodeList) { return DoMatch(new ConcreteNodeListAccessor(nodeList), element, scope); } return DoMatch(new InterfaceNodeListAccessor(parentElement.ChildNodes), element, scope); } return false; } private bool DoMatch(T nodes, IElement element, IElement? scope) where T : INodeListAccessor { int step = base.Step; int num = Math.Sign(step); int num2 = 0; ISelector kind = base.Kind; bool flag = base.Kind == AllSelector.Instance; int offset = base.Offset; int length = nodes.Length; for (int i = 0; i < length; i++) { if (!(nodes[i] is IElement element2) || (!flag && !kind.Match(element2, scope))) { continue; } num2++; if (element2 != element) { continue; } int num3 = num2 - offset; if (num3 != 0) { if (Math.Sign(num3) == num) { return num3 % step == 0; } return false; } return true; } return false; } } internal sealed class FirstColumnSelector : ChildSelector, ISelector { public FirstColumnSelector(int step, int offset, ISelector kind) : base(PseudoClassNames.NthColumn, step, offset, kind) { } public bool Match(IElement element, IElement? scope) { IElement parentElement = element.ParentElement; if (parentElement != null) { if (parentElement.ChildNodes is NodeList nodeList) { return DoMatch(new ConcreteNodeListAccessor(nodeList), element); } return DoMatch(new InterfaceNodeListAccessor(parentElement.ChildNodes), element); } return false; } private bool DoMatch(T nodes, IElement element) where T : INodeListAccessor { int step = base.Step; int num = Math.Sign(step); int num2 = 0; int offset = base.Offset; int length = nodes.Length; for (int i = 0; i < length; i++) { if (!(nodes[i] is IHtmlTableCellElement { ColumnSpan: var columnSpan } htmlTableCellElement)) { continue; } num2 += columnSpan; if (htmlTableCellElement != element) { continue; } int num3 = num2 - offset; int num4 = 0; while (num4 < columnSpan) { if (num3 == 0 || (Math.Sign(num3) == num && num3 % step == 0)) { return true; } num4++; num3--; } return false; } return false; } } internal sealed class FirstTypeSelector : ChildSelector, ISelector { public FirstTypeSelector(int step, int offset, ISelector kind) : base(PseudoClassNames.NthOfType, step, offset, kind) { } public bool Match(IElement element, IElement? scope) { IElement parentElement = element.ParentElement; if (parentElement != null) { if (parentElement.ChildNodes is NodeList nodeList) { return DoMatch(new ConcreteNodeListAccessor(nodeList), element); } return DoMatch(new InterfaceNodeListAccessor(parentElement.ChildNodes), element); } return false; } private bool DoMatch(T nodes, IElement element) where T : INodeListAccessor { int num = 0; int step = base.Step; int num2 = Math.Sign(step); int offset = base.Offset; int length = nodes.Length; string nodeName = element.NodeName; for (int i = 0; i < length; i++) { if (!(nodes[i] is IElement element2) || !element2.NodeName.Is(nodeName)) { continue; } num++; if (element2 != element) { continue; } int num3 = num - offset; if (num3 != 0) { if (Math.Sign(num3) == num2) { return num3 % step == 0; } return false; } return true; } return false; } } internal sealed class IdSelector : ISelector { private readonly string _id; public Priority Specificity => Priority.OneId; public string Text => "#" + CssUtilities.Escape(_id); public IdSelector(string id) { _id = id; } public void Accept(ISelectorVisitor visitor) { visitor.Id(_id); } public bool Match(IElement element, IElement? scope) { return element.Id.Is(_id); } } internal sealed class LastChildSelector : ChildSelector, ISelector { protected override bool IncludeParameterInSpecificity => true; public LastChildSelector(int step, int offset, ISelector kind) : base(PseudoClassNames.NthLastChild, step, offset, kind) { } public bool Match(IElement element, IElement? scope) { IElement parentElement = element.ParentElement; if (parentElement != null) { if (parentElement.ChildNodes is NodeList nodeList) { return DoMatch(new ConcreteNodeListAccessor(nodeList), element, scope); } return DoMatch(new InterfaceNodeListAccessor(parentElement.ChildNodes), element, scope); } return false; } private bool DoMatch(T nodes, IElement element, IElement? scope) where T : INodeListAccessor { int step = base.Step; int num = Math.Sign(step); int num2 = 0; ISelector kind = base.Kind; bool flag = base.Kind == AllSelector.Instance; int offset = base.Offset; for (int num3 = nodes.Length - 1; num3 >= 0; num3--) { if (nodes[num3] is IElement element2 && (flag || kind.Match(element2, scope))) { num2++; if (element2 == element) { int num4 = num2 - offset; if (num4 != 0) { if (Math.Sign(num4) == num) { return num4 % step == 0; } return false; } return true; } } } return false; } } internal sealed class LastColumnSelector : ChildSelector, ISelector { public LastColumnSelector(int step, int offset, ISelector kind) : base(PseudoClassNames.NthLastColumn, step, offset, kind) { } public bool Match(IElement element, IElement? scope) { IElement parentElement = element.ParentElement; if (parentElement != null) { if (parentElement.ChildNodes is NodeList nodeList) { return DoMatch(new ConcreteNodeListAccessor(nodeList), element); } return DoMatch(new InterfaceNodeListAccessor(parentElement.ChildNodes), element); } return false; } private bool DoMatch(T nodes, IElement element) where T : INodeListAccessor { int step = base.Step; int num = Math.Sign(step); int num2 = 0; int offset = base.Offset; for (int num3 = nodes.Length - 1; num3 >= 0; num3--) { if (nodes[num3] is IHtmlTableCellElement { ColumnSpan: var columnSpan } htmlTableCellElement) { num2 += columnSpan; if (htmlTableCellElement == element) { int num4 = num2 - offset; int num5 = 0; while (num5 < columnSpan) { if (num4 == 0 || (Math.Sign(num4) == num && num4 % step == 0)) { return true; } num5++; num4--; } return false; } } } return false; } } internal sealed class LastTypeSelector : ChildSelector, ISelector { public LastTypeSelector(int step, int offset, ISelector kind) : base(PseudoClassNames.NthLastOfType, step, offset, kind) { } public bool Match(IElement element, IElement? scope) { IElement parentElement = element.ParentElement; if (parentElement != null) { if (parentElement.ChildNodes is NodeList nodeList) { return DoMatch(new ConcreteNodeListAccessor(nodeList), element); } return DoMatch(new InterfaceNodeListAccessor(parentElement.ChildNodes), element); } return false; } private bool DoMatch(T nodes, IElement element) where T : INodeListAccessor { int step = base.Step; int num = Math.Sign(step); int num2 = 0; int offset = base.Offset; string nodeName = element.NodeName; for (int num3 = nodes.Length - 1; num3 >= 0; num3--) { if (nodes[num3] is IElement element2 && element2.NodeName.Is(nodeName)) { num2++; if (element2 == element) { int num4 = num2 - offset; if (num4 != 0) { if (Math.Sign(num4) == num) { return num4 % step == 0; } return false; } return true; } } } return false; } } internal sealed class ListSelector : Selectors, ISelector, IMultiSelector { public void Accept(ISelectorVisitor visitor) { visitor.List(_selectors); } public bool Match(IElement element, IElement? scope) { for (int i = 0; i < _selectors.Count; i++) { if (_selectors[i].Match(element, scope)) { return true; } } return false; } public ISelector? GetMatchingSelector(IElement element, IElement? scope = null) { foreach (ISelector item in _selectors.OrderByDescending((ISelector m) => m.Specificity)) { if (item.Match(element, scope)) { return item; } } return null; } protected override string Stringify() { string[] array = new string[_selectors.Count]; for (int i = 0; i < _selectors.Count; i++) { array[i] = _selectors[i].Text; } return string.Join(", ", array); } protected override Priority ComputeSpecificity() { Priority priority = Priority.Zero; for (int i = 0; i < _selectors.Count; i++) { Priority specificity = _selectors[i].Specificity; if (specificity > priority) { priority = specificity; } } return priority; } } internal sealed class NamespaceSelector : ISelector { private readonly string _prefix; public Priority Specificity => Priority.Zero; public string Text => CssUtilities.Escape(_prefix); public NamespaceSelector(string prefix) { _prefix = prefix; } public bool Match(IElement element, IElement? scope) { return element.MatchesCssNamespace(_prefix); } public void Accept(ISelectorVisitor visitor) { visitor.Type(_prefix); } } internal sealed class NestedSelector : ISelector { public static readonly ISelector Instance = new NestedSelector(); public Priority Specificity => Priority.OneClass; public string Text => "&"; private NestedSelector() { } public void Accept(ISelectorVisitor visitor) { visitor.Type(Text); } public bool Match(IElement element, IElement? scope) { return element.Owner.DocumentElement == element; } } internal sealed class PseudoClassSelector : ISelector { private readonly Predicate _action; private readonly string _pseudoClass; public Priority Specificity { get; } public string Text => PseudoClassNames.Separator + _pseudoClass; public PseudoClassSelector(Predicate action, string pseudoClass) { _action = action; _pseudoClass = pseudoClass; Specificity = Priority.OneClass; } public PseudoClassSelector(Predicate action, string pseudoClass, Priority specificity) { _action = action; _pseudoClass = pseudoClass; Specificity = specificity; } public void Accept(ISelectorVisitor visitor) { visitor.PseudoClass(_pseudoClass); } public bool Match(IElement element, IElement? scope) { return _action(element); } } internal sealed class PseudoElementSelector : ISelector { private readonly Predicate _action; private readonly string _pseudoElement; public Priority Specificity => Priority.OneTag; public string Text => PseudoElementNames.Separator + CssUtilities.Escape(_pseudoElement); public PseudoElementSelector(Predicate action, string pseudoElement) { _action = action; _pseudoElement = pseudoElement; } public void Accept(ISelectorVisitor visitor) { visitor.PseudoElement(_pseudoElement); } public bool Match(IElement element, IElement? scope) { return _action(element); } } internal sealed class ScopePseudoClassSelector : ISelector { public static readonly ISelector Instance = new ScopePseudoClassSelector(); public Priority Specificity => Priority.OneClass; public string Text => PseudoClassNames.Separator + PseudoClassNames.Scope; private ScopePseudoClassSelector() { } public void Accept(ISelectorVisitor visitor) { visitor.PseudoClass(PseudoClassNames.Scope); } public bool Match(IElement element, IElement? scope) { IElement element2 = scope ?? element.Owner.DocumentElement; return element == element2; } } internal abstract class Selectors : IEnumerable, IEnumerable { protected readonly List _selectors; public Priority Specificity => ComputeSpecificity(); public string Text => Stringify(); public int Length => _selectors.Count; public ISelector this[int index] { get { return _selectors[index]; } set { _selectors[index] = value; } } public Selectors() { _selectors = new List(); } protected abstract Priority ComputeSpecificity(); protected abstract string Stringify(); public void Add(ISelector selector) { _selectors.Add(selector); } public void Remove(ISelector selector) { _selectors.Remove(selector); } public IEnumerator GetEnumerator() { return _selectors.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal sealed class TypeSelector : ISelector { private readonly string _type; internal string TypeName => _type; public Priority Specificity => Priority.OneTag; public string Text => CssUtilities.Escape(_type); public TypeSelector(string type) { _type = type; } public void Accept(ISelectorVisitor visitor) { visitor.Type(_type); } public bool Match(IElement element, IElement? scope) { return _type.Isi(element.LocalName); } } public interface ISelector { string Text { get; } Priority Specificity { get; } bool Match(IElement element, IElement? scope); void Accept(ISelectorVisitor visitor); } public static class SelectorExtensions { private readonly struct SelectorState { public readonly ISelector Selector; public readonly IElement? Scope; public SelectorState(ISelector selector, IElement? scope) { Selector = selector; Scope = scope; } } public static IElement? MatchAny(this ISelector selector, IEnumerable elements, IElement? scope) { Stack stack = new Stack(); foreach (IElement element2 in elements) { stack.Clear(); IEnumerator enumerator2 = element2.GetDescendantsAndSelf(stack, (INode node, SelectorState state) => node is IElement element && state.Selector.Match(element, state.Scope), new SelectorState(selector, scope)).GetEnumerator(); if (enumerator2.MoveNext()) { return (IElement)enumerator2.Current; } } return null; } public static IHtmlCollection MatchAll(this ISelector selector, IEnumerable elements, IElement? scope) { List list = new List(); selector.MatchAll(elements, scope, list); return new HtmlCollection(list); } public static bool Match(this ISelector selector, IElement element) { return selector.Match(element, element?.Owner.DocumentElement); } private static void MatchAll(this ISelector selector, IEnumerable elements, IElement? scope, List result) { Stack stack = new Stack(); foreach (IElement element2 in elements) { stack.Clear(); foreach (INode item in element2.GetDescendantsAndSelf(stack, (INode node, SelectorState state) => node is IElement element && state.Selector.Match(element, state.Scope), new SelectorState(selector, scope))) { result.Add((IElement)item); } } } } public static class StyleExtensions { public static IEnumerable GetAllStyleSheetSets(this IStyleSheetList sheets) { List existing = new List(); foreach (IStyleSheet sheet in sheets) { string title = sheet.Title; if (!string.IsNullOrEmpty(title) && !existing.Contains(title)) { existing.Add(title); yield return title; } } } public static IEnumerable GetEnabledStyleSheetSets(this IStyleSheetList sheets) { List list = new List(); foreach (IStyleSheet sheet in sheets) { string title = sheet.Title; if (!string.IsNullOrEmpty(title) && !list.Contains(title) && sheet.IsDisabled) { list.Add(title); } } return sheets.GetAllStyleSheetSets().Except(list); } public static void EnableStyleSheetSet(this IStyleSheetList sheets, string name) { foreach (IStyleSheet sheet in sheets) { string title = sheet.Title; if (!string.IsNullOrEmpty(title)) { sheet.IsDisabled = title != name; } } } public static IStyleSheetList CreateStyleSheets(this INode parent) { return new StyleSheetList(parent.GetStyleSheets()); } public static IStringList CreateStyleSheetSets(this INode parent) { return new StringList(from m in parent.GetStyleSheets() select m.Title into m where m != null select m); } public static IEnumerable GetStyleSheets(this INode parent) { if (parent.ChildNodes.Length == 0) { yield break; } Stack st = new Stack(); for (int num = parent.ChildNodes.Length - 1; num >= 0; num--) { st.Push(parent.ChildNodes[num]); } while (st.Count > 0) { INode child = st.Pop(); if (child.NodeType == NodeType.Element && child is ILinkStyle linkStyle) { IStyleSheet sheet = linkStyle.Sheet; if (sheet != null && !sheet.IsDisabled) { yield return sheet; } } for (int num2 = child.ChildNodes.Length - 1; num2 >= 0; num2--) { st.Push(child.ChildNodes[num2]); } } } public static string? LocateNamespace(this IStyleSheetList sheets, string prefix) { string text = null; int length = sheets.Length; for (int i = 0; i < length; i++) { if (text != null) { break; } text = sheets[i]?.LocateNamespace(prefix); } return text; } } } namespace AngleSharp.Html { internal class OrdinalStringOrMemoryComparer : IEqualityComparer { public static OrdinalStringOrMemoryComparer Instance { get; } = new OrdinalStringOrMemoryComparer(); public int GetHashCode(StringOrMemory obj) { return obj.GetHashCode(); } public bool Equals(StringOrMemory x, StringOrMemory y) { return x.Equals(y); } } public class DefaultInputTypeFactory : IInputTypeFactory { public delegate BaseInputType Creator(IHtmlInputElement input); private readonly Dictionary _creators = new Dictionary(StringComparer.OrdinalIgnoreCase) { { InputTypeNames.Text, (IHtmlInputElement input) => new TextInputType(input, InputTypeNames.Text) }, { InputTypeNames.Date, (IHtmlInputElement input) => new DateInputType(input, InputTypeNames.Date) }, { InputTypeNames.Week, (IHtmlInputElement input) => new WeekInputType(input, InputTypeNames.Week) }, { InputTypeNames.Datetime, (IHtmlInputElement input) => new DatetimeInputType(input, InputTypeNames.Datetime) }, { InputTypeNames.DatetimeLocal, (IHtmlInputElement input) => new DatetimeLocalInputType(input, InputTypeNames.DatetimeLocal) }, { InputTypeNames.Time, (IHtmlInputElement input) => new TimeInputType(input, InputTypeNames.Time) }, { InputTypeNames.Month, (IHtmlInputElement input) => new MonthInputType(input, InputTypeNames.Month) }, { InputTypeNames.Range, (IHtmlInputElement input) => new NumberInputType(input, InputTypeNames.Range) }, { InputTypeNames.Number, (IHtmlInputElement input) => new NumberInputType(input, InputTypeNames.Number) }, { InputTypeNames.Hidden, (IHtmlInputElement input) => new ButtonInputType(input, InputTypeNames.Hidden) }, { InputTypeNames.Search, (IHtmlInputElement input) => new TextInputType(input, InputTypeNames.Search) }, { InputTypeNames.Email, (IHtmlInputElement input) => new EmailInputType(input, InputTypeNames.Email) }, { InputTypeNames.Tel, (IHtmlInputElement input) => new PatternInputType(input, InputTypeNames.Tel) }, { InputTypeNames.Url, (IHtmlInputElement input) => new UrlInputType(input, InputTypeNames.Url) }, { InputTypeNames.Password, (IHtmlInputElement input) => new PatternInputType(input, InputTypeNames.Password) }, { InputTypeNames.Color, (IHtmlInputElement input) => new ColorInputType(input, InputTypeNames.Color) }, { InputTypeNames.Checkbox, (IHtmlInputElement input) => new CheckedInputType(input, InputTypeNames.Checkbox) }, { InputTypeNames.Radio, (IHtmlInputElement input) => new CheckedInputType(input, InputTypeNames.Radio) }, { InputTypeNames.File, (IHtmlInputElement input) => new FileInputType(input, InputTypeNames.File) }, { InputTypeNames.Submit, (IHtmlInputElement input) => new SubmitInputType(input, InputTypeNames.Submit) }, { InputTypeNames.Reset, (IHtmlInputElement input) => new ButtonInputType(input, InputTypeNames.Reset) }, { InputTypeNames.Image, (IHtmlInputElement input) => new ImageInputType(input, InputTypeNames.Image) }, { InputTypeNames.Button, (IHtmlInputElement input) => new ButtonInputType(input, InputTypeNames.Button) } }; public void Register(string type, Creator creator) { _creators.Add(type, creator); } public Creator? Unregister(string type) { if (_creators.TryGetValue(type, out Creator value)) { _creators.Remove(type); } return value; } protected virtual BaseInputType CreateDefault(IHtmlInputElement input, string type) { return _creators[InputTypeNames.Text](input); } public BaseInputType Create(IHtmlInputElement input, string type) { if (!string.IsNullOrEmpty(type) && _creators.TryGetValue(type, out Creator value)) { return value(input); } return CreateDefault(input, type); } } public class DefaultLinkRelationFactory : ILinkRelationFactory { public delegate BaseLinkRelation Creator(IHtmlLinkElement link); private readonly Dictionary _creators = new Dictionary(StringComparer.OrdinalIgnoreCase) { { LinkRelNames.StyleSheet, (IHtmlLinkElement link) => new StyleSheetLinkRelation(link) }, { LinkRelNames.Import, (IHtmlLinkElement link) => new ImportLinkRelation(link) } }; public void Register(string rel, Creator creator) { _creators.Add(rel, creator); } public Creator? Unregister(string rel) { if (_creators.TryGetValue(rel, out Creator value)) { _creators.Remove(rel); } return value; } protected virtual BaseLinkRelation? CreateDefault(IHtmlLinkElement link, string? rel) { return null; } public BaseLinkRelation? Create(IHtmlLinkElement link, string? rel) { if (rel != null && _creators.TryGetValue(rel, out Creator value)) { return value(link); } return CreateDefault(link, rel); } } [Flags] internal enum EventFlags : byte { None = 0, StopPropagation = 1, StopImmediatePropagation = 2, Canceled = 4, Initialized = 8, Dispatch = 0x10 } internal sealed class FormControlState { private readonly string _name; private readonly string _type; private readonly string? _value; public string Name => _name; public string? Value => _value; public string Type => _type; public FormControlState(string name, string type, string? value) { _name = name; _type = type; _value = value; } } public sealed class FormDataSet : IEnumerable, IEnumerable { private readonly List _entries; private string _boundary; public string Boundary => _boundary; public FormDataSet() { _boundary = Guid.NewGuid().ToString(); _entries = new List(); } public Stream AsMultipart(IHtmlEncoder? htmlEncoder, Encoding? encoding = null) { return BuildRequestContent(encoding, delegate(StreamWriter stream) { Connect(new MultipartFormDataSetVisitor(htmlEncoder ?? new DefaultHtmlEncoder(), stream.Encoding, _boundary), stream); }); } public Stream AsUrlEncoded(Encoding? encoding = null) { return BuildRequestContent(encoding, delegate(StreamWriter stream) { Connect(new UrlEncodedFormDataSetVisitor(stream.Encoding), stream); }); } public Stream AsPlaintext(Encoding? encoding = null) { return BuildRequestContent(encoding, delegate(StreamWriter stream) { Connect(new PlaintextFormDataSetVisitor(), stream); }); } public Stream AsJson() { return BuildRequestContent(TextEncoding.Utf8, delegate(StreamWriter stream) { Connect(new JsonFormDataSetVisitor(), stream); }); } public Stream As(IFormSubmitter submitter, Encoding? encoding = null) { return BuildRequestContent(encoding, delegate(StreamWriter stream) { Connect(submitter, stream); }); } public void Append(string name, string value, string type) { if (type.Isi(InputTypeNames.Radio)) { FormDataSetEntry formDataSetEntry = _entries.FirstOrDefault((FormDataSetEntry s) => s.Name.Is(name) && s.Type.Isi(InputTypeNames.Radio)); if (formDataSetEntry != null) { _entries.Remove(formDataSetEntry); } } if (type.Isi(TagNames.Textarea)) { name = name.NormalizeLineEndings(); value = value.NormalizeLineEndings(); } _entries.Add(new TextDataSetEntry(name, value, type)); } public void Append(string name, IFile value, string type) { if (type.Isi(InputTypeNames.File)) { name = name.NormalizeLineEndings(); } _entries.Add(new FileDataSetEntry(name, value, type)); } private Stream BuildRequestContent(Encoding? encoding, Action process) { if (encoding == null) { encoding = TextEncoding.Utf8; } MemoryStream memoryStream = new MemoryStream(); FixPotentialBoundaryCollisions(encoding); ReplaceCharset(encoding); StreamWriter streamWriter = new StreamWriter(memoryStream, encoding); process(streamWriter); streamWriter.Flush(); memoryStream.Position = 0L; return memoryStream; } private void Connect(IFormSubmitter submitter, StreamWriter stream) { foreach (FormDataSetEntry entry in _entries) { entry.Accept(submitter); } submitter.Serialize(stream); } private void ReplaceCharset(Encoding encoding) { for (int i = 0; i < _entries.Count; i++) { FormDataSetEntry formDataSetEntry = _entries[i]; if (!string.IsNullOrEmpty(formDataSetEntry.Name) && formDataSetEntry.Name == "_charset_" && formDataSetEntry.Type.Isi(InputTypeNames.Hidden)) { _entries[i] = new TextDataSetEntry(formDataSetEntry.Name, encoding.WebName, formDataSetEntry.Type); } } } private void FixPotentialBoundaryCollisions(Encoding encoding) { bool flag = false; do { for (int i = 0; i < _entries.Count; i++) { if (flag = _entries[i].Contains(_boundary, encoding)) { _boundary = Guid.NewGuid().ToString(); break; } } } while (flag); } public IEnumerator GetEnumerator() { return _entries.Select((FormDataSetEntry m) => m.Name).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public static class FormMethodNames { public static readonly string Get = "get"; public static readonly string Post = "post"; public static readonly string Dialog = "dialog"; } internal sealed class HtmlElementFactory : IElementFactory { private delegate HtmlElement Creator(Document owner, string? prefix); internal static readonly HtmlElementFactory Instance = new HtmlElementFactory(); private readonly Dictionary creators = new Dictionary(StringComparer.OrdinalIgnoreCase) { { TagNames.Div, (Document document, string? prefix) => new HtmlDivElement(document, prefix) }, { TagNames.A, (Document document, string? prefix) => new HtmlAnchorElement(document, prefix) }, { TagNames.Img, (Document document, string? prefix) => new HtmlImageElement(document, prefix) }, { TagNames.P, (Document document, string? prefix) => new HtmlParagraphElement(document, prefix) }, { TagNames.Br, (Document document, string? prefix) => new HtmlBreakRowElement(document, prefix) }, { TagNames.Input, (Document document, string? prefix) => new HtmlInputElement(document, prefix) }, { TagNames.Button, (Document document, string? prefix) => new HtmlButtonElement(document, prefix) }, { TagNames.Textarea, (Document document, string? prefix) => new HtmlTextAreaElement(document, prefix) }, { TagNames.Li, (Document document, string? prefix) => new HtmlListItemElement(document, TagNames.Li, prefix) }, { TagNames.H1, (Document document, string? prefix) => new HtmlHeadingElement(document, TagNames.H1, prefix) }, { TagNames.H2, (Document document, string? prefix) => new HtmlHeadingElement(document, TagNames.H2, prefix) }, { TagNames.H3, (Document document, string? prefix) => new HtmlHeadingElement(document, TagNames.H3, prefix) }, { TagNames.H4, (Document document, string? prefix) => new HtmlHeadingElement(document, TagNames.H4, prefix) }, { TagNames.H5, (Document document, string? prefix) => new HtmlHeadingElement(document, TagNames.H5, prefix) }, { TagNames.H6, (Document document, string? prefix) => new HtmlHeadingElement(document, TagNames.H6, prefix) }, { TagNames.Ul, (Document document, string? prefix) => new HtmlUnorderedListElement(document, prefix) }, { TagNames.Ol, (Document document, string? prefix) => new HtmlOrderedListElement(document, prefix) }, { TagNames.Dl, (Document document, string? prefix) => new HtmlDefinitionListElement(document, prefix) }, { TagNames.Link, (Document document, string? prefix) => new HtmlLinkElement(document, prefix) }, { TagNames.Meta, (Document document, string? prefix) => new HtmlMetaElement(document, prefix) }, { TagNames.Label, (Document document, string? prefix) => new HtmlLabelElement(document, prefix) }, { TagNames.Fieldset, (Document document, string? prefix) => new HtmlFieldSetElement(document, prefix) }, { TagNames.Legend, (Document document, string? prefix) => new HtmlLegendElement(document, prefix) }, { TagNames.Form, (Document document, string? prefix) => new HtmlFormElement(document, prefix) }, { TagNames.Select, (Document document, string? prefix) => new HtmlSelectElement(document, prefix) }, { TagNames.Pre, (Document document, string? prefix) => new HtmlPreElement(document, prefix) }, { TagNames.Hr, (Document document, string? prefix) => new HtmlHrElement(document, prefix) }, { TagNames.Dir, (Document document, string? prefix) => new HtmlDirectoryElement(document, prefix) }, { TagNames.Font, (Document document, string? prefix) => new HtmlFontElement(document, prefix) }, { TagNames.Param, (Document document, string? prefix) => new HtmlParamElement(document, prefix) }, { TagNames.BlockQuote, (Document document, string? prefix) => new HtmlQuoteElement(document, TagNames.BlockQuote, prefix) }, { TagNames.Quote, (Document document, string? prefix) => new HtmlQuoteElement(document, TagNames.Quote, prefix) }, { TagNames.Q, (Document document, string? prefix) => new HtmlQuoteElement(document, TagNames.Q, prefix) }, { TagNames.Canvas, (Document document, string? prefix) => new HtmlCanvasElement(document, prefix) }, { TagNames.Caption, (Document document, string? prefix) => new HtmlTableCaptionElement(document, prefix) }, { TagNames.Td, (Document document, string? prefix) => new HtmlTableDataCellElement(document, prefix) }, { TagNames.Tr, (Document document, string? prefix) => new HtmlTableRowElement(document, prefix) }, { TagNames.Table, (Document document, string? prefix) => new HtmlTableElement(document, prefix) }, { TagNames.Tbody, (Document document, string? prefix) => new HtmlTableSectionElement(document, TagNames.Tbody, prefix) }, { TagNames.Th, (Document document, string? prefix) => new HtmlTableHeaderCellElement(document, prefix) }, { TagNames.Tfoot, (Document document, string? prefix) => new HtmlTableSectionElement(document, TagNames.Tfoot, prefix) }, { TagNames.Thead, (Document document, string? prefix) => new HtmlTableSectionElement(document, TagNames.Thead, prefix) }, { TagNames.Colgroup, (Document document, string? prefix) => new HtmlTableColgroupElement(document, prefix) }, { TagNames.Col, (Document document, string? prefix) => new HtmlTableColElement(document, prefix) }, { TagNames.Del, (Document document, string? prefix) => new HtmlModElement(document, TagNames.Del, prefix) }, { TagNames.Ins, (Document document, string? prefix) => new HtmlModElement(document, TagNames.Ins, prefix) }, { TagNames.Applet, (Document document, string? prefix) => new HtmlAppletElement(document, prefix) }, { TagNames.Object, (Document document, string? prefix) => new HtmlObjectElement(document, prefix) }, { TagNames.Optgroup, (Document document, string? prefix) => new HtmlOptionsGroupElement(document, prefix) }, { TagNames.Option, (Document document, string? prefix) => new HtmlOptionElement(document, prefix) }, { TagNames.Style, (Document document, string? prefix) => new HtmlStyleElement(document, prefix) }, { TagNames.Script, (Document document, string? prefix) => new HtmlScriptElement(document, prefix) }, { TagNames.Iframe, (Document document, string? prefix) => new HtmlIFrameElement(document, prefix) }, { TagNames.Dd, (Document document, string? prefix) => new HtmlListItemElement(document, TagNames.Dd, prefix) }, { TagNames.Dt, (Document document, string? prefix) => new HtmlListItemElement(document, TagNames.Dt, prefix) }, { TagNames.Frameset, (Document document, string? prefix) => new HtmlFrameSetElement(document, prefix) }, { TagNames.Frame, (Document document, string? prefix) => new HtmlFrameElement(document, prefix) }, { TagNames.Audio, (Document document, string? prefix) => new HtmlAudioElement(document, prefix) }, { TagNames.Video, (Document document, string? prefix) => new HtmlVideoElement(document, prefix) }, { TagNames.Span, (Document document, string? prefix) => new HtmlSpanElement(document, prefix) }, { TagNames.Dialog, (Document document, string? prefix) => new HtmlDialogElement(document, prefix) }, { TagNames.Details, (Document document, string? prefix) => new HtmlDetailsElement(document, prefix) }, { TagNames.Source, (Document document, string? prefix) => new HtmlSourceElement(document, prefix) }, { TagNames.Track, (Document document, string? prefix) => new HtmlTrackElement(document, prefix) }, { TagNames.Wbr, (Document document, string? prefix) => new HtmlWbrElement(document, prefix) }, { TagNames.B, (Document document, string? prefix) => new HtmlBoldElement(document, prefix) }, { TagNames.Big, (Document document, string? prefix) => new HtmlBigElement(document, prefix) }, { TagNames.Strike, (Document document, string? prefix) => new HtmlStrikeElement(document, prefix) }, { TagNames.Code, (Document document, string? prefix) => new HtmlCodeElement(document, prefix) }, { TagNames.Em, (Document document, string? prefix) => new HtmlEmphasizeElement(document, prefix) }, { TagNames.I, (Document document, string? prefix) => new HtmlItalicElement(document, prefix) }, { TagNames.S, (Document document, string? prefix) => new HtmlStruckElement(document, prefix) }, { TagNames.Small, (Document document, string? prefix) => new HtmlSmallElement(document, prefix) }, { TagNames.Strong, (Document document, string? prefix) => new HtmlStrongElement(document, prefix) }, { TagNames.U, (Document document, string? prefix) => new HtmlUnderlineElement(document, prefix) }, { TagNames.Tt, (Document document, string? prefix) => new HtmlTeletypeTextElement(document, prefix) }, { TagNames.Address, (Document document, string? prefix) => new HtmlAddressElement(document, prefix) }, { TagNames.Main, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Main, prefix) }, { TagNames.Summary, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Summary, prefix) }, { TagNames.Center, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Center, prefix) }, { TagNames.Listing, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Listing, prefix) }, { TagNames.Nav, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Nav, prefix) }, { TagNames.Article, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Article, prefix) }, { TagNames.Aside, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Aside, prefix) }, { TagNames.Figcaption, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Figcaption, prefix) }, { TagNames.Figure, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Figure, prefix) }, { TagNames.Section, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Section, prefix) }, { TagNames.Footer, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Footer, prefix) }, { TagNames.Header, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Header, prefix) }, { TagNames.Hgroup, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Hgroup, prefix) }, { TagNames.Cite, (Document document, string? prefix) => new HtmlElement(document, TagNames.Cite, prefix) }, { TagNames.Ruby, (Document document, string? prefix) => new HtmlRubyElement(document, prefix) }, { TagNames.Rt, (Document document, string? prefix) => new HtmlRtElement(document, prefix) }, { TagNames.Rp, (Document document, string? prefix) => new HtmlRpElement(document, prefix) }, { TagNames.Rtc, (Document document, string? prefix) => new HtmlRtcElement(document, prefix) }, { TagNames.Rb, (Document document, string? prefix) => new HtmlRbElement(document, prefix) }, { TagNames.Map, (Document document, string? prefix) => new HtmlMapElement(document, prefix) }, { TagNames.Datalist, (Document document, string? prefix) => new HtmlDataListElement(document, prefix) }, { TagNames.Xmp, (Document document, string? prefix) => new HtmlXmpElement(document, prefix) }, { TagNames.Picture, (Document document, string? prefix) => new HtmlPictureElement(document, prefix) }, { TagNames.Template, (Document document, string? prefix) => new HtmlTemplateElement(document, prefix) }, { TagNames.Time, (Document document, string? prefix) => new HtmlTimeElement(document, prefix) }, { TagNames.Progress, (Document document, string? prefix) => new HtmlProgressElement(document, prefix) }, { TagNames.Meter, (Document document, string? prefix) => new HtmlMeterElement(document, prefix) }, { TagNames.Output, (Document document, string? prefix) => new HtmlOutputElement(document, prefix) }, { TagNames.Keygen, (Document document, string? prefix) => new HtmlKeygenElement(document, prefix) }, { TagNames.Title, (Document document, string? prefix) => new HtmlTitleElement(document, prefix) }, { TagNames.Head, (Document document, string? prefix) => new HtmlHeadElement(document, prefix) }, { TagNames.Body, (Document document, string? prefix) => new HtmlBodyElement(document, prefix) }, { TagNames.Html, (Document document, string? prefix) => new HtmlHtmlElement(document, prefix) }, { TagNames.Area, (Document document, string? prefix) => new HtmlAreaElement(document, prefix) }, { TagNames.Embed, (Document document, string? prefix) => new HtmlEmbedElement(document, prefix) }, { TagNames.MenuItem, (Document document, string? prefix) => new HtmlMenuItemElement(document, prefix) }, { TagNames.Slot, (Document document, string? prefix) => new HtmlSlotElement(document, prefix) }, { TagNames.NoScript, (Document document, string? prefix) => new HtmlNoScriptElement(document, prefix, false) }, { TagNames.NoEmbed, (Document document, string? prefix) => new HtmlNoEmbedElement(document, prefix) }, { TagNames.NoFrames, (Document document, string? prefix) => new HtmlNoFramesElement(document, prefix) }, { TagNames.NoBr, (Document document, string? prefix) => new HtmlNoNewlineElement(document, prefix) }, { TagNames.Menu, (Document document, string? prefix) => new HtmlMenuElement(document, prefix) }, { TagNames.Base, (Document document, string? prefix) => new HtmlBaseElement(document, prefix) }, { TagNames.BaseFont, (Document document, string? prefix) => new HtmlBaseFontElement(document, prefix) }, { TagNames.Bgsound, (Document document, string? prefix) => new HtmlBgsoundElement(document, prefix) }, { TagNames.Marquee, (Document document, string? prefix) => new HtmlMarqueeElement(document, prefix) }, { TagNames.Data, (Document document, string? prefix) => new HtmlDataElement(document, prefix) }, { TagNames.Plaintext, (Document document, string? prefix) => new HtmlSemanticElement(document, TagNames.Plaintext, prefix) }, { TagNames.IsIndex, (Document document, string? prefix) => new HtmlIsIndexElement(document, prefix) }, { TagNames.Mark, (Document document, string? _) => new HtmlElement(document, TagNames.Mark) }, { TagNames.Sub, (Document document, string? _) => new HtmlElement(document, TagNames.Sub) }, { TagNames.Sup, (Document document, string? _) => new HtmlElement(document, TagNames.Sup) }, { TagNames.Dfn, (Document document, string? _) => new HtmlElement(document, TagNames.Dfn) }, { TagNames.Kbd, (Document document, string? _) => new HtmlElement(document, TagNames.Kbd) }, { TagNames.Var, (Document document, string? _) => new HtmlElement(document, TagNames.Var) }, { TagNames.Samp, (Document document, string? _) => new HtmlElement(document, TagNames.Samp) }, { TagNames.Abbr, (Document document, string? _) => new HtmlElement(document, TagNames.Abbr) }, { TagNames.Bdi, (Document document, string? _) => new HtmlElement(document, TagNames.Bdi) }, { TagNames.Bdo, (Document document, string? _) => new HtmlElement(document, TagNames.Bdo) } }; public HtmlElement Create(Document document, string localName, string? prefix = null, NodeFlags flags = NodeFlags.None) { if (creators.TryGetValue(localName, out Creator value)) { return value(document, prefix); } return new HtmlUnknownElement(document, localName.HtmlLower(), prefix, flags); } } public sealed class HtmlEntityProvider : IEntityProvider, IReverseEntityProvider, IEntityProviderExtended { private readonly Dictionary> _entities; private static readonly HtmlEntityProvider Instance = new HtmlEntityProvider(); public static readonly IEntityProvider Resolver = Instance; public static readonly IEntityProviderExtended ResolverExtended = Instance; public static IReverseEntityProvider ReverseResolver => Instance; private HtmlEntityProvider() { Dictionary> source = new Dictionary> { { 'a', GetSymbolLittleA() }, { 'A', GetSymbolBigA() }, { 'b', GetSymbolLittleB() }, { 'B', GetSymbolBigB() }, { 'c', GetSymbolLittleC() }, { 'C', GetSymbolBigC() }, { 'd', GetSymbolLittleD() }, { 'D', GetSymbolBigD() }, { 'e', GetSymbolLittleE() }, { 'E', GetSymbolBigE() }, { 'f', GetSymbolLittleF() }, { 'F', GetSymbolBigF() }, { 'g', GetSymbolLittleG() }, { 'G', GetSymbolBigG() }, { 'h', GetSymbolLittleH() }, { 'H', GetSymbolBigH() }, { 'i', GetSymbolLittleI() }, { 'I', GetSymbolBigI() }, { 'j', GetSymbolLittleJ() }, { 'J', GetSymbolBigJ() }, { 'k', GetSymbolLittleK() }, { 'K', GetSymbolBigK() }, { 'l', GetSymbolLittleL() }, { 'L', GetSymbolBigL() }, { 'm', GetSymbolLittleM() }, { 'M', GetSymbolBigM() }, { 'n', GetSymbolLittleN() }, { 'N', GetSymbolBigN() }, { 'o', GetSymbolLittleO() }, { 'O', GetSymbolBigO() }, { 'p', GetSymbolLittleP() }, { 'P', GetSymbolBigP() }, { 'q', GetSymbolLittleQ() }, { 'Q', GetSymbolBigQ() }, { 'r', GetSymbolLittleR() }, { 'R', GetSymbolBigR() }, { 's', GetSymbolLittleS() }, { 'S', GetSymbolBigS() }, { 't', GetSymbolLittleT() }, { 'T', GetSymbolBigT() }, { 'u', GetSymbolLittleU() }, { 'U', GetSymbolBigU() }, { 'v', GetSymbolLittleV() }, { 'V', GetSymbolBigV() }, { 'w', GetSymbolLittleW() }, { 'W', GetSymbolBigW() }, { 'x', GetSymbolLittleX() }, { 'X', GetSymbolBigX() }, { 'y', GetSymbolLittleY() }, { 'Y', GetSymbolBigY() }, { 'z', GetSymbolLittleZ() }, { 'Z', GetSymbolBigZ() } }; _entities = source.ToDictionary((KeyValuePair> k) => k.Key, (KeyValuePair> v) => v.Value.ToDictionary((KeyValuePair k) => new StringOrMemory(k.Key), (KeyValuePair keyValuePair) => keyValuePair.Value, OrdinalStringOrMemoryComparer.Instance)); } private Dictionary GetSymbolLittleA() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "aacute;", Convert(225)); AddSingle(dictionary, "abreve;", Convert(259)); AddSingle(dictionary, "ac;", Convert(8766)); AddSingle(dictionary, "acd;", Convert(8767)); AddSingle(dictionary, "acE;", Convert(8766, 819)); AddBoth(dictionary, "acirc;", Convert(226)); AddBoth(dictionary, "acute;", Convert(180)); AddSingle(dictionary, "acy;", Convert(1072)); AddBoth(dictionary, "aelig;", Convert(230)); AddSingle(dictionary, "af;", Convert(8289)); AddSingle(dictionary, "afr;", Convert(120094)); AddBoth(dictionary, "agrave;", Convert(224)); AddSingle(dictionary, "alefsym;", Convert(8501)); AddSingle(dictionary, "aleph;", Convert(8501)); AddSingle(dictionary, "alpha;", Convert(945)); AddSingle(dictionary, "amacr;", Convert(257)); AddSingle(dictionary, "amalg;", Convert(10815)); AddBoth(dictionary, "amp;", Convert(38)); AddSingle(dictionary, "and;", Convert(8743)); AddSingle(dictionary, "andand;", Convert(10837)); AddSingle(dictionary, "andd;", Convert(10844)); AddSingle(dictionary, "andslope;", Convert(10840)); AddSingle(dictionary, "andv;", Convert(10842)); AddSingle(dictionary, "ang;", Convert(8736)); AddSingle(dictionary, "ange;", Convert(10660)); AddSingle(dictionary, "angle;", Convert(8736)); AddSingle(dictionary, "angmsd;", Convert(8737)); AddSingle(dictionary, "angmsdaa;", Convert(10664)); AddSingle(dictionary, "angmsdab;", Convert(10665)); AddSingle(dictionary, "angmsdac;", Convert(10666)); AddSingle(dictionary, "angmsdad;", Convert(10667)); AddSingle(dictionary, "angmsdae;", Convert(10668)); AddSingle(dictionary, "angmsdaf;", Convert(10669)); AddSingle(dictionary, "angmsdag;", Convert(10670)); AddSingle(dictionary, "angmsdah;", Convert(10671)); AddSingle(dictionary, "angrt;", Convert(8735)); AddSingle(dictionary, "angrtvb;", Convert(8894)); AddSingle(dictionary, "angrtvbd;", Convert(10653)); AddSingle(dictionary, "angsph;", Convert(8738)); AddSingle(dictionary, "angst;", Convert(197)); AddSingle(dictionary, "angzarr;", Convert(9084)); AddSingle(dictionary, "aogon;", Convert(261)); AddSingle(dictionary, "aopf;", Convert(120146)); AddSingle(dictionary, "ap;", Convert(8776)); AddSingle(dictionary, "apacir;", Convert(10863)); AddSingle(dictionary, "apE;", Convert(10864)); AddSingle(dictionary, "ape;", Convert(8778)); AddSingle(dictionary, "apid;", Convert(8779)); AddSingle(dictionary, "apos;", Convert(39)); AddSingle(dictionary, "approx;", Convert(8776)); AddSingle(dictionary, "approxeq;", Convert(8778)); AddBoth(dictionary, "aring;", Convert(229)); AddSingle(dictionary, "ascr;", Convert(119990)); AddSingle(dictionary, "ast;", Convert(42)); AddSingle(dictionary, "asymp;", Convert(8776)); AddSingle(dictionary, "asympeq;", Convert(8781)); AddBoth(dictionary, "atilde;", Convert(227)); AddBoth(dictionary, "auml;", Convert(228)); AddSingle(dictionary, "awconint;", Convert(8755)); AddSingle(dictionary, "awint;", Convert(10769)); return dictionary; } private Dictionary GetSymbolBigA() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Aogon;", Convert(260)); AddSingle(dictionary, "Aopf;", Convert(120120)); AddSingle(dictionary, "ApplyFunction;", Convert(8289)); AddBoth(dictionary, "Aring;", Convert(197)); AddSingle(dictionary, "Ascr;", Convert(119964)); AddSingle(dictionary, "Assign;", Convert(8788)); AddBoth(dictionary, "Atilde;", Convert(195)); AddBoth(dictionary, "Auml;", Convert(196)); AddBoth(dictionary, "Aacute;", Convert(193)); AddSingle(dictionary, "Abreve;", Convert(258)); AddBoth(dictionary, "Acirc;", Convert(194)); AddSingle(dictionary, "Acy;", Convert(1040)); AddBoth(dictionary, "AElig;", Convert(198)); AddSingle(dictionary, "Afr;", Convert(120068)); AddBoth(dictionary, "Agrave;", Convert(192)); AddSingle(dictionary, "Alpha;", Convert(913)); AddSingle(dictionary, "Amacr;", Convert(256)); AddBoth(dictionary, "AMP;", Convert(38)); AddSingle(dictionary, "And;", Convert(10835)); return dictionary; } private Dictionary GetSymbolLittleB() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "backcong;", Convert(8780)); AddSingle(dictionary, "backepsilon;", Convert(1014)); AddSingle(dictionary, "backprime;", Convert(8245)); AddSingle(dictionary, "backsim;", Convert(8765)); AddSingle(dictionary, "backsimeq;", Convert(8909)); AddSingle(dictionary, "barvee;", Convert(8893)); AddSingle(dictionary, "barwed;", Convert(8965)); AddSingle(dictionary, "barwedge;", Convert(8965)); AddSingle(dictionary, "bbrk;", Convert(9141)); AddSingle(dictionary, "bbrktbrk;", Convert(9142)); AddSingle(dictionary, "bcong;", Convert(8780)); AddSingle(dictionary, "bcy;", Convert(1073)); AddSingle(dictionary, "bdquo;", Convert(8222)); AddSingle(dictionary, "becaus;", Convert(8757)); AddSingle(dictionary, "because;", Convert(8757)); AddSingle(dictionary, "bemptyv;", Convert(10672)); AddSingle(dictionary, "bepsi;", Convert(1014)); AddSingle(dictionary, "bernou;", Convert(8492)); AddSingle(dictionary, "beta;", Convert(946)); AddSingle(dictionary, "beth;", Convert(8502)); AddSingle(dictionary, "between;", Convert(8812)); AddSingle(dictionary, "bfr;", Convert(120095)); AddSingle(dictionary, "bigcap;", Convert(8898)); AddSingle(dictionary, "bigcirc;", Convert(9711)); AddSingle(dictionary, "bigcup;", Convert(8899)); AddSingle(dictionary, "bigodot;", Convert(10752)); AddSingle(dictionary, "bigoplus;", Convert(10753)); AddSingle(dictionary, "bigotimes;", Convert(10754)); AddSingle(dictionary, "bigsqcup;", Convert(10758)); AddSingle(dictionary, "bigstar;", Convert(9733)); AddSingle(dictionary, "bigtriangledown;", Convert(9661)); AddSingle(dictionary, "bigtriangleup;", Convert(9651)); AddSingle(dictionary, "biguplus;", Convert(10756)); AddSingle(dictionary, "bigvee;", Convert(8897)); AddSingle(dictionary, "bigwedge;", Convert(8896)); AddSingle(dictionary, "bkarow;", Convert(10509)); AddSingle(dictionary, "blacklozenge;", Convert(10731)); AddSingle(dictionary, "blacksquare;", Convert(9642)); AddSingle(dictionary, "blacktriangle;", Convert(9652)); AddSingle(dictionary, "blacktriangledown;", Convert(9662)); AddSingle(dictionary, "blacktriangleleft;", Convert(9666)); AddSingle(dictionary, "blacktriangleright;", Convert(9656)); AddSingle(dictionary, "blank;", Convert(9251)); AddSingle(dictionary, "blk12;", Convert(9618)); AddSingle(dictionary, "blk14;", Convert(9617)); AddSingle(dictionary, "blk34;", Convert(9619)); AddSingle(dictionary, "block;", Convert(9608)); AddSingle(dictionary, "bne;", Convert(61, 8421)); AddSingle(dictionary, "bnequiv;", Convert(8801, 8421)); AddSingle(dictionary, "bNot;", Convert(10989)); AddSingle(dictionary, "bnot;", Convert(8976)); AddSingle(dictionary, "bopf;", Convert(120147)); AddSingle(dictionary, "bot;", Convert(8869)); AddSingle(dictionary, "bottom;", Convert(8869)); AddSingle(dictionary, "bowtie;", Convert(8904)); AddSingle(dictionary, "boxbox;", Convert(10697)); AddSingle(dictionary, "boxDL;", Convert(9559)); AddSingle(dictionary, "boxDl;", Convert(9558)); AddSingle(dictionary, "boxdL;", Convert(9557)); AddSingle(dictionary, "boxdl;", Convert(9488)); AddSingle(dictionary, "boxDR;", Convert(9556)); AddSingle(dictionary, "boxDr;", Convert(9555)); AddSingle(dictionary, "boxdR;", Convert(9554)); AddSingle(dictionary, "boxdr;", Convert(9484)); AddSingle(dictionary, "boxH;", Convert(9552)); AddSingle(dictionary, "boxh;", Convert(9472)); AddSingle(dictionary, "boxHD;", Convert(9574)); AddSingle(dictionary, "boxHd;", Convert(9572)); AddSingle(dictionary, "boxhD;", Convert(9573)); AddSingle(dictionary, "boxhd;", Convert(9516)); AddSingle(dictionary, "boxHU;", Convert(9577)); AddSingle(dictionary, "boxHu;", Convert(9575)); AddSingle(dictionary, "boxhU;", Convert(9576)); AddSingle(dictionary, "boxhu;", Convert(9524)); AddSingle(dictionary, "boxminus;", Convert(8863)); AddSingle(dictionary, "boxplus;", Convert(8862)); AddSingle(dictionary, "boxtimes;", Convert(8864)); AddSingle(dictionary, "boxUL;", Convert(9565)); AddSingle(dictionary, "boxUl;", Convert(9564)); AddSingle(dictionary, "boxuL;", Convert(9563)); AddSingle(dictionary, "boxul;", Convert(9496)); AddSingle(dictionary, "boxUR;", Convert(9562)); AddSingle(dictionary, "boxUr;", Convert(9561)); AddSingle(dictionary, "boxuR;", Convert(9560)); AddSingle(dictionary, "boxur;", Convert(9492)); AddSingle(dictionary, "boxV;", Convert(9553)); AddSingle(dictionary, "boxv;", Convert(9474)); AddSingle(dictionary, "boxVH;", Convert(9580)); AddSingle(dictionary, "boxVh;", Convert(9579)); AddSingle(dictionary, "boxvH;", Convert(9578)); AddSingle(dictionary, "boxvh;", Convert(9532)); AddSingle(dictionary, "boxVL;", Convert(9571)); AddSingle(dictionary, "boxVl;", Convert(9570)); AddSingle(dictionary, "boxvL;", Convert(9569)); AddSingle(dictionary, "boxvl;", Convert(9508)); AddSingle(dictionary, "boxVR;", Convert(9568)); AddSingle(dictionary, "boxVr;", Convert(9567)); AddSingle(dictionary, "boxvR;", Convert(9566)); AddSingle(dictionary, "boxvr;", Convert(9500)); AddSingle(dictionary, "bprime;", Convert(8245)); AddSingle(dictionary, "breve;", Convert(728)); AddBoth(dictionary, "brvbar;", Convert(166)); AddSingle(dictionary, "bscr;", Convert(119991)); AddSingle(dictionary, "bsemi;", Convert(8271)); AddSingle(dictionary, "bsim;", Convert(8765)); AddSingle(dictionary, "bsime;", Convert(8909)); AddSingle(dictionary, "bsol;", Convert(92)); AddSingle(dictionary, "bsolb;", Convert(10693)); AddSingle(dictionary, "bsolhsub;", Convert(10184)); AddSingle(dictionary, "bull;", Convert(8226)); AddSingle(dictionary, "bullet;", Convert(8226)); AddSingle(dictionary, "bump;", Convert(8782)); AddSingle(dictionary, "bumpE;", Convert(10926)); AddSingle(dictionary, "bumpe;", Convert(8783)); AddSingle(dictionary, "bumpeq;", Convert(8783)); return dictionary; } private Dictionary GetSymbolBigB() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Backslash;", Convert(8726)); AddSingle(dictionary, "Barv;", Convert(10983)); AddSingle(dictionary, "Barwed;", Convert(8966)); AddSingle(dictionary, "Bcy;", Convert(1041)); AddSingle(dictionary, "Because;", Convert(8757)); AddSingle(dictionary, "Bernoullis;", Convert(8492)); AddSingle(dictionary, "Beta;", Convert(914)); AddSingle(dictionary, "Bfr;", Convert(120069)); AddSingle(dictionary, "Bopf;", Convert(120121)); AddSingle(dictionary, "Breve;", Convert(728)); AddSingle(dictionary, "Bscr;", Convert(8492)); AddSingle(dictionary, "Bumpeq;", Convert(8782)); return dictionary; } private Dictionary GetSymbolLittleC() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "cacute;", Convert(263)); AddSingle(dictionary, "cap;", Convert(8745)); AddSingle(dictionary, "capand;", Convert(10820)); AddSingle(dictionary, "capbrcup;", Convert(10825)); AddSingle(dictionary, "capcap;", Convert(10827)); AddSingle(dictionary, "capcup;", Convert(10823)); AddSingle(dictionary, "capdot;", Convert(10816)); AddSingle(dictionary, "caps;", Convert(8745, 65024)); AddSingle(dictionary, "caret;", Convert(8257)); AddSingle(dictionary, "caron;", Convert(711)); AddSingle(dictionary, "ccaps;", Convert(10829)); AddSingle(dictionary, "ccaron;", Convert(269)); AddBoth(dictionary, "ccedil;", Convert(231)); AddSingle(dictionary, "ccirc;", Convert(265)); AddSingle(dictionary, "ccups;", Convert(10828)); AddSingle(dictionary, "ccupssm;", Convert(10832)); AddSingle(dictionary, "cdot;", Convert(267)); AddBoth(dictionary, "cedil;", Convert(184)); AddSingle(dictionary, "cemptyv;", Convert(10674)); AddBoth(dictionary, "cent;", Convert(162)); AddSingle(dictionary, "centerdot;", Convert(183)); AddSingle(dictionary, "cfr;", Convert(120096)); AddSingle(dictionary, "chcy;", Convert(1095)); AddSingle(dictionary, "check;", Convert(10003)); AddSingle(dictionary, "checkmark;", Convert(10003)); AddSingle(dictionary, "chi;", Convert(967)); AddSingle(dictionary, "cir;", Convert(9675)); AddSingle(dictionary, "circ;", Convert(710)); AddSingle(dictionary, "circeq;", Convert(8791)); AddSingle(dictionary, "circlearrowleft;", Convert(8634)); AddSingle(dictionary, "circlearrowright;", Convert(8635)); AddSingle(dictionary, "circledast;", Convert(8859)); AddSingle(dictionary, "circledcirc;", Convert(8858)); AddSingle(dictionary, "circleddash;", Convert(8861)); AddSingle(dictionary, "circledR;", Convert(174)); AddSingle(dictionary, "circledS;", Convert(9416)); AddSingle(dictionary, "cirE;", Convert(10691)); AddSingle(dictionary, "cire;", Convert(8791)); AddSingle(dictionary, "cirfnint;", Convert(10768)); AddSingle(dictionary, "cirmid;", Convert(10991)); AddSingle(dictionary, "cirscir;", Convert(10690)); AddSingle(dictionary, "clubs;", Convert(9827)); AddSingle(dictionary, "clubsuit;", Convert(9827)); AddSingle(dictionary, "colon;", Convert(58)); AddSingle(dictionary, "colone;", Convert(8788)); AddSingle(dictionary, "coloneq;", Convert(8788)); AddSingle(dictionary, "comma;", Convert(44)); AddSingle(dictionary, "commat;", Convert(64)); AddSingle(dictionary, "comp;", Convert(8705)); AddSingle(dictionary, "compfn;", Convert(8728)); AddSingle(dictionary, "complement;", Convert(8705)); AddSingle(dictionary, "complexes;", Convert(8450)); AddSingle(dictionary, "cong;", Convert(8773)); AddSingle(dictionary, "congdot;", Convert(10861)); AddSingle(dictionary, "conint;", Convert(8750)); AddSingle(dictionary, "copf;", Convert(120148)); AddSingle(dictionary, "coprod;", Convert(8720)); AddBoth(dictionary, "copy;", Convert(169)); AddSingle(dictionary, "copysr;", Convert(8471)); AddSingle(dictionary, "crarr;", Convert(8629)); AddSingle(dictionary, "cross;", Convert(10007)); AddSingle(dictionary, "cscr;", Convert(119992)); AddSingle(dictionary, "csub;", Convert(10959)); AddSingle(dictionary, "csube;", Convert(10961)); AddSingle(dictionary, "csup;", Convert(10960)); AddSingle(dictionary, "csupe;", Convert(10962)); AddSingle(dictionary, "ctdot;", Convert(8943)); AddSingle(dictionary, "cudarrl;", Convert(10552)); AddSingle(dictionary, "cudarrr;", Convert(10549)); AddSingle(dictionary, "cuepr;", Convert(8926)); AddSingle(dictionary, "cuesc;", Convert(8927)); AddSingle(dictionary, "cularr;", Convert(8630)); AddSingle(dictionary, "cularrp;", Convert(10557)); AddSingle(dictionary, "cup;", Convert(8746)); AddSingle(dictionary, "cupbrcap;", Convert(10824)); AddSingle(dictionary, "cupcap;", Convert(10822)); AddSingle(dictionary, "cupcup;", Convert(10826)); AddSingle(dictionary, "cupdot;", Convert(8845)); AddSingle(dictionary, "cupor;", Convert(10821)); AddSingle(dictionary, "cups;", Convert(8746, 65024)); AddSingle(dictionary, "curarr;", Convert(8631)); AddSingle(dictionary, "curarrm;", Convert(10556)); AddSingle(dictionary, "curlyeqprec;", Convert(8926)); AddSingle(dictionary, "curlyeqsucc;", Convert(8927)); AddSingle(dictionary, "curlyvee;", Convert(8910)); AddSingle(dictionary, "curlywedge;", Convert(8911)); AddBoth(dictionary, "curren;", Convert(164)); AddSingle(dictionary, "curvearrowleft;", Convert(8630)); AddSingle(dictionary, "curvearrowright;", Convert(8631)); AddSingle(dictionary, "cuvee;", Convert(8910)); AddSingle(dictionary, "cuwed;", Convert(8911)); AddSingle(dictionary, "cwconint;", Convert(8754)); AddSingle(dictionary, "cwint;", Convert(8753)); AddSingle(dictionary, "cylcty;", Convert(9005)); return dictionary; } private Dictionary GetSymbolBigC() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Cacute;", Convert(262)); AddSingle(dictionary, "Cap;", Convert(8914)); AddSingle(dictionary, "CapitalDifferentialD;", Convert(8517)); AddSingle(dictionary, "Cayleys;", Convert(8493)); AddSingle(dictionary, "Ccaron;", Convert(268)); AddBoth(dictionary, "Ccedil;", Convert(199)); AddSingle(dictionary, "Ccirc;", Convert(264)); AddSingle(dictionary, "Cconint;", Convert(8752)); AddSingle(dictionary, "Cdot;", Convert(266)); AddSingle(dictionary, "Cedilla;", Convert(184)); AddSingle(dictionary, "CenterDot;", Convert(183)); AddSingle(dictionary, "Cfr;", Convert(8493)); AddSingle(dictionary, "CHcy;", Convert(1063)); AddSingle(dictionary, "Chi;", Convert(935)); AddSingle(dictionary, "CircleDot;", Convert(8857)); AddSingle(dictionary, "CircleMinus;", Convert(8854)); AddSingle(dictionary, "CirclePlus;", Convert(8853)); AddSingle(dictionary, "CircleTimes;", Convert(8855)); AddSingle(dictionary, "ClockwiseContourIntegral;", Convert(8754)); AddSingle(dictionary, "CloseCurlyDoubleQuote;", Convert(8221)); AddSingle(dictionary, "CloseCurlyQuote;", Convert(8217)); AddSingle(dictionary, "Colon;", Convert(8759)); AddSingle(dictionary, "Colone;", Convert(10868)); AddSingle(dictionary, "Congruent;", Convert(8801)); AddSingle(dictionary, "Conint;", Convert(8751)); AddSingle(dictionary, "ContourIntegral;", Convert(8750)); AddSingle(dictionary, "Copf;", Convert(8450)); AddSingle(dictionary, "Coproduct;", Convert(8720)); AddBoth(dictionary, "COPY;", Convert(169)); AddSingle(dictionary, "CounterClockwiseContourIntegral;", Convert(8755)); AddSingle(dictionary, "Cross;", Convert(10799)); AddSingle(dictionary, "Cscr;", Convert(119966)); AddSingle(dictionary, "Cup;", Convert(8915)); AddSingle(dictionary, "CupCap;", Convert(8781)); return dictionary; } private Dictionary GetSymbolLittleD() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "dagger;", Convert(8224)); AddSingle(dictionary, "daleth;", Convert(8504)); AddSingle(dictionary, "dArr;", Convert(8659)); AddSingle(dictionary, "darr;", Convert(8595)); AddSingle(dictionary, "dash;", Convert(8208)); AddSingle(dictionary, "dashv;", Convert(8867)); AddSingle(dictionary, "dbkarow;", Convert(10511)); AddSingle(dictionary, "dblac;", Convert(733)); AddSingle(dictionary, "dcaron;", Convert(271)); AddSingle(dictionary, "dcy;", Convert(1076)); AddSingle(dictionary, "dd;", Convert(8518)); AddSingle(dictionary, "ddagger;", Convert(8225)); AddSingle(dictionary, "ddarr;", Convert(8650)); AddSingle(dictionary, "ddotseq;", Convert(10871)); AddBoth(dictionary, "deg;", Convert(176)); AddSingle(dictionary, "delta;", Convert(948)); AddSingle(dictionary, "demptyv;", Convert(10673)); AddSingle(dictionary, "dfisht;", Convert(10623)); AddSingle(dictionary, "dfr;", Convert(120097)); AddSingle(dictionary, "dHar;", Convert(10597)); AddSingle(dictionary, "dharl;", Convert(8643)); AddSingle(dictionary, "dharr;", Convert(8642)); AddSingle(dictionary, "diam;", Convert(8900)); AddSingle(dictionary, "diamond;", Convert(8900)); AddSingle(dictionary, "diamondsuit;", Convert(9830)); AddSingle(dictionary, "diams;", Convert(9830)); AddSingle(dictionary, "die;", Convert(168)); AddSingle(dictionary, "digamma;", Convert(989)); AddSingle(dictionary, "disin;", Convert(8946)); AddSingle(dictionary, "div;", Convert(247)); AddBoth(dictionary, "divide;", Convert(247)); AddSingle(dictionary, "divideontimes;", Convert(8903)); AddSingle(dictionary, "divonx;", Convert(8903)); AddSingle(dictionary, "djcy;", Convert(1106)); AddSingle(dictionary, "dlcorn;", Convert(8990)); AddSingle(dictionary, "dlcrop;", Convert(8973)); AddSingle(dictionary, "dollar;", Convert(36)); AddSingle(dictionary, "dopf;", Convert(120149)); AddSingle(dictionary, "dot;", Convert(729)); AddSingle(dictionary, "doteq;", Convert(8784)); AddSingle(dictionary, "doteqdot;", Convert(8785)); AddSingle(dictionary, "dotminus;", Convert(8760)); AddSingle(dictionary, "dotplus;", Convert(8724)); AddSingle(dictionary, "dotsquare;", Convert(8865)); AddSingle(dictionary, "doublebarwedge;", Convert(8966)); AddSingle(dictionary, "downarrow;", Convert(8595)); AddSingle(dictionary, "downdownarrows;", Convert(8650)); AddSingle(dictionary, "downharpoonleft;", Convert(8643)); AddSingle(dictionary, "downharpoonright;", Convert(8642)); AddSingle(dictionary, "drbkarow;", Convert(10512)); AddSingle(dictionary, "drcorn;", Convert(8991)); AddSingle(dictionary, "drcrop;", Convert(8972)); AddSingle(dictionary, "dscr;", Convert(119993)); AddSingle(dictionary, "dscy;", Convert(1109)); AddSingle(dictionary, "dsol;", Convert(10742)); AddSingle(dictionary, "dstrok;", Convert(273)); AddSingle(dictionary, "dtdot;", Convert(8945)); AddSingle(dictionary, "dtri;", Convert(9663)); AddSingle(dictionary, "dtrif;", Convert(9662)); AddSingle(dictionary, "duarr;", Convert(8693)); AddSingle(dictionary, "duhar;", Convert(10607)); AddSingle(dictionary, "dwangle;", Convert(10662)); AddSingle(dictionary, "dzcy;", Convert(1119)); AddSingle(dictionary, "dzigrarr;", Convert(10239)); return dictionary; } private Dictionary GetSymbolBigD() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Dagger;", Convert(8225)); AddSingle(dictionary, "Darr;", Convert(8609)); AddSingle(dictionary, "Dashv;", Convert(10980)); AddSingle(dictionary, "Dcaron;", Convert(270)); AddSingle(dictionary, "Dcy;", Convert(1044)); AddSingle(dictionary, "DD;", Convert(8517)); AddSingle(dictionary, "DDotrahd;", Convert(10513)); AddSingle(dictionary, "Del;", Convert(8711)); AddSingle(dictionary, "Delta;", Convert(916)); AddSingle(dictionary, "Dfr;", Convert(120071)); AddSingle(dictionary, "DiacriticalAcute;", Convert(180)); AddSingle(dictionary, "DiacriticalDot;", Convert(729)); AddSingle(dictionary, "DiacriticalDoubleAcute;", Convert(733)); AddSingle(dictionary, "DiacriticalGrave;", Convert(96)); AddSingle(dictionary, "DiacriticalTilde;", Convert(732)); AddSingle(dictionary, "Diamond;", Convert(8900)); AddSingle(dictionary, "DifferentialD;", Convert(8518)); AddSingle(dictionary, "DJcy;", Convert(1026)); AddSingle(dictionary, "Dopf;", Convert(120123)); AddSingle(dictionary, "Dot;", Convert(168)); AddSingle(dictionary, "DotDot;", Convert(8412)); AddSingle(dictionary, "DotEqual;", Convert(8784)); AddSingle(dictionary, "DoubleContourIntegral;", Convert(8751)); AddSingle(dictionary, "DoubleDot;", Convert(168)); AddSingle(dictionary, "DoubleDownArrow;", Convert(8659)); AddSingle(dictionary, "DoubleLeftArrow;", Convert(8656)); AddSingle(dictionary, "DoubleLeftRightArrow;", Convert(8660)); AddSingle(dictionary, "DoubleLeftTee;", Convert(10980)); AddSingle(dictionary, "DoubleLongLeftArrow;", Convert(10232)); AddSingle(dictionary, "DoubleLongLeftRightArrow;", Convert(10234)); AddSingle(dictionary, "DoubleLongRightArrow;", Convert(10233)); AddSingle(dictionary, "DoubleRightArrow;", Convert(8658)); AddSingle(dictionary, "DoubleRightTee;", Convert(8872)); AddSingle(dictionary, "DoubleUpArrow;", Convert(8657)); AddSingle(dictionary, "DoubleUpDownArrow;", Convert(8661)); AddSingle(dictionary, "DoubleVerticalBar;", Convert(8741)); AddSingle(dictionary, "DownArrow;", Convert(8595)); AddSingle(dictionary, "Downarrow;", Convert(8659)); AddSingle(dictionary, "DownArrowBar;", Convert(10515)); AddSingle(dictionary, "DownArrowUpArrow;", Convert(8693)); AddSingle(dictionary, "DownBreve;", Convert(785)); AddSingle(dictionary, "DownLeftRightVector;", Convert(10576)); AddSingle(dictionary, "DownLeftTeeVector;", Convert(10590)); AddSingle(dictionary, "DownLeftVector;", Convert(8637)); AddSingle(dictionary, "DownLeftVectorBar;", Convert(10582)); AddSingle(dictionary, "DownRightTeeVector;", Convert(10591)); AddSingle(dictionary, "DownRightVector;", Convert(8641)); AddSingle(dictionary, "DownRightVectorBar;", Convert(10583)); AddSingle(dictionary, "DownTee;", Convert(8868)); AddSingle(dictionary, "DownTeeArrow;", Convert(8615)); AddSingle(dictionary, "Dscr;", Convert(119967)); AddSingle(dictionary, "DScy;", Convert(1029)); AddSingle(dictionary, "Dstrok;", Convert(272)); AddSingle(dictionary, "DZcy;", Convert(1039)); return dictionary; } private Dictionary GetSymbolLittleE() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "eacute;", Convert(233)); AddSingle(dictionary, "easter;", Convert(10862)); AddSingle(dictionary, "ecaron;", Convert(283)); AddSingle(dictionary, "ecir;", Convert(8790)); AddBoth(dictionary, "ecirc;", Convert(234)); AddSingle(dictionary, "ecolon;", Convert(8789)); AddSingle(dictionary, "ecy;", Convert(1101)); AddSingle(dictionary, "eDDot;", Convert(10871)); AddSingle(dictionary, "eDot;", Convert(8785)); AddSingle(dictionary, "edot;", Convert(279)); AddSingle(dictionary, "ee;", Convert(8519)); AddSingle(dictionary, "efDot;", Convert(8786)); AddSingle(dictionary, "efr;", Convert(120098)); AddSingle(dictionary, "eg;", Convert(10906)); AddBoth(dictionary, "egrave;", Convert(232)); AddSingle(dictionary, "egs;", Convert(10902)); AddSingle(dictionary, "egsdot;", Convert(10904)); AddSingle(dictionary, "el;", Convert(10905)); AddSingle(dictionary, "elinters;", Convert(9191)); AddSingle(dictionary, "ell;", Convert(8467)); AddSingle(dictionary, "els;", Convert(10901)); AddSingle(dictionary, "elsdot;", Convert(10903)); AddSingle(dictionary, "emacr;", Convert(275)); AddSingle(dictionary, "empty;", Convert(8709)); AddSingle(dictionary, "emptyset;", Convert(8709)); AddSingle(dictionary, "emptyv;", Convert(8709)); AddSingle(dictionary, "emsp;", Convert(8195)); AddSingle(dictionary, "emsp13;", Convert(8196)); AddSingle(dictionary, "emsp14;", Convert(8197)); AddSingle(dictionary, "eng;", Convert(331)); AddSingle(dictionary, "ensp;", Convert(8194)); AddSingle(dictionary, "eogon;", Convert(281)); AddSingle(dictionary, "eopf;", Convert(120150)); AddSingle(dictionary, "epar;", Convert(8917)); AddSingle(dictionary, "eparsl;", Convert(10723)); AddSingle(dictionary, "eplus;", Convert(10865)); AddSingle(dictionary, "epsi;", Convert(949)); AddSingle(dictionary, "epsilon;", Convert(949)); AddSingle(dictionary, "epsiv;", Convert(1013)); AddSingle(dictionary, "eqcirc;", Convert(8790)); AddSingle(dictionary, "eqcolon;", Convert(8789)); AddSingle(dictionary, "eqsim;", Convert(8770)); AddSingle(dictionary, "eqslantgtr;", Convert(10902)); AddSingle(dictionary, "eqslantless;", Convert(10901)); AddSingle(dictionary, "equals;", Convert(61)); AddSingle(dictionary, "equest;", Convert(8799)); AddSingle(dictionary, "equiv;", Convert(8801)); AddSingle(dictionary, "equivDD;", Convert(10872)); AddSingle(dictionary, "eqvparsl;", Convert(10725)); AddSingle(dictionary, "erarr;", Convert(10609)); AddSingle(dictionary, "erDot;", Convert(8787)); AddSingle(dictionary, "escr;", Convert(8495)); AddSingle(dictionary, "esdot;", Convert(8784)); AddSingle(dictionary, "esim;", Convert(8770)); AddSingle(dictionary, "eta;", Convert(951)); AddBoth(dictionary, "eth;", Convert(240)); AddBoth(dictionary, "euml;", Convert(235)); AddSingle(dictionary, "euro;", Convert(8364)); AddSingle(dictionary, "excl;", Convert(33)); AddSingle(dictionary, "exist;", Convert(8707)); AddSingle(dictionary, "expectation;", Convert(8496)); AddSingle(dictionary, "exponentiale;", Convert(8519)); return dictionary; } private Dictionary GetSymbolBigE() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "Eacute;", Convert(201)); AddSingle(dictionary, "Ecaron;", Convert(282)); AddBoth(dictionary, "Ecirc;", Convert(202)); AddSingle(dictionary, "Ecy;", Convert(1069)); AddSingle(dictionary, "Edot;", Convert(278)); AddSingle(dictionary, "Efr;", Convert(120072)); AddBoth(dictionary, "Egrave;", Convert(200)); AddSingle(dictionary, "Element;", Convert(8712)); AddSingle(dictionary, "Emacr;", Convert(274)); AddSingle(dictionary, "EmptySmallSquare;", Convert(9723)); AddSingle(dictionary, "EmptyVerySmallSquare;", Convert(9643)); AddSingle(dictionary, "ENG;", Convert(330)); AddSingle(dictionary, "Eogon;", Convert(280)); AddSingle(dictionary, "Eopf;", Convert(120124)); AddSingle(dictionary, "Epsilon;", Convert(917)); AddSingle(dictionary, "Equal;", Convert(10869)); AddSingle(dictionary, "EqualTilde;", Convert(8770)); AddSingle(dictionary, "Equilibrium;", Convert(8652)); AddSingle(dictionary, "Escr;", Convert(8496)); AddSingle(dictionary, "Esim;", Convert(10867)); AddSingle(dictionary, "Eta;", Convert(919)); AddBoth(dictionary, "ETH;", Convert(208)); AddBoth(dictionary, "Euml;", Convert(203)); AddSingle(dictionary, "Exists;", Convert(8707)); AddSingle(dictionary, "ExponentialE;", Convert(8519)); return dictionary; } private Dictionary GetSymbolLittleF() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "fallingdotseq;", Convert(8786)); AddSingle(dictionary, "fcy;", Convert(1092)); AddSingle(dictionary, "female;", Convert(9792)); AddSingle(dictionary, "ffilig;", Convert(64259)); AddSingle(dictionary, "fflig;", Convert(64256)); AddSingle(dictionary, "ffllig;", Convert(64260)); AddSingle(dictionary, "ffr;", Convert(120099)); AddSingle(dictionary, "filig;", Convert(64257)); AddSingle(dictionary, "fjlig;", Convert(102, 106)); AddSingle(dictionary, "flat;", Convert(9837)); AddSingle(dictionary, "fllig;", Convert(64258)); AddSingle(dictionary, "fltns;", Convert(9649)); AddSingle(dictionary, "fnof;", Convert(402)); AddSingle(dictionary, "fopf;", Convert(120151)); AddSingle(dictionary, "forall;", Convert(8704)); AddSingle(dictionary, "fork;", Convert(8916)); AddSingle(dictionary, "forkv;", Convert(10969)); AddSingle(dictionary, "fpartint;", Convert(10765)); AddBoth(dictionary, "frac12;", Convert(189)); AddSingle(dictionary, "frac13;", Convert(8531)); AddBoth(dictionary, "frac14;", Convert(188)); AddSingle(dictionary, "frac15;", Convert(8533)); AddSingle(dictionary, "frac16;", Convert(8537)); AddSingle(dictionary, "frac18;", Convert(8539)); AddSingle(dictionary, "frac23;", Convert(8532)); AddSingle(dictionary, "frac25;", Convert(8534)); AddBoth(dictionary, "frac34;", Convert(190)); AddSingle(dictionary, "frac35;", Convert(8535)); AddSingle(dictionary, "frac38;", Convert(8540)); AddSingle(dictionary, "frac45;", Convert(8536)); AddSingle(dictionary, "frac56;", Convert(8538)); AddSingle(dictionary, "frac58;", Convert(8541)); AddSingle(dictionary, "frac78;", Convert(8542)); AddSingle(dictionary, "frasl;", Convert(8260)); AddSingle(dictionary, "frown;", Convert(8994)); AddSingle(dictionary, "fscr;", Convert(119995)); return dictionary; } private Dictionary GetSymbolBigF() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Fcy;", Convert(1060)); AddSingle(dictionary, "Ffr;", Convert(120073)); AddSingle(dictionary, "FilledSmallSquare;", Convert(9724)); AddSingle(dictionary, "FilledVerySmallSquare;", Convert(9642)); AddSingle(dictionary, "Fopf;", Convert(120125)); AddSingle(dictionary, "ForAll;", Convert(8704)); AddSingle(dictionary, "Fouriertrf;", Convert(8497)); AddSingle(dictionary, "Fscr;", Convert(8497)); return dictionary; } private Dictionary GetSymbolLittleG() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "gacute;", Convert(501)); AddSingle(dictionary, "gamma;", Convert(947)); AddSingle(dictionary, "gammad;", Convert(989)); AddSingle(dictionary, "gap;", Convert(10886)); AddSingle(dictionary, "gbreve;", Convert(287)); AddSingle(dictionary, "gcirc;", Convert(285)); AddSingle(dictionary, "gcy;", Convert(1075)); AddSingle(dictionary, "gdot;", Convert(289)); AddSingle(dictionary, "gE;", Convert(8807)); AddSingle(dictionary, "ge;", Convert(8805)); AddSingle(dictionary, "gEl;", Convert(10892)); AddSingle(dictionary, "gel;", Convert(8923)); AddSingle(dictionary, "geq;", Convert(8805)); AddSingle(dictionary, "geqq;", Convert(8807)); AddSingle(dictionary, "geqslant;", Convert(10878)); AddSingle(dictionary, "ges;", Convert(10878)); AddSingle(dictionary, "gescc;", Convert(10921)); AddSingle(dictionary, "gesdot;", Convert(10880)); AddSingle(dictionary, "gesdoto;", Convert(10882)); AddSingle(dictionary, "gesdotol;", Convert(10884)); AddSingle(dictionary, "gesl;", Convert(8923, 65024)); AddSingle(dictionary, "gesles;", Convert(10900)); AddSingle(dictionary, "gfr;", Convert(120100)); AddSingle(dictionary, "gg;", Convert(8811)); AddSingle(dictionary, "ggg;", Convert(8921)); AddSingle(dictionary, "gimel;", Convert(8503)); AddSingle(dictionary, "gjcy;", Convert(1107)); AddSingle(dictionary, "gl;", Convert(8823)); AddSingle(dictionary, "gla;", Convert(10917)); AddSingle(dictionary, "glE;", Convert(10898)); AddSingle(dictionary, "glj;", Convert(10916)); AddSingle(dictionary, "gnap;", Convert(10890)); AddSingle(dictionary, "gnapprox;", Convert(10890)); AddSingle(dictionary, "gnE;", Convert(8809)); AddSingle(dictionary, "gne;", Convert(10888)); AddSingle(dictionary, "gneq;", Convert(10888)); AddSingle(dictionary, "gneqq;", Convert(8809)); AddSingle(dictionary, "gnsim;", Convert(8935)); AddSingle(dictionary, "gopf;", Convert(120152)); AddSingle(dictionary, "grave;", Convert(96)); AddSingle(dictionary, "gscr;", Convert(8458)); AddSingle(dictionary, "gsim;", Convert(8819)); AddSingle(dictionary, "gsime;", Convert(10894)); AddSingle(dictionary, "gsiml;", Convert(10896)); AddBoth(dictionary, "gt;", Convert(62)); AddSingle(dictionary, "gtcc;", Convert(10919)); AddSingle(dictionary, "gtcir;", Convert(10874)); AddSingle(dictionary, "gtdot;", Convert(8919)); AddSingle(dictionary, "gtlPar;", Convert(10645)); AddSingle(dictionary, "gtquest;", Convert(10876)); AddSingle(dictionary, "gtrapprox;", Convert(10886)); AddSingle(dictionary, "gtrarr;", Convert(10616)); AddSingle(dictionary, "gtrdot;", Convert(8919)); AddSingle(dictionary, "gtreqless;", Convert(8923)); AddSingle(dictionary, "gtreqqless;", Convert(10892)); AddSingle(dictionary, "gtrless;", Convert(8823)); AddSingle(dictionary, "gtrsim;", Convert(8819)); AddSingle(dictionary, "gvertneqq;", Convert(8809, 65024)); AddSingle(dictionary, "gvnE;", Convert(8809, 65024)); return dictionary; } private Dictionary GetSymbolBigG() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Gamma;", Convert(915)); AddSingle(dictionary, "Gammad;", Convert(988)); AddSingle(dictionary, "Gbreve;", Convert(286)); AddSingle(dictionary, "Gcedil;", Convert(290)); AddSingle(dictionary, "Gcirc;", Convert(284)); AddSingle(dictionary, "Gcy;", Convert(1043)); AddSingle(dictionary, "Gdot;", Convert(288)); AddSingle(dictionary, "Gfr;", Convert(120074)); AddSingle(dictionary, "Gg;", Convert(8921)); AddSingle(dictionary, "GJcy;", Convert(1027)); AddSingle(dictionary, "Gopf;", Convert(120126)); AddSingle(dictionary, "GreaterEqual;", Convert(8805)); AddSingle(dictionary, "GreaterEqualLess;", Convert(8923)); AddSingle(dictionary, "GreaterFullEqual;", Convert(8807)); AddSingle(dictionary, "GreaterGreater;", Convert(10914)); AddSingle(dictionary, "GreaterLess;", Convert(8823)); AddSingle(dictionary, "GreaterSlantEqual;", Convert(10878)); AddSingle(dictionary, "GreaterTilde;", Convert(8819)); AddSingle(dictionary, "Gscr;", Convert(119970)); AddBoth(dictionary, "GT;", Convert(62)); AddSingle(dictionary, "Gt;", Convert(8811)); return dictionary; } private Dictionary GetSymbolLittleH() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "hairsp;", Convert(8202)); AddSingle(dictionary, "half;", Convert(189)); AddSingle(dictionary, "hamilt;", Convert(8459)); AddSingle(dictionary, "hardcy;", Convert(1098)); AddSingle(dictionary, "hArr;", Convert(8660)); AddSingle(dictionary, "harr;", Convert(8596)); AddSingle(dictionary, "harrcir;", Convert(10568)); AddSingle(dictionary, "harrw;", Convert(8621)); AddSingle(dictionary, "hbar;", Convert(8463)); AddSingle(dictionary, "hcirc;", Convert(293)); AddSingle(dictionary, "hearts;", Convert(9829)); AddSingle(dictionary, "heartsuit;", Convert(9829)); AddSingle(dictionary, "hellip;", Convert(8230)); AddSingle(dictionary, "hercon;", Convert(8889)); AddSingle(dictionary, "hfr;", Convert(120101)); AddSingle(dictionary, "hksearow;", Convert(10533)); AddSingle(dictionary, "hkswarow;", Convert(10534)); AddSingle(dictionary, "hoarr;", Convert(8703)); AddSingle(dictionary, "homtht;", Convert(8763)); AddSingle(dictionary, "hookleftarrow;", Convert(8617)); AddSingle(dictionary, "hookrightarrow;", Convert(8618)); AddSingle(dictionary, "hopf;", Convert(120153)); AddSingle(dictionary, "horbar;", Convert(8213)); AddSingle(dictionary, "hscr;", Convert(119997)); AddSingle(dictionary, "hslash;", Convert(8463)); AddSingle(dictionary, "hstrok;", Convert(295)); AddSingle(dictionary, "hybull;", Convert(8259)); AddSingle(dictionary, "hyphen;", Convert(8208)); return dictionary; } private Dictionary GetSymbolBigH() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Hacek;", Convert(711)); AddSingle(dictionary, "HARDcy;", Convert(1066)); AddSingle(dictionary, "Hat;", Convert(94)); AddSingle(dictionary, "Hcirc;", Convert(292)); AddSingle(dictionary, "Hfr;", Convert(8460)); AddSingle(dictionary, "HilbertSpace;", Convert(8459)); AddSingle(dictionary, "Hopf;", Convert(8461)); AddSingle(dictionary, "HorizontalLine;", Convert(9472)); AddSingle(dictionary, "Hscr;", Convert(8459)); AddSingle(dictionary, "Hstrok;", Convert(294)); AddSingle(dictionary, "HumpDownHump;", Convert(8782)); AddSingle(dictionary, "HumpEqual;", Convert(8783)); return dictionary; } private Dictionary GetSymbolLittleI() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "iacute;", Convert(237)); AddSingle(dictionary, "ic;", Convert(8291)); AddBoth(dictionary, "icirc;", Convert(238)); AddSingle(dictionary, "icy;", Convert(1080)); AddSingle(dictionary, "iecy;", Convert(1077)); AddBoth(dictionary, "iexcl;", Convert(161)); AddSingle(dictionary, "iff;", Convert(8660)); AddSingle(dictionary, "ifr;", Convert(120102)); AddBoth(dictionary, "igrave;", Convert(236)); AddSingle(dictionary, "ii;", Convert(8520)); AddSingle(dictionary, "iiiint;", Convert(10764)); AddSingle(dictionary, "iiint;", Convert(8749)); AddSingle(dictionary, "iinfin;", Convert(10716)); AddSingle(dictionary, "iiota;", Convert(8489)); AddSingle(dictionary, "ijlig;", Convert(307)); AddSingle(dictionary, "imacr;", Convert(299)); AddSingle(dictionary, "image;", Convert(8465)); AddSingle(dictionary, "imagline;", Convert(8464)); AddSingle(dictionary, "imagpart;", Convert(8465)); AddSingle(dictionary, "imath;", Convert(305)); AddSingle(dictionary, "imof;", Convert(8887)); AddSingle(dictionary, "imped;", Convert(437)); AddSingle(dictionary, "in;", Convert(8712)); AddSingle(dictionary, "incare;", Convert(8453)); AddSingle(dictionary, "infin;", Convert(8734)); AddSingle(dictionary, "infintie;", Convert(10717)); AddSingle(dictionary, "inodot;", Convert(305)); AddSingle(dictionary, "int;", Convert(8747)); AddSingle(dictionary, "intcal;", Convert(8890)); AddSingle(dictionary, "integers;", Convert(8484)); AddSingle(dictionary, "intercal;", Convert(8890)); AddSingle(dictionary, "intlarhk;", Convert(10775)); AddSingle(dictionary, "intprod;", Convert(10812)); AddSingle(dictionary, "iocy;", Convert(1105)); AddSingle(dictionary, "iogon;", Convert(303)); AddSingle(dictionary, "iopf;", Convert(120154)); AddSingle(dictionary, "iota;", Convert(953)); AddSingle(dictionary, "iprod;", Convert(10812)); AddBoth(dictionary, "iquest;", Convert(191)); AddSingle(dictionary, "iscr;", Convert(119998)); AddSingle(dictionary, "isin;", Convert(8712)); AddSingle(dictionary, "isindot;", Convert(8949)); AddSingle(dictionary, "isinE;", Convert(8953)); AddSingle(dictionary, "isins;", Convert(8948)); AddSingle(dictionary, "isinsv;", Convert(8947)); AddSingle(dictionary, "isinv;", Convert(8712)); AddSingle(dictionary, "it;", Convert(8290)); AddSingle(dictionary, "itilde;", Convert(297)); AddSingle(dictionary, "iukcy;", Convert(1110)); AddBoth(dictionary, "iuml;", Convert(239)); return dictionary; } private Dictionary GetSymbolBigI() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "Iacute;", Convert(205)); AddBoth(dictionary, "Icirc;", Convert(206)); AddSingle(dictionary, "Icy;", Convert(1048)); AddSingle(dictionary, "Idot;", Convert(304)); AddSingle(dictionary, "IEcy;", Convert(1045)); AddSingle(dictionary, "Ifr;", Convert(8465)); AddBoth(dictionary, "Igrave;", Convert(204)); AddSingle(dictionary, "IJlig;", Convert(306)); AddSingle(dictionary, "Im;", Convert(8465)); AddSingle(dictionary, "Imacr;", Convert(298)); AddSingle(dictionary, "ImaginaryI;", Convert(8520)); AddSingle(dictionary, "Implies;", Convert(8658)); AddSingle(dictionary, "Int;", Convert(8748)); AddSingle(dictionary, "Integral;", Convert(8747)); AddSingle(dictionary, "Intersection;", Convert(8898)); AddSingle(dictionary, "InvisibleComma;", Convert(8291)); AddSingle(dictionary, "InvisibleTimes;", Convert(8290)); AddSingle(dictionary, "IOcy;", Convert(1025)); AddSingle(dictionary, "Iogon;", Convert(302)); AddSingle(dictionary, "Iopf;", Convert(120128)); AddSingle(dictionary, "Iota;", Convert(921)); AddSingle(dictionary, "Iscr;", Convert(8464)); AddSingle(dictionary, "Itilde;", Convert(296)); AddSingle(dictionary, "Iukcy;", Convert(1030)); AddBoth(dictionary, "Iuml;", Convert(207)); return dictionary; } private Dictionary GetSymbolLittleJ() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "jcirc;", Convert(309)); AddSingle(dictionary, "jcy;", Convert(1081)); AddSingle(dictionary, "jfr;", Convert(120103)); AddSingle(dictionary, "jmath;", Convert(567)); AddSingle(dictionary, "jopf;", Convert(120155)); AddSingle(dictionary, "jscr;", Convert(119999)); AddSingle(dictionary, "jsercy;", Convert(1112)); AddSingle(dictionary, "jukcy;", Convert(1108)); return dictionary; } private Dictionary GetSymbolBigJ() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Jcirc;", Convert(308)); AddSingle(dictionary, "Jcy;", Convert(1049)); AddSingle(dictionary, "Jfr;", Convert(120077)); AddSingle(dictionary, "Jopf;", Convert(120129)); AddSingle(dictionary, "Jscr;", Convert(119973)); AddSingle(dictionary, "Jsercy;", Convert(1032)); AddSingle(dictionary, "Jukcy;", Convert(1028)); return dictionary; } private Dictionary GetSymbolLittleK() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "kappa;", Convert(954)); AddSingle(dictionary, "kappav;", Convert(1008)); AddSingle(dictionary, "kcedil;", Convert(311)); AddSingle(dictionary, "kcy;", Convert(1082)); AddSingle(dictionary, "kfr;", Convert(120104)); AddSingle(dictionary, "kgreen;", Convert(312)); AddSingle(dictionary, "khcy;", Convert(1093)); AddSingle(dictionary, "kjcy;", Convert(1116)); AddSingle(dictionary, "kopf;", Convert(120156)); AddSingle(dictionary, "kscr;", Convert(120000)); return dictionary; } private Dictionary GetSymbolBigK() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Kappa;", Convert(922)); AddSingle(dictionary, "Kcedil;", Convert(310)); AddSingle(dictionary, "Kcy;", Convert(1050)); AddSingle(dictionary, "Kfr;", Convert(120078)); AddSingle(dictionary, "KHcy;", Convert(1061)); AddSingle(dictionary, "KJcy;", Convert(1036)); AddSingle(dictionary, "Kopf;", Convert(120130)); AddSingle(dictionary, "Kscr;", Convert(119974)); return dictionary; } private Dictionary GetSymbolLittleL() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "lAarr;", Convert(8666)); AddSingle(dictionary, "lacute;", Convert(314)); AddSingle(dictionary, "laemptyv;", Convert(10676)); AddSingle(dictionary, "lagran;", Convert(8466)); AddSingle(dictionary, "lambda;", Convert(955)); AddSingle(dictionary, "lang;", Convert(10216)); AddSingle(dictionary, "langd;", Convert(10641)); AddSingle(dictionary, "langle;", Convert(10216)); AddSingle(dictionary, "lap;", Convert(10885)); AddBoth(dictionary, "laquo;", Convert(171)); AddSingle(dictionary, "lArr;", Convert(8656)); AddSingle(dictionary, "larr;", Convert(8592)); AddSingle(dictionary, "larrb;", Convert(8676)); AddSingle(dictionary, "larrbfs;", Convert(10527)); AddSingle(dictionary, "larrfs;", Convert(10525)); AddSingle(dictionary, "larrhk;", Convert(8617)); AddSingle(dictionary, "larrlp;", Convert(8619)); AddSingle(dictionary, "larrpl;", Convert(10553)); AddSingle(dictionary, "larrsim;", Convert(10611)); AddSingle(dictionary, "larrtl;", Convert(8610)); AddSingle(dictionary, "lat;", Convert(10923)); AddSingle(dictionary, "lAtail;", Convert(10523)); AddSingle(dictionary, "latail;", Convert(10521)); AddSingle(dictionary, "late;", Convert(10925)); AddSingle(dictionary, "lates;", Convert(10925, 65024)); AddSingle(dictionary, "lBarr;", Convert(10510)); AddSingle(dictionary, "lbarr;", Convert(10508)); AddSingle(dictionary, "lbbrk;", Convert(10098)); AddSingle(dictionary, "lbrace;", Convert(123)); AddSingle(dictionary, "lbrack;", Convert(91)); AddSingle(dictionary, "lbrke;", Convert(10635)); AddSingle(dictionary, "lbrksld;", Convert(10639)); AddSingle(dictionary, "lbrkslu;", Convert(10637)); AddSingle(dictionary, "lcaron;", Convert(318)); AddSingle(dictionary, "lcedil;", Convert(316)); AddSingle(dictionary, "lceil;", Convert(8968)); AddSingle(dictionary, "lcub;", Convert(123)); AddSingle(dictionary, "lcy;", Convert(1083)); AddSingle(dictionary, "ldca;", Convert(10550)); AddSingle(dictionary, "ldquo;", Convert(8220)); AddSingle(dictionary, "ldquor;", Convert(8222)); AddSingle(dictionary, "ldrdhar;", Convert(10599)); AddSingle(dictionary, "ldrushar;", Convert(10571)); AddSingle(dictionary, "ldsh;", Convert(8626)); AddSingle(dictionary, "lE;", Convert(8806)); AddSingle(dictionary, "le;", Convert(8804)); AddSingle(dictionary, "leftarrow;", Convert(8592)); AddSingle(dictionary, "leftarrowtail;", Convert(8610)); AddSingle(dictionary, "leftharpoondown;", Convert(8637)); AddSingle(dictionary, "leftharpoonup;", Convert(8636)); AddSingle(dictionary, "leftleftarrows;", Convert(8647)); AddSingle(dictionary, "leftrightarrow;", Convert(8596)); AddSingle(dictionary, "leftrightarrows;", Convert(8646)); AddSingle(dictionary, "leftrightharpoons;", Convert(8651)); AddSingle(dictionary, "leftrightsquigarrow;", Convert(8621)); AddSingle(dictionary, "leftthreetimes;", Convert(8907)); AddSingle(dictionary, "lEg;", Convert(10891)); AddSingle(dictionary, "leg;", Convert(8922)); AddSingle(dictionary, "leq;", Convert(8804)); AddSingle(dictionary, "leqq;", Convert(8806)); AddSingle(dictionary, "leqslant;", Convert(10877)); AddSingle(dictionary, "les;", Convert(10877)); AddSingle(dictionary, "lescc;", Convert(10920)); AddSingle(dictionary, "lesdot;", Convert(10879)); AddSingle(dictionary, "lesdoto;", Convert(10881)); AddSingle(dictionary, "lesdotor;", Convert(10883)); AddSingle(dictionary, "lesg;", Convert(8922, 65024)); AddSingle(dictionary, "lesges;", Convert(10899)); AddSingle(dictionary, "lessapprox;", Convert(10885)); AddSingle(dictionary, "lessdot;", Convert(8918)); AddSingle(dictionary, "lesseqgtr;", Convert(8922)); AddSingle(dictionary, "lesseqqgtr;", Convert(10891)); AddSingle(dictionary, "lessgtr;", Convert(8822)); AddSingle(dictionary, "lesssim;", Convert(8818)); AddSingle(dictionary, "lfisht;", Convert(10620)); AddSingle(dictionary, "lfloor;", Convert(8970)); AddSingle(dictionary, "lfr;", Convert(120105)); AddSingle(dictionary, "lg;", Convert(8822)); AddSingle(dictionary, "lgE;", Convert(10897)); AddSingle(dictionary, "lHar;", Convert(10594)); AddSingle(dictionary, "lhard;", Convert(8637)); AddSingle(dictionary, "lharu;", Convert(8636)); AddSingle(dictionary, "lharul;", Convert(10602)); AddSingle(dictionary, "lhblk;", Convert(9604)); AddSingle(dictionary, "ljcy;", Convert(1113)); AddSingle(dictionary, "ll;", Convert(8810)); AddSingle(dictionary, "llarr;", Convert(8647)); AddSingle(dictionary, "llcorner;", Convert(8990)); AddSingle(dictionary, "llhard;", Convert(10603)); AddSingle(dictionary, "lltri;", Convert(9722)); AddSingle(dictionary, "lmidot;", Convert(320)); AddSingle(dictionary, "lmoust;", Convert(9136)); AddSingle(dictionary, "lmoustache;", Convert(9136)); AddSingle(dictionary, "lnap;", Convert(10889)); AddSingle(dictionary, "lnapprox;", Convert(10889)); AddSingle(dictionary, "lnE;", Convert(8808)); AddSingle(dictionary, "lne;", Convert(10887)); AddSingle(dictionary, "lneq;", Convert(10887)); AddSingle(dictionary, "lneqq;", Convert(8808)); AddSingle(dictionary, "lnsim;", Convert(8934)); AddSingle(dictionary, "loang;", Convert(10220)); AddSingle(dictionary, "loarr;", Convert(8701)); AddSingle(dictionary, "lobrk;", Convert(10214)); AddSingle(dictionary, "longleftarrow;", Convert(10229)); AddSingle(dictionary, "longleftrightarrow;", Convert(10231)); AddSingle(dictionary, "longmapsto;", Convert(10236)); AddSingle(dictionary, "longrightarrow;", Convert(10230)); AddSingle(dictionary, "looparrowleft;", Convert(8619)); AddSingle(dictionary, "looparrowright;", Convert(8620)); AddSingle(dictionary, "lopar;", Convert(10629)); AddSingle(dictionary, "lopf;", Convert(120157)); AddSingle(dictionary, "loplus;", Convert(10797)); AddSingle(dictionary, "lotimes;", Convert(10804)); AddSingle(dictionary, "lowast;", Convert(8727)); AddSingle(dictionary, "lowbar;", Convert(95)); AddSingle(dictionary, "loz;", Convert(9674)); AddSingle(dictionary, "lozenge;", Convert(9674)); AddSingle(dictionary, "lozf;", Convert(10731)); AddSingle(dictionary, "lpar;", Convert(40)); AddSingle(dictionary, "lparlt;", Convert(10643)); AddSingle(dictionary, "lrarr;", Convert(8646)); AddSingle(dictionary, "lrcorner;", Convert(8991)); AddSingle(dictionary, "lrhar;", Convert(8651)); AddSingle(dictionary, "lrhard;", Convert(10605)); AddSingle(dictionary, "lrm;", Convert(8206)); AddSingle(dictionary, "lrtri;", Convert(8895)); AddSingle(dictionary, "lsaquo;", Convert(8249)); AddSingle(dictionary, "lscr;", Convert(120001)); AddSingle(dictionary, "lsh;", Convert(8624)); AddSingle(dictionary, "lsim;", Convert(8818)); AddSingle(dictionary, "lsime;", Convert(10893)); AddSingle(dictionary, "lsimg;", Convert(10895)); AddSingle(dictionary, "lsqb;", Convert(91)); AddSingle(dictionary, "lsquo;", Convert(8216)); AddSingle(dictionary, "lsquor;", Convert(8218)); AddSingle(dictionary, "lstrok;", Convert(322)); AddBoth(dictionary, "lt;", Convert(60)); AddSingle(dictionary, "ltcc;", Convert(10918)); AddSingle(dictionary, "ltcir;", Convert(10873)); AddSingle(dictionary, "ltdot;", Convert(8918)); AddSingle(dictionary, "lthree;", Convert(8907)); AddSingle(dictionary, "ltimes;", Convert(8905)); AddSingle(dictionary, "ltlarr;", Convert(10614)); AddSingle(dictionary, "ltquest;", Convert(10875)); AddSingle(dictionary, "ltri;", Convert(9667)); AddSingle(dictionary, "ltrie;", Convert(8884)); AddSingle(dictionary, "ltrif;", Convert(9666)); AddSingle(dictionary, "ltrPar;", Convert(10646)); AddSingle(dictionary, "lurdshar;", Convert(10570)); AddSingle(dictionary, "luruhar;", Convert(10598)); AddSingle(dictionary, "lvertneqq;", Convert(8808, 65024)); AddSingle(dictionary, "lvnE;", Convert(8808, 65024)); return dictionary; } private Dictionary GetSymbolBigL() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Lacute;", Convert(313)); AddSingle(dictionary, "Lambda;", Convert(923)); AddSingle(dictionary, "Lang;", Convert(10218)); AddSingle(dictionary, "Laplacetrf;", Convert(8466)); AddSingle(dictionary, "Larr;", Convert(8606)); AddSingle(dictionary, "Lcaron;", Convert(317)); AddSingle(dictionary, "Lcedil;", Convert(315)); AddSingle(dictionary, "Lcy;", Convert(1051)); AddSingle(dictionary, "LeftAngleBracket;", Convert(10216)); AddSingle(dictionary, "LeftArrow;", Convert(8592)); AddSingle(dictionary, "Leftarrow;", Convert(8656)); AddSingle(dictionary, "LeftArrowBar;", Convert(8676)); AddSingle(dictionary, "LeftArrowRightArrow;", Convert(8646)); AddSingle(dictionary, "LeftCeiling;", Convert(8968)); AddSingle(dictionary, "LeftDoubleBracket;", Convert(10214)); AddSingle(dictionary, "LeftDownTeeVector;", Convert(10593)); AddSingle(dictionary, "LeftDownVector;", Convert(8643)); AddSingle(dictionary, "LeftDownVectorBar;", Convert(10585)); AddSingle(dictionary, "LeftFloor;", Convert(8970)); AddSingle(dictionary, "LeftRightArrow;", Convert(8596)); AddSingle(dictionary, "Leftrightarrow;", Convert(8660)); AddSingle(dictionary, "LeftRightVector;", Convert(10574)); AddSingle(dictionary, "LeftTee;", Convert(8867)); AddSingle(dictionary, "LeftTeeArrow;", Convert(8612)); AddSingle(dictionary, "LeftTeeVector;", Convert(10586)); AddSingle(dictionary, "LeftTriangle;", Convert(8882)); AddSingle(dictionary, "LeftTriangleBar;", Convert(10703)); AddSingle(dictionary, "LeftTriangleEqual;", Convert(8884)); AddSingle(dictionary, "LeftUpDownVector;", Convert(10577)); AddSingle(dictionary, "LeftUpTeeVector;", Convert(10592)); AddSingle(dictionary, "LeftUpVector;", Convert(8639)); AddSingle(dictionary, "LeftUpVectorBar;", Convert(10584)); AddSingle(dictionary, "LeftVector;", Convert(8636)); AddSingle(dictionary, "LeftVectorBar;", Convert(10578)); AddSingle(dictionary, "LessEqualGreater;", Convert(8922)); AddSingle(dictionary, "LessFullEqual;", Convert(8806)); AddSingle(dictionary, "LessGreater;", Convert(8822)); AddSingle(dictionary, "LessLess;", Convert(10913)); AddSingle(dictionary, "LessSlantEqual;", Convert(10877)); AddSingle(dictionary, "LessTilde;", Convert(8818)); AddSingle(dictionary, "Lfr;", Convert(120079)); AddSingle(dictionary, "LJcy;", Convert(1033)); AddSingle(dictionary, "Ll;", Convert(8920)); AddSingle(dictionary, "Lleftarrow;", Convert(8666)); AddSingle(dictionary, "Lmidot;", Convert(319)); AddSingle(dictionary, "LongLeftArrow;", Convert(10229)); AddSingle(dictionary, "Longleftarrow;", Convert(10232)); AddSingle(dictionary, "LongLeftRightArrow;", Convert(10231)); AddSingle(dictionary, "Longleftrightarrow;", Convert(10234)); AddSingle(dictionary, "LongRightArrow;", Convert(10230)); AddSingle(dictionary, "Longrightarrow;", Convert(10233)); AddSingle(dictionary, "Lopf;", Convert(120131)); AddSingle(dictionary, "LowerLeftArrow;", Convert(8601)); AddSingle(dictionary, "LowerRightArrow;", Convert(8600)); AddSingle(dictionary, "Lscr;", Convert(8466)); AddSingle(dictionary, "Lsh;", Convert(8624)); AddSingle(dictionary, "Lstrok;", Convert(321)); AddBoth(dictionary, "LT;", Convert(60)); AddSingle(dictionary, "Lt;", Convert(8810)); return dictionary; } private Dictionary GetSymbolLittleM() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "macr;", Convert(175)); AddSingle(dictionary, "male;", Convert(9794)); AddSingle(dictionary, "malt;", Convert(10016)); AddSingle(dictionary, "maltese;", Convert(10016)); AddSingle(dictionary, "map;", Convert(8614)); AddSingle(dictionary, "mapsto;", Convert(8614)); AddSingle(dictionary, "mapstodown;", Convert(8615)); AddSingle(dictionary, "mapstoleft;", Convert(8612)); AddSingle(dictionary, "mapstoup;", Convert(8613)); AddSingle(dictionary, "marker;", Convert(9646)); AddSingle(dictionary, "mcomma;", Convert(10793)); AddSingle(dictionary, "mcy;", Convert(1084)); AddSingle(dictionary, "mdash;", Convert(8212)); AddSingle(dictionary, "mDDot;", Convert(8762)); AddSingle(dictionary, "measuredangle;", Convert(8737)); AddSingle(dictionary, "mfr;", Convert(120106)); AddSingle(dictionary, "mho;", Convert(8487)); AddBoth(dictionary, "micro;", Convert(181)); AddSingle(dictionary, "mid;", Convert(8739)); AddSingle(dictionary, "midast;", Convert(42)); AddSingle(dictionary, "midcir;", Convert(10992)); AddBoth(dictionary, "middot;", Convert(183)); AddSingle(dictionary, "minus;", Convert(8722)); AddSingle(dictionary, "minusb;", Convert(8863)); AddSingle(dictionary, "minusd;", Convert(8760)); AddSingle(dictionary, "minusdu;", Convert(10794)); AddSingle(dictionary, "mlcp;", Convert(10971)); AddSingle(dictionary, "mldr;", Convert(8230)); AddSingle(dictionary, "mnplus;", Convert(8723)); AddSingle(dictionary, "models;", Convert(8871)); AddSingle(dictionary, "mopf;", Convert(120158)); AddSingle(dictionary, "mp;", Convert(8723)); AddSingle(dictionary, "mscr;", Convert(120002)); AddSingle(dictionary, "mstpos;", Convert(8766)); AddSingle(dictionary, "mu;", Convert(956)); AddSingle(dictionary, "multimap;", Convert(8888)); AddSingle(dictionary, "mumap;", Convert(8888)); return dictionary; } private Dictionary GetSymbolBigM() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Map;", Convert(10501)); AddSingle(dictionary, "Mcy;", Convert(1052)); AddSingle(dictionary, "MediumSpace;", Convert(8287)); AddSingle(dictionary, "Mellintrf;", Convert(8499)); AddSingle(dictionary, "Mfr;", Convert(120080)); AddSingle(dictionary, "MinusPlus;", Convert(8723)); AddSingle(dictionary, "Mopf;", Convert(120132)); AddSingle(dictionary, "Mscr;", Convert(8499)); AddSingle(dictionary, "Mu;", Convert(924)); return dictionary; } private Dictionary GetSymbolLittleN() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "nabla;", Convert(8711)); AddSingle(dictionary, "nacute;", Convert(324)); AddSingle(dictionary, "nang;", Convert(8736, 8402)); AddSingle(dictionary, "nap;", Convert(8777)); AddSingle(dictionary, "napE;", Convert(10864, 824)); AddSingle(dictionary, "napid;", Convert(8779, 824)); AddSingle(dictionary, "napos;", Convert(329)); AddSingle(dictionary, "napprox;", Convert(8777)); AddSingle(dictionary, "natur;", Convert(9838)); AddSingle(dictionary, "natural;", Convert(9838)); AddSingle(dictionary, "naturals;", Convert(8469)); AddBoth(dictionary, "nbsp;", Convert(160)); AddSingle(dictionary, "nbump;", Convert(8782, 824)); AddSingle(dictionary, "nbumpe;", Convert(8783, 824)); AddSingle(dictionary, "ncap;", Convert(10819)); AddSingle(dictionary, "ncaron;", Convert(328)); AddSingle(dictionary, "ncedil;", Convert(326)); AddSingle(dictionary, "ncong;", Convert(8775)); AddSingle(dictionary, "ncongdot;", Convert(10861, 824)); AddSingle(dictionary, "ncup;", Convert(10818)); AddSingle(dictionary, "ncy;", Convert(1085)); AddSingle(dictionary, "ndash;", Convert(8211)); AddSingle(dictionary, "ne;", Convert(8800)); AddSingle(dictionary, "nearhk;", Convert(10532)); AddSingle(dictionary, "neArr;", Convert(8663)); AddSingle(dictionary, "nearr;", Convert(8599)); AddSingle(dictionary, "nearrow;", Convert(8599)); AddSingle(dictionary, "nedot;", Convert(8784, 824)); AddSingle(dictionary, "nequiv;", Convert(8802)); AddSingle(dictionary, "nesear;", Convert(10536)); AddSingle(dictionary, "nesim;", Convert(8770, 824)); AddSingle(dictionary, "nexist;", Convert(8708)); AddSingle(dictionary, "nexists;", Convert(8708)); AddSingle(dictionary, "nfr;", Convert(120107)); AddSingle(dictionary, "ngE;", Convert(8807, 824)); AddSingle(dictionary, "nge;", Convert(8817)); AddSingle(dictionary, "ngeq;", Convert(8817)); AddSingle(dictionary, "ngeqq;", Convert(8807, 824)); AddSingle(dictionary, "ngeqslant;", Convert(10878, 824)); AddSingle(dictionary, "nges;", Convert(10878, 824)); AddSingle(dictionary, "nGg;", Convert(8921, 824)); AddSingle(dictionary, "ngsim;", Convert(8821)); AddSingle(dictionary, "nGt;", Convert(8811, 8402)); AddSingle(dictionary, "ngt;", Convert(8815)); AddSingle(dictionary, "ngtr;", Convert(8815)); AddSingle(dictionary, "nGtv;", Convert(8811, 824)); AddSingle(dictionary, "nhArr;", Convert(8654)); AddSingle(dictionary, "nharr;", Convert(8622)); AddSingle(dictionary, "nhpar;", Convert(10994)); AddSingle(dictionary, "ni;", Convert(8715)); AddSingle(dictionary, "nis;", Convert(8956)); AddSingle(dictionary, "nisd;", Convert(8954)); AddSingle(dictionary, "niv;", Convert(8715)); AddSingle(dictionary, "njcy;", Convert(1114)); AddSingle(dictionary, "nlArr;", Convert(8653)); AddSingle(dictionary, "nlarr;", Convert(8602)); AddSingle(dictionary, "nldr;", Convert(8229)); AddSingle(dictionary, "nlE;", Convert(8806, 824)); AddSingle(dictionary, "nle;", Convert(8816)); AddSingle(dictionary, "nLeftarrow;", Convert(8653)); AddSingle(dictionary, "nleftarrow;", Convert(8602)); AddSingle(dictionary, "nLeftrightarrow;", Convert(8654)); AddSingle(dictionary, "nleftrightarrow;", Convert(8622)); AddSingle(dictionary, "nleq;", Convert(8816)); AddSingle(dictionary, "nleqq;", Convert(8806, 824)); AddSingle(dictionary, "nleqslant;", Convert(10877, 824)); AddSingle(dictionary, "nles;", Convert(10877, 824)); AddSingle(dictionary, "nless;", Convert(8814)); AddSingle(dictionary, "nLl;", Convert(8920, 824)); AddSingle(dictionary, "nlsim;", Convert(8820)); AddSingle(dictionary, "nLt;", Convert(8810, 8402)); AddSingle(dictionary, "nlt;", Convert(8814)); AddSingle(dictionary, "nltri;", Convert(8938)); AddSingle(dictionary, "nltrie;", Convert(8940)); AddSingle(dictionary, "nLtv;", Convert(8810, 824)); AddSingle(dictionary, "nmid;", Convert(8740)); AddSingle(dictionary, "nopf;", Convert(120159)); AddBoth(dictionary, "not;", Convert(172)); AddSingle(dictionary, "notin;", Convert(8713)); AddSingle(dictionary, "notindot;", Convert(8949, 824)); AddSingle(dictionary, "notinE;", Convert(8953, 824)); AddSingle(dictionary, "notinva;", Convert(8713)); AddSingle(dictionary, "notinvb;", Convert(8951)); AddSingle(dictionary, "notinvc;", Convert(8950)); AddSingle(dictionary, "notni;", Convert(8716)); AddSingle(dictionary, "notniva;", Convert(8716)); AddSingle(dictionary, "notnivb;", Convert(8958)); AddSingle(dictionary, "notnivc;", Convert(8957)); AddSingle(dictionary, "npar;", Convert(8742)); AddSingle(dictionary, "nparallel;", Convert(8742)); AddSingle(dictionary, "nparsl;", Convert(11005, 8421)); AddSingle(dictionary, "npart;", Convert(8706, 824)); AddSingle(dictionary, "npolint;", Convert(10772)); AddSingle(dictionary, "npr;", Convert(8832)); AddSingle(dictionary, "nprcue;", Convert(8928)); AddSingle(dictionary, "npre;", Convert(10927, 824)); AddSingle(dictionary, "nprec;", Convert(8832)); AddSingle(dictionary, "npreceq;", Convert(10927, 824)); AddSingle(dictionary, "nrArr;", Convert(8655)); AddSingle(dictionary, "nrarr;", Convert(8603)); AddSingle(dictionary, "nrarrc;", Convert(10547, 824)); AddSingle(dictionary, "nrarrw;", Convert(8605, 824)); AddSingle(dictionary, "nRightarrow;", Convert(8655)); AddSingle(dictionary, "nrightarrow;", Convert(8603)); AddSingle(dictionary, "nrtri;", Convert(8939)); AddSingle(dictionary, "nrtrie;", Convert(8941)); AddSingle(dictionary, "nsc;", Convert(8833)); AddSingle(dictionary, "nsccue;", Convert(8929)); AddSingle(dictionary, "nsce;", Convert(10928, 824)); AddSingle(dictionary, "nscr;", Convert(120003)); AddSingle(dictionary, "nshortmid;", Convert(8740)); AddSingle(dictionary, "nshortparallel;", Convert(8742)); AddSingle(dictionary, "nsim;", Convert(8769)); AddSingle(dictionary, "nsime;", Convert(8772)); AddSingle(dictionary, "nsimeq;", Convert(8772)); AddSingle(dictionary, "nsmid;", Convert(8740)); AddSingle(dictionary, "nspar;", Convert(8742)); AddSingle(dictionary, "nsqsube;", Convert(8930)); AddSingle(dictionary, "nsqsupe;", Convert(8931)); AddSingle(dictionary, "nsub;", Convert(8836)); AddSingle(dictionary, "nsubE;", Convert(10949, 824)); AddSingle(dictionary, "nsube;", Convert(8840)); AddSingle(dictionary, "nsubset;", Convert(8834, 8402)); AddSingle(dictionary, "nsubseteq;", Convert(8840)); AddSingle(dictionary, "nsubseteqq;", Convert(10949, 824)); AddSingle(dictionary, "nsucc;", Convert(8833)); AddSingle(dictionary, "nsucceq;", Convert(10928, 824)); AddSingle(dictionary, "nsup;", Convert(8837)); AddSingle(dictionary, "nsupE;", Convert(10950, 824)); AddSingle(dictionary, "nsupe;", Convert(8841)); AddSingle(dictionary, "nsupset;", Convert(8835, 8402)); AddSingle(dictionary, "nsupseteq;", Convert(8841)); AddSingle(dictionary, "nsupseteqq;", Convert(10950, 824)); AddSingle(dictionary, "ntgl;", Convert(8825)); AddBoth(dictionary, "ntilde;", Convert(241)); AddSingle(dictionary, "ntlg;", Convert(8824)); AddSingle(dictionary, "ntriangleleft;", Convert(8938)); AddSingle(dictionary, "ntrianglelefteq;", Convert(8940)); AddSingle(dictionary, "ntriangleright;", Convert(8939)); AddSingle(dictionary, "ntrianglerighteq;", Convert(8941)); AddSingle(dictionary, "nu;", Convert(957)); AddSingle(dictionary, "num;", Convert(35)); AddSingle(dictionary, "numero;", Convert(8470)); AddSingle(dictionary, "numsp;", Convert(8199)); AddSingle(dictionary, "nvap;", Convert(8781, 8402)); AddSingle(dictionary, "nVDash;", Convert(8879)); AddSingle(dictionary, "nVdash;", Convert(8878)); AddSingle(dictionary, "nvDash;", Convert(8877)); AddSingle(dictionary, "nvdash;", Convert(8876)); AddSingle(dictionary, "nvge;", Convert(8805, 8402)); AddSingle(dictionary, "nvgt;", Convert(62, 8402)); AddSingle(dictionary, "nvHarr;", Convert(10500)); AddSingle(dictionary, "nvinfin;", Convert(10718)); AddSingle(dictionary, "nvlArr;", Convert(10498)); AddSingle(dictionary, "nvle;", Convert(8804, 8402)); AddSingle(dictionary, "nvlt;", Convert(60, 8402)); AddSingle(dictionary, "nvltrie;", Convert(8884, 8402)); AddSingle(dictionary, "nvrArr;", Convert(10499)); AddSingle(dictionary, "nvrtrie;", Convert(8885, 8402)); AddSingle(dictionary, "nvsim;", Convert(8764, 8402)); AddSingle(dictionary, "nwarhk;", Convert(10531)); AddSingle(dictionary, "nwArr;", Convert(8662)); AddSingle(dictionary, "nwarr;", Convert(8598)); AddSingle(dictionary, "nwarrow;", Convert(8598)); AddSingle(dictionary, "nwnear;", Convert(10535)); return dictionary; } private Dictionary GetSymbolBigN() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Nacute;", Convert(323)); AddSingle(dictionary, "Ncaron;", Convert(327)); AddSingle(dictionary, "Ncedil;", Convert(325)); AddSingle(dictionary, "NegativeMediumSpace;", Convert(8203)); AddSingle(dictionary, "NegativeThickSpace;", Convert(8203)); AddSingle(dictionary, "NegativeThinSpace;", Convert(8203)); AddSingle(dictionary, "NegativeVeryThinSpace;", Convert(8203)); AddSingle(dictionary, "NestedGreaterGreater;", Convert(8811)); AddSingle(dictionary, "NestedLessLess;", Convert(8810)); AddSingle(dictionary, "Ncy;", Convert(1053)); AddSingle(dictionary, "Nfr;", Convert(120081)); AddSingle(dictionary, "NoBreak;", Convert(8288)); AddSingle(dictionary, "NonBreakingSpace;", Convert(160)); AddSingle(dictionary, "Nopf;", Convert(8469)); AddSingle(dictionary, "NewLine;", Convert(10)); AddSingle(dictionary, "NJcy;", Convert(1034)); AddSingle(dictionary, "Not;", Convert(10988)); AddSingle(dictionary, "NotCongruent;", Convert(8802)); AddSingle(dictionary, "NotCupCap;", Convert(8813)); AddSingle(dictionary, "NotDoubleVerticalBar;", Convert(8742)); AddSingle(dictionary, "NotElement;", Convert(8713)); AddSingle(dictionary, "NotEqual;", Convert(8800)); AddSingle(dictionary, "NotEqualTilde;", Convert(8770, 824)); AddSingle(dictionary, "NotExists;", Convert(8708)); AddSingle(dictionary, "NotGreater;", Convert(8815)); AddSingle(dictionary, "NotGreaterEqual;", Convert(8817)); AddSingle(dictionary, "NotGreaterFullEqual;", Convert(8807, 824)); AddSingle(dictionary, "NotGreaterGreater;", Convert(8811, 824)); AddSingle(dictionary, "NotGreaterLess;", Convert(8825)); AddSingle(dictionary, "NotGreaterSlantEqual;", Convert(10878, 824)); AddSingle(dictionary, "NotGreaterTilde;", Convert(8821)); AddSingle(dictionary, "NotHumpDownHump;", Convert(8782, 824)); AddSingle(dictionary, "NotHumpEqual;", Convert(8783, 824)); AddSingle(dictionary, "NotLeftTriangle;", Convert(8938)); AddSingle(dictionary, "NotLeftTriangleBar;", Convert(10703, 824)); AddSingle(dictionary, "NotLeftTriangleEqual;", Convert(8940)); AddSingle(dictionary, "NotLess;", Convert(8814)); AddSingle(dictionary, "NotLessEqual;", Convert(8816)); AddSingle(dictionary, "NotLessGreater;", Convert(8824)); AddSingle(dictionary, "NotLessLess;", Convert(8810, 824)); AddSingle(dictionary, "NotLessSlantEqual;", Convert(10877, 824)); AddSingle(dictionary, "NotLessTilde;", Convert(8820)); AddSingle(dictionary, "NotNestedGreaterGreater;", Convert(10914, 824)); AddSingle(dictionary, "NotNestedLessLess;", Convert(10913, 824)); AddSingle(dictionary, "NotPrecedes;", Convert(8832)); AddSingle(dictionary, "NotPrecedesEqual;", Convert(10927, 824)); AddSingle(dictionary, "NotPrecedesSlantEqual;", Convert(8928)); AddSingle(dictionary, "NotReverseElement;", Convert(8716)); AddSingle(dictionary, "NotRightTriangle;", Convert(8939)); AddSingle(dictionary, "NotRightTriangleBar;", Convert(10704, 824)); AddSingle(dictionary, "NotRightTriangleEqual;", Convert(8941)); AddSingle(dictionary, "NotSquareSubset;", Convert(8847, 824)); AddSingle(dictionary, "NotSquareSubsetEqual;", Convert(8930)); AddSingle(dictionary, "NotSquareSuperset;", Convert(8848, 824)); AddSingle(dictionary, "NotSquareSupersetEqual;", Convert(8931)); AddSingle(dictionary, "NotSubset;", Convert(8834, 8402)); AddSingle(dictionary, "NotSubsetEqual;", Convert(8840)); AddSingle(dictionary, "NotSucceeds;", Convert(8833)); AddSingle(dictionary, "NotSucceedsEqual;", Convert(10928, 824)); AddSingle(dictionary, "NotSucceedsSlantEqual;", Convert(8929)); AddSingle(dictionary, "NotSucceedsTilde;", Convert(8831, 824)); AddSingle(dictionary, "NotSuperset;", Convert(8835, 8402)); AddSingle(dictionary, "NotSupersetEqual;", Convert(8841)); AddSingle(dictionary, "NotTilde;", Convert(8769)); AddSingle(dictionary, "NotTildeEqual;", Convert(8772)); AddSingle(dictionary, "NotTildeFullEqual;", Convert(8775)); AddSingle(dictionary, "NotTildeTilde;", Convert(8777)); AddSingle(dictionary, "NotVerticalBar;", Convert(8740)); AddSingle(dictionary, "Nscr;", Convert(119977)); AddBoth(dictionary, "Ntilde;", Convert(209)); AddSingle(dictionary, "Nu;", Convert(925)); return dictionary; } private Dictionary GetSymbolLittleO() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "oacute;", Convert(243)); AddSingle(dictionary, "oast;", Convert(8859)); AddSingle(dictionary, "ocir;", Convert(8858)); AddBoth(dictionary, "ocirc;", Convert(244)); AddSingle(dictionary, "ocy;", Convert(1086)); AddSingle(dictionary, "odash;", Convert(8861)); AddSingle(dictionary, "odblac;", Convert(337)); AddSingle(dictionary, "odiv;", Convert(10808)); AddSingle(dictionary, "odot;", Convert(8857)); AddSingle(dictionary, "odsold;", Convert(10684)); AddSingle(dictionary, "oelig;", Convert(339)); AddSingle(dictionary, "ofcir;", Convert(10687)); AddSingle(dictionary, "ofr;", Convert(120108)); AddSingle(dictionary, "ogon;", Convert(731)); AddBoth(dictionary, "ograve;", Convert(242)); AddSingle(dictionary, "ogt;", Convert(10689)); AddSingle(dictionary, "ohbar;", Convert(10677)); AddSingle(dictionary, "ohm;", Convert(937)); AddSingle(dictionary, "oint;", Convert(8750)); AddSingle(dictionary, "olarr;", Convert(8634)); AddSingle(dictionary, "olcir;", Convert(10686)); AddSingle(dictionary, "olcross;", Convert(10683)); AddSingle(dictionary, "oline;", Convert(8254)); AddSingle(dictionary, "olt;", Convert(10688)); AddSingle(dictionary, "omacr;", Convert(333)); AddSingle(dictionary, "omega;", Convert(969)); AddSingle(dictionary, "omicron;", Convert(959)); AddSingle(dictionary, "omid;", Convert(10678)); AddSingle(dictionary, "ominus;", Convert(8854)); AddSingle(dictionary, "oopf;", Convert(120160)); AddSingle(dictionary, "opar;", Convert(10679)); AddSingle(dictionary, "operp;", Convert(10681)); AddSingle(dictionary, "oplus;", Convert(8853)); AddSingle(dictionary, "or;", Convert(8744)); AddSingle(dictionary, "orarr;", Convert(8635)); AddSingle(dictionary, "ord;", Convert(10845)); AddSingle(dictionary, "order;", Convert(8500)); AddSingle(dictionary, "orderof;", Convert(8500)); AddBoth(dictionary, "ordf;", Convert(170)); AddBoth(dictionary, "ordm;", Convert(186)); AddSingle(dictionary, "origof;", Convert(8886)); AddSingle(dictionary, "oror;", Convert(10838)); AddSingle(dictionary, "orslope;", Convert(10839)); AddSingle(dictionary, "orv;", Convert(10843)); AddSingle(dictionary, "oS;", Convert(9416)); AddSingle(dictionary, "oscr;", Convert(8500)); AddBoth(dictionary, "oslash;", Convert(248)); AddSingle(dictionary, "osol;", Convert(8856)); AddBoth(dictionary, "otilde;", Convert(245)); AddSingle(dictionary, "otimes;", Convert(8855)); AddSingle(dictionary, "otimesas;", Convert(10806)); AddBoth(dictionary, "ouml;", Convert(246)); AddSingle(dictionary, "ovbar;", Convert(9021)); return dictionary; } private Dictionary GetSymbolBigO() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "Oacute;", Convert(211)); AddBoth(dictionary, "Ocirc;", Convert(212)); AddSingle(dictionary, "Ocy;", Convert(1054)); AddSingle(dictionary, "Odblac;", Convert(336)); AddSingle(dictionary, "OElig;", Convert(338)); AddSingle(dictionary, "Ofr;", Convert(120082)); AddBoth(dictionary, "Ograve;", Convert(210)); AddSingle(dictionary, "Omacr;", Convert(332)); AddSingle(dictionary, "Omega;", Convert(937)); AddSingle(dictionary, "Omicron;", Convert(927)); AddSingle(dictionary, "Oopf;", Convert(120134)); AddSingle(dictionary, "OpenCurlyDoubleQuote;", Convert(8220)); AddSingle(dictionary, "OpenCurlyQuote;", Convert(8216)); AddSingle(dictionary, "Or;", Convert(10836)); AddSingle(dictionary, "Oscr;", Convert(119978)); AddBoth(dictionary, "Oslash;", Convert(216)); AddBoth(dictionary, "Otilde;", Convert(213)); AddSingle(dictionary, "Otimes;", Convert(10807)); AddBoth(dictionary, "Ouml;", Convert(214)); AddSingle(dictionary, "OverBar;", Convert(8254)); AddSingle(dictionary, "OverBrace;", Convert(9182)); AddSingle(dictionary, "OverBracket;", Convert(9140)); AddSingle(dictionary, "OverParenthesis;", Convert(9180)); return dictionary; } private Dictionary GetSymbolLittleP() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "pfr;", Convert(120109)); AddSingle(dictionary, "par;", Convert(8741)); AddBoth(dictionary, "para;", Convert(182)); AddSingle(dictionary, "parallel;", Convert(8741)); AddSingle(dictionary, "parsim;", Convert(10995)); AddSingle(dictionary, "parsl;", Convert(11005)); AddSingle(dictionary, "part;", Convert(8706)); AddSingle(dictionary, "pcy;", Convert(1087)); AddSingle(dictionary, "percnt;", Convert(37)); AddSingle(dictionary, "period;", Convert(46)); AddSingle(dictionary, "permil;", Convert(8240)); AddSingle(dictionary, "perp;", Convert(8869)); AddSingle(dictionary, "pertenk;", Convert(8241)); AddSingle(dictionary, "phi;", Convert(966)); AddSingle(dictionary, "phiv;", Convert(981)); AddSingle(dictionary, "phmmat;", Convert(8499)); AddSingle(dictionary, "phone;", Convert(9742)); AddSingle(dictionary, "pi;", Convert(960)); AddSingle(dictionary, "pitchfork;", Convert(8916)); AddSingle(dictionary, "piv;", Convert(982)); AddSingle(dictionary, "planck;", Convert(8463)); AddSingle(dictionary, "planckh;", Convert(8462)); AddSingle(dictionary, "plankv;", Convert(8463)); AddSingle(dictionary, "plus;", Convert(43)); AddSingle(dictionary, "plusacir;", Convert(10787)); AddSingle(dictionary, "plusb;", Convert(8862)); AddSingle(dictionary, "pluscir;", Convert(10786)); AddSingle(dictionary, "plusdo;", Convert(8724)); AddSingle(dictionary, "plusdu;", Convert(10789)); AddSingle(dictionary, "pluse;", Convert(10866)); AddBoth(dictionary, "plusmn;", Convert(177)); AddSingle(dictionary, "plussim;", Convert(10790)); AddSingle(dictionary, "plustwo;", Convert(10791)); AddSingle(dictionary, "pm;", Convert(177)); AddSingle(dictionary, "pointint;", Convert(10773)); AddSingle(dictionary, "popf;", Convert(120161)); AddBoth(dictionary, "pound;", Convert(163)); AddSingle(dictionary, "pr;", Convert(8826)); AddSingle(dictionary, "prap;", Convert(10935)); AddSingle(dictionary, "prcue;", Convert(8828)); AddSingle(dictionary, "prE;", Convert(10931)); AddSingle(dictionary, "pre;", Convert(10927)); AddSingle(dictionary, "prec;", Convert(8826)); AddSingle(dictionary, "precapprox;", Convert(10935)); AddSingle(dictionary, "preccurlyeq;", Convert(8828)); AddSingle(dictionary, "preceq;", Convert(10927)); AddSingle(dictionary, "precnapprox;", Convert(10937)); AddSingle(dictionary, "precneqq;", Convert(10933)); AddSingle(dictionary, "precnsim;", Convert(8936)); AddSingle(dictionary, "precsim;", Convert(8830)); AddSingle(dictionary, "prime;", Convert(8242)); AddSingle(dictionary, "primes;", Convert(8473)); AddSingle(dictionary, "prnap;", Convert(10937)); AddSingle(dictionary, "prnE;", Convert(10933)); AddSingle(dictionary, "prnsim;", Convert(8936)); AddSingle(dictionary, "prod;", Convert(8719)); AddSingle(dictionary, "profalar;", Convert(9006)); AddSingle(dictionary, "profline;", Convert(8978)); AddSingle(dictionary, "profsurf;", Convert(8979)); AddSingle(dictionary, "prop;", Convert(8733)); AddSingle(dictionary, "propto;", Convert(8733)); AddSingle(dictionary, "prsim;", Convert(8830)); AddSingle(dictionary, "prurel;", Convert(8880)); AddSingle(dictionary, "pscr;", Convert(120005)); AddSingle(dictionary, "psi;", Convert(968)); AddSingle(dictionary, "puncsp;", Convert(8200)); return dictionary; } private Dictionary GetSymbolBigP() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "PartialD;", Convert(8706)); AddSingle(dictionary, "Pcy;", Convert(1055)); AddSingle(dictionary, "Pfr;", Convert(120083)); AddSingle(dictionary, "Phi;", Convert(934)); AddSingle(dictionary, "Pi;", Convert(928)); AddSingle(dictionary, "PlusMinus;", Convert(177)); AddSingle(dictionary, "Poincareplane;", Convert(8460)); AddSingle(dictionary, "Popf;", Convert(8473)); AddSingle(dictionary, "Pr;", Convert(10939)); AddSingle(dictionary, "Precedes;", Convert(8826)); AddSingle(dictionary, "PrecedesEqual;", Convert(10927)); AddSingle(dictionary, "PrecedesSlantEqual;", Convert(8828)); AddSingle(dictionary, "PrecedesTilde;", Convert(8830)); AddSingle(dictionary, "Prime;", Convert(8243)); AddSingle(dictionary, "Product;", Convert(8719)); AddSingle(dictionary, "Proportion;", Convert(8759)); AddSingle(dictionary, "Proportional;", Convert(8733)); AddSingle(dictionary, "Pscr;", Convert(119979)); AddSingle(dictionary, "Psi;", Convert(936)); return dictionary; } private Dictionary GetSymbolLittleQ() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "qfr;", Convert(120110)); AddSingle(dictionary, "qint;", Convert(10764)); AddSingle(dictionary, "qopf;", Convert(120162)); AddSingle(dictionary, "qprime;", Convert(8279)); AddSingle(dictionary, "qscr;", Convert(120006)); AddSingle(dictionary, "quaternions;", Convert(8461)); AddSingle(dictionary, "quatint;", Convert(10774)); AddSingle(dictionary, "quest;", Convert(63)); AddSingle(dictionary, "questeq;", Convert(8799)); AddBoth(dictionary, "quot;", Convert(34)); return dictionary; } private Dictionary GetSymbolBigQ() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Qfr;", Convert(120084)); AddSingle(dictionary, "Qopf;", Convert(8474)); AddSingle(dictionary, "Qscr;", Convert(119980)); AddBoth(dictionary, "QUOT;", Convert(34)); return dictionary; } private Dictionary GetSymbolLittleR() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "rAarr;", Convert(8667)); AddSingle(dictionary, "race;", Convert(8765, 817)); AddSingle(dictionary, "racute;", Convert(341)); AddSingle(dictionary, "radic;", Convert(8730)); AddSingle(dictionary, "raemptyv;", Convert(10675)); AddSingle(dictionary, "rang;", Convert(10217)); AddSingle(dictionary, "rangd;", Convert(10642)); AddSingle(dictionary, "range;", Convert(10661)); AddSingle(dictionary, "rangle;", Convert(10217)); AddBoth(dictionary, "raquo;", Convert(187)); AddSingle(dictionary, "rArr;", Convert(8658)); AddSingle(dictionary, "rarr;", Convert(8594)); AddSingle(dictionary, "rarrap;", Convert(10613)); AddSingle(dictionary, "rarrb;", Convert(8677)); AddSingle(dictionary, "rarrbfs;", Convert(10528)); AddSingle(dictionary, "rarrc;", Convert(10547)); AddSingle(dictionary, "rarrfs;", Convert(10526)); AddSingle(dictionary, "rarrhk;", Convert(8618)); AddSingle(dictionary, "rarrlp;", Convert(8620)); AddSingle(dictionary, "rarrpl;", Convert(10565)); AddSingle(dictionary, "rarrsim;", Convert(10612)); AddSingle(dictionary, "rarrtl;", Convert(8611)); AddSingle(dictionary, "rarrw;", Convert(8605)); AddSingle(dictionary, "rAtail;", Convert(10524)); AddSingle(dictionary, "ratail;", Convert(10522)); AddSingle(dictionary, "ratio;", Convert(8758)); AddSingle(dictionary, "rationals;", Convert(8474)); AddSingle(dictionary, "rBarr;", Convert(10511)); AddSingle(dictionary, "rbarr;", Convert(10509)); AddSingle(dictionary, "rbbrk;", Convert(10099)); AddSingle(dictionary, "rbrace;", Convert(125)); AddSingle(dictionary, "rbrack;", Convert(93)); AddSingle(dictionary, "rbrke;", Convert(10636)); AddSingle(dictionary, "rbrksld;", Convert(10638)); AddSingle(dictionary, "rbrkslu;", Convert(10640)); AddSingle(dictionary, "rcaron;", Convert(345)); AddSingle(dictionary, "rcedil;", Convert(343)); AddSingle(dictionary, "rceil;", Convert(8969)); AddSingle(dictionary, "rcub;", Convert(125)); AddSingle(dictionary, "rcy;", Convert(1088)); AddSingle(dictionary, "rdca;", Convert(10551)); AddSingle(dictionary, "rdldhar;", Convert(10601)); AddSingle(dictionary, "rdquo;", Convert(8221)); AddSingle(dictionary, "rdquor;", Convert(8221)); AddSingle(dictionary, "rdsh;", Convert(8627)); AddSingle(dictionary, "real;", Convert(8476)); AddSingle(dictionary, "realine;", Convert(8475)); AddSingle(dictionary, "realpart;", Convert(8476)); AddSingle(dictionary, "reals;", Convert(8477)); AddSingle(dictionary, "rect;", Convert(9645)); AddBoth(dictionary, "reg;", Convert(174)); AddSingle(dictionary, "rfisht;", Convert(10621)); AddSingle(dictionary, "rfloor;", Convert(8971)); AddSingle(dictionary, "rfr;", Convert(120111)); AddSingle(dictionary, "rHar;", Convert(10596)); AddSingle(dictionary, "rhard;", Convert(8641)); AddSingle(dictionary, "rharu;", Convert(8640)); AddSingle(dictionary, "rharul;", Convert(10604)); AddSingle(dictionary, "rho;", Convert(961)); AddSingle(dictionary, "rhov;", Convert(1009)); AddSingle(dictionary, "rightarrow;", Convert(8594)); AddSingle(dictionary, "rightarrowtail;", Convert(8611)); AddSingle(dictionary, "rightharpoondown;", Convert(8641)); AddSingle(dictionary, "rightharpoonup;", Convert(8640)); AddSingle(dictionary, "rightleftarrows;", Convert(8644)); AddSingle(dictionary, "rightleftharpoons;", Convert(8652)); AddSingle(dictionary, "rightrightarrows;", Convert(8649)); AddSingle(dictionary, "rightsquigarrow;", Convert(8605)); AddSingle(dictionary, "rightthreetimes;", Convert(8908)); AddSingle(dictionary, "ring;", Convert(730)); AddSingle(dictionary, "risingdotseq;", Convert(8787)); AddSingle(dictionary, "rlarr;", Convert(8644)); AddSingle(dictionary, "rlhar;", Convert(8652)); AddSingle(dictionary, "rlm;", Convert(8207)); AddSingle(dictionary, "rmoust;", Convert(9137)); AddSingle(dictionary, "rmoustache;", Convert(9137)); AddSingle(dictionary, "rnmid;", Convert(10990)); AddSingle(dictionary, "roang;", Convert(10221)); AddSingle(dictionary, "roarr;", Convert(8702)); AddSingle(dictionary, "robrk;", Convert(10215)); AddSingle(dictionary, "ropar;", Convert(10630)); AddSingle(dictionary, "ropf;", Convert(120163)); AddSingle(dictionary, "roplus;", Convert(10798)); AddSingle(dictionary, "rotimes;", Convert(10805)); AddSingle(dictionary, "rpar;", Convert(41)); AddSingle(dictionary, "rpargt;", Convert(10644)); AddSingle(dictionary, "rppolint;", Convert(10770)); AddSingle(dictionary, "rrarr;", Convert(8649)); AddSingle(dictionary, "rsaquo;", Convert(8250)); AddSingle(dictionary, "rscr;", Convert(120007)); AddSingle(dictionary, "rsh;", Convert(8625)); AddSingle(dictionary, "rsqb;", Convert(93)); AddSingle(dictionary, "rsquo;", Convert(8217)); AddSingle(dictionary, "rsquor;", Convert(8217)); AddSingle(dictionary, "rthree;", Convert(8908)); AddSingle(dictionary, "rtimes;", Convert(8906)); AddSingle(dictionary, "rtri;", Convert(9657)); AddSingle(dictionary, "rtrie;", Convert(8885)); AddSingle(dictionary, "rtrif;", Convert(9656)); AddSingle(dictionary, "rtriltri;", Convert(10702)); AddSingle(dictionary, "ruluhar;", Convert(10600)); AddSingle(dictionary, "rx;", Convert(8478)); return dictionary; } private Dictionary GetSymbolBigR() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Racute;", Convert(340)); AddSingle(dictionary, "Rang;", Convert(10219)); AddSingle(dictionary, "Rarr;", Convert(8608)); AddSingle(dictionary, "Rarrtl;", Convert(10518)); AddSingle(dictionary, "RBarr;", Convert(10512)); AddSingle(dictionary, "Rcaron;", Convert(344)); AddSingle(dictionary, "Rcedil;", Convert(342)); AddSingle(dictionary, "Rcy;", Convert(1056)); AddSingle(dictionary, "Re;", Convert(8476)); AddBoth(dictionary, "REG;", Convert(174)); AddSingle(dictionary, "ReverseElement;", Convert(8715)); AddSingle(dictionary, "ReverseEquilibrium;", Convert(8651)); AddSingle(dictionary, "ReverseUpEquilibrium;", Convert(10607)); AddSingle(dictionary, "Rfr;", Convert(8476)); AddSingle(dictionary, "Rho;", Convert(929)); AddSingle(dictionary, "RightAngleBracket;", Convert(10217)); AddSingle(dictionary, "RightArrow;", Convert(8594)); AddSingle(dictionary, "Rightarrow;", Convert(8658)); AddSingle(dictionary, "RightArrowBar;", Convert(8677)); AddSingle(dictionary, "RightArrowLeftArrow;", Convert(8644)); AddSingle(dictionary, "RightCeiling;", Convert(8969)); AddSingle(dictionary, "RightDoubleBracket;", Convert(10215)); AddSingle(dictionary, "RightDownTeeVector;", Convert(10589)); AddSingle(dictionary, "RightDownVector;", Convert(8642)); AddSingle(dictionary, "RightDownVectorBar;", Convert(10581)); AddSingle(dictionary, "RightFloor;", Convert(8971)); AddSingle(dictionary, "RightTee;", Convert(8866)); AddSingle(dictionary, "RightTeeArrow;", Convert(8614)); AddSingle(dictionary, "RightTeeVector;", Convert(10587)); AddSingle(dictionary, "RightTriangle;", Convert(8883)); AddSingle(dictionary, "RightTriangleBar;", Convert(10704)); AddSingle(dictionary, "RightTriangleEqual;", Convert(8885)); AddSingle(dictionary, "RightUpDownVector;", Convert(10575)); AddSingle(dictionary, "RightUpTeeVector;", Convert(10588)); AddSingle(dictionary, "RightUpVector;", Convert(8638)); AddSingle(dictionary, "RightUpVectorBar;", Convert(10580)); AddSingle(dictionary, "RightVector;", Convert(8640)); AddSingle(dictionary, "RightVectorBar;", Convert(10579)); AddSingle(dictionary, "Ropf;", Convert(8477)); AddSingle(dictionary, "RoundImplies;", Convert(10608)); AddSingle(dictionary, "Rrightarrow;", Convert(8667)); AddSingle(dictionary, "Rscr;", Convert(8475)); AddSingle(dictionary, "Rsh;", Convert(8625)); AddSingle(dictionary, "RuleDelayed;", Convert(10740)); return dictionary; } private Dictionary GetSymbolLittleS() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "sacute;", Convert(347)); AddSingle(dictionary, "sbquo;", Convert(8218)); AddSingle(dictionary, "sc;", Convert(8827)); AddSingle(dictionary, "scap;", Convert(10936)); AddSingle(dictionary, "scaron;", Convert(353)); AddSingle(dictionary, "sccue;", Convert(8829)); AddSingle(dictionary, "scE;", Convert(10932)); AddSingle(dictionary, "sce;", Convert(10928)); AddSingle(dictionary, "scedil;", Convert(351)); AddSingle(dictionary, "scirc;", Convert(349)); AddSingle(dictionary, "scnap;", Convert(10938)); AddSingle(dictionary, "scnE;", Convert(10934)); AddSingle(dictionary, "scnsim;", Convert(8937)); AddSingle(dictionary, "scpolint;", Convert(10771)); AddSingle(dictionary, "scsim;", Convert(8831)); AddSingle(dictionary, "scy;", Convert(1089)); AddSingle(dictionary, "sdot;", Convert(8901)); AddSingle(dictionary, "sdotb;", Convert(8865)); AddSingle(dictionary, "sdote;", Convert(10854)); AddSingle(dictionary, "searhk;", Convert(10533)); AddSingle(dictionary, "seArr;", Convert(8664)); AddSingle(dictionary, "searr;", Convert(8600)); AddSingle(dictionary, "searrow;", Convert(8600)); AddBoth(dictionary, "sect;", Convert(167)); AddSingle(dictionary, "semi;", Convert(59)); AddSingle(dictionary, "seswar;", Convert(10537)); AddSingle(dictionary, "setminus;", Convert(8726)); AddSingle(dictionary, "setmn;", Convert(8726)); AddSingle(dictionary, "sext;", Convert(10038)); AddSingle(dictionary, "sfr;", Convert(120112)); AddSingle(dictionary, "sfrown;", Convert(8994)); AddSingle(dictionary, "sharp;", Convert(9839)); AddSingle(dictionary, "shchcy;", Convert(1097)); AddSingle(dictionary, "shcy;", Convert(1096)); AddSingle(dictionary, "shortmid;", Convert(8739)); AddSingle(dictionary, "shortparallel;", Convert(8741)); AddBoth(dictionary, "shy;", Convert(173)); AddSingle(dictionary, "sigma;", Convert(963)); AddSingle(dictionary, "sigmaf;", Convert(962)); AddSingle(dictionary, "sigmav;", Convert(962)); AddSingle(dictionary, "sim;", Convert(8764)); AddSingle(dictionary, "simdot;", Convert(10858)); AddSingle(dictionary, "sime;", Convert(8771)); AddSingle(dictionary, "simeq;", Convert(8771)); AddSingle(dictionary, "simg;", Convert(10910)); AddSingle(dictionary, "simgE;", Convert(10912)); AddSingle(dictionary, "siml;", Convert(10909)); AddSingle(dictionary, "simlE;", Convert(10911)); AddSingle(dictionary, "simne;", Convert(8774)); AddSingle(dictionary, "simplus;", Convert(10788)); AddSingle(dictionary, "simrarr;", Convert(10610)); AddSingle(dictionary, "slarr;", Convert(8592)); AddSingle(dictionary, "smallsetminus;", Convert(8726)); AddSingle(dictionary, "smashp;", Convert(10803)); AddSingle(dictionary, "smeparsl;", Convert(10724)); AddSingle(dictionary, "smid;", Convert(8739)); AddSingle(dictionary, "smile;", Convert(8995)); AddSingle(dictionary, "smt;", Convert(10922)); AddSingle(dictionary, "smte;", Convert(10924)); AddSingle(dictionary, "smtes;", Convert(10924, 65024)); AddSingle(dictionary, "softcy;", Convert(1100)); AddSingle(dictionary, "sol;", Convert(47)); AddSingle(dictionary, "solb;", Convert(10692)); AddSingle(dictionary, "solbar;", Convert(9023)); AddSingle(dictionary, "sopf;", Convert(120164)); AddSingle(dictionary, "spades;", Convert(9824)); AddSingle(dictionary, "spadesuit;", Convert(9824)); AddSingle(dictionary, "spar;", Convert(8741)); AddSingle(dictionary, "sqcap;", Convert(8851)); AddSingle(dictionary, "sqcaps;", Convert(8851, 65024)); AddSingle(dictionary, "sqcup;", Convert(8852)); AddSingle(dictionary, "sqcups;", Convert(8852, 65024)); AddSingle(dictionary, "sqsub;", Convert(8847)); AddSingle(dictionary, "sqsube;", Convert(8849)); AddSingle(dictionary, "sqsubset;", Convert(8847)); AddSingle(dictionary, "sqsubseteq;", Convert(8849)); AddSingle(dictionary, "sqsup;", Convert(8848)); AddSingle(dictionary, "sqsupe;", Convert(8850)); AddSingle(dictionary, "sqsupset;", Convert(8848)); AddSingle(dictionary, "sqsupseteq;", Convert(8850)); AddSingle(dictionary, "squ;", Convert(9633)); AddSingle(dictionary, "square;", Convert(9633)); AddSingle(dictionary, "squarf;", Convert(9642)); AddSingle(dictionary, "squf;", Convert(9642)); AddSingle(dictionary, "srarr;", Convert(8594)); AddSingle(dictionary, "sscr;", Convert(120008)); AddSingle(dictionary, "ssetmn;", Convert(8726)); AddSingle(dictionary, "ssmile;", Convert(8995)); AddSingle(dictionary, "sstarf;", Convert(8902)); AddSingle(dictionary, "star;", Convert(9734)); AddSingle(dictionary, "starf;", Convert(9733)); AddSingle(dictionary, "straightepsilon;", Convert(1013)); AddSingle(dictionary, "straightphi;", Convert(981)); AddSingle(dictionary, "strns;", Convert(175)); AddSingle(dictionary, "sub;", Convert(8834)); AddSingle(dictionary, "subdot;", Convert(10941)); AddSingle(dictionary, "subE;", Convert(10949)); AddSingle(dictionary, "sube;", Convert(8838)); AddSingle(dictionary, "subedot;", Convert(10947)); AddSingle(dictionary, "submult;", Convert(10945)); AddSingle(dictionary, "subnE;", Convert(10955)); AddSingle(dictionary, "subne;", Convert(8842)); AddSingle(dictionary, "subplus;", Convert(10943)); AddSingle(dictionary, "subrarr;", Convert(10617)); AddSingle(dictionary, "subset;", Convert(8834)); AddSingle(dictionary, "subseteq;", Convert(8838)); AddSingle(dictionary, "subseteqq;", Convert(10949)); AddSingle(dictionary, "subsetneq;", Convert(8842)); AddSingle(dictionary, "subsetneqq;", Convert(10955)); AddSingle(dictionary, "subsim;", Convert(10951)); AddSingle(dictionary, "subsub;", Convert(10965)); AddSingle(dictionary, "subsup;", Convert(10963)); AddSingle(dictionary, "succ;", Convert(8827)); AddSingle(dictionary, "succapprox;", Convert(10936)); AddSingle(dictionary, "succcurlyeq;", Convert(8829)); AddSingle(dictionary, "succeq;", Convert(10928)); AddSingle(dictionary, "succnapprox;", Convert(10938)); AddSingle(dictionary, "succneqq;", Convert(10934)); AddSingle(dictionary, "succnsim;", Convert(8937)); AddSingle(dictionary, "succsim;", Convert(8831)); AddSingle(dictionary, "sum;", Convert(8721)); AddSingle(dictionary, "sung;", Convert(9834)); AddSingle(dictionary, "sup;", Convert(8835)); AddBoth(dictionary, "sup1;", Convert(185)); AddBoth(dictionary, "sup2;", Convert(178)); AddBoth(dictionary, "sup3;", Convert(179)); AddSingle(dictionary, "supdot;", Convert(10942)); AddSingle(dictionary, "supdsub;", Convert(10968)); AddSingle(dictionary, "supE;", Convert(10950)); AddSingle(dictionary, "supe;", Convert(8839)); AddSingle(dictionary, "supedot;", Convert(10948)); AddSingle(dictionary, "suphsol;", Convert(10185)); AddSingle(dictionary, "suphsub;", Convert(10967)); AddSingle(dictionary, "suplarr;", Convert(10619)); AddSingle(dictionary, "supmult;", Convert(10946)); AddSingle(dictionary, "supnE;", Convert(10956)); AddSingle(dictionary, "supne;", Convert(8843)); AddSingle(dictionary, "supplus;", Convert(10944)); AddSingle(dictionary, "supset;", Convert(8835)); AddSingle(dictionary, "supseteq;", Convert(8839)); AddSingle(dictionary, "supseteqq;", Convert(10950)); AddSingle(dictionary, "supsetneq;", Convert(8843)); AddSingle(dictionary, "supsetneqq;", Convert(10956)); AddSingle(dictionary, "supsim;", Convert(10952)); AddSingle(dictionary, "supsub;", Convert(10964)); AddSingle(dictionary, "supsup;", Convert(10966)); AddSingle(dictionary, "swarhk;", Convert(10534)); AddSingle(dictionary, "swArr;", Convert(8665)); AddSingle(dictionary, "swarr;", Convert(8601)); AddSingle(dictionary, "swarrow;", Convert(8601)); AddSingle(dictionary, "swnwar;", Convert(10538)); AddBoth(dictionary, "szlig;", Convert(223)); return dictionary; } private Dictionary GetSymbolBigS() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Sacute;", Convert(346)); AddSingle(dictionary, "Sc;", Convert(10940)); AddSingle(dictionary, "Scaron;", Convert(352)); AddSingle(dictionary, "Scedil;", Convert(350)); AddSingle(dictionary, "Scirc;", Convert(348)); AddSingle(dictionary, "Scy;", Convert(1057)); AddSingle(dictionary, "Sfr;", Convert(120086)); AddSingle(dictionary, "SHCHcy;", Convert(1065)); AddSingle(dictionary, "SHcy;", Convert(1064)); AddSingle(dictionary, "ShortDownArrow;", Convert(8595)); AddSingle(dictionary, "ShortLeftArrow;", Convert(8592)); AddSingle(dictionary, "ShortRightArrow;", Convert(8594)); AddSingle(dictionary, "ShortUpArrow;", Convert(8593)); AddSingle(dictionary, "Sigma;", Convert(931)); AddSingle(dictionary, "SmallCircle;", Convert(8728)); AddSingle(dictionary, "SOFTcy;", Convert(1068)); AddSingle(dictionary, "Sopf;", Convert(120138)); AddSingle(dictionary, "Sqrt;", Convert(8730)); AddSingle(dictionary, "Square;", Convert(9633)); AddSingle(dictionary, "SquareIntersection;", Convert(8851)); AddSingle(dictionary, "SquareSubset;", Convert(8847)); AddSingle(dictionary, "SquareSubsetEqual;", Convert(8849)); AddSingle(dictionary, "SquareSuperset;", Convert(8848)); AddSingle(dictionary, "SquareSupersetEqual;", Convert(8850)); AddSingle(dictionary, "SquareUnion;", Convert(8852)); AddSingle(dictionary, "Sscr;", Convert(119982)); AddSingle(dictionary, "Star;", Convert(8902)); AddSingle(dictionary, "Sub;", Convert(8912)); AddSingle(dictionary, "Subset;", Convert(8912)); AddSingle(dictionary, "SubsetEqual;", Convert(8838)); AddSingle(dictionary, "Succeeds;", Convert(8827)); AddSingle(dictionary, "SucceedsEqual;", Convert(10928)); AddSingle(dictionary, "SucceedsSlantEqual;", Convert(8829)); AddSingle(dictionary, "SucceedsTilde;", Convert(8831)); AddSingle(dictionary, "SuchThat;", Convert(8715)); AddSingle(dictionary, "Sum;", Convert(8721)); AddSingle(dictionary, "Sup;", Convert(8913)); AddSingle(dictionary, "Superset;", Convert(8835)); AddSingle(dictionary, "SupersetEqual;", Convert(8839)); AddSingle(dictionary, "Supset;", Convert(8913)); return dictionary; } private Dictionary GetSymbolLittleT() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "target;", Convert(8982)); AddSingle(dictionary, "tau;", Convert(964)); AddSingle(dictionary, "tbrk;", Convert(9140)); AddSingle(dictionary, "tcaron;", Convert(357)); AddSingle(dictionary, "tcedil;", Convert(355)); AddSingle(dictionary, "tcy;", Convert(1090)); AddSingle(dictionary, "tdot;", Convert(8411)); AddSingle(dictionary, "telrec;", Convert(8981)); AddSingle(dictionary, "tfr;", Convert(120113)); AddSingle(dictionary, "there4;", Convert(8756)); AddSingle(dictionary, "therefore;", Convert(8756)); AddSingle(dictionary, "theta;", Convert(952)); AddSingle(dictionary, "thetasym;", Convert(977)); AddSingle(dictionary, "thetav;", Convert(977)); AddSingle(dictionary, "thickapprox;", Convert(8776)); AddSingle(dictionary, "thicksim;", Convert(8764)); AddSingle(dictionary, "thinsp;", Convert(8201)); AddSingle(dictionary, "thkap;", Convert(8776)); AddSingle(dictionary, "thksim;", Convert(8764)); AddBoth(dictionary, "thorn;", Convert(254)); AddSingle(dictionary, "tilde;", Convert(732)); AddBoth(dictionary, "times;", Convert(215)); AddSingle(dictionary, "timesb;", Convert(8864)); AddSingle(dictionary, "timesbar;", Convert(10801)); AddSingle(dictionary, "timesd;", Convert(10800)); AddSingle(dictionary, "tint;", Convert(8749)); AddSingle(dictionary, "toea;", Convert(10536)); AddSingle(dictionary, "top;", Convert(8868)); AddSingle(dictionary, "topbot;", Convert(9014)); AddSingle(dictionary, "topcir;", Convert(10993)); AddSingle(dictionary, "topf;", Convert(120165)); AddSingle(dictionary, "topfork;", Convert(10970)); AddSingle(dictionary, "tosa;", Convert(10537)); AddSingle(dictionary, "tprime;", Convert(8244)); AddSingle(dictionary, "trade;", Convert(8482)); AddSingle(dictionary, "triangle;", Convert(9653)); AddSingle(dictionary, "triangledown;", Convert(9663)); AddSingle(dictionary, "triangleleft;", Convert(9667)); AddSingle(dictionary, "trianglelefteq;", Convert(8884)); AddSingle(dictionary, "triangleq;", Convert(8796)); AddSingle(dictionary, "triangleright;", Convert(9657)); AddSingle(dictionary, "trianglerighteq;", Convert(8885)); AddSingle(dictionary, "tridot;", Convert(9708)); AddSingle(dictionary, "trie;", Convert(8796)); AddSingle(dictionary, "triminus;", Convert(10810)); AddSingle(dictionary, "triplus;", Convert(10809)); AddSingle(dictionary, "trisb;", Convert(10701)); AddSingle(dictionary, "tritime;", Convert(10811)); AddSingle(dictionary, "trpezium;", Convert(9186)); AddSingle(dictionary, "tscr;", Convert(120009)); AddSingle(dictionary, "tscy;", Convert(1094)); AddSingle(dictionary, "tshcy;", Convert(1115)); AddSingle(dictionary, "tstrok;", Convert(359)); AddSingle(dictionary, "twixt;", Convert(8812)); AddSingle(dictionary, "twoheadleftarrow;", Convert(8606)); AddSingle(dictionary, "twoheadrightarrow;", Convert(8608)); return dictionary; } private Dictionary GetSymbolBigT() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Tab;", Convert(9)); AddSingle(dictionary, "Tau;", Convert(932)); AddSingle(dictionary, "Tcaron;", Convert(356)); AddSingle(dictionary, "Tcedil;", Convert(354)); AddSingle(dictionary, "Tcy;", Convert(1058)); AddSingle(dictionary, "Tfr;", Convert(120087)); AddSingle(dictionary, "Therefore;", Convert(8756)); AddSingle(dictionary, "Theta;", Convert(920)); AddSingle(dictionary, "ThickSpace;", Convert(8287, 8202)); AddSingle(dictionary, "ThinSpace;", Convert(8201)); AddBoth(dictionary, "THORN;", Convert(222)); AddSingle(dictionary, "Tilde;", Convert(8764)); AddSingle(dictionary, "TildeEqual;", Convert(8771)); AddSingle(dictionary, "TildeFullEqual;", Convert(8773)); AddSingle(dictionary, "TildeTilde;", Convert(8776)); AddSingle(dictionary, "Topf;", Convert(120139)); AddSingle(dictionary, "TRADE;", Convert(8482)); AddSingle(dictionary, "TripleDot;", Convert(8411)); AddSingle(dictionary, "Tscr;", Convert(119983)); AddSingle(dictionary, "TScy;", Convert(1062)); AddSingle(dictionary, "TSHcy;", Convert(1035)); AddSingle(dictionary, "Tstrok;", Convert(358)); return dictionary; } private Dictionary GetSymbolLittleU() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "uacute;", Convert(250)); AddSingle(dictionary, "uArr;", Convert(8657)); AddSingle(dictionary, "uarr;", Convert(8593)); AddSingle(dictionary, "ubrcy;", Convert(1118)); AddSingle(dictionary, "ubreve;", Convert(365)); AddBoth(dictionary, "ucirc;", Convert(251)); AddSingle(dictionary, "ucy;", Convert(1091)); AddSingle(dictionary, "udarr;", Convert(8645)); AddSingle(dictionary, "udblac;", Convert(369)); AddSingle(dictionary, "udhar;", Convert(10606)); AddSingle(dictionary, "ufisht;", Convert(10622)); AddSingle(dictionary, "ufr;", Convert(120114)); AddBoth(dictionary, "ugrave;", Convert(249)); AddSingle(dictionary, "uHar;", Convert(10595)); AddSingle(dictionary, "uharl;", Convert(8639)); AddSingle(dictionary, "uharr;", Convert(8638)); AddSingle(dictionary, "uhblk;", Convert(9600)); AddSingle(dictionary, "ulcorn;", Convert(8988)); AddSingle(dictionary, "ulcorner;", Convert(8988)); AddSingle(dictionary, "ulcrop;", Convert(8975)); AddSingle(dictionary, "ultri;", Convert(9720)); AddSingle(dictionary, "umacr;", Convert(363)); AddBoth(dictionary, "uml;", Convert(168)); AddSingle(dictionary, "uogon;", Convert(371)); AddSingle(dictionary, "uopf;", Convert(120166)); AddSingle(dictionary, "uparrow;", Convert(8593)); AddSingle(dictionary, "updownarrow;", Convert(8597)); AddSingle(dictionary, "upharpoonleft;", Convert(8639)); AddSingle(dictionary, "upharpoonright;", Convert(8638)); AddSingle(dictionary, "uplus;", Convert(8846)); AddSingle(dictionary, "upsi;", Convert(965)); AddSingle(dictionary, "upsih;", Convert(978)); AddSingle(dictionary, "upsilon;", Convert(965)); AddSingle(dictionary, "upuparrows;", Convert(8648)); AddSingle(dictionary, "urcorn;", Convert(8989)); AddSingle(dictionary, "urcorner;", Convert(8989)); AddSingle(dictionary, "urcrop;", Convert(8974)); AddSingle(dictionary, "uring;", Convert(367)); AddSingle(dictionary, "urtri;", Convert(9721)); AddSingle(dictionary, "uscr;", Convert(120010)); AddSingle(dictionary, "utdot;", Convert(8944)); AddSingle(dictionary, "utilde;", Convert(361)); AddSingle(dictionary, "utri;", Convert(9653)); AddSingle(dictionary, "utrif;", Convert(9652)); AddSingle(dictionary, "uuarr;", Convert(8648)); AddBoth(dictionary, "uuml;", Convert(252)); AddSingle(dictionary, "uwangle;", Convert(10663)); return dictionary; } private Dictionary GetSymbolBigU() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "Uacute;", Convert(218)); AddSingle(dictionary, "Uarr;", Convert(8607)); AddSingle(dictionary, "Uarrocir;", Convert(10569)); AddSingle(dictionary, "Ubrcy;", Convert(1038)); AddSingle(dictionary, "Ubreve;", Convert(364)); AddBoth(dictionary, "Ucirc;", Convert(219)); AddSingle(dictionary, "Ucy;", Convert(1059)); AddSingle(dictionary, "Udblac;", Convert(368)); AddSingle(dictionary, "Ufr;", Convert(120088)); AddBoth(dictionary, "Ugrave;", Convert(217)); AddSingle(dictionary, "Umacr;", Convert(362)); AddSingle(dictionary, "UnderBar;", Convert(95)); AddSingle(dictionary, "UnderBrace;", Convert(9183)); AddSingle(dictionary, "UnderBracket;", Convert(9141)); AddSingle(dictionary, "UnderParenthesis;", Convert(9181)); AddSingle(dictionary, "Union;", Convert(8899)); AddSingle(dictionary, "UnionPlus;", Convert(8846)); AddSingle(dictionary, "Uogon;", Convert(370)); AddSingle(dictionary, "Uopf;", Convert(120140)); AddSingle(dictionary, "UpArrow;", Convert(8593)); AddSingle(dictionary, "Uparrow;", Convert(8657)); AddSingle(dictionary, "UpArrowBar;", Convert(10514)); AddSingle(dictionary, "UpArrowDownArrow;", Convert(8645)); AddSingle(dictionary, "UpDownArrow;", Convert(8597)); AddSingle(dictionary, "Updownarrow;", Convert(8661)); AddSingle(dictionary, "UpEquilibrium;", Convert(10606)); AddSingle(dictionary, "UpperLeftArrow;", Convert(8598)); AddSingle(dictionary, "UpperRightArrow;", Convert(8599)); AddSingle(dictionary, "Upsi;", Convert(978)); AddSingle(dictionary, "Upsilon;", Convert(933)); AddSingle(dictionary, "UpTee;", Convert(8869)); AddSingle(dictionary, "UpTeeArrow;", Convert(8613)); AddSingle(dictionary, "Uring;", Convert(366)); AddSingle(dictionary, "Uscr;", Convert(119984)); AddSingle(dictionary, "Utilde;", Convert(360)); AddBoth(dictionary, "Uuml;", Convert(220)); return dictionary; } private Dictionary GetSymbolLittleV() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "vangrt;", Convert(10652)); AddSingle(dictionary, "varepsilon;", Convert(1013)); AddSingle(dictionary, "varkappa;", Convert(1008)); AddSingle(dictionary, "varnothing;", Convert(8709)); AddSingle(dictionary, "varphi;", Convert(981)); AddSingle(dictionary, "varpi;", Convert(982)); AddSingle(dictionary, "varpropto;", Convert(8733)); AddSingle(dictionary, "vArr;", Convert(8661)); AddSingle(dictionary, "varr;", Convert(8597)); AddSingle(dictionary, "varrho;", Convert(1009)); AddSingle(dictionary, "varsigma;", Convert(962)); AddSingle(dictionary, "varsubsetneq;", Convert(8842, 65024)); AddSingle(dictionary, "varsubsetneqq;", Convert(10955, 65024)); AddSingle(dictionary, "varsupsetneq;", Convert(8843, 65024)); AddSingle(dictionary, "varsupsetneqq;", Convert(10956, 65024)); AddSingle(dictionary, "vartheta;", Convert(977)); AddSingle(dictionary, "vartriangleleft;", Convert(8882)); AddSingle(dictionary, "vartriangleright;", Convert(8883)); AddSingle(dictionary, "vBar;", Convert(10984)); AddSingle(dictionary, "vBarv;", Convert(10985)); AddSingle(dictionary, "vcy;", Convert(1074)); AddSingle(dictionary, "vDash;", Convert(8872)); AddSingle(dictionary, "vdash;", Convert(8866)); AddSingle(dictionary, "vee;", Convert(8744)); AddSingle(dictionary, "veebar;", Convert(8891)); AddSingle(dictionary, "veeeq;", Convert(8794)); AddSingle(dictionary, "vellip;", Convert(8942)); AddSingle(dictionary, "verbar;", Convert(124)); AddSingle(dictionary, "vert;", Convert(124)); AddSingle(dictionary, "vfr;", Convert(120115)); AddSingle(dictionary, "vltri;", Convert(8882)); AddSingle(dictionary, "vnsub;", Convert(8834, 8402)); AddSingle(dictionary, "vnsup;", Convert(8835, 8402)); AddSingle(dictionary, "vopf;", Convert(120167)); AddSingle(dictionary, "vprop;", Convert(8733)); AddSingle(dictionary, "vrtri;", Convert(8883)); AddSingle(dictionary, "vscr;", Convert(120011)); AddSingle(dictionary, "vsubnE;", Convert(10955, 65024)); AddSingle(dictionary, "vsubne;", Convert(8842, 65024)); AddSingle(dictionary, "vsupnE;", Convert(10956, 65024)); AddSingle(dictionary, "vsupne;", Convert(8843, 65024)); AddSingle(dictionary, "vzigzag;", Convert(10650)); return dictionary; } private Dictionary GetSymbolBigV() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Vbar;", Convert(10987)); AddSingle(dictionary, "Vcy;", Convert(1042)); AddSingle(dictionary, "VDash;", Convert(8875)); AddSingle(dictionary, "Vdash;", Convert(8873)); AddSingle(dictionary, "Vdashl;", Convert(10982)); AddSingle(dictionary, "Vee;", Convert(8897)); AddSingle(dictionary, "Verbar;", Convert(8214)); AddSingle(dictionary, "Vert;", Convert(8214)); AddSingle(dictionary, "VerticalBar;", Convert(8739)); AddSingle(dictionary, "VerticalLine;", Convert(124)); AddSingle(dictionary, "VerticalSeparator;", Convert(10072)); AddSingle(dictionary, "VerticalTilde;", Convert(8768)); AddSingle(dictionary, "VeryThinSpace;", Convert(8202)); AddSingle(dictionary, "Vfr;", Convert(120089)); AddSingle(dictionary, "Vopf;", Convert(120141)); AddSingle(dictionary, "Vscr;", Convert(119985)); AddSingle(dictionary, "Vvdash;", Convert(8874)); return dictionary; } private Dictionary GetSymbolLittleW() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "wcirc;", Convert(373)); AddSingle(dictionary, "wedbar;", Convert(10847)); AddSingle(dictionary, "wedge;", Convert(8743)); AddSingle(dictionary, "wedgeq;", Convert(8793)); AddSingle(dictionary, "weierp;", Convert(8472)); AddSingle(dictionary, "wfr;", Convert(120116)); AddSingle(dictionary, "wopf;", Convert(120168)); AddSingle(dictionary, "wp;", Convert(8472)); AddSingle(dictionary, "wr;", Convert(8768)); AddSingle(dictionary, "wreath;", Convert(8768)); AddSingle(dictionary, "wscr;", Convert(120012)); return dictionary; } private Dictionary GetSymbolBigW() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Wcirc;", Convert(372)); AddSingle(dictionary, "Wedge;", Convert(8896)); AddSingle(dictionary, "Wfr;", Convert(120090)); AddSingle(dictionary, "Wopf;", Convert(120142)); AddSingle(dictionary, "Wscr;", Convert(119986)); return dictionary; } private Dictionary GetSymbolLittleX() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "xcap;", Convert(8898)); AddSingle(dictionary, "xcirc;", Convert(9711)); AddSingle(dictionary, "xcup;", Convert(8899)); AddSingle(dictionary, "xdtri;", Convert(9661)); AddSingle(dictionary, "xfr;", Convert(120117)); AddSingle(dictionary, "xhArr;", Convert(10234)); AddSingle(dictionary, "xharr;", Convert(10231)); AddSingle(dictionary, "xi;", Convert(958)); AddSingle(dictionary, "xlArr;", Convert(10232)); AddSingle(dictionary, "xlarr;", Convert(10229)); AddSingle(dictionary, "xmap;", Convert(10236)); AddSingle(dictionary, "xnis;", Convert(8955)); AddSingle(dictionary, "xodot;", Convert(10752)); AddSingle(dictionary, "xopf;", Convert(120169)); AddSingle(dictionary, "xoplus;", Convert(10753)); AddSingle(dictionary, "xotime;", Convert(10754)); AddSingle(dictionary, "xrArr;", Convert(10233)); AddSingle(dictionary, "xrarr;", Convert(10230)); AddSingle(dictionary, "xscr;", Convert(120013)); AddSingle(dictionary, "xsqcup;", Convert(10758)); AddSingle(dictionary, "xuplus;", Convert(10756)); AddSingle(dictionary, "xutri;", Convert(9651)); AddSingle(dictionary, "xvee;", Convert(8897)); AddSingle(dictionary, "xwedge;", Convert(8896)); return dictionary; } private Dictionary GetSymbolBigX() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Xfr;", Convert(120091)); AddSingle(dictionary, "Xi;", Convert(926)); AddSingle(dictionary, "Xopf;", Convert(120143)); AddSingle(dictionary, "Xscr;", Convert(119987)); return dictionary; } private Dictionary GetSymbolLittleY() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "yacute;", Convert(253)); AddSingle(dictionary, "yacy;", Convert(1103)); AddSingle(dictionary, "ycirc;", Convert(375)); AddSingle(dictionary, "ycy;", Convert(1099)); AddBoth(dictionary, "yen;", Convert(165)); AddSingle(dictionary, "yfr;", Convert(120118)); AddSingle(dictionary, "yicy;", Convert(1111)); AddSingle(dictionary, "yopf;", Convert(120170)); AddSingle(dictionary, "yscr;", Convert(120014)); AddSingle(dictionary, "yucy;", Convert(1102)); AddBoth(dictionary, "yuml;", Convert(255)); return dictionary; } private Dictionary GetSymbolBigY() { Dictionary dictionary = new Dictionary(); AddBoth(dictionary, "Yacute;", Convert(221)); AddSingle(dictionary, "YAcy;", Convert(1071)); AddSingle(dictionary, "Ycirc;", Convert(374)); AddSingle(dictionary, "Ycy;", Convert(1067)); AddSingle(dictionary, "Yfr;", Convert(120092)); AddSingle(dictionary, "YIcy;", Convert(1031)); AddSingle(dictionary, "Yopf;", Convert(120144)); AddSingle(dictionary, "Yscr;", Convert(119988)); AddSingle(dictionary, "YUcy;", Convert(1070)); AddSingle(dictionary, "Yuml;", Convert(376)); return dictionary; } private Dictionary GetSymbolLittleZ() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "zacute;", Convert(378)); AddSingle(dictionary, "zcaron;", Convert(382)); AddSingle(dictionary, "zcy;", Convert(1079)); AddSingle(dictionary, "zdot;", Convert(380)); AddSingle(dictionary, "zeetrf;", Convert(8488)); AddSingle(dictionary, "zeta;", Convert(950)); AddSingle(dictionary, "zfr;", Convert(120119)); AddSingle(dictionary, "zhcy;", Convert(1078)); AddSingle(dictionary, "zigrarr;", Convert(8669)); AddSingle(dictionary, "zopf;", Convert(120171)); AddSingle(dictionary, "zscr;", Convert(120015)); AddSingle(dictionary, "zwj;", Convert(8205)); AddSingle(dictionary, "zwnj;", Convert(8204)); return dictionary; } private Dictionary GetSymbolBigZ() { Dictionary dictionary = new Dictionary(); AddSingle(dictionary, "Zacute;", Convert(377)); AddSingle(dictionary, "Zcaron;", Convert(381)); AddSingle(dictionary, "Zcy;", Convert(1047)); AddSingle(dictionary, "Zdot;", Convert(379)); AddSingle(dictionary, "ZeroWidthSpace;", Convert(8203)); AddSingle(dictionary, "Zeta;", Convert(918)); AddSingle(dictionary, "Zfr;", Convert(8488)); AddSingle(dictionary, "ZHcy;", Convert(1046)); AddSingle(dictionary, "Zopf;", Convert(8484)); AddSingle(dictionary, "Zscr;", Convert(119989)); return dictionary; } public string? GetSymbol(string name) { if (!string.IsNullOrEmpty(name) && _entities.TryGetValue(name[0], out Dictionary value) && value.TryGetValue(name.AsMemory(), out var value2)) { return value2; } return null; } public string? GetSymbol(StringOrMemory name) { if (name.Memory.Length != 0 && _entities.TryGetValue(name[0], out Dictionary value) && value.TryGetValue(name, out var value2)) { return value2; } return null; } public string? GetName(string symbol) { foreach (KeyValuePair> entity in _entities) { foreach (KeyValuePair item in entity.Value) { if (item.Value == symbol) { return item.Key.ToString(); } } } return null; } private static string Convert(int code) { return char.ConvertFromUtf32(code); } private static string Convert(int leading, int trailing) { return char.ConvertFromUtf32(leading) + char.ConvertFromUtf32(trailing); } public static bool IsInvalidNumber(int code) { if ((code < 55296 || code > 57343) && code >= 0) { return code > 1114111; } return true; } public static bool IsInCharacterTable(int code) { if (code != 0 && code != 13 && code != 128 && code != 129 && code != 130 && code != 131 && code != 132 && code != 133 && code != 134 && code != 135 && code != 136 && code != 137 && code != 138 && code != 139 && code != 140 && code != 141 && code != 142 && code != 143 && code != 144 && code != 145 && code != 146 && code != 147 && code != 148 && code != 149 && code != 150 && code != 151 && code != 152 && code != 153 && code != 154 && code != 155 && code != 156 && code != 157 && code != 158) { return code == 159; } return true; } public static string? GetSymbolFromTable(int code) { return code switch { 0 => Convert(65533), 13 => Convert(13), 128 => Convert(8364), 129 => Convert(129), 130 => Convert(8218), 131 => Convert(402), 132 => Convert(8222), 133 => Convert(8230), 134 => Convert(8224), 135 => Convert(8225), 136 => Convert(710), 137 => Convert(8240), 138 => Convert(352), 139 => Convert(8249), 140 => Convert(338), 141 => Convert(141), 142 => Convert(381), 143 => Convert(143), 144 => Convert(144), 145 => Convert(8216), 146 => Convert(8217), 147 => Convert(8220), 148 => Convert(8221), 149 => Convert(8226), 150 => Convert(8211), 151 => Convert(8212), 152 => Convert(732), 153 => Convert(8482), 154 => Convert(353), 155 => Convert(8250), 156 => Convert(339), 157 => Convert(157), 158 => Convert(382), 159 => Convert(376), _ => null, }; } public static bool IsInInvalidRange(int code) { if ((code < 1 || code > 8) && (code < 14 || code > 31) && (code < 127 || code > 159) && (code < 64976 || code > 65007) && code != 11 && code != 65534 && code != 65535 && code != 131070 && code != 196606 && code != 131071 && code != 196607 && code != 262142 && code != 262143 && code != 327678 && code != 327679 && code != 393214 && code != 393215 && code != 458750 && code != 458751 && code != 524286 && code != 524287 && code != 589822 && code != 589823 && code != 655358 && code != 655359 && code != 720894 && code != 720895 && code != 786430 && code != 786431 && code != 851966 && code != 851967 && code != 917502 && code != 917503 && code != 983038 && code != 983039 && code != 1048574 && code != 1048575 && code != 1114110) { return code == 1114111; } return true; } private static void AddSingle(Dictionary symbols, string key, string value) { symbols.Add(key, value); } private static void AddBoth(Dictionary symbols, string key, string value) { symbols.Add(key, value); symbols.Add(key.Remove(key.Length - 1), value); } } public class HtmlMarkupFormatter : IMarkupFormatter { public static readonly IMarkupFormatter Instance = new HtmlMarkupFormatter(); public virtual string Comment(IComment comment) { return ""; } public virtual string Doctype(IDocumentType doctype) { string ids = GetIds(doctype.PublicIdentifier, doctype.SystemIdentifier); return ""; } public virtual string Processing(IProcessingInstruction processing) { string text = processing.Target + " " + processing.Data; return ""; } public virtual string LiteralText(ICharacterData text) { return text.Data; } public virtual string Text(ICharacterData text) { return EscapeText(text.Data); } public virtual string OpenTag(IElement element, bool selfClosing) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); stringBuilder.Append('<'); if (!string.IsNullOrEmpty(element.Prefix)) { stringBuilder.Append(element.Prefix).Append(':'); } stringBuilder.Append(element.LocalName); foreach (IAttr attribute in element.Attributes) { stringBuilder.Append(' ').Append(Attribute(attribute)); } stringBuilder.Append('>'); return stringBuilder.ToPool(); } public virtual string CloseTag(IElement element, bool selfClosing) { string prefix = element.Prefix; string localName = element.LocalName; string text = ((!string.IsNullOrEmpty(prefix)) ? (prefix + ":" + localName) : localName); if (!selfClosing) { return ""; } return string.Empty; } protected virtual string Attribute(IAttr attr) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); WriteAttributeName(attr, stringBuilder); if (attr.Value != null) { stringBuilder.Append('=').Append('"'); WriteAttributeValue(attr, stringBuilder); return stringBuilder.Append('"').ToPool(); } return stringBuilder.ToPool(); } internal static void WriteAttributeName(IAttr attr, StringBuilder stringBuilder) { string namespaceUri = attr.NamespaceUri; string localName = attr.LocalName; if (string.IsNullOrEmpty(namespaceUri)) { stringBuilder.Append(localName); } else if (namespaceUri.Is(NamespaceNames.XmlUri)) { stringBuilder.Append(NamespaceNames.XmlPrefix).Append(':').Append(localName); } else if (namespaceUri.Is(NamespaceNames.XLinkUri)) { stringBuilder.Append(NamespaceNames.XLinkPrefix).Append(':').Append(localName); } else if (namespaceUri.Is(NamespaceNames.XmlNsUri)) { stringBuilder.Append(XmlNamespaceLocalName(localName)); } else { stringBuilder.Append(attr.Name); } } internal static void WriteAttributeValue(IAttr attr, StringBuilder stringBuilder) { string text = attr.Value ?? string.Empty; for (int i = 0; i < text.Length; i++) { switch (text[i]) { case '&': stringBuilder.Append("&"); break; case '\u00a0': stringBuilder.Append(" "); break; case '"': stringBuilder.Append("""); break; default: stringBuilder.Append(text[i]); break; } } } public static string EscapeText(string content) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); for (int i = 0; i < content.Length; i++) { switch (content[i]) { case '&': stringBuilder.Append("&"); break; case '\u00a0': stringBuilder.Append(" "); break; case '>': stringBuilder.Append(">"); break; case '<': stringBuilder.Append("<"); break; default: stringBuilder.Append(content[i]); break; } } return stringBuilder.ToPool(); } public static string GetIds(string publicId, string systemId) { if (string.IsNullOrEmpty(publicId) && string.IsNullOrEmpty(systemId)) { return string.Empty; } if (string.IsNullOrEmpty(systemId)) { return " PUBLIC \"" + publicId + "\""; } if (string.IsNullOrEmpty(publicId)) { return " SYSTEM \"" + systemId + "\""; } return $" PUBLIC \"{publicId}\" \"{systemId}\""; } public static string XmlNamespaceLocalName(string name) { if (!(name != NamespaceNames.XmlNsPrefix)) { return name; } return NamespaceNames.XmlNsPrefix + ":" + name; } } public interface IInputTypeFactory { BaseInputType Create(IHtmlInputElement input, string type); } public interface ILinkRelationFactory { BaseLinkRelation? Create(IHtmlLinkElement link, string? relation); } public static class InputTypeNames { public static readonly string Hidden = "hidden"; public static readonly string Text = "text"; public static readonly string Search = "search"; public static readonly string Tel = "tel"; public static readonly string Url = "url"; public static readonly string Email = "email"; public static readonly string Password = "password"; public static readonly string Datetime = "datetime"; public static readonly string DatetimeLocal = "datetime-local"; public static readonly string Date = "date"; public static readonly string Month = "month"; public static readonly string Week = "week"; public static readonly string Time = "time"; public static readonly string Number = "number"; public static readonly string Range = "range"; public static readonly string Color = "color"; public static readonly string Checkbox = "checkbox"; public static readonly string Radio = "radio"; public static readonly string File = "file"; public static readonly string Submit = "submit"; public static readonly string Image = "image"; public static readonly string Reset = "reset"; public static readonly string Button = "button"; public static readonly string SelectMultiple = "select-multiple"; public static readonly string SelectOne = "select-one"; } public static class LinkRelNames { public static readonly string StyleSheet = "stylesheet"; public static readonly string Import = "import"; public static readonly string Author = "author"; public static readonly string Prefetch = "prefetch"; public static readonly string Icon = "icon"; public static readonly string Prev = "prev"; public static readonly string Next = "next"; public static readonly string License = "license"; public static readonly string Alternate = "alternate"; public static readonly string Search = "search"; public static readonly string Pingback = "pingback"; public static readonly string Sidebar = "sidebar"; } public class MinifyMarkupFormatter : HtmlMarkupFormatter { private IEnumerable _preservedTags = new string[2] { TagNames.Pre, TagNames.Textarea }; public IEnumerable PreservedTags { get { return _preservedTags ?? Array.Empty(); } set { _preservedTags = value; } } public bool ShouldKeepStandardElements { get; set; } public bool ShouldKeepComments { get; set; } public bool ShouldKeepAttributeQuotes { get; set; } public bool ShouldKeepEmptyAttributes { get; set; } public bool ShouldKeepImpliedEndTag { get; set; } public override string Comment(IComment comment) { if (!ShouldKeepComments) { return string.Empty; } return base.Comment(comment); } public override string Text(ICharacterData text) { if (text.Parent is IHtmlHeadElement || text.Parent is IHtmlHtmlElement) { return string.Empty; } string text2 = base.Text(text); if (!PreservedTags.Contains(text.ParentElement?.LocalName)) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); bool flag = false; bool flag2 = true; foreach (char c in text2) { if (c.IsWhiteSpaceCharacter()) { if (!flag) { stringBuilder.Append(' '); flag = true; } } else { stringBuilder.Append(c); flag2 = false; flag = false; } } if (!flag2 || ShouldOutput(text)) { return stringBuilder.ToPool(); } stringBuilder.ReturnToPool(); return string.Empty; } return text2; } public override string OpenTag(IElement element, bool selfClosing) { if (!CanBeRemoved(element)) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); stringBuilder.Append('<'); if (!string.IsNullOrEmpty(element.Prefix)) { stringBuilder.Append(element.Prefix).Append(':'); } stringBuilder.Append(element.LocalName); foreach (IAttr attribute in element.Attributes) { if (!ShouldKeep(element, attribute)) { continue; } if (!element.IsBooleanAttribute(attribute.Name)) { string value = Attribute(attribute); if (!string.IsNullOrEmpty(value)) { stringBuilder.Append(' ').Append(value); } } else { stringBuilder.Append(' ').Append(attribute.Name); } } if (stringBuilder[stringBuilder.Length - 1] == '/') { stringBuilder.Append(' '); } stringBuilder.Append('>'); return stringBuilder.ToPool(); } return string.Empty; } public override string CloseTag(IElement element, bool selfClosing) { if (!CanBeRemoved(element) && !CanBeSkipped(element)) { return base.CloseTag(element, selfClosing); } return string.Empty; } protected override string Attribute(IAttr attr) { string value = attr.Value; StringBuilder stringBuilder; int num; if (ShouldKeepEmptyAttributes || !string.IsNullOrEmpty(value)) { stringBuilder = StringBuilderPool.Obtain(); HtmlMarkupFormatter.WriteAttributeName(attr, stringBuilder); if (value != null) { stringBuilder.Append('='); if (!ShouldKeepAttributeQuotes) { num = (value.Any(MustBeQuotedAttributeValue) ? 1 : 0); if (num == 0) { goto IL_0068; } } else { num = 1; } stringBuilder.Append('"'); goto IL_0068; } goto IL_007a; } return string.Empty; IL_0068: HtmlMarkupFormatter.WriteAttributeValue(attr, stringBuilder); if (num != 0) { stringBuilder.Append('"'); } goto IL_007a; IL_007a: return stringBuilder.ToPool(); } private bool CanBeRemoved(IElement element) { if (!ShouldKeepStandardElements && element.Attributes.Length == 0) { return element.LocalName.IsOneOf(TagNames.Html, TagNames.Head, TagNames.Body); } return false; } private bool CanBeSkipped(IElement element) { if (!ShouldKeepImpliedEndTag && element.Flags.HasFlag(NodeFlags.ImpliedEnd)) { if (element.NextElementSibling != null) { return element.NextElementSibling.LocalName == element.LocalName; } return true; } return false; } private static bool ShouldOutput(ICharacterData text) { if (text.Parent is HtmlBodyElement) { if (text.NextSibling != null) { return text.PreviousSibling != null; } return false; } return true; } private static bool ShouldKeep(IElement element, IAttr attribute) { if (!IsStandardScript(element, attribute)) { return !IsStandardStyle(element, attribute); } return false; } private static bool IsStandardScript(IElement element, IAttr attr) { if (element is HtmlScriptElement && attr.Name.Is(AttributeNames.Type)) { return attr.Value.Is(MimeTypeNames.DefaultJavaScript); } return false; } private static bool IsStandardStyle(IElement element, IAttr attr) { if (element is HtmlStyleElement && attr.Name.Is(AttributeNames.Type)) { return attr.Value.Is(MimeTypeNames.Css); } return false; } private static bool MustBeQuotedAttributeValue(char c) { if (!c.IsWhiteSpaceCharacter() && c != '"' && c != '\'' && c != '=' && c != '>' && c != '<') { return c == '`'; } return true; } } public class PrettyMarkupFormatter : HtmlMarkupFormatter { private string _indentString; private string _newLineString; private int _indentCount; private IEnumerable? _preserveTextFormatting; public string Indentation { get { return _indentString; } set { _indentString = value; } } public string NewLine { get { return _newLineString; } set { _newLineString = value; } } public PrettyMarkupFormatter() { _indentCount = 0; _indentString = "\t"; _newLineString = "\n"; } public PrettyMarkupFormatter(IEnumerable preserveTextFormatting) { _indentCount = 0; _indentString = "\t"; _newLineString = "\n"; _preserveTextFormatting = from y in preserveTextFormatting.SelectMany((INode x) => x.ChildNodes) where y is ICharacterData select y; } public override string Comment(IComment comment) { return IndentBefore() + base.Comment(comment); } public override string Doctype(IDocumentType doctype) { string text = string.Empty; if (doctype.ParentElement != null) { text = IndentBefore(); } return text + base.Doctype(doctype) + NewLine; } public override string Processing(IProcessingInstruction processing) { return IndentBefore() + base.Processing(processing); } public override string Text(ICharacterData text) { IEnumerable? preserveTextFormatting = _preserveTextFormatting; if (preserveTextFormatting != null && preserveTextFormatting.Contains(text)) { return text.Data.TrimEnd('\n').Replace("\n", IndentBefore(1)); } string data = text.Data; string text2 = string.Empty; string text3 = data.Replace('\n', ' '); if (!(text.NextSibling is ICharacterData)) { text3 = text3.TrimEnd(); } if (text3.Length > 0 && !(text.PreviousSibling is ICharacterData) && text3[0].IsSpaceCharacter()) { text3 = text3.TrimStart(); text2 = IndentBefore(); } return text2 + HtmlMarkupFormatter.EscapeText(text3); } public override string OpenTag(IElement element, bool selfClosing) { string text = string.Empty; IText text2 = element.PreviousSibling as IText; if (element.ParentElement != null && (text2 == null || EndsWithSpace(text2))) { text = IndentBefore(); } _indentCount++; return text + base.OpenTag(element, selfClosing); } public override string CloseTag(IElement element, bool selfClosing) { _indentCount--; string text = string.Empty; IText text2 = element.LastChild as IText; if (element.HasChildNodes && (text2 == null || EndsWithSpace(text2))) { text = IndentBefore(); } return text + base.CloseTag(element, selfClosing); } private static bool EndsWithSpace(ICharacterData text) { string data = text.Data; if (data.Length > 0) { return data[data.Length - 1].IsSpaceCharacter(); } return false; } private string IndentBefore(int i = 0) { return _newLineString + string.Join(string.Empty, Enumerable.Repeat(_indentString, _indentCount - i)); } } 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 static Regex CreateRegex() { string pattern = "(\\([^)]+\\))?\\s*(.+)"; try { return new Regex(pattern, RegexOptions.Compiled | RegexOptions.ECMAScript | RegexOptions.CultureInvariant); } catch { return new Regex(pattern, RegexOptions.ECMAScript); } } public static IEnumerable 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) { continue; } 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.0; string[] array = text.Split(' '); for (int num = array.Length - 1; num >= 0; num--) { string text2 = array[num]; char c = ((text2.Length > 0) ? text2[text2.Length - 1] : '\0'); 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.0); } } return result; } private double GetWidthFromLength(string length) { return 0.0; } private double GetWidthFromSourceSize(string sourceSizes) { string[] array = sourceSizes.Trim().Split(','); for (int i = 0; i < array.Length; i++) { MediaSize mediaSize = ParseSize(array[i]); string length = mediaSize.Length; _ = mediaSize.Media; string.IsNullOrEmpty(length); } return GetWidthFromLength(FullWidth); } public IEnumerable GetCandidates(string? srcset, string? sizes) { if (srcset == null || srcset.Length <= 0) { yield break; } foreach (ImageCandidate item in Parse(srcset)) { if (item.Url != null) { yield return item.Url; } } } } [Flags] public enum ValidationErrors : ushort { None = 0, ValueMissing = 1, TypeMismatch = 2, PatternMismatch = 4, TooLong = 8, TooShort = 0x10, RangeUnderflow = 0x20, RangeOverflow = 0x40, StepMismatch = 0x80, BadInput = 0x100, Custom = 0x200 } } namespace AngleSharp.Html.Parser { internal static class HtmlAttributesLookup { private static readonly Dictionary WellKnownAttributeNames = new Dictionary(OrdinalStringOrMemoryComparer.Instance) { { "name", "name" }, { "http-equiv", "http-equiv" }, { "scheme", "scheme" }, { "content", "content" }, { "class", "class" }, { "style", "style" }, { "label", "label" }, { "action", "action" }, { "prompt", "prompt" }, { "href", "href" }, { "hreflang", "hreflang" }, { "lang", "lang" }, { "disabled", "disabled" }, { "selected", "selected" }, { "value", "value" }, { "title", "title" }, { "type", "type" }, { "rel", "rel" }, { "rev", "rev" }, { "accesskey", "accesskey" }, { "download", "download" }, { "media", "media" }, { "target", "target" }, { "charset", "charset" }, { "alt", "alt" }, { "coords", "coords" }, { "shape", "shape" }, { "formaction", "formaction" }, { "formmethod", "formmethod" }, { "formtarget", "formtarget" }, { "formenctype", "formenctype" }, { "formnovalidate", "formnovalidate" }, { "dirname", "dirname" }, { "dir", "dir" }, { "nonce", "nonce" }, { "noresize", "noresize" }, { "src", "src" }, { "srcset", "srcset" }, { "srclang", "srclang" }, { "srcdoc", "srcdoc" }, { "scrolling", "scrolling" }, { "longdesc", "longdesc" }, { "frameborder", "frameborder" }, { "width", "width" }, { "height", "height" }, { "marginwidth", "marginwidth" }, { "marginheight", "marginheight" }, { "cols", "cols" }, { "rows", "rows" }, { "align", "align" }, { "encoding", "encoding" }, { "standalone", "standalone" }, { "version", "version" }, { "dropzone", "dropzone" }, { "draggable", "draggable" }, { "spellcheck", "spellcheck" }, { "tabindex", "tabindex" }, { "contenteditable", "contenteditable" }, { "translate", "translate" }, { "contextmenu", "contextmenu" }, { "hidden", "hidden" }, { "id", "id" }, { "sizes", "sizes" }, { "scoped", "scoped" }, { "reversed", "reversed" }, { "start", "start" }, { "ping", "ping" }, { "ismap", "ismap" }, { "usemap", "usemap" }, { "crossorigin", "crossorigin" }, { "sandbox", "sandbox" }, { "allowfullscreen", "allowfullscreen" }, { "allowpaymentrequest", "allowpaymentrequest" }, { "data", "data" }, { "typemustmatch", "typemustmatch" }, { "autofocus", "autofocus" }, { "accept-charset", "accept-charset" }, { "enctype", "enctype" }, { "autocomplete", "autocomplete" }, { "method", "method" }, { "novalidate", "novalidate" }, { "for", "for" }, { "seamless", "seamless" }, { "valign", "valign" }, { "span", "span" }, { "bgcolor", "bgcolor" }, { "colspan", "colspan" }, { "referrerpolicy", "referrerpolicy" }, { "rowspan", "rowspan" }, { "nowrap", "nowrap" }, { "abbr", "abbr" }, { "scope", "scope" }, { "headers", "headers" }, { "axis", "axis" }, { "border", "border" }, { "cellpadding", "cellpadding" }, { "rules", "rules" }, { "summary", "summary" }, { "cellspacing", "cellspacing" }, { "frame", "frame" }, { "form", "form" }, { "required", "required" }, { "multiple", "multiple" }, { "min", "min" }, { "max", "max" }, { "open", "open" }, { "challenge", "challenge" }, { "keytype", "keytype" }, { "size", "size" }, { "wrap", "wrap" }, { "maxlength", "maxlength" }, { "minlength", "minlength" }, { "placeholder", "placeholder" }, { "readonly", "readonly" }, { "accept", "accept" }, { "pattern", "pattern" }, { "step", "step" }, { "list", "list" }, { "checked", "checked" }, { "kind", "kind" }, { "default", "default" }, { "autoplay", "autoplay" }, { "preload", "preload" }, { "loop", "loop" }, { "controls", "controls" }, { "muted", "muted" }, { "mediagroup", "mediagroup" }, { "poster", "poster" }, { "color", "color" }, { "face", "face" }, { "command", "command" }, { "icon", "icon" }, { "radiogroup", "radiogroup" }, { "cite", "cite" }, { "async", "async" }, { "defer", "defer" }, { "language", "language" }, { "event", "event" }, { "alink", "alink" }, { "background", "background" }, { "link", "link" }, { "text", "text" }, { "vlink", "vlink" }, { "show", "show" }, { "role", "role" }, { "actuate", "actuate" }, { "arcrole", "arcrole" }, { "space", "space" }, { "window", "window" }, { "manifest", "manifest" }, { "datetime", "datetime" }, { "low", "low" }, { "high", "high" }, { "optimum", "optimum" }, { "slot", "slot" }, { "body", "body" }, { "integrity", "integrity" }, { "clear", "clear" }, { "codetype", "codetype" }, { "compact", "compact" }, { "declare", "declare" }, { "direction", "direction" }, { "nohref", "nohref" }, { "noshade", "noshade" }, { "valuetype", "valuetype" } }; private static readonly int MaxLength = WellKnownAttributeNames.Keys.Select((StringOrMemory x) => x.Length).Max(); public static string? TryGetWellKnownAttributeName(ICharBuffer builder) { char[] array = ArrayPool.Shared.Rent(MaxLength); try { ReadOnlyMemory? readOnlyMemory = builder.TryCopyTo(array); if (readOnlyMemory.HasValue && WellKnownAttributeNames.TryGetValue(new StringOrMemory(readOnlyMemory.Value), out string value)) { return value; } return null; } finally { ArrayPool.Shared.Return(array); } } } internal class HtmlDomBuilder : IDisposable where TDocument : class, IConstructableDocument where TElement : class, IConstructableElement { private readonly TokenConsumer _consumeAsDelegate; private readonly HtmlTokenizer _tokenizer; private readonly TDocument _document; private readonly List _openElements; private readonly List _formattingElements; private readonly Stack _templateModes; private IConstructableElement? _currentFormElement; private HtmlTreeMode _currentMode; private HtmlTreeMode _previousMode; private HtmlParserOptions _options; private IConstructableElement? _fragmentContext; private bool _foster; private bool _frameset; private bool _ended; private Func? _shouldEnd; private readonly IDomConstructionElementFactory _elementFactory; private Task? _waiting; private readonly bool _emitWhitespaceTextNodes; public bool IsFragmentCase => _fragmentContext != null; public IConstructableElement? AdjustedCurrentNode { get { if (_fragmentContext == null || _openElements.Count != 1) { return CurrentNode; } return _fragmentContext; } } public IConstructableElement CurrentNode { get { if (_openElements.Count <= 0) { return null; } return _openElements[_openElements.Count - 1]; } } public event EventHandler Error { add { _tokenizer.Error += value; } remove { _tokenizer.Error -= value; } } public HtmlDomBuilder(IDomConstructionElementFactory elementFactory, TDocument document, HtmlTokenizerOptions? maybeOptions = null, bool emitWhitespaceTextNodes = false, Func? shouldEnd = null) { _shouldEnd = shouldEnd; _elementFactory = elementFactory; _tokenizer = new HtmlTokenizer(document.Source, HtmlEntityProvider.ResolverExtended); _document = document; _openElements = new List(); _templateModes = new Stack(); _formattingElements = new List(); _frameset = true; _currentMode = HtmlTreeMode.Initial; _ended = false; _consumeAsDelegate = Consume; _emitWhitespaceTextNodes = emitWhitespaceTextNodes; document.Builder = this; if (maybeOptions.HasValue) { HtmlTokenizerOptions value = maybeOptions.Value; _tokenizer.IsStrictMode = value.IsStrictMode; _tokenizer.IsSupportingProcessingInstructions = value.IsSupportingProcessingInstructions; _tokenizer.IsNotConsumingCharacterReferences = value.IsNotConsumingCharacterReferences; _tokenizer.IsPreservingAttributeNames = value.IsPreservingAttributeNames; _tokenizer.SkipRawText = value.SkipRawText; _tokenizer.SkipScriptText = value.SkipScriptText; _tokenizer.SkipDataText = value.SkipDataText; _tokenizer.ShouldEmitAttribute = value.ShouldEmitAttribute; _tokenizer.SkipDataText = value.SkipDataText; _tokenizer.SkipScriptText = value.SkipScriptText; _tokenizer.SkipRawText = value.SkipRawText; _tokenizer.SkipComments = value.SkipComments; _tokenizer.SkipPlaintext = value.SkipPlaintext; _tokenizer.SkipRCDataText = value.SkipRCDataText; _tokenizer.SkipCDATA = value.SkipCDATA; _tokenizer.SkipProcessingInstructions = value.SkipProcessingInstructions; _tokenizer.DisableElementPositionTracking = value.DisableElementPositionTracking; } } public TDocument Parse(HtmlParserOptions options, TokenizerMiddleware? middleware = null) { SetOptions(options); do { ref StructHtmlToken structToken = ref _tokenizer.GetStructToken(); if (structToken.Type == HtmlTokenType.EndOfFile) { Consume(ref structToken); break; } if (middleware == null) { Consume(ref structToken); } else if (middleware(ref structToken, _consumeAsDelegate) == TokenConsumptionResult.Stop) { StructHtmlToken token = StructHtmlToken.EndOfFile(default(TextPosition)); Consume(ref token); break; } } while (!_ended); return _document; } public async Task ParseAsync(HtmlParserOptions options, TokenizerMiddleware? middleware = null, CancellationToken cancelToken = default(CancellationToken)) { TextSource source = _document.Source; SetOptions(options); if (middleware == null) { middleware = delegate(ref StructHtmlToken token, TokenConsumer next) { next(ref token); return TokenConsumptionResult.Continue; }; } do { if (source.Length - source.Index < 1024) { await source.PrefetchAsync(8192, cancelToken).ConfigureAwait(continueOnCapturedContext: false); } cancelToken.ThrowIfCancellationRequested(); if (Worker(middleware)) { break; } if (_waiting != null) { await _waiting.ConfigureAwait(continueOnCapturedContext: false); _waiting = null; } } while (!_ended); if (_waiting != null) { await _waiting.ConfigureAwait(continueOnCapturedContext: false); _waiting = null; } return _document; bool Worker(TokenizerMiddleware tokenizerMiddleware) { StructHtmlToken token = _tokenizer.GetStructToken(); if (token.Type == HtmlTokenType.EndOfFile) { Consume(ref token); return true; } if (tokenizerMiddleware(ref token, _consumeAsDelegate) == TokenConsumptionResult.Stop) { StructHtmlToken token2 = StructHtmlToken.EndOfFile(default(TextPosition)); Consume(ref token2); return true; } return false; } } private void Restart() { _currentMode = HtmlTreeMode.Initial; _tokenizer.State = HtmlParseMode.PCData; _document.Clear(); _ended = false; _frameset = true; _openElements.Clear(); _formattingElements.Clear(); _templateModes.Clear(); } private void Reset() { for (int num = _openElements.Count - 1; num >= 0; num--) { IConstructableElement element = _openElements[num]; bool flag = num == 0; if (flag && _fragmentContext != null) { element = _fragmentContext; } HtmlTreeMode? htmlTreeMode = element.SelectMode(flag, _templateModes); if (htmlTreeMode.HasValue) { _currentMode = htmlTreeMode.Value; break; } } } public TDocument ParseFragment(HtmlParserOptions options, TElement context) { context = context ?? throw new ArgumentNullException("context"); _fragmentContext = context; StringOrMemory localName = context.LocalName; if (localName.IsOneOf(TagNames.Title, TagNames.Textarea)) { _tokenizer.State = HtmlParseMode.RCData; } else if (localName.IsOneOf(TagNames.Style, TagNames.Xmp, TagNames.Iframe, TagNames.NoEmbed)) { _tokenizer.State = HtmlParseMode.Rawtext; } else if (localName.Is(TagNames.Script)) { _tokenizer.State = HtmlParseMode.Script; } else if (localName.Is(TagNames.Plaintext)) { _tokenizer.State = HtmlParseMode.Plaintext; } else if (localName.Is(TagNames.NoScript) && (options.IsScripting || context.Flags.HasFlag(NodeFlags.LiteralText))) { _tokenizer.State = HtmlParseMode.Rawtext; } else if (localName.Is(TagNames.NoFrames) && !options.IsNotSupportingFrames) { _tokenizer.State = HtmlParseMode.Rawtext; } TElement val = _elementFactory.Create(_document, TagNames.Html); _document.AddNode(val); _openElements.Add(val); if (context is IConstructableTemplateElement) { _templateModes.Push(HtmlTreeMode.InTemplate); } Reset(); _tokenizer.IsAcceptingCharacterData = !AdjustedCurrentNode.Flags.HasFlag(NodeFlags.HtmlMember); IConstructableNode constructableNode = context; do { if (constructableNode is IConstructableFormElement currentFormElement) { _currentFormElement = currentFormElement; break; } constructableNode = constructableNode.Parent; } while (constructableNode != null); return Parse(options); } private void Consume(ref StructHtmlToken token) { IConstructableElement adjustedCurrentNode = AdjustedCurrentNode; if (adjustedCurrentNode == null || token.Type == HtmlTokenType.EndOfFile || adjustedCurrentNode.Flags.HasFlag(NodeFlags.HtmlMember) || (adjustedCurrentNode.Flags.HasFlag(NodeFlags.HtmlTip) && token.IsHtmlCompatible) || (adjustedCurrentNode.Flags.HasFlag(NodeFlags.MathTip) && token.IsMathCompatible) || (adjustedCurrentNode.Flags.HasFlag(NodeFlags.MathMember) && token.IsSvg && adjustedCurrentNode.LocalName.Is(TagNames.AnnotationXml))) { Home(ref token); } else { Foreign(ref token); } } private void SetOptions(HtmlParserOptions options) { _tokenizer.IsStrictMode = options.IsStrictMode; _tokenizer.IsSupportingProcessingInstructions = options.IsSupportingProcessingInstructions; _tokenizer.IsNotConsumingCharacterReferences = options.IsNotConsumingCharacterReferences; _tokenizer.IsPreservingAttributeNames = options.IsPreservingAttributeNames; _tokenizer.SkipRawText = options.SkipRawText; _tokenizer.SkipScriptText = options.SkipScriptText; _tokenizer.SkipDataText = options.SkipDataText; _tokenizer.SkipScriptText = options.SkipScriptText; _tokenizer.SkipRawText = options.SkipRawText; _tokenizer.SkipComments = options.SkipComments; _tokenizer.SkipPlaintext = options.SkipPlaintext; _tokenizer.SkipRCDataText = options.SkipRCDataText; _tokenizer.SkipCDATA = options.SkipCDATA; _tokenizer.SkipProcessingInstructions = options.SkipProcessingInstructions; _tokenizer.ShouldEmitAttribute = options.ShouldEmitAttribute; _tokenizer.DisableElementPositionTracking = options.DisableElementPositionTracking; _options = options; } private void Home(ref StructHtmlToken token) { switch (_currentMode) { case HtmlTreeMode.Initial: Initial(ref token); break; case HtmlTreeMode.BeforeHtml: BeforeHtml(ref token); break; case HtmlTreeMode.BeforeHead: BeforeHead(ref token); break; case HtmlTreeMode.InHead: InHead(ref token); break; case HtmlTreeMode.InHeadNoScript: InHeadNoScript(ref token); break; case HtmlTreeMode.AfterHead: AfterHead(ref token); break; case HtmlTreeMode.InBody: InBody(ref token); break; case HtmlTreeMode.Text: Text(ref token); break; case HtmlTreeMode.InTable: InTable(ref token); break; case HtmlTreeMode.InCaption: InCaption(ref token); break; case HtmlTreeMode.InColumnGroup: InColumnGroup(ref token); break; case HtmlTreeMode.InTableBody: InTableBody(ref token); break; case HtmlTreeMode.InRow: InRow(ref token); break; case HtmlTreeMode.InCell: InCell(ref token); break; case HtmlTreeMode.InSelect: InSelect(ref token); break; case HtmlTreeMode.InSelectInTable: InSelectInTable(ref token); break; case HtmlTreeMode.InTemplate: InTemplate(ref token); break; case HtmlTreeMode.AfterBody: AfterBody(ref token); break; case HtmlTreeMode.InFrameset: InFrameset(ref token); break; case HtmlTreeMode.AfterFrameset: AfterFrameset(ref token); break; case HtmlTreeMode.AfterAfterBody: AfterAfterBody(ref token); break; case HtmlTreeMode.AfterAfterFrameset: AfterAfterFrameset(ref token); break; } } private void Initial(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Doctype: { if (!token.IsValid) { RaiseErrorOccurred(HtmlParseError.DoctypeInvalid, ref token); } IConstructableNode node = _elementFactory.CreateDocumentType(_document, token.Name, token.PublicIdentifier, token.SystemIdentifier); _document.AddNode(node); _document.QuirksMode = token.GetQuirksMode(); _currentMode = HtmlTreeMode.BeforeHtml; return; } case HtmlTokenType.Character: token.CleanStart(); if (token.IsEmpty) { return; } break; case HtmlTokenType.Comment: _document.AddComment(ref token); return; } if (!_options.IsEmbedded) { RaiseErrorOccurred(HtmlParseError.DoctypeMissing, ref token); _document.QuirksMode = QuirksMode.On; } _currentMode = HtmlTreeMode.BeforeHtml; BeforeHtml(ref token); } private void BeforeHtml(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: token.CleanStart(); if (token.IsEmpty) { return; } break; case HtmlTokenType.Comment: _document.AddComment(ref token); return; case HtmlTokenType.StartTag: if (token.Name.Is(TagNames.Html)) { AddRoot(ref token); _currentMode = HtmlTreeMode.BeforeHead; return; } break; case HtmlTokenType.EndTag: if (!TagNames.AllBeforeHead.Contains(token.Name)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); return; } break; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; } StructHtmlToken token2 = StructHtmlToken.Open(TagNames.Html); BeforeHtml(ref token2); BeforeHead(ref token); } private void BeforeHead(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: token.CleanStart(); if (token.IsEmpty) { return; } break; case HtmlTokenType.StartTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Html)) { InBody(ref token); return; } if (name.Is(TagNames.Head)) { TElement element = _elementFactory.Create(_document, TagNames.Head); AddElement(element, ref token); _currentMode = HtmlTreeMode.InHead; return; } break; } case HtmlTokenType.EndTag: if (!TagNames.AllBeforeHead.Contains(token.Name)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); return; } break; case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); return; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; } StructHtmlToken token2 = StructHtmlToken.Open(TagNames.Head); BeforeHead(ref token2); InHead(ref token); } private void InHead(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: { StringOrMemory text = token.TrimStart(); AddCharacters(text); if (token.IsEmpty) { return; } break; } case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); return; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; case HtmlTokenType.StartTag: { StringOrMemory name2 = token.Name; if (name2.Is(TagNames.Html)) { InBody(ref token); return; } if (name2.Is(TagNames.Meta)) { IConstructableMetaElement constructableMetaElement = _elementFactory.CreateMeta(_document); AddElement(constructableMetaElement, ref token, acknowledgeSelfClosing: true); CloseCurrentNode(); try { constructableMetaElement.Handle(); return; } catch (NotSupportedException exception) { _document.TrackError(exception); Restart(); return; } } if (TagNames.AllHeadBase.Contains(name2)) { AddElement(ref token, acknowledgeSelfClosing: true); CloseCurrentNode(); return; } if (name2.Is(TagNames.Title)) { RCDataAlgorithm(ref token); return; } if (name2.Is(TagNames.Style)) { RawtextAlgorithm(ref token); return; } if (name2.Is(TagNames.NoScript)) { bool isScripting = _options.IsScripting; TElement element = _elementFactory.CreateNoScript(_document, isScripting); AddElement(element, ref token); if (isScripting) { SwitchToRawtext(); } else { _currentMode = HtmlTreeMode.InHeadNoScript; } return; } if (name2.Is(TagNames.NoFrames)) { if (_options.IsNotSupportingFrames) { AddElement(ref token); _currentMode = HtmlTreeMode.InBody; } else { RawtextAlgorithm(ref token); } return; } if (name2.Is(TagNames.Script)) { IConstructableScriptElement element2 = _elementFactory.CreateScript(_document, parserInserted: true, IsFragmentCase); AddElement(element2, ref token); _tokenizer.State = HtmlParseMode.Script; _previousMode = _currentMode; _currentMode = HtmlTreeMode.Text; return; } if (name2.Is(TagNames.Head)) { RaiseErrorOccurred(HtmlParseError.HeadTagMisplaced, ref token); return; } if (name2.Is(TagNames.Template)) { AddTemplateElement(ref token); return; } if (IsCustomElementEverywhere(name2)) { AddElement(ref token); return; } break; } case HtmlTokenType.EndTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Head)) { CloseCurrentNode(); _currentMode = HtmlTreeMode.AfterHead; _waiting = _document.WaitForReadyAsync(CancellationToken.None); return; } if (name.Is(TagNames.Template)) { if (TagCurrentlyOpen(TagNames.Template)) { GenerateImpliedEndTags(); if (!CurrentNode.LocalName.Is(TagNames.Template)) { RaiseErrorOccurred(HtmlParseError.TagClosingMismatch, ref token); } CloseTemplate(); } else { RaiseErrorOccurred(HtmlParseError.TagInappropriate, ref token); } return; } if (IsCustomElementEverywhere(name)) { GenerateImpliedEndTags(); CloseCurrentNode(); return; } if (!name.IsOneOf(TagNames.Html, TagNames.Body, TagNames.Br)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); return; } break; } } CloseCurrentNode(); _currentMode = HtmlTreeMode.AfterHead; AfterHead(ref token); } private void InHeadNoScript(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: { StringOrMemory text = token.TrimStart(); AddCharacters(text); if (token.IsEmpty) { return; } break; } case HtmlTokenType.Comment: InHead(ref token); return; case HtmlTokenType.StartTag: { StringOrMemory name2 = token.Name; if (TagNames.AllNoScript.Contains(name2)) { InHead(ref token); return; } if (name2.Is(TagNames.Html)) { InBody(ref token); return; } if (name2.IsOneOf(TagNames.Head, TagNames.NoScript)) { RaiseErrorOccurred(HtmlParseError.TagInappropriate, ref token); return; } break; } case HtmlTokenType.EndTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.NoScript)) { CloseCurrentNode(); _currentMode = HtmlTreeMode.InHead; return; } if (!name.Is(TagNames.Br)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); return; } break; } case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; } RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); CloseCurrentNode(); _currentMode = HtmlTreeMode.InHead; InHead(ref token); } private void AfterHead(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: { StringOrMemory text = token.TrimStart(); AddCharacters(text); if (token.IsEmpty) { return; } break; } case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); return; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; case HtmlTokenType.StartTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Html)) { InBody(ref token); return; } if (name.Is(TagNames.Body)) { AfterHeadStartTagBody(ref token); return; } if (name.Is(TagNames.Frameset)) { TElement element = _elementFactory.Create(_document, TagNames.Frameset); AddElement(element, ref token); _currentMode = HtmlTreeMode.InFrameset; return; } if (TagNames.AllHeadNoTemplate.Contains(name)) { RaiseErrorOccurred(HtmlParseError.TagMustBeInHead, ref token); IConstructableElement head = _document.Head; _openElements.Add(head); InHead(ref token); CloseNode(head); return; } if (name.Is(TagNames.Head)) { RaiseErrorOccurred(HtmlParseError.HeadTagMisplaced, ref token); return; } break; } case HtmlTokenType.EndTag: if (!token.Name.IsOneOf(TagNames.Html, TagNames.Body, TagNames.Br)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); return; } break; } StructHtmlToken token2 = StructHtmlToken.Open(TagNames.Body); AfterHeadStartTagBody(ref token2); _frameset = true; Home(ref token); } private void InBodyStartTag(ref StructHtmlToken tag) { StringOrMemory name = tag.Name; if (name.Is(TagNames.Div)) { if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } AddElement(ref tag); } else if (name.Is(TagNames.A)) { int num = _formattingElements.Count - 1; while (num >= 0 && _formattingElements[num] != null) { if (_formattingElements[num].LocalName.Is(TagNames.A)) { IConstructableElement constructableElement = _formattingElements[num]; RaiseErrorOccurred(HtmlParseError.AnchorNested, ref tag); StructHtmlToken tag2 = StructHtmlToken.Close(TagNames.A); HeisenbergAlgorithm(ref tag2); CloseNode(constructableElement); _formattingElements.Remove(constructableElement); break; } num--; } ReconstructFormatting(); TElement element = _elementFactory.Create(_document, TagNames.A); AddElement(element, ref tag); _formattingElements.AddFormatting(element); } else if (name.Is(TagNames.Span)) { ReconstructFormatting(); AddElement(ref tag); } else if (name.Is(TagNames.Li)) { InBodyStartTagListItem(ref tag); } else if (name.Is(TagNames.Img)) { InBodyStartTagBreakrow(ref tag); } else if (name.IsOneOf(TagNames.Ul, TagNames.P)) { if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } AddElement(ref tag); } else if (TagNames.AllSemanticFormatting.Contains(name)) { ReconstructFormatting(); _formattingElements.AddFormatting(AddElement(ref tag)); } else if (name.Is(TagNames.Script)) { InHead(ref tag); } else if (TagNames.AllHeadings.Contains(name)) { if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } if (TagNames.AllHeadings.Contains(CurrentNode.LocalName)) { RaiseErrorOccurred(HtmlParseError.HeadingNested, ref tag); CloseCurrentNode(); } TElement element2 = _elementFactory.Create(_document, name); AddElement(element2, ref tag); } else if (name.Is(TagNames.Input)) { ReconstructFormatting(); TElement element3 = _elementFactory.Create(_document, TagNames.Input); AddElement(element3, ref tag, acknowledgeSelfClosing: true); CloseCurrentNode(); if (!tag.GetAttribute(AttributeNames.Type).Isi(AttributeNames.Hidden)) { _frameset = false; } } else if (name.Is(TagNames.Form)) { if (_currentFormElement == null) { if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } _currentFormElement = _elementFactory.CreateForm(_document); AddElement(_currentFormElement, ref tag); } else { RaiseErrorOccurred(HtmlParseError.FormAlreadyOpen, ref tag); } } else if (TagNames.AllBody.Contains(name)) { if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } AddElement(ref tag); } else if (TagNames.AllClassicFormatting.Contains(name)) { ReconstructFormatting(); _formattingElements.AddFormatting(AddElement(ref tag)); } else if (TagNames.AllHead.Contains(name)) { InHead(ref tag); } else if (name.IsOneOf(TagNames.Pre, TagNames.Listing)) { if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } AddElement(ref tag); _frameset = false; PreventNewLine(); } else if (name.Is(TagNames.Button)) { if (IsInScope(TagNames.Button)) { RaiseErrorOccurred(HtmlParseError.ButtonInScope, ref tag); InBodyEndTagBlock(ref tag); InBody(ref tag); } else { ReconstructFormatting(); TElement element4 = _elementFactory.Create(_document, TagNames.Button); AddElement(element4, ref tag); _frameset = false; } } else if (name.Is(TagNames.Table)) { if (_document.QuirksMode != QuirksMode.On && IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } TElement element5 = _elementFactory.Create(_document, TagNames.Table); AddElement(element5, ref tag); _frameset = false; _currentMode = HtmlTreeMode.InTable; } else if (TagNames.AllBodyBreakrow.Contains(name)) { InBodyStartTagBreakrow(ref tag); } else if (TagNames.AllBodyClosed.Contains(name)) { AddElement(ref tag, acknowledgeSelfClosing: true); CloseCurrentNode(); } else if (name.Is(TagNames.Hr)) { if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } TElement element6 = _elementFactory.Create(_document, TagNames.Hr); AddElement(element6, ref tag, acknowledgeSelfClosing: true); CloseCurrentNode(); _frameset = false; } else if (name.Is(TagNames.Textarea)) { TElement element7 = _elementFactory.Create(_document, TagNames.Textarea); AddElement(element7, ref tag); _tokenizer.State = HtmlParseMode.RCData; _previousMode = _currentMode; _frameset = false; _currentMode = HtmlTreeMode.Text; PreventNewLine(); } else if (name.Is(TagNames.Select)) { ReconstructFormatting(); TElement element8 = _elementFactory.Create(_document, TagNames.Select); AddElement(element8, ref tag); _frameset = false; HtmlTreeMode currentMode = _currentMode; HtmlTreeMode currentMode2 = ((currentMode - 8 > HtmlTreeMode.BeforeHtml && currentMode - 11 > HtmlTreeMode.BeforeHead) ? HtmlTreeMode.InSelect : HtmlTreeMode.InSelectInTable); _currentMode = currentMode2; } else if (name.IsOneOf(TagNames.Optgroup, TagNames.Option)) { if (CurrentNode.LocalName.Is(TagNames.Option)) { StructHtmlToken tag3 = StructHtmlToken.Close(TagNames.Option); InBodyEndTagAnythingElse(ref tag3); } ReconstructFormatting(); AddElement(ref tag); } else if (name.IsOneOf(TagNames.Dd, TagNames.Dt)) { InBodyStartTagDefinitionItem(ref tag); } else if (name.Is(TagNames.Iframe)) { _frameset = false; RawtextAlgorithm(ref tag); } else if (TagNames.AllBodyObsolete.Contains(name)) { ReconstructFormatting(); AddElement(ref tag); _formattingElements.AddScopeMarker(); _frameset = false; } else if (name.Is(TagNames.Image)) { RaiseErrorOccurred(HtmlParseError.ImageTagNamedWrong, ref tag); tag.Name = TagNames.Img; InBodyStartTagBreakrow(ref tag); } else if (name.Is(TagNames.NoBr)) { ReconstructFormatting(); if (IsInScope(TagNames.NoBr)) { RaiseErrorOccurred(HtmlParseError.NobrInScope, ref tag); HeisenbergAlgorithm(ref tag); ReconstructFormatting(); } _formattingElements.AddFormatting(AddElement(ref tag)); } else if (name.Is(TagNames.Xmp)) { if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } ReconstructFormatting(); _frameset = false; RawtextAlgorithm(ref tag); } else if (name.IsOneOf(TagNames.Rb, TagNames.Rtc)) { if (IsInScope(TagNames.Ruby)) { GenerateImpliedEndTags(); if (!CurrentNode.LocalName.Is(TagNames.Ruby)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref tag); } } AddElement(ref tag); } else if (name.IsOneOf(TagNames.Rp, TagNames.Rt)) { if (IsInScope(TagNames.Ruby)) { GenerateImpliedEndTagsExceptFor(TagNames.Rtc); if (!CurrentNode.LocalName.IsOneOf(TagNames.Ruby, TagNames.Rtc)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref tag); } } AddElement(ref tag); } else if (name.Is(TagNames.NoEmbed)) { RawtextAlgorithm(ref tag); } else if (name.Is(TagNames.NoScript)) { bool isScripting = _options.IsScripting; TElement element9 = _elementFactory.CreateNoScript(_document, isScripting); if (isScripting) { AddElement(element9, ref tag); SwitchToRawtext(); } else { ReconstructFormatting(); AddElement(element9, ref tag); } } else if (name.Is(TagNames.Math)) { IConstructableMathElement element10 = _elementFactory.CreateMath(_document, name); ReconstructFormatting(); AddElement(element10.Setup(ref tag)); if (tag.IsSelfClosing) { CloseNode(element10); } } else if (name.Is(TagNames.Svg)) { IConstructableSvgElement element11 = _elementFactory.CreateSvg(_document, name); ReconstructFormatting(); AddElement(element11.Setup(ref tag)); if (tag.IsSelfClosing) { CloseNode(element11); } } else if (name.Is(TagNames.Plaintext)) { if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } AddElement(ref tag); _tokenizer.State = HtmlParseMode.Plaintext; } else if (name.Is(TagNames.Frameset)) { RaiseErrorOccurred(HtmlParseError.FramesetMisplaced, ref tag); if (_openElements.Count != 1 && _openElements[1].LocalName.Is(TagNames.Body) && _frameset) { _openElements[1].RemoveFromParent(); while (_openElements.Count > 1) { CloseCurrentNode(); } TElement element12 = _elementFactory.Create(_document, TagNames.Frameset); AddElement(element12, ref tag); _currentMode = HtmlTreeMode.InFrameset; } } else if (name.Is(TagNames.Html)) { RaiseErrorOccurred(HtmlParseError.HtmlTagMisplaced, ref tag); if (_templateModes.Count == 0) { _openElements[0].SetUniqueAttributes(ref tag); } } else if (name.Is(TagNames.Body)) { RaiseErrorOccurred(HtmlParseError.BodyTagMisplaced, ref tag); if (_templateModes.Count == 0 && _openElements.Count > 1 && _openElements[1].LocalName.Is(TagNames.Body)) { _frameset = false; _openElements[1].SetUniqueAttributes(ref tag); } } else if (name.Is(TagNames.IsIndex)) { RaiseErrorOccurred(HtmlParseError.TagInappropriate, ref tag); if (_currentFormElement != null) { return; } StructHtmlToken token = StructHtmlToken.Open(TagNames.Form); InBody(ref token); if (tag.GetAttribute(AttributeNames.Action).Length > 0) { _currentFormElement.SetAttribute(null, AttributeNames.Action, tag.GetAttribute(AttributeNames.Action)); } token = StructHtmlToken.Open(TagNames.Hr); InBody(ref token); token = StructHtmlToken.Open(TagNames.Label); InBody(ref token); if (tag.GetAttribute(AttributeNames.Prompt).Length > 0) { AddCharacters(tag.GetAttribute(AttributeNames.Prompt)); } else { AddCharacters("This is a searchable index. Enter search keywords: "); } StructHtmlToken token2 = StructHtmlToken.Open(TagNames.Input); token2.AddAttribute(AttributeNames.Name, TagNames.IsIndex); for (int i = 0; i < tag.Attributes.Count; i++) { MemoryHtmlAttributeToken memoryHtmlAttributeToken = tag.Attributes[i]; if (!memoryHtmlAttributeToken.Name.IsOneOf(AttributeNames.Name, AttributeNames.Action, AttributeNames.Prompt)) { token2.AddAttribute(memoryHtmlAttributeToken.Name, memoryHtmlAttributeToken.Value); } } InBody(ref token2); token = StructHtmlToken.Close(TagNames.Label); InBody(ref token); token = StructHtmlToken.Open(TagNames.Hr); InBody(ref token); token = StructHtmlToken.Close(TagNames.Form); InBody(ref token); } else if (TagNames.AllNested.Contains(name)) { RaiseErrorOccurred(HtmlParseError.TagCannotStartHere, ref tag); } else { ReconstructFormatting(); AddElement(ref tag); } } private void InBodyEndTag(ref StructHtmlToken tag) { StringOrMemory name = tag.Name; if (name.Is(TagNames.Div)) { InBodyEndTagBlock(ref tag); } else if (name.Is(TagNames.A)) { HeisenbergAlgorithm(ref tag); } else if (name.Is(TagNames.Li)) { if (IsInListItemScope()) { GenerateImpliedEndTagsExceptFor(name); if (!CurrentNode.LocalName.Is(TagNames.Li)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref tag); } ClearStackBackTo(TagNames.Li); CloseCurrentNode(); } else { RaiseErrorOccurred(HtmlParseError.ListItemNotInScope, ref tag); } } else if (name.Is(TagNames.P)) { InBodyEndTagParagraph(ref tag); } else if (TagNames.AllBlocks.Contains(name)) { InBodyEndTagBlock(ref tag); } else if (TagNames.AllFormatting.Contains(name)) { HeisenbergAlgorithm(ref tag); } else if (name.Is(TagNames.Form)) { IConstructableElement currentFormElement = _currentFormElement; _currentFormElement = null; if (currentFormElement != null && IsInScope(currentFormElement.LocalName)) { GenerateImpliedEndTags(); if (CurrentNode != currentFormElement) { RaiseErrorOccurred(HtmlParseError.FormClosedWrong, ref tag); } CloseNode(currentFormElement); } else { RaiseErrorOccurred(HtmlParseError.FormNotInScope, ref tag); } } else if (name.Is(TagNames.Br)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref tag); StructHtmlToken token = StructHtmlToken.Open(TagNames.Br); Consume(ref token); } else if (TagNames.AllHeadings.Contains(name)) { if (IsInScope(TagNames.AllHeadings)) { GenerateImpliedEndTags(); if (!CurrentNode.LocalName.Is(name)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref tag); } ClearStackBackTo(TagNames.AllHeadings); CloseCurrentNode(); } else { RaiseErrorOccurred(HtmlParseError.HeadingNotInScope, ref tag); } } else if (name.IsOneOf(TagNames.Dd, TagNames.Dt)) { if (IsInScope(name)) { GenerateImpliedEndTagsExceptFor(name); if (!CurrentNode.LocalName.Is(name)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref tag); } ClearStackBackTo(name); CloseCurrentNode(); } else { RaiseErrorOccurred(HtmlParseError.ListItemNotInScope, ref tag); } } else if (name.IsOneOf(TagNames.Applet, TagNames.Marquee, TagNames.Object)) { if (IsInScope(name)) { GenerateImpliedEndTags(); if (!CurrentNode.LocalName.Is(name)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref tag); } ClearStackBackTo(name); CloseCurrentNode(); _formattingElements.ClearFormatting(); } else { RaiseErrorOccurred(HtmlParseError.ObjectNotInScope, ref tag); } } else if (name.Is(TagNames.Body)) { InBodyEndTagBody(ref tag); } else if (name.Is(TagNames.Html)) { if (InBodyEndTagBody(ref tag)) { AfterBody(ref tag); } } else if (name.Is(TagNames.Template)) { InHead(ref tag); } else { InBodyEndTagAnythingElse(ref tag); } } private void InBody(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: ReconstructFormatting(); AddCharacters(token.Data); _frameset = !token.HasContent && _frameset; break; case HtmlTokenType.StartTag: InBodyStartTag(ref token); break; case HtmlTokenType.EndTag: InBodyEndTag(ref token); break; case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); break; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); break; case HtmlTokenType.EndOfFile: CheckBodyOnClosing(ref token); if (_templateModes.Count != 0) { InTemplate(ref token); } else { End(); } break; } } private void Text(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: AddCharacters(token.Data); break; case HtmlTokenType.EndTag: if (!token.Name.Is(TagNames.Script)) { CloseCurrentNode(); _currentMode = _previousMode; } else { HandleScript((IConstructableScriptElement)CurrentNode); } break; case HtmlTokenType.EndOfFile: RaiseErrorOccurred(HtmlParseError.EOF, ref token); CloseCurrentNode(); _currentMode = _previousMode; Consume(ref token); break; case HtmlTokenType.Comment: break; } } private void InTable(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); return; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; case HtmlTokenType.StartTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Caption)) { ClearStackBackTo(TagNames.Table); _formattingElements.AddScopeMarker(); TElement element = _elementFactory.Create(_document, TagNames.Caption); AddElement(element, ref token); _currentMode = HtmlTreeMode.InCaption; } else if (name.Is(TagNames.Colgroup)) { ClearStackBackTo(TagNames.Table); TElement element2 = _elementFactory.Create(_document, TagNames.Colgroup); AddElement(element2, ref token); _currentMode = HtmlTreeMode.InColumnGroup; } else if (name.Is(TagNames.Col)) { StructHtmlToken token2 = StructHtmlToken.Open(TagNames.Colgroup); InTable(ref token2); InColumnGroup(ref token); } else if (TagNames.AllTableSections.Contains(name)) { ClearStackBackTo(TagNames.Table); TElement element3 = _elementFactory.Create(_document, name); AddElement(element3, ref token); _currentMode = HtmlTreeMode.InTableBody; } else if (TagNames.AllTableCellsRows.Contains(name)) { StructHtmlToken token3 = StructHtmlToken.Open(TagNames.Tbody); InTable(ref token3); InTableBody(ref token); } else if (name.Is(TagNames.Table)) { RaiseErrorOccurred(HtmlParseError.TableNesting, ref token); if (InTableEndTagTable(ref token)) { Home(ref token); } } else if (name.Is(TagNames.Input)) { StructHtmlToken tag = token; if (tag.GetAttribute(AttributeNames.Type).Isi(AttributeNames.Hidden)) { RaiseErrorOccurred(HtmlParseError.InputUnexpected, ref token); TElement element4 = _elementFactory.Create(_document, TagNames.Input); AddElement(element4, ref tag, acknowledgeSelfClosing: true); CloseCurrentNode(); } else { RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); InBodyWithFoster(ref token); } } else if (name.Is(TagNames.Form)) { RaiseErrorOccurred(HtmlParseError.FormInappropriate, ref token); if (_currentFormElement == null) { _currentFormElement = _elementFactory.CreateForm(_document); AddElement(_currentFormElement, ref token); CloseCurrentNode(); } } else if (TagNames.AllTableHead.Contains(name)) { InHead(ref token); } else if (IsCustomElementEverywhere(name)) { InHead(ref token); } else { RaiseErrorOccurred(HtmlParseError.IllegalElementInTableDetected, ref token); InBodyWithFoster(ref token); } return; } case HtmlTokenType.EndTag: { StringOrMemory name2 = token.Name; if (name2.Is(TagNames.Table)) { InTableEndTagTable(ref token); return; } if (name2.Is(TagNames.Template)) { InHead(ref token); return; } if (TagNames.AllTableSpecial.Contains(name2) || TagNames.AllTableInner.Contains(name2)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); return; } if (IsCustomElementEverywhere(name2)) { InHead(ref token); return; } RaiseErrorOccurred(HtmlParseError.IllegalElementInTableDetected, ref token); InBodyWithFoster(ref token); return; } case HtmlTokenType.EndOfFile: InBody(ref token); return; case HtmlTokenType.Character: if (TagNames.AllTableMajor.Contains(CurrentNode.LocalName)) { InTableText(ref token); return; } break; } RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); InBodyWithFoster(ref token); } private void InTableText(ref StructHtmlToken token) { if (token.HasContent) { RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); InBodyWithFoster(ref token); } else { AddCharacters(token.Data); } } private void InCaption(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.EndTag: { StringOrMemory name2 = token.Name; if (name2.Is(TagNames.Caption)) { InCaptionEndTagCaption(ref token); return; } if (TagNames.AllCaptionStart.Contains(name2)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); return; } if (name2.Is(TagNames.Table)) { RaiseErrorOccurred(HtmlParseError.TableNesting, ref token); if (InCaptionEndTagCaption(ref token)) { InTable(ref token); } return; } if (IsCustomElementEverywhere(name2)) { InHead(ref token); return; } break; } case HtmlTokenType.StartTag: { StringOrMemory name = token.Name; if (TagNames.AllCaptionEnd.Contains(name)) { RaiseErrorOccurred(HtmlParseError.TagCannotStartHere, ref token); if (InCaptionEndTagCaption(ref token)) { InTable(ref token); } return; } if (IsCustomElementEverywhere(name)) { InHead(ref token); return; } break; } } InBody(ref token); } private void InColumnGroup(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: { StringOrMemory text = token.TrimStart(); AddCharacters(text); if (token.IsEmpty) { return; } break; } case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); return; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; case HtmlTokenType.StartTag: { StringOrMemory name2 = token.Name; if (name2.Is(TagNames.Html)) { InBody(ref token); return; } if (name2.Is(TagNames.Col)) { TElement element = _elementFactory.Create(_document, TagNames.Col); AddElement(element, ref token, acknowledgeSelfClosing: true); CloseCurrentNode(); return; } if (name2.Is(TagNames.Template) || IsCustomElementEverywhere(name2)) { InHead(ref token); return; } break; } case HtmlTokenType.EndTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Colgroup)) { InColumnGroupEndTagColgroup(ref token); return; } if (name.Is(TagNames.Col)) { RaiseErrorOccurred(HtmlParseError.TagClosedWrong, ref token); return; } if (name.Is(TagNames.Template) || IsCustomElementEverywhere(name)) { InHead(ref token); return; } break; } case HtmlTokenType.EndOfFile: InBody(ref token); return; } if (InColumnGroupEndTagColgroup(ref token)) { InTable(ref token); } } private void InTableBody(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.StartTag: { StringOrMemory name2 = token.Name; if (name2.Is(TagNames.Tr)) { ClearStackBackTo(TagNames.AllTableSections); TElement element = _elementFactory.Create(_document, TagNames.Tr); AddElement(element, ref token); _currentMode = HtmlTreeMode.InRow; return; } if (TagNames.AllTableCells.Contains(name2)) { StructHtmlToken token2 = StructHtmlToken.Open(TagNames.Tr); InTableBody(ref token2); InRow(ref token); return; } if (TagNames.AllTableGeneral.Contains(name2)) { InTableBodyCloseTable(ref token); return; } break; } case HtmlTokenType.EndTag: { StringOrMemory name = token.Name; if (TagNames.AllTableSections.Contains(name)) { if (IsInTableScope(name)) { ClearStackBackTo(TagNames.AllTableSections); CloseCurrentNode(); _currentMode = HtmlTreeMode.InTable; } else { RaiseErrorOccurred(HtmlParseError.TableSectionNotInScope, ref token); } return; } if (name.Is(TagNames.Tr) || TagNames.AllTableSpecial.Contains(name)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); return; } if (name.Is(TagNames.Table)) { InTableBodyCloseTable(ref token); return; } break; } } InTable(ref token); } private void InRow(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.StartTag: { StringOrMemory name2 = token.Name; if (TagNames.AllTableCells.Contains(name2)) { ClearStackBackTo(TagNames.Tr); AddElement(ref token); _currentMode = HtmlTreeMode.InCell; _formattingElements.AddScopeMarker(); return; } if (name2.Is(TagNames.Tr) || TagNames.AllTableGeneral.Contains(name2)) { if (InRowEndTagTablerow(ref token)) { InTableBody(ref token); } return; } break; } case HtmlTokenType.EndTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Tr)) { InRowEndTagTablerow(ref token); return; } if (name.Is(TagNames.Table)) { if (InRowEndTagTablerow(ref token)) { InTableBody(ref token); } return; } if (TagNames.AllTableSections.Contains(name)) { if (IsInTableScope(name)) { InRowEndTagTablerow(ref token); InTableBody(ref token); } else { RaiseErrorOccurred(HtmlParseError.TableSectionNotInScope, ref token); } return; } if (TagNames.AllTableSpecial.Contains(name)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); return; } break; } } InTable(ref token); } private void InCell(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.StartTag: { StringOrMemory name2 = token.Name; if (TagNames.AllTableCellsRows.Contains(name2) || TagNames.AllTableGeneral.Contains(name2)) { if (IsInTableScope(TagNames.AllTableCells)) { InCellEndTagCell(ref token); Home(ref token); } else { RaiseErrorOccurred(HtmlParseError.TableCellNotInScope, ref token); } return; } break; } case HtmlTokenType.EndTag: { StringOrMemory name = token.Name; if (TagNames.AllTableCells.Contains(name)) { InCellEndTagCell(ref token); } else if (TagNames.AllTableCore.Contains(name)) { if (IsInTableScope(name)) { InCellEndTagCell(ref token); Home(ref token); } else { RaiseErrorOccurred(HtmlParseError.TableNotInScope, ref token); } } else if (!TagNames.AllTableSpecial.Contains(name)) { InBody(ref token); } else { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); } return; } } InBody(ref token); } private void InSelect(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: AddCharacters(token.Data); break; case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); break; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); break; case HtmlTokenType.StartTag: { StringOrMemory name2 = token.Name; if (name2.Is(TagNames.Html)) { InBody(ref token); } else if (name2.Is(TagNames.Option)) { if (CurrentNode.LocalName.Is(TagNames.Option)) { InSelectEndTagOption(ref token); } TElement element = _elementFactory.Create(_document, TagNames.Option); AddElement(element, ref token); } else if (name2.Is(TagNames.Optgroup)) { if (CurrentNode.LocalName.Is(TagNames.Option)) { InSelectEndTagOption(ref token); } if (CurrentNode.LocalName.Is(TagNames.Optgroup)) { InSelectEndTagOptgroup(ref token); } TElement element2 = _elementFactory.Create(_document, TagNames.Optgroup); AddElement(element2, ref token); } else if (name2.Is(TagNames.Select)) { RaiseErrorOccurred(HtmlParseError.SelectNesting, ref token); InSelectEndTagSelect(); } else if (TagNames.AllInput.Contains(name2)) { RaiseErrorOccurred(HtmlParseError.IllegalElementInSelectDetected, ref token); if (IsInSelectScope(TagNames.Select)) { InSelectEndTagSelect(); Home(ref token); } } else if (name2.IsOneOf(TagNames.Template, TagNames.Script) || IsCustomElementEverywhere(name2)) { InHead(ref token); } else { RaiseErrorOccurred(HtmlParseError.IllegalElementInSelectDetected, ref token); } break; } case HtmlTokenType.EndTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Template) || IsCustomElementEverywhere(name)) { InHead(ref token); } else if (name.Is(TagNames.Optgroup)) { InSelectEndTagOptgroup(ref token); } else if (name.Is(TagNames.Option)) { InSelectEndTagOption(ref token); } else if (name.Is(TagNames.Select) && IsInSelectScope(TagNames.Select)) { InSelectEndTagSelect(); } else if (name.Is(TagNames.Select)) { RaiseErrorOccurred(HtmlParseError.SelectNotInScope, ref token); } else { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); } break; } case HtmlTokenType.EndOfFile: InBody(ref token); break; default: RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); break; } } private void InSelectInTable(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.StartTag: { StringOrMemory name2 = token.Name; if (TagNames.AllTableSelects.Contains(name2)) { RaiseErrorOccurred(HtmlParseError.IllegalElementInSelectDetected, ref token); InSelectEndTagSelect(); Home(ref token); return; } break; } case HtmlTokenType.EndTag: { StringOrMemory name = token.Name; if (TagNames.AllTableSelects.Contains(name)) { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); if (IsInTableScope(name)) { InSelectEndTagSelect(); Home(ref token); } return; } break; } } InSelect(ref token); } private void InTemplate(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.StartTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Script) || TagNames.AllHead.Contains(name)) { InHead(ref token); } else if (TagNames.AllTableRoot.Contains(name)) { TemplateStep(ref token, HtmlTreeMode.InTable); } else if (name.Is(TagNames.Col)) { TemplateStep(ref token, HtmlTreeMode.InColumnGroup); } else if (name.Is(TagNames.Tr)) { TemplateStep(ref token, HtmlTreeMode.InTableBody); } else if (TagNames.AllTableCells.Contains(name)) { TemplateStep(ref token, HtmlTreeMode.InRow); } else { TemplateStep(ref token, HtmlTreeMode.InBody); } break; } case HtmlTokenType.EndTag: if (token.Name.Is(TagNames.Template)) { InHead(ref token); } else { RaiseErrorOccurred(HtmlParseError.TagCannotEndHere, ref token); } break; case HtmlTokenType.EndOfFile: if (TagCurrentlyOpen(TagNames.Template)) { RaiseErrorOccurred(HtmlParseError.EOF, ref token); CloseTemplate(); Home(ref token); } else { End(); } break; default: InBody(ref token); break; } } private void AfterBody(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: { StringOrMemory text = token.TrimStart(); ReconstructFormatting(); AddCharacters(text); if (token.IsEmpty) { return; } break; } case HtmlTokenType.Comment: _openElements[0].AddComment(ref token); return; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; case HtmlTokenType.StartTag: if (token.Name.Is(TagNames.Html)) { InBody(ref token); return; } break; case HtmlTokenType.EndTag: if (token.Name.Is(TagNames.Html)) { if (IsFragmentCase) { RaiseErrorOccurred(HtmlParseError.TagInvalidInFragmentMode, ref token); } else { _currentMode = HtmlTreeMode.AfterAfterBody; } return; } break; case HtmlTokenType.EndOfFile: End(); return; } RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); _currentMode = HtmlTreeMode.InBody; InBody(ref token); } private void InFrameset(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: { StringOrMemory text = token.TrimStart(); AddCharacters(text); if (token.IsEmpty) { return; } break; } case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); return; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; case HtmlTokenType.StartTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Html)) { InBody(ref token); return; } if (name.Is(TagNames.Frameset)) { TElement element = _elementFactory.Create(_document, TagNames.Frameset); AddElement(element, ref token); return; } if (name.Is(TagNames.Frame)) { if (_options.IsNotSupportingFrames) { TElement element2 = _elementFactory.CreateUnknown(_document, name); AddElement(element2, ref token); } else { IConstructableFrameElement element3 = _elementFactory.CreateFrame(_document); AddElement(element3, ref token, acknowledgeSelfClosing: true); } CloseCurrentNode(); return; } if (name.Is(TagNames.NoFrames)) { InHead(ref token); return; } break; } case HtmlTokenType.EndTag: if (!token.Name.Is(TagNames.Frameset)) { break; } if (CurrentNode != _openElements[0]) { CloseCurrentNode(); if (!IsFragmentCase && !CurrentNode.LocalName.Is(TagNames.Frameset)) { _currentMode = HtmlTreeMode.AfterFrameset; } } else { RaiseErrorOccurred(HtmlParseError.CurrentNodeIsRoot, ref token); } return; case HtmlTokenType.EndOfFile: if (CurrentNode != _document.DocumentElement) { RaiseErrorOccurred(HtmlParseError.CurrentNodeIsNotRoot, ref token); } End(); return; } RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); } private void AfterFrameset(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: { StringOrMemory text = token.TrimStart(); AddCharacters(text); if (token.IsEmpty) { return; } break; } case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); return; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); return; case HtmlTokenType.StartTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Html)) { InBody(ref token); return; } if (name.Is(TagNames.NoFrames)) { InHead(ref token); return; } break; } case HtmlTokenType.EndTag: if (token.Name.Is(TagNames.Html)) { _currentMode = HtmlTreeMode.AfterAfterFrameset; return; } break; case HtmlTokenType.EndOfFile: End(); return; } RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); } private void AfterAfterBody(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: { StringOrMemory text = token.TrimStart(); ReconstructFormatting(); AddCharacters(text); if (token.IsEmpty) { return; } break; } case HtmlTokenType.EndOfFile: End(); return; case HtmlTokenType.Comment: _document.AddComment(ref token); return; case HtmlTokenType.Doctype: InBody(ref token); return; case HtmlTokenType.StartTag: if (token.Name.Is(TagNames.Html)) { InBody(ref token); return; } break; } RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); _currentMode = HtmlTreeMode.InBody; InBody(ref token); } private void AfterAfterFrameset(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Comment: _document.AddComment(ref token); return; case HtmlTokenType.Character: { StringOrMemory text = token.TrimStart(); ReconstructFormatting(); AddCharacters(text); if (token.IsEmpty) { return; } break; } case HtmlTokenType.Doctype: InBody(ref token); return; case HtmlTokenType.StartTag: { StringOrMemory name = token.Name; if (name.Is(TagNames.Html)) { InBody(ref token); return; } if (name.Is(TagNames.NoFrames)) { InHead(ref token); return; } break; } case HtmlTokenType.EndOfFile: End(); return; } RaiseErrorOccurred(HtmlParseError.TokenNotPossible, ref token); } private void TemplateStep(ref StructHtmlToken token, HtmlTreeMode mode) { _templateModes.Pop(); _templateModes.Push(mode); _currentMode = mode; Home(ref token); } private void CloseTemplate() { if (_templateModes.Count == 0) { return; } while (_openElements.Count > 0) { IConstructableElement currentNode = CurrentNode; CloseCurrentNode(); if (currentNode is IConstructableTemplateElement constructableTemplateElement) { constructableTemplateElement.PopulateFragment(); break; } } CloseTemplateMode(); } private void CloseTemplateMode() { _formattingElements.ClearFormatting(); _templateModes.Pop(); Reset(); } private void InTableBodyCloseTable(ref StructHtmlToken tag) { if (IsInTableScope(TagNames.AllTableSections)) { ClearStackBackTo(TagNames.AllTableSections); CloseCurrentNode(); _currentMode = HtmlTreeMode.InTable; InTable(ref tag); } else { RaiseErrorOccurred(HtmlParseError.TableSectionNotInScope, ref tag); } } private void InSelectEndTagOption(ref StructHtmlToken token) { if (CurrentNode.LocalName.Is(TagNames.Option)) { CloseCurrentNode(); } else { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref token); } } private void InSelectEndTagOptgroup(ref StructHtmlToken token) { if (_openElements.Count > 1 && _openElements[_openElements.Count - 1].LocalName.Is(TagNames.Option) && _openElements[_openElements.Count - 2].LocalName.Is(TagNames.Optgroup)) { CloseCurrentNode(); } if (CurrentNode.LocalName.Is(TagNames.Optgroup)) { CloseCurrentNode(); } else { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref token); } } private bool InColumnGroupEndTagColgroup(ref StructHtmlToken token) { if (CurrentNode.LocalName.Is(TagNames.Colgroup)) { CloseCurrentNode(); _currentMode = HtmlTreeMode.InTable; return true; } RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref token); return false; } private void AfterHeadStartTagBody(ref StructHtmlToken token) { TElement element = _elementFactory.Create(_document, TagNames.Body); AddElement(element, ref token); _frameset = false; _currentMode = HtmlTreeMode.InBody; } private void RawtextAlgorithm(ref StructHtmlToken tag) { AddElement(ref tag); SwitchToRawtext(); } private void SwitchToRawtext() { _previousMode = _currentMode; _currentMode = HtmlTreeMode.Text; _tokenizer.State = HtmlParseMode.Rawtext; } private void RCDataAlgorithm(ref StructHtmlToken tag) { AddElement(ref tag); _previousMode = _currentMode; _currentMode = HtmlTreeMode.Text; _tokenizer.State = HtmlParseMode.RCData; } private void InBodyStartTagListItem(ref StructHtmlToken tag) { int num = _openElements.Count - 1; IConstructableElement constructableElement = _openElements[num]; _frameset = false; while (true) { if (constructableElement.LocalName.Is(TagNames.Li)) { StructHtmlToken token = StructHtmlToken.Close(constructableElement.LocalName); InBody(ref token); break; } if (constructableElement.Flags.HasFlag(NodeFlags.Special) && !TagNames.AllBasicBlocks.Contains(constructableElement.LocalName)) { break; } constructableElement = _openElements[--num]; } if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } AddElement(ref tag); } private void InBodyStartTagDefinitionItem(ref StructHtmlToken tag) { _frameset = false; int num = _openElements.Count - 1; IConstructableElement constructableElement = _openElements[num]; while (true) { if (constructableElement.LocalName.IsOneOf(TagNames.Dd, TagNames.Dt)) { StructHtmlToken token = StructHtmlToken.Close(constructableElement.LocalName); InBody(ref token); break; } if (constructableElement.Flags.HasFlag(NodeFlags.Special) && !TagNames.AllBasicBlocks.Contains(constructableElement.LocalName)) { break; } constructableElement = _openElements[--num]; } if (IsInButtonScope()) { InBodyEndTagParagraph(ref tag); } AddElement(ref tag); } private bool InBodyEndTagBlock(ref StructHtmlToken tag) { if (IsInScope(tag.Name)) { GenerateImpliedEndTags(); if (!CurrentNode.LocalName.Is(tag.Name)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref tag); } ClearStackBackTo(tag.Name); CloseCurrentNode(); return true; } RaiseErrorOccurred(HtmlParseError.BlockNotInScope, ref tag); return false; } private void HeisenbergAlgorithm(ref StructHtmlToken tag) { IConstructableElement currentNode = CurrentNode; if (currentNode.NamespaceUri.Is(NamespaceNames.HtmlUri) && currentNode.LocalName.Is(tag.Name) && !_formattingElements.Contains(currentNode)) { CloseCurrentNode(); return; } for (int i = 0; i < 8; i++) { IConstructableElement constructableElement = null; IConstructableElement constructableElement2 = null; int num = 0; int num2 = 0; int num3 = _formattingElements.Count - 1; while (num3 >= 0 && _formattingElements[num3] != null) { if (_formattingElements[num3].LocalName.Is(tag.Name)) { num = num3; constructableElement = _formattingElements[num3]; break; } num3--; } if (constructableElement == null) { InBodyEndTagAnythingElse(ref tag); break; } int num4 = _openElements.IndexOf(constructableElement); if (num4 == -1) { RaiseErrorOccurred(HtmlParseError.FormattingElementNotFound, ref tag); _formattingElements.Remove(constructableElement); break; } if (!IsInScope(constructableElement.LocalName)) { RaiseErrorOccurred(HtmlParseError.ElementNotInScope, ref tag); break; } if (num4 != _openElements.Count - 1) { RaiseErrorOccurred(HtmlParseError.TagClosedWrong, ref tag); } int num5 = num; for (int j = num4 + 1; j < _openElements.Count; j++) { if (_openElements[j].Flags.HasFlag(NodeFlags.Special)) { num = j; constructableElement2 = _openElements[j]; break; } } if (constructableElement2 == null) { do { constructableElement2 = CurrentNode; CloseCurrentNode(); } while (constructableElement2 != constructableElement); _formattingElements.Remove(constructableElement); break; } IConstructableElement constructableElement3 = _openElements[num4 - 1]; IConstructableElement constructableElement4 = constructableElement2; while (true) { num2++; IConstructableElement constructableElement5 = _openElements[--num]; if (constructableElement5 == constructableElement) { break; } if (num2 > 3 && _formattingElements.Contains(constructableElement5)) { _formattingElements.Remove(constructableElement5); } if (!_formattingElements.Contains(constructableElement5)) { CloseNode(constructableElement5); continue; } IConstructableElement constructableElement6 = CopyElement(constructableElement5); constructableElement3.AddNode(constructableElement6); _openElements[num] = constructableElement6; for (int k = 0; k != _formattingElements.Count; k++) { if (_formattingElements[k] == constructableElement5) { _formattingElements[k] = constructableElement6; break; } } constructableElement5 = constructableElement6; if (constructableElement4 == constructableElement2) { num5++; } constructableElement4.Parent?.RemoveChild(constructableElement4); constructableElement5.AddNode(constructableElement4); constructableElement4 = constructableElement5; } constructableElement4.Parent?.RemoveChild(constructableElement4); if (!TagNames.AllTableMajor.Contains(constructableElement3.LocalName)) { constructableElement3.AddNode(constructableElement4); } else { AddElementWithFoster(constructableElement4); } IConstructableElement constructableElement7 = CopyElement(constructableElement); while (constructableElement2.ChildNodes.Length > 0) { IConstructableNode constructableNode = constructableElement2.ChildNodes[0]; constructableElement2.RemoveNode(0, constructableNode); constructableElement7.AddNode(constructableNode); } constructableElement2.AddNode(constructableElement7); _formattingElements.Remove(constructableElement); if (num5 > _formattingElements.Count) { num5 = _formattingElements.Count; } _formattingElements.Insert(num5, constructableElement7); CloseNode(constructableElement); _openElements.Insert(_openElements.IndexOf(constructableElement2) + 1, constructableElement7); } } private IConstructableElement CopyElement(IConstructableElement element) { return (IConstructableElement)element.ShallowCopy(); } private void InBodyWithFoster(ref StructHtmlToken token) { _foster = true; InBody(ref token); _foster = false; } private void InBodyEndTagAnythingElse(ref StructHtmlToken tag) { int num = _openElements.Count - 1; for (IConstructableElement constructableElement = CurrentNode; constructableElement != null; constructableElement = _openElements[--num]) { if (constructableElement.LocalName.Is(tag.Name)) { GenerateImpliedEndTagsExceptFor(tag.Name); if (!constructableElement.LocalName.Is(tag.Name)) { RaiseErrorOccurred(HtmlParseError.TagClosedWrong, ref tag); } CloseNodesFrom(num); break; } if (constructableElement.Flags.HasFlag(NodeFlags.Special)) { RaiseErrorOccurred(HtmlParseError.TagClosedWrong, ref tag); break; } } } private bool InBodyEndTagBody(ref StructHtmlToken token) { if (IsInScope(TagNames.Body)) { CheckBodyOnClosing(ref token); _currentMode = HtmlTreeMode.AfterBody; return true; } RaiseErrorOccurred(HtmlParseError.BodyNotInScope, ref token); return false; } private void InBodyStartTagBreakrow(ref StructHtmlToken tag) { ReconstructFormatting(); AddElement(ref tag, acknowledgeSelfClosing: true); CloseCurrentNode(); _frameset = false; } private bool InBodyEndTagParagraph(ref StructHtmlToken token) { if (IsInButtonScope()) { GenerateImpliedEndTagsExceptFor(TagNames.P); if (!CurrentNode.LocalName.Is(TagNames.P)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref token); } ClearStackBackTo(TagNames.P); CloseCurrentNode(); return true; } RaiseErrorOccurred(HtmlParseError.ParagraphNotInScope, ref token); StructHtmlToken token2 = StructHtmlToken.Open(TagNames.P); Consume(ref token2); InBodyEndTagParagraph(ref token); return false; } private bool InTableEndTagTable(ref StructHtmlToken token) { if (IsInTableScope(TagNames.Table)) { ClearStackBackTo(TagNames.Table); CloseCurrentNode(); Reset(); return true; } RaiseErrorOccurred(HtmlParseError.TableNotInScope, ref token); return false; } private bool InRowEndTagTablerow(ref StructHtmlToken token) { if (IsInTableScope(TagNames.Tr)) { ClearStackBackTo(TagNames.Tr); CloseCurrentNode(); _currentMode = HtmlTreeMode.InTableBody; return true; } RaiseErrorOccurred(HtmlParseError.TableRowNotInScope, ref token); return false; } private void InSelectEndTagSelect() { ClearStackBackTo(TagNames.Select); CloseCurrentNode(); Reset(); } private bool InCaptionEndTagCaption(ref StructHtmlToken token) { if (IsInTableScope(TagNames.Caption)) { GenerateImpliedEndTags(); if (!CurrentNode.LocalName.Is(TagNames.Caption)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref token); } ClearStackBackTo(TagNames.Caption); CloseCurrentNode(); _formattingElements.ClearFormatting(); _currentMode = HtmlTreeMode.InTable; return true; } RaiseErrorOccurred(HtmlParseError.CaptionNotInScope, ref token); return false; } private void InCellEndTagCell(ref StructHtmlToken token) { GenerateImpliedEndTags(); if (!TagNames.AllTableCells.Contains(CurrentNode.LocalName)) { RaiseErrorOccurred(HtmlParseError.TagDoesNotMatchCurrentNode, ref token); } ClearStackBackTo(TagNames.AllTableCells); CloseCurrentNode(); _formattingElements.ClearFormatting(); _currentMode = HtmlTreeMode.InRow; } private void Foreign(ref StructHtmlToken token) { switch (token.Type) { case HtmlTokenType.Character: AddCharacters(token.Data.Replace('\0', '\ufffd')); _frameset = !token.HasContent && _frameset; break; case HtmlTokenType.StartTag: { StringOrMemory name2 = token.Name; if (name2.Is(TagNames.Font)) { for (int i = 0; i != token.Attributes.Count; i++) { if (token.Attributes[i].Name.IsOneOf(AttributeNames.Color, AttributeNames.Face, AttributeNames.Size)) { ForeignNormalTag(ref token); return; } } ForeignSpecialTag(ref token); } else if (TagNames.AllForeignExceptions.Contains(name2)) { ForeignNormalTag(ref token); } else { ForeignSpecialTag(ref token); } break; } case HtmlTokenType.EndTag: { StringOrMemory name = token.Name; IConstructableElement constructableElement = CurrentNode; if (constructableElement is IConstructableScriptElement script) { HandleScript(script); break; } if (!constructableElement.LocalName.Is(name)) { RaiseErrorOccurred(HtmlParseError.TagClosingMismatch, ref token); } for (int num = _openElements.Count - 1; num > 0; num--) { if (constructableElement.LocalName.Isi(name)) { CloseNodesFrom(num); break; } constructableElement = _openElements[num - 1]; if (constructableElement.Flags.HasFlag(NodeFlags.HtmlMember)) { Home(ref token); break; } } break; } case HtmlTokenType.Comment: CurrentNode.AddComment(ref token); break; case HtmlTokenType.Doctype: RaiseErrorOccurred(HtmlParseError.DoctypeTagInappropriate, ref token); break; } } private void ForeignSpecialTag(ref StructHtmlToken tag) { IConstructableElement constructableElement = CreateForeignElementFrom(ref tag); if (constructableElement != null) { bool isSelfClosing = tag.IsSelfClosing; CurrentNode.AddNode(constructableElement); if (isSelfClosing) { constructableElement.SetupElement(); } if (!isSelfClosing) { _openElements.Add(constructableElement); _tokenizer.IsAcceptingCharacterData = true; } else if (tag.Name.Is(TagNames.Script)) { StructHtmlToken token = StructHtmlToken.Close(TagNames.Script); Foreign(ref token); } } } private IConstructableElement? CreateForeignElementFrom(ref StructHtmlToken tag) { if (AdjustedCurrentNode.Flags.HasFlag(NodeFlags.MathMember)) { StringOrMemory name = tag.Name; IConstructableMathElement element = _elementFactory.CreateMath(_document, name); AuxiliarySetupSteps(element, ref tag); return element.Setup(ref tag); } if (AdjustedCurrentNode.Flags.HasFlag(NodeFlags.SvgMember)) { StringOrMemory name2 = tag.Name.SanatizeSvgTagName(); IConstructableSvgElement element2 = _elementFactory.CreateSvg(_document, name2); AuxiliarySetupSteps(element2, ref tag); return element2.Setup(ref tag); } return null; } private void ForeignNormalTag(ref StructHtmlToken tag) { RaiseErrorOccurred(HtmlParseError.TagCannotStartHere, ref tag); if (!IsFragmentCase) { IConstructableElement currentNode = CurrentNode; do { if (currentNode.LocalName.Is(TagNames.AnnotationXml)) { StringOrMemory attribute = currentNode.GetAttribute(default(StringOrMemory), AttributeNames.Encoding); if (attribute.Isi(MimeTypeNames.Html) || attribute.Isi(MimeTypeNames.ApplicationXHtml)) { AddElement(ref tag); return; } } CloseCurrentNode(); currentNode = CurrentNode; } while ((currentNode.Flags & (NodeFlags.HtmlMember | NodeFlags.HtmlTip | NodeFlags.MathTip)) == 0); Consume(ref tag); } else { ForeignSpecialTag(ref tag); } } private bool IsInScope(StringOrMemory tagName) { for (int num = _openElements.Count - 1; num >= 0; num--) { IConstructableElement constructableElement = _openElements[num]; if (constructableElement.LocalName.Is(tagName)) { return true; } if (constructableElement.Flags.HasFlag(NodeFlags.Scoped)) { return false; } } return false; } private bool IsInScope(HashSet tags) { for (int num = _openElements.Count - 1; num >= 0; num--) { IConstructableElement constructableElement = _openElements[num]; if (tags.Contains(constructableElement.LocalName)) { return true; } if (constructableElement.Flags.HasFlag(NodeFlags.Scoped)) { return false; } } return false; } private bool IsInListItemScope() { for (int num = _openElements.Count - 1; num >= 0; num--) { IConstructableElement constructableElement = _openElements[num]; if (constructableElement.LocalName.Is(TagNames.Li)) { return true; } if (constructableElement.Flags.HasFlag(NodeFlags.Scoped) || constructableElement.Flags.HasFlag(NodeFlags.HtmlListScoped)) { return false; } } return false; } private bool IsInButtonScope() { for (int num = _openElements.Count - 1; num >= 0; num--) { IConstructableElement constructableElement = _openElements[num]; if (constructableElement.LocalName.Is(TagNames.P)) { return true; } if (constructableElement.Flags.HasFlag(NodeFlags.Scoped) || constructableElement.LocalName.Is(TagNames.Button)) { return false; } } return false; } private bool IsInTableScope(HashSet tags) { for (int num = _openElements.Count - 1; num >= 0; num--) { IConstructableElement constructableElement = _openElements[num]; if (tags.Contains(constructableElement.LocalName)) { return true; } if (constructableElement.Flags.HasFlag(NodeFlags.HtmlTableScoped)) { return false; } } return false; } private bool IsInTableScope(StringOrMemory tagName) { for (int num = _openElements.Count - 1; num >= 0; num--) { IConstructableElement constructableElement = _openElements[num]; if (constructableElement.LocalName.Is(tagName)) { return true; } if (constructableElement.Flags.HasFlag(NodeFlags.HtmlTableScoped)) { return false; } } return false; } private bool IsInSelectScope(StringOrMemory tagName) { for (int num = _openElements.Count - 1; num >= 0; num--) { IConstructableElement constructableElement = _openElements[num]; if (constructableElement.LocalName.Is(tagName)) { return true; } if (!constructableElement.Flags.HasFlag(NodeFlags.HtmlSelectScoped)) { return false; } } return false; } private bool IsCustomElementEverywhere(StringOrMemory tagName) { if (_options.IsAcceptingCustomElementsEverywhere) { return tagName.IsCustomElement(); } return false; } private void HandleScript(IConstructableScriptElement script) { if (script == null) { return; } if (IsFragmentCase) { CloseCurrentNode(); _currentMode = _previousMode; return; } _document.PerformMicrotaskCheckpoint(); _document.ProvideStableState(); CloseCurrentNode(); _currentMode = _previousMode; if (script.Prepare(_document)) { _waiting = RunScript(script); } } private async Task RunScript(IConstructableScriptElement script) { await _document.WaitForReadyAsync(CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); await script.RunAsync(CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); } private void CheckBodyOnClosing(ref StructHtmlToken token) { for (int i = 0; i < _openElements.Count; i++) { if (!_openElements[i].Flags.HasFlag(NodeFlags.ImplicitlyClosed)) { RaiseErrorOccurred(HtmlParseError.BodyClosedWrong, ref token); break; } } } private bool TagCurrentlyOpen(StringOrMemory tagName) { for (int i = 0; i < _openElements.Count; i++) { if (_openElements[i].LocalName.Is(tagName)) { return true; } } return false; } private void PreventNewLine() { StructHtmlToken token = _tokenizer.GetStructToken(); if (token.Type == HtmlTokenType.Character) { token.RemoveNewLine(); } Home(ref token); } private void End() { while (_openElements.Count != 0) { CloseCurrentNode(); } if (_document.IsLoading) { _waiting = _document.FinishLoadingAsync(); } } private void AddRoot(ref StructHtmlToken tag) { TElement val = _elementFactory.Create(_document, TagNames.Html); _document.AddNode(val); SetupElement(val, ref tag, acknowledgeSelfClosing: false); _openElements.Add(val); _tokenizer.IsAcceptingCharacterData = false; _document.ApplyManifest(); } private void CheckEnded(IConstructableElement element) { Func? shouldEnd = _shouldEnd; if (shouldEnd != null && shouldEnd(element)) { _ended = true; } } private void CloseNodeAt(int index) { IConstructableElement constructableElement = _openElements[index]; constructableElement.SetupElement(); _openElements.RemoveAt(index); CheckEnded(constructableElement); } private void CloseNode(IConstructableElement element) { element.SetupElement(); _openElements.Remove(element); CheckEnded(element); } private void CloseNodesFrom(int index) { for (int num = _openElements.Count - 1; num > index; num--) { CloseNodeAt(num); } CloseCurrentNode(); } private void CloseCurrentNode() { if (_openElements.Count > 0) { CloseNodeAt(_openElements.Count - 1); IConstructableElement adjustedCurrentNode = AdjustedCurrentNode; _tokenizer.IsAcceptingCharacterData = adjustedCurrentNode != null && !adjustedCurrentNode.Flags.HasFlag(NodeFlags.HtmlMember); } } private void SetupElement(IConstructableElement element, ref StructHtmlToken tag, bool acknowledgeSelfClosing) { if (tag.IsSelfClosing && !acknowledgeSelfClosing) { RaiseErrorOccurred(HtmlParseError.TagCannotBeSelfClosed, ref tag); } AuxiliarySetupSteps(element, ref tag); element.SetAttributes(tag.Attributes); } private TElement AddElement(ref StructHtmlToken tag, bool acknowledgeSelfClosing = false) { TElement val = _elementFactory.Create(_document, tag.Name); SetupElement(val, ref tag, acknowledgeSelfClosing); AddElement(val); return val; } private void AddTemplateElement(ref StructHtmlToken tag) { IConstructableTemplateElement element = _elementFactory.CreateTemplate(_document); AddElement(element, ref tag); _formattingElements.AddScopeMarker(); _frameset = false; _currentMode = HtmlTreeMode.InTemplate; _templateModes.Push(HtmlTreeMode.InTemplate); } private void AddElement(IConstructableElement element, ref StructHtmlToken tag, bool acknowledgeSelfClosing = false) { SetupElement(element, ref tag, acknowledgeSelfClosing); AddElement(element); } private void AddElement(IConstructableElement element) { IConstructableElement currentNode = CurrentNode; if (_foster && TagNames.AllTableMajor.Contains(currentNode.LocalName)) { AddElementWithFoster(element); } else { currentNode.AddNode(element); } _openElements.Add(element); _tokenizer.IsAcceptingCharacterData = !element.Flags.HasFlag(NodeFlags.HtmlMember); } private void AddElementWithFoster(IConstructableElement element) { bool flag = false; int num = _openElements.Count; while (--num != 0) { IConstructableElement constructableElement = _openElements[num]; if (constructableElement is HtmlTemplateElement) { constructableElement.AddNode(element); return; } if (constructableElement is HtmlTableElement) { flag = true; break; } } IConstructableElement constructableElement2 = _openElements[num]; IConstructableNode constructableNode = constructableElement2.Parent ?? _openElements[num + 1]; if (flag && constructableElement2.Parent != null) { for (int i = 0; i < constructableNode.ChildNodes.Length; i++) { if (constructableNode.ChildNodes[i] == constructableElement2) { constructableNode.InsertNode(i, element); break; } } } else { constructableNode.AddNode(element); } } private void AddCharacters(StringOrMemory text) { if (text.Length != 0) { IConstructableElement currentNode = CurrentNode; if (_foster && TagNames.AllTableMajor.Contains(currentNode.LocalName)) { AddCharactersWithFoster(text); } else { currentNode.AppendText(text, _emitWhitespaceTextNodes); } } } private void AddCharactersWithFoster(StringOrMemory text) { bool flag = false; int num = _openElements.Count; while (--num != 0) { if (_openElements[num].LocalName.Is(TagNames.Template)) { _openElements[num].AppendText(text, _emitWhitespaceTextNodes); return; } if (_openElements[num].LocalName.Is(TagNames.Table)) { flag = true; break; } } IConstructableNode constructableNode = _openElements[num].Parent ?? _openElements[num + 1]; if (flag && _openElements[num].Parent != null) { for (int i = 0; i < constructableNode.ChildNodes.Length; i++) { if (constructableNode.ChildNodes[i] == _openElements[num]) { constructableNode.InsertText(i, text, _emitWhitespaceTextNodes); break; } } } else { constructableNode.AppendText(text, _emitWhitespaceTextNodes); } } private void AuxiliarySetupSteps(IConstructableElement element, ref StructHtmlToken tag) { if (_options.IsKeepingSourceReferences) { element.SourceReference = tag.ToHtmlToken(); } if (_options.OnCreated != null && element is IElement arg) { _options.OnCreated(arg, tag.Position); } } private void ClearStackBackTo(StringOrMemory tagName) { IConstructableElement currentNode = CurrentNode; while (!currentNode.LocalName.Is(tagName) && !(currentNode is HtmlHtmlElement) && !(currentNode is HtmlTemplateElement)) { CloseCurrentNode(); currentNode = CurrentNode; } } private void ClearStackBackTo(HashSet tags) { IConstructableElement currentNode = CurrentNode; while (!tags.Contains(currentNode.LocalName) && !currentNode.LocalName.IsOneOf(TagNames.Html, TagNames.Template)) { CloseCurrentNode(); currentNode = CurrentNode; } } private void GenerateImpliedEndTagsExceptFor(StringOrMemory tagName) { IConstructableElement currentNode = CurrentNode; while (currentNode.Flags.HasFlag(NodeFlags.ImpliedEnd) && !currentNode.LocalName.Is(tagName)) { CloseCurrentNode(); currentNode = CurrentNode; } } private void GenerateImpliedEndTags() { while (CurrentNode.Flags.HasFlag(NodeFlags.ImpliedEnd)) { CloseCurrentNode(); } } private void ReconstructFormatting() { if (_formattingElements.Count == 0) { return; } int i = _formattingElements.Count - 1; IConstructableElement constructableElement = _formattingElements[i]; if (constructableElement == null || _openElements.Contains(constructableElement)) { return; } while (i > 0) { constructableElement = _formattingElements[--i]; if (constructableElement == null || _openElements.Contains(constructableElement)) { i++; break; } } for (; i < _formattingElements.Count; i++) { IConstructableElement constructableElement2 = CopyElement(_formattingElements[i]); AddElement(constructableElement2); _formattingElements[i] = constructableElement2; } } private void RaiseErrorOccurred(HtmlParseError code, ref StructHtmlToken token) { _tokenizer.RaiseErrorOccurred(code, token.Position); } public void Dispose() { _tokenizer.Dispose(); } } internal sealed class HtmlDomBuilder : HtmlDomBuilder { public HtmlDomBuilder(IHtmlElementConstructionFactory elementFactory, HtmlDocument document, HtmlTokenizerOptions? maybeOptions = null, string? stopAt = null) : base((IDomConstructionElementFactory)elementFactory, (Document)document, maybeOptions, emitWhitespaceTextNodes: true, (stopAt != null) ? ((Func)((IConstructableElement e) => e.Prefix.Length == 0 && e.LocalName.Is(stopAt))) : null) { } } internal static class HtmlDomBuilderExtensions { public static HtmlTreeMode? SelectMode(this IConstructableElement element, bool isLast, Stack templateModes) { if (element.Flags.HasFlag(NodeFlags.HtmlMember)) { StringOrMemory localName = element.LocalName; if (localName.Is(TagNames.Select)) { return HtmlTreeMode.InSelect; } if (TagNames.AllTableCells.Contains(localName)) { return isLast ? HtmlTreeMode.InBody : HtmlTreeMode.InCell; } if (localName.Is(TagNames.Tr)) { return HtmlTreeMode.InRow; } if (TagNames.AllTableSections.Contains(localName)) { return HtmlTreeMode.InTableBody; } if (localName.Is(TagNames.Body)) { return HtmlTreeMode.InBody; } if (localName.Is(TagNames.Table)) { return HtmlTreeMode.InTable; } if (localName.Is(TagNames.Caption)) { return HtmlTreeMode.InCaption; } if (localName.Is(TagNames.Colgroup)) { return HtmlTreeMode.InColumnGroup; } if (localName.Is(TagNames.Template) && templateModes.Count > 0) { return templateModes.Peek(); } if (localName.Is(TagNames.Html)) { return HtmlTreeMode.BeforeHead; } if (localName.Is(TagNames.Head)) { return isLast ? HtmlTreeMode.InBody : HtmlTreeMode.InHead; } if (localName.Is(TagNames.Frameset)) { return HtmlTreeMode.InFrameset; } } if (isLast) { return HtmlTreeMode.InBody; } return null; } public static int GetCode(this HtmlParseError code) { return (int)code; } public static void SetUniqueAttributes(this TElement element, ref StructHtmlToken token) where TElement : class, IConstructableElement { for (int num = token.Attributes.Count - 1; num >= 0; num--) { if (element.HasAttribute(token.Attributes[num].Name)) { token.RemoveAttributeAt(num); } } element.SetAttributes(token.Attributes); } public static void AddFormatting(this List formatting, Element element) { formatting.AddFormatting(element); } public static void AddFormatting(this List formatting, TElement element) where TElement : class, IConstructableElement { int num = 0; for (int num2 = formatting.Count - 1; num2 >= 0; num2--) { TElement val = formatting[num2]; if (val == null) { break; } if (val.NodeName.Is(element.NodeName) && val.NamespaceUri.Is(element.NamespaceUri) && val.Attributes.SameAs(element.Attributes) && ++num == 3) { formatting.RemoveAt(num2); break; } } formatting.Add(element); } public static void ClearFormatting(this List formatting) { formatting.ClearFormatting(); } public static void ClearFormatting(this List formatting) where TElement : class, IConstructableElement { while (formatting.Count != 0) { int index = formatting.Count - 1; TElement val = formatting[index]; formatting.RemoveAt(index); if (val == null) { break; } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AddScopeMarker(this List formatting) { formatting.AddScopeMarker(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AddScopeMarker(this List formatting) where TElement : class, IConstructableElement { formatting.Add(null); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AddComment(this Element parent, HtmlToken token) { parent.AddNode(token.IsProcessingInstruction ? ((CharacterData)ProcessingInstruction.Create(parent.Owner, token.Data)) : ((CharacterData)new Comment(parent.Owner, token.Data))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AddComment(this Element parent, ref StructHtmlToken token) { parent.AddNode(token.IsProcessingInstruction ? ((CharacterData)ProcessingInstruction.Create(parent.Owner, token.Data.ToString())) : ((CharacterData)new Comment(parent.Owner, token.Data.ToString()))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AddComment(this Document parent, HtmlToken token) { parent.AddNode(token.IsProcessingInstruction ? ((CharacterData)ProcessingInstruction.Create(parent, token.Data)) : ((CharacterData)new Comment(parent, token.Data))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AddComment(this Document parent, ref StructHtmlToken token) { parent.AddNode(token.IsProcessingInstruction ? ((CharacterData)ProcessingInstruction.Create(parent, token.Data.ToString())) : ((CharacterData)new Comment(parent, token.Data.ToString()))); } public static QuirksMode GetQuirksMode(this HtmlDoctypeToken doctype) { if (doctype.IsFullQuirks) { return QuirksMode.On; } if (doctype.IsLimitedQuirks) { return QuirksMode.Limited; } return QuirksMode.Off; } public static QuirksMode GetQuirksMode(this ref StructHtmlToken doctype) { if (doctype.IsFullQuirks) { return QuirksMode.On; } if (doctype.IsLimitedQuirks) { return QuirksMode.Limited; } return QuirksMode.Off; } } internal static class HtmlForeignExtensions { private static readonly Dictionary svgAttributeNames = new Dictionary(OrdinalStringOrMemoryComparer.Instance) { { "attributename", "attributeName" }, { "attributetype", "attributeType" }, { "basefrequency", "baseFrequency" }, { "baseprofile", "baseProfile" }, { "calcmode", "calcMode" }, { "clippathunits", "clipPathUnits" }, { "contentscripttype", "contentScriptType" }, { "contentstyletype", "contentStyleType" }, { "diffuseconstant", "diffuseConstant" }, { "edgemode", "edgeMode" }, { "externalresourcesrequired", "externalResourcesRequired" }, { "filterres", "filterRes" }, { "filterunits", "filterUnits" }, { "glyphref", "glyphRef" }, { "gradienttransform", "gradientTransform" }, { "gradientunits", "gradientUnits" }, { "kernelmatrix", "kernelMatrix" }, { "kernelunitlength", "kernelUnitLength" }, { "keypoints", "keyPoints" }, { "keysplines", "keySplines" }, { "keytimes", "keyTimes" }, { "lengthadjust", "lengthAdjust" }, { "limitingconeangle", "limitingConeAngle" }, { "markerheight", "markerHeight" }, { "markerunits", "markerUnits" }, { "markerwidth", "markerWidth" }, { "maskcontentunits", "maskContentUnits" }, { "maskunits", "maskUnits" }, { "numoctaves", "numOctaves" }, { "pathlength", "pathLength" }, { "patterncontentunits", "patternContentUnits" }, { "patterntransform", "patternTransform" }, { "patternunits", "patternUnits" }, { "pointsatx", "pointsAtX" }, { "pointsaty", "pointsAtY" }, { "pointsatz", "pointsAtZ" }, { "preservealpha", "preserveAlpha" }, { "preserveaspectratio", "preserveAspectRatio" }, { "primitiveunits", "primitiveUnits" }, { "refx", "refX" }, { "refy", "refY" }, { "repeatcount", "repeatCount" }, { "repeatdur", "repeatDur" }, { "requiredextensions", "requiredExtensions" }, { "requiredfeatures", "requiredFeatures" }, { "specularconstant", "specularConstant" }, { "specularexponent", "specularExponent" }, { "spreadmethod", "spreadMethod" }, { "startoffset", "startOffset" }, { "stddeviation", "stdDeviation" }, { "stitchtiles", "stitchTiles" }, { "surfacescale", "surfaceScale" }, { "systemlanguage", "systemLanguage" }, { "tablevalues", "tableValues" }, { "targetx", "targetX" }, { "targety", "targetY" }, { "textlength", "textLength" }, { "viewbox", "viewBox" }, { "viewtarget", "viewTarget" }, { "xchannelselector", "xChannelSelector" }, { "ychannelselector", "yChannelSelector" }, { "zoomandpan", "zoomAndPan" } }; private static readonly Dictionary svgAdjustedTagNames = new Dictionary(OrdinalStringOrMemoryComparer.Instance) { { "altglyph", "altGlyph" }, { "altglyphdef", "altGlyphDef" }, { "altglyphitem", "altGlyphItem" }, { "animatecolor", "animateColor" }, { "animatemotion", "animateMotion" }, { "animatetransform", "animateTransform" }, { "clippath", "clipPath" }, { "feblend", "feBlend" }, { "fecolormatrix", "feColorMatrix" }, { "fecomponenttransfer", "feComponentTransfer" }, { "fecomposite", "feComposite" }, { "feconvolvematrix", "feConvolveMatrix" }, { "fediffuselighting", "feDiffuseLighting" }, { "fedisplacementmap", "feDisplacementMap" }, { "fedistantlight", "feDistantLight" }, { "feflood", "feFlood" }, { "fefunca", "feFuncA" }, { "fefuncb", "feFuncB" }, { "fefuncg", "feFuncG" }, { "fefuncr", "feFuncR" }, { "fegaussianblur", "feGaussianBlur" }, { "feimage", "feImage" }, { "femerge", "feMerge" }, { "femergenode", "feMergeNode" }, { "femorphology", "feMorphology" }, { "feoffset", "feOffset" }, { "fepointlight", "fePointLight" }, { "fespecularlighting", "feSpecularLighting" }, { "fespotlight", "feSpotLight" }, { "fetile", "feTile" }, { "feturbulence", "feTurbulence" }, { "foreignobject", "foreignObject" }, { "glyphref", "glyphRef" }, { "lineargradient", "linearGradient" }, { "radialgradient", "radialGradient" }, { "textpath", "textPath" } }; public static StringOrMemory SanatizeSvgTagName(this StringOrMemory localName) { if (svgAdjustedTagNames.TryGetValue(localName, out string value)) { return value; } return localName; } public static IConstructableMathElement Setup(this IConstructableMathElement element, ref StructHtmlToken tag) { int count = tag.Attributes.Count; for (int i = 0; i < count; i++) { MemoryHtmlAttributeToken memoryHtmlAttributeToken = tag.Attributes[i]; StringOrMemory name = memoryHtmlAttributeToken.Name; StringOrMemory value = memoryHtmlAttributeToken.Value; element.AdjustAttribute(name.AdjustToMathAttribute(), value); } return element; } public static IConstructableSvgElement Setup(this IConstructableSvgElement element, ref StructHtmlToken tag) { int count = tag.Attributes.Count; for (int i = 0; i < count; i++) { MemoryHtmlAttributeToken memoryHtmlAttributeToken = tag.Attributes[i]; StringOrMemory name = memoryHtmlAttributeToken.Name; StringOrMemory value = memoryHtmlAttributeToken.Value; element.AdjustAttribute(name.AdjustToSvgAttribute(), value); } return element; } public static void AdjustAttribute(this IConstructableElement element, StringOrMemory name, StringOrMemory value) { string text = null; if (IsXLinkAttribute(name)) { StringOrMemory stringOrMemory = new StringOrMemory(name.Memory.Slice(name.Memory.Span.IndexOf(':') + 1)); if (stringOrMemory.IsXmlName() && stringOrMemory.IsQualifiedName()) { text = NamespaceNames.XLinkUri; name = stringOrMemory; } } else if (IsXmlAttribute(name)) { text = NamespaceNames.XmlUri; } else if (IsXmlNamespaceAttribute(name)) { text = NamespaceNames.XmlNsUri; } if (text == null) { element.SetOwnAttribute(name, value); } else { element.SetAttribute(text, name, value); } } public static StringOrMemory AdjustToMathAttribute(this StringOrMemory attributeName) { if (attributeName == "definitionurl") { return "definitionURL"; } return attributeName; } public static StringOrMemory AdjustToSvgAttribute(this StringOrMemory attributeName) { if (svgAttributeNames.TryGetValue(attributeName, out string value)) { return value; } return attributeName; } private static bool IsXmlNamespaceAttribute(StringOrMemory name) { if (name.Length > 4) { if (!name.Is(NamespaceNames.XmlNsPrefix)) { return name == "xmlns:xlink"; } return true; } return false; } private static bool IsXmlAttribute(StringOrMemory name) { if (name.Length > 7 && "xml:".EqualsSubset(name, 0, 4)) { if (!TagNames.Base.EqualsSubset(name, 4, 4) && !AttributeNames.Lang.EqualsSubset(name, 4, 4)) { return AttributeNames.Space.EqualsSubset(name, 4, 5); } return true; } return false; } private static bool IsXLinkAttribute(StringOrMemory name) { if (name.Length > 9 && "xlink:".EqualsSubset(name, 0, 6)) { if (!AttributeNames.Actuate.EqualsSubset(name, 6, 7) && !AttributeNames.Arcrole.EqualsSubset(name, 6, 7) && !AttributeNames.Href.EqualsSubset(name, 6, 4) && !AttributeNames.Role.EqualsSubset(name, 6, 4) && !AttributeNames.Show.EqualsSubset(name, 6, 4) && !AttributeNames.Type.EqualsSubset(name, 6, 4)) { return AttributeNames.Title.EqualsSubset(name, 6, 5); } return true; } return false; } private static bool EqualsSubset(this string a, StringOrMemory b, int index, int length) { if (length > a.Length) { return false; } if (length > b.Length - index) { return false; } ReadOnlySpan readOnlySpan = a.AsSpan(); ReadOnlySpan span = readOnlySpan.Slice(0, length); readOnlySpan = b.Memory.Span; return span.SequenceEqual(readOnlySpan.Slice(index, length)); } } public enum HtmlParseError : byte { [DomDescription("Unexpected end of the given file.")] EOF = 0, [DomDescription("NULL character replaced by repl. character.")] Null = 1, [DomDescription("Bogus comment detected.")] BogusComment = 26, [DomDescription("Ambiguous open tag.")] AmbiguousOpenTag = 27, [DomDescription("The tag has been closed unexpectedly.")] TagClosedWrong = 28, [DomDescription("The closing slash has been misplaced.")] ClosingSlashMisplaced = 29, [DomDescription("Undefined markup declaration found.")] UndefinedMarkupDeclaration = 30, [DomDescription("Comment ended with an exclamation mark.")] CommentEndedWithEM = 31, [DomDescription("Comment ended with a dash.")] CommentEndedWithDash = 32, [DomDescription("Comment ended with an unexpected character.")] CommentEndedUnexpected = 33, [DomDescription("The given tag cannot be self-closed.")] TagCannotBeSelfClosed = 34, [DomDescription("End tags can never be self-closed.")] EndTagCannotBeSelfClosed = 35, [DomDescription("End tags cannot carry attributes.")] EndTagCannotHaveAttributes = 36, [DomDescription("No caption tag has been found within the local scope.")] CaptionNotInScope = 37, [DomDescription("No select tag has been found within the local scope.")] SelectNotInScope = 38, [DomDescription("No table row has been found within the local scope.")] TableRowNotInScope = 39, [DomDescription("No table has been found within the local scope.")] TableNotInScope = 40, [DomDescription("No paragraph has been found within the local scope.")] ParagraphNotInScope = 41, [DomDescription("No body has been found within the local scope.")] BodyNotInScope = 42, [DomDescription("No block element has been found within the local scope.")] BlockNotInScope = 43, [DomDescription("No table cell has been found within the local scope.")] TableCellNotInScope = 44, [DomDescription("No table section has been found within the local scope.")] TableSectionNotInScope = 45, [DomDescription("No object element has been found within the local scope.")] ObjectNotInScope = 46, [DomDescription("No heading element has been found within the local scope.")] HeadingNotInScope = 47, [DomDescription("No list item has been found within the local scope.")] ListItemNotInScope = 48, [DomDescription("No form has been found within the local scope.")] FormNotInScope = 49, [DomDescription("No button has been found within the local scope.")] ButtonInScope = 50, [DomDescription("No nobr element has been found within the local scope.")] NobrInScope = 51, [DomDescription("No element has been found within the local scope.")] ElementNotInScope = 52, [DomDescription("Character reference found no numbers.")] CharacterReferenceWrongNumber = 53, [DomDescription("Character reference found no semicolon.")] CharacterReferenceSemicolonMissing = 54, [DomDescription("Character reference within an invalid range.")] CharacterReferenceInvalidRange = 55, [DomDescription("Character reference is an invalid number.")] CharacterReferenceInvalidNumber = 56, [DomDescription("Character reference is an invalid code.")] CharacterReferenceInvalidCode = 57, [DomDescription("Character reference is not terminated by a semicolon.")] CharacterReferenceNotTerminated = 58, [DomDescription("Character reference in attribute contains an invalid character (=).")] CharacterReferenceAttributeEqualsFound = 59, [DomDescription("The specified item has not been found.")] ItemNotFound = 60, [DomDescription("The encoding operation (either encoded or decoding) failed.")] EncodingError = 61, [DomDescription("Doctype unexpected character after the name detected.")] DoctypeUnexpectedAfterName = 64, [DomDescription("Invalid character in the public identifier detected.")] DoctypePublicInvalid = 65, [DomDescription("Invalid character in the doctype detected.")] DoctypeInvalidCharacter = 66, [DomDescription("Invalid character in the system identifier detected.")] DoctypeSystemInvalid = 67, [DomDescription("The doctype tag is misplaced and ignored.")] DoctypeTagInappropriate = 68, [DomDescription("The given doctype tag is invalid.")] DoctypeInvalid = 69, [DomDescription("Doctype encountered unexpected character.")] DoctypeUnexpected = 70, [DomDescription("The doctype tag is missing.")] DoctypeMissing = 71, [DomDescription("The given public identifier for the notation declaration is invalid.")] NotationPublicInvalid = 72, [DomDescription("The given system identifier for the notation declaration is invalid.")] NotationSystemInvalid = 73, [DomDescription("The type declaration is missing a valid definition.")] TypeDeclarationUndefined = 74, [DomDescription("A required quantifier is missing in the provided expression.")] QuantifierMissing = 75, [DomDescription("The double quotation marks have been misplaced.")] DoubleQuotationMarkUnexpected = 80, [DomDescription("The single quotation marks have been misplaced.")] SingleQuotationMarkUnexpected = 81, [DomDescription("The attribute's name contains an invalid character.")] AttributeNameInvalid = 96, [DomDescription("The attribute's value contains an invalid character.")] AttributeValueInvalid = 97, [DomDescription("The beginning of a new attribute has been expected.")] AttributeNameExpected = 98, [DomDescription("The attribute has already been added.")] AttributeDuplicateOmitted = 99, [DomDescription("The given tag must be placed in head tag.")] TagMustBeInHead = 112, [DomDescription("The given tag is not appropriate for the current position.")] TagInappropriate = 113, [DomDescription("The given tag cannot end at the current position.")] TagCannotEndHere = 114, [DomDescription("The given tag cannot start at the current position.")] TagCannotStartHere = 115, [DomDescription("The given form cannot be placed at the current position.")] FormInappropriate = 116, [DomDescription("The given input cannot be placed at the current position.")] InputUnexpected = 117, [DomDescription("The closing tag and the currently open tag do not match.")] TagClosingMismatch = 118, [DomDescription("The given end tag does not match the current node.")] TagDoesNotMatchCurrentNode = 119, [DomDescription("This position does not support a linebreak (LF, FF).")] LineBreakUnexpected = 120, [DomDescription("The head tag can only be placed once inside the html tag.")] HeadTagMisplaced = 128, [DomDescription("The html tag can only be placed once as the root element.")] HtmlTagMisplaced = 129, [DomDescription("The body tag can only be placed once inside the html tag.")] BodyTagMisplaced = 130, [DomDescription("The image tag has been named image instead of img.")] ImageTagNamedWrong = 131, [DomDescription("Tables cannot be nested.")] TableNesting = 132, [DomDescription("An illegal element has been detected in a table.")] IllegalElementInTableDetected = 133, [DomDescription("Select elements cannot be nested.")] SelectNesting = 134, [DomDescription("An illegal element has been detected in a select.")] IllegalElementInSelectDetected = 135, [DomDescription("The frameset element has been misplaced.")] FramesetMisplaced = 136, [DomDescription("Headings cannot be nested.")] HeadingNested = 137, [DomDescription("Anchor elements cannot be nested.")] AnchorNested = 138, [DomDescription("The given token cannot be inserted here.")] TokenNotPossible = 144, [DomDescription("The current node is not the root element.")] CurrentNodeIsNotRoot = 145, [DomDescription("The current node is the root element.")] CurrentNodeIsRoot = 146, [DomDescription("This tag is invalid in fragment mode.")] TagInvalidInFragmentMode = 147, [DomDescription("There is already an open form.")] FormAlreadyOpen = 148, [DomDescription("The form has been closed wrong.")] FormClosedWrong = 149, [DomDescription("The body has been closed wrong.")] BodyClosedWrong = 150, [DomDescription("An expected formatting element has not been found.")] FormattingElementNotFound = 151 } public class HtmlParseException : Exception { public TextPosition Position { get; } public int Code { get; } public HtmlParseException(int code, string message, TextPosition position) : base(message) { Code = code; Position = position; } } public enum HtmlParseMode : byte { PCData, RCData, Plaintext, Rawtext, Script } public class HtmlParser : EventTarget, IHtmlParser, IParser, IEventTarget { private readonly HtmlParserOptions _options; private readonly IBrowsingContext _context; public HtmlParserOptions Options => _options; public event DomEventHandler Parsing { add { AddEventListener(EventNames.Parsing, value); } remove { RemoveEventListener(EventNames.Parsing, value); } } public event DomEventHandler Parsed { add { AddEventListener(EventNames.Parsed, value); } remove { RemoveEventListener(EventNames.Parsed, value); } } public event DomEventHandler Error { add { AddEventListener(EventNames.Error, value); } remove { RemoveEventListener(EventNames.Error, value); } } public HtmlParser() : this(null) { } public HtmlParser(HtmlParserOptions options) : this(options, null) { } internal HtmlParser(IBrowsingContext? context) : this(new HtmlParserOptions { IsScripting = (context?.IsScripting() ?? false) }, context) { } public HtmlParser(HtmlParserOptions options, IBrowsingContext? context) { _options = options; _context = context ?? BrowsingContext.NewFrom((IHtmlParser)this); } public IHtmlDocument ParseDocument(string source) { HtmlDocument document = CreateDocument(source); return Parse(document); } public IHtmlHeadElement? ParseHead(string source) { HtmlDocument document = CreateDocument(source); return Parse(document, TagNames.Head).Head; } public INodeList ParseFragment(Stream source, IElement contextElement) { HtmlDocument document = CreateDocument(source); return ParseFragment(document, contextElement); } public INodeList ParseFragment(string source, IElement contextElement) { HtmlDocument document = CreateDocument(source); return ParseFragment(document, contextElement); } public IHtmlDocument ParseDocument(Stream source) { HtmlDocument document = CreateDocument(source); return Parse(document); } public IHtmlDocument ParseDocument(char[] source, int length = 0) { HtmlDocument document = CreateDocument(source, length); return Parse(document); } public IHtmlDocument ParseDocument(ReadOnlyMemory chars) { HtmlDocument document = CreateDocument(chars); return Parse(document); } public IHtmlDocument ParseDocument(TextSource source) { HtmlDocument document = CreateDocument(source); return Parse(document); } public TDocument ParseDocument(TextSource source, TokenizerMiddleware? middleware = null) where TDocument : class, IConstructableDocument where TElement : class, IConstructableElement { IDomConstructionElementFactory? obj = _context.GetService>() ?? throw new InvalidOperationException("No read-only construction factory found."); TDocument val = obj.CreateDocument(source, _context); HtmlDomBuilder htmlDomBuilder = new HtmlDomBuilder(obj, val); if (HasEventListener(EventNames.Error)) { htmlDomBuilder.Error += delegate(object? _, HtmlErrorEvent ev) { InvokeEventListener(ev); }; } htmlDomBuilder.Parse(_options, middleware); return val; } public IHtmlHeadElement? ParseHead(Stream source) { HtmlDocument document = CreateDocument(source); return Parse(document, TagNames.Head).Head; } public Task ParseDocumentAsync(string source, CancellationToken cancel) { HtmlDocument document = CreateDocument(source); return ParseAsync(document, cancel); } public Task ParseDocumentAsync(Stream source, CancellationToken cancel) { HtmlDocument document = CreateDocument(source); return ParseAsync(document, cancel); } public async Task ParseHeadAsync(string source, CancellationToken cancel) { HtmlDocument document = CreateDocument(source); return (await ParseAsync(document, cancel, TagNames.Head).ConfigureAwait(continueOnCapturedContext: false)).Head; } public async Task ParseHeadAsync(Stream source, CancellationToken cancel) { HtmlDocument document = CreateDocument(source); return (await ParseAsync(document, cancel, TagNames.Head).ConfigureAwait(continueOnCapturedContext: false)).Head; } async Task IHtmlParser.ParseDocumentAsync(IDocument document, CancellationToken cancel) { HtmlDocument document2 = (HtmlDocument)document; return await ParseAsync(document2, cancel).ConfigureAwait(continueOnCapturedContext: false); } private HtmlDocument CreateDocument(string source) { TextSource textSource = new TextSource(source); return CreateDocument(textSource); } private HtmlDocument CreateDocument(Stream source) { Encoding defaultEncoding = _context.GetDefaultEncoding(); TextSource textSource = new TextSource(source, defaultEncoding); return CreateDocument(textSource); } private HtmlDocument CreateDocument(ReadOnlyMemory chars) { TextSource textSource = new TextSource(new ReadOnlyMemoryTextSource(chars)); return CreateDocument(textSource); } private HtmlDocument CreateDocument(char[] source, int length = 0) { CharArrayTextSource source2 = new CharArrayTextSource(source, (length == 0) ? source.Length : length); return CreateDocument(new TextSource(source2)); } private HtmlDocument CreateDocument(TextSource textSource) { return new HtmlDocument(_context, textSource); } private HtmlDomBuilder CreateBuilder(HtmlDocument document, string? stopAt) { HtmlDomBuilder htmlDomBuilder = new HtmlDomBuilder(maybeOptions: new HtmlTokenizerOptions(_options), elementFactory: _context.GetService() ?? HtmlDomConstructionFactory.Instance, document: document, stopAt: stopAt); if (HasEventListener(EventNames.Error)) { htmlDomBuilder.Error += delegate(object? _, HtmlErrorEvent ev) { InvokeEventListener(ev); }; } return htmlDomBuilder; } private IHtmlDocument Parse(HtmlDocument document, string? stopAt = null) { HtmlDomBuilder htmlDomBuilder = CreateBuilder(document, stopAt); InvokeHtmlParseEvent(document, completed: false); htmlDomBuilder.Parse(_options); InvokeHtmlParseEvent(document, completed: true); return document; } private async Task ParseAsync(HtmlDocument document, CancellationToken cancel, string? stopAt = null) { HtmlDomBuilder htmlDomBuilder = CreateBuilder(document, stopAt); InvokeHtmlParseEvent(document, completed: false); await htmlDomBuilder.ParseAsync(_options, null, cancel).ConfigureAwait(continueOnCapturedContext: false); InvokeHtmlParseEvent(document, completed: true); return document; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void InvokeHtmlParseEvent(HtmlDocument document, bool completed) { if (base.HasEventListeners) { InvokeEventListener(new HtmlParseEvent(document, completed)); } } private INodeList ParseFragment(HtmlDocument document, IElement contextElement) { HtmlDomBuilder htmlDomBuilder = new HtmlDomBuilder(HtmlDomConstructionFactory.Instance, document); if (contextElement is Element element) { Element element2 = document.CreateElementFrom(element.LocalName, element.Prefix); IElement documentElement = htmlDomBuilder.ParseFragment(_options, element2).DocumentElement; element2.AppendNodes(documentElement.ChildNodes.ToArray()); return element2.ChildNodes; } return htmlDomBuilder.Parse(_options).ChildNodes; } } public static class HtmlParserExtensions { public static Task ParseDocumentAsync(this IHtmlParser parser, string source) { return parser.ParseDocumentAsync(source, CancellationToken.None); } public static Task ParseDocumentAsync(this IHtmlParser parser, Stream source) { return parser.ParseDocumentAsync(source, CancellationToken.None); } public static Task ParseHeadAsync(this IHtmlParser parser, string source) { return parser.ParseHeadAsync(source, CancellationToken.None); } public static Task ParseHeadAsync(this IHtmlParser parser, Stream source) { return parser.ParseHeadAsync(source, CancellationToken.None); } public static Task ParseDocumentAsync(this IHtmlParser parser, IDocument document) { return parser.ParseDocumentAsync(document, CancellationToken.None); } } public struct HtmlParserOptions { public bool IsEmbedded { get; set; } public bool IsAcceptingCustomElementsEverywhere { get; set; } public bool IsPreservingAttributeNames { get; set; } public bool IsNotSupportingFrames { get; set; } public bool IsScripting { get; set; } public bool IsStrictMode { get; set; } public bool IsSupportingProcessingInstructions { get; set; } public bool IsKeepingSourceReferences { get; set; } public bool IsNotConsumingCharacterReferences { get; set; } public Action? OnCreated { get; set; } public bool DisableElementPositionTracking { get; set; } public bool SkipComments { get; set; } public bool SkipPlaintext { get; set; } public bool SkipRCDataText { get; set; } public bool SkipCDATA { get; set; } public bool SkipProcessingInstructions { get; set; } public ShouldEmitAttribute? ShouldEmitAttribute { get; set; } public bool SkipDataText { get; set; } public bool SkipScriptText { get; set; } public bool SkipRawText { get; set; } } internal static class HtmlTagNameLookup { public static string? TryGetWellKnownTagName(ICharBuffer builder) { switch (builder.Length) { case 1: return builder[0] switch { 'p' => TagNames.P, 'b' => TagNames.B, 'i' => TagNames.I, 's' => TagNames.S, 'u' => TagNames.U, 'q' => TagNames.Q, 'a' => TagNames.A, _ => null, }; case 2: switch (builder[1]) { case 'p': if (!CharsAreEqual(builder, TagNames.Rp)) { return null; } return TagNames.Rp; case 't': switch (builder[0]) { case 'r': if (!CharsAreEqual(builder, TagNames.Rt)) { return null; } return TagNames.Rt; case 'd': if (!CharsAreEqual(builder, TagNames.Dt)) { return null; } return TagNames.Dt; case 't': if (!CharsAreEqual(builder, TagNames.Tt)) { return null; } return TagNames.Tt; default: return null; } case 'b': if (!CharsAreEqual(builder, TagNames.Rb)) { return null; } return TagNames.Rb; case 'h': if (!CharsAreEqual(builder, TagNames.Th)) { return null; } return TagNames.Th; case 'd': switch (builder[0]) { case 't': if (!CharsAreEqual(builder, TagNames.Td)) { return null; } return TagNames.Td; case 'd': if (!CharsAreEqual(builder, TagNames.Dd)) { return null; } return TagNames.Dd; default: return null; } case 'r': switch (builder[0]) { case 't': if (!CharsAreEqual(builder, TagNames.Tr)) { return null; } return TagNames.Tr; case 'b': if (!CharsAreEqual(builder, TagNames.Br)) { return null; } return TagNames.Br; case 'h': if (!CharsAreEqual(builder, TagNames.Hr)) { return null; } return TagNames.Hr; default: return null; } case 'l': switch (builder[0]) { case 'o': if (!CharsAreEqual(builder, TagNames.Ol)) { return null; } return TagNames.Ol; case 'u': if (!CharsAreEqual(builder, TagNames.Ul)) { return null; } return TagNames.Ul; case 'd': if (!CharsAreEqual(builder, TagNames.Dl)) { return null; } return TagNames.Dl; default: return null; } case 'i': switch (builder[0]) { case 'l': if (!CharsAreEqual(builder, TagNames.Li)) { return null; } return TagNames.Li; case 'm': if (!CharsAreEqual(builder, TagNames.Mi)) { return null; } return TagNames.Mi; default: return null; } case 'm': if (!CharsAreEqual(builder, TagNames.Em)) { return null; } return TagNames.Em; case '1': if (!CharsAreEqual(builder, TagNames.H1)) { return null; } return TagNames.H1; case '2': if (!CharsAreEqual(builder, TagNames.H2)) { return null; } return TagNames.H2; case '3': if (!CharsAreEqual(builder, TagNames.H3)) { return null; } return TagNames.H3; case '4': if (!CharsAreEqual(builder, TagNames.H4)) { return null; } return TagNames.H4; case '5': if (!CharsAreEqual(builder, TagNames.H5)) { return null; } return TagNames.H5; case '6': if (!CharsAreEqual(builder, TagNames.H6)) { return null; } return TagNames.H6; case 'o': if (!CharsAreEqual(builder, TagNames.Mo)) { return null; } return TagNames.Mo; case 'n': if (!CharsAreEqual(builder, TagNames.Mn)) { return null; } return TagNames.Mn; case 's': if (!CharsAreEqual(builder, TagNames.Ms)) { return null; } return TagNames.Ms; default: return null; } case 3: switch (builder[0]) { case 'v': if (!CharsAreEqual(builder, TagNames.Var)) { return null; } return TagNames.Var; case 's': switch (builder[2]) { case 'b': if (!CharsAreEqual(builder, TagNames.Sub)) { return null; } return TagNames.Sub; case 'p': if (!CharsAreEqual(builder, TagNames.Sup)) { return null; } return TagNames.Sup; case 'g': if (!CharsAreEqual(builder, TagNames.Svg)) { return null; } return TagNames.Svg; default: return null; } case 'r': if (!CharsAreEqual(builder, TagNames.Rtc)) { return null; } return TagNames.Rtc; case 'i': switch (builder[1]) { case 'n': if (!CharsAreEqual(builder, TagNames.Ins)) { return null; } return TagNames.Ins; case 'm': if (!CharsAreEqual(builder, TagNames.Img)) { return null; } return TagNames.Img; default: return null; } case 'd': switch (builder[2]) { case 'l': if (!CharsAreEqual(builder, TagNames.Del)) { return null; } return TagNames.Del; case 'v': if (!CharsAreEqual(builder, TagNames.Div)) { return null; } return TagNames.Div; case 'r': if (!CharsAreEqual(builder, TagNames.Dir)) { return null; } return TagNames.Dir; case 'n': if (!CharsAreEqual(builder, TagNames.Dfn)) { return null; } return TagNames.Dfn; default: return null; } case 'c': if (!CharsAreEqual(builder, TagNames.Col)) { return null; } return TagNames.Col; case 'p': if (!CharsAreEqual(builder, TagNames.Pre)) { return null; } return TagNames.Pre; case 'b': switch (builder[2]) { case 'g': if (!CharsAreEqual(builder, TagNames.Big)) { return null; } return TagNames.Big; case 'i': if (!CharsAreEqual(builder, TagNames.Bdi)) { return null; } return TagNames.Bdi; case 'o': if (!CharsAreEqual(builder, TagNames.Bdo)) { return null; } return TagNames.Bdo; default: return null; } case 'x': switch (builder[2]) { case 'p': if (!CharsAreEqual(builder, TagNames.Xmp)) { return null; } return TagNames.Xmp; case 'l': if (!CharsAreEqual(builder, TagNames.Xml)) { return null; } return TagNames.Xml; default: return null; } case 'w': if (!CharsAreEqual(builder, TagNames.Wbr)) { return null; } return TagNames.Wbr; case 'n': if (!CharsAreEqual(builder, TagNames.Nav)) { return null; } return TagNames.Nav; case 'm': if (!CharsAreEqual(builder, TagNames.Map)) { return null; } return TagNames.Map; case 'k': if (!CharsAreEqual(builder, TagNames.Kbd)) { return null; } return TagNames.Kbd; default: return null; } case 4: switch (builder[3]) { case 'l': if (!CharsAreEqual(builder, TagNames.Html)) { return null; } return TagNames.Html; case 'y': switch (builder[0]) { case 'b': if (!CharsAreEqual(builder, TagNames.Body)) { return null; } return TagNames.Body; case 'r': if (!CharsAreEqual(builder, TagNames.Ruby)) { return null; } return TagNames.Ruby; default: return null; } case 'd': if (!CharsAreEqual(builder, TagNames.Head)) { return null; } return TagNames.Head; case 'a': switch (builder[0]) { case 'm': if (!CharsAreEqual(builder, TagNames.Meta)) { return null; } return TagNames.Meta; case 'd': if (!CharsAreEqual(builder, TagNames.Data)) { return null; } return TagNames.Data; case 'a': if (!CharsAreEqual(builder, TagNames.Area)) { return null; } return TagNames.Area; default: return null; } case 'u': if (!CharsAreEqual(builder, TagNames.Menu)) { return null; } return TagNames.Menu; case 't': switch (builder[0]) { case 'f': if (!CharsAreEqual(builder, TagNames.Font)) { return null; } return TagNames.Font; case 's': if (!CharsAreEqual(builder, TagNames.Slot)) { return null; } return TagNames.Slot; default: return null; } case 'n': switch (builder[0]) { case 's': if (!CharsAreEqual(builder, TagNames.Span)) { return null; } return TagNames.Span; case 'm': if (!CharsAreEqual(builder, TagNames.Main)) { return null; } return TagNames.Main; default: return null; } case 'm': if (!CharsAreEqual(builder, TagNames.Form)) { return null; } return TagNames.Form; case 'e': switch (builder[2]) { case 'd': if (!CharsAreEqual(builder, TagNames.Code)) { return null; } return TagNames.Code; case 's': if (!CharsAreEqual(builder, TagNames.Base)) { return null; } return TagNames.Base; case 't': if (!CharsAreEqual(builder, TagNames.Cite)) { return null; } return TagNames.Cite; case 'm': if (!CharsAreEqual(builder, TagNames.Time)) { return null; } return TagNames.Time; default: return null; } case 'r': switch (builder[0]) { case 'n': if (!CharsAreEqual(builder, TagNames.NoBr)) { return null; } return TagNames.NoBr; case 'a': if (!CharsAreEqual(builder, TagNames.Abbr)) { return null; } return TagNames.Abbr; default: return null; } case 'k': switch (builder[0]) { case 'l': if (!CharsAreEqual(builder, TagNames.Link)) { return null; } return TagNames.Link; case 'm': if (!CharsAreEqual(builder, TagNames.Mark)) { return null; } return TagNames.Mark; default: return null; } case 'p': if (!CharsAreEqual(builder, TagNames.Samp)) { return null; } return TagNames.Samp; case 'h': if (!CharsAreEqual(builder, TagNames.Math)) { return null; } return TagNames.Math; case 'c': if (!CharsAreEqual(builder, TagNames.Desc)) { return null; } return TagNames.Desc; default: return null; } case 5: switch (builder[1]) { case 'i': switch (builder[0]) { case 't': if (!CharsAreEqual(builder, TagNames.Title)) { return null; } return TagNames.Title; case 'v': if (!CharsAreEqual(builder, TagNames.Video)) { return null; } return TagNames.Video; default: return null; } case 't': switch (builder[0]) { case 's': if (!CharsAreEqual(builder, TagNames.Style)) { return null; } return TagNames.Style; case 'm': if (!CharsAreEqual(builder, TagNames.Mtext)) { return null; } return TagNames.Mtext; default: return null; } case 'm': switch (builder[0]) { case 'e': if (!CharsAreEqual(builder, TagNames.Embed)) { return null; } return TagNames.Embed; case 's': if (!CharsAreEqual(builder, TagNames.Small)) { return null; } return TagNames.Small; case 'i': if (!CharsAreEqual(builder, TagNames.Image)) { return null; } return TagNames.Image; default: return null; } case 'a': switch (builder[0]) { case 'p': if (!CharsAreEqual(builder, TagNames.Param)) { return null; } return TagNames.Param; case 't': if (!CharsAreEqual(builder, TagNames.Table)) { return null; } return TagNames.Table; case 'l': if (!CharsAreEqual(builder, TagNames.Label)) { return null; } return TagNames.Label; default: return null; } case 'h': if (!CharsAreEqual(builder, TagNames.Thead)) { return null; } return TagNames.Thead; case 'b': if (!CharsAreEqual(builder, TagNames.Tbody)) { return null; } return TagNames.Tbody; case 'f': if (!CharsAreEqual(builder, TagNames.Tfoot)) { return null; } return TagNames.Tfoot; case 'n': if (!CharsAreEqual(builder, TagNames.Input)) { return null; } return TagNames.Input; case 'r': switch (builder[0]) { case 'f': if (!CharsAreEqual(builder, TagNames.Frame)) { return null; } return TagNames.Frame; case 't': if (!CharsAreEqual(builder, TagNames.Track)) { return null; } return TagNames.Track; default: return null; } case 'u': switch (builder[0]) { case 'a': if (!CharsAreEqual(builder, TagNames.Audio)) { return null; } return TagNames.Audio; case 'q': if (!CharsAreEqual(builder, TagNames.Quote)) { return null; } return TagNames.Quote; default: return null; } case 's': if (!CharsAreEqual(builder, TagNames.Aside)) { return null; } return TagNames.Aside; case 'e': if (!CharsAreEqual(builder, TagNames.Meter)) { return null; } return TagNames.Meter; default: return null; } case 6: switch (builder[3]) { case 'i': switch (builder[1]) { case 'c': if (!CharsAreEqual(builder, TagNames.Script)) { return null; } return TagNames.Script; case 't': if (!CharsAreEqual(builder, TagNames.Strike)) { return null; } return TagNames.Strike; case 'p': if (!CharsAreEqual(builder, TagNames.Option)) { return null; } return TagNames.Option; default: return null; } case 'l': switch (builder[0]) { case 'a': if (!CharsAreEqual(builder, TagNames.Applet)) { return null; } return TagNames.Applet; case 'd': if (!CharsAreEqual(builder, TagNames.Dialog)) { return null; } return TagNames.Dialog; default: return null; } case 'e': switch (builder[0]) { case 'o': if (!CharsAreEqual(builder, TagNames.Object)) { return null; } return TagNames.Object; case 'l': if (!CharsAreEqual(builder, TagNames.Legend)) { return null; } return TagNames.Legend; case 's': if (!CharsAreEqual(builder, TagNames.Select)) { return null; } return TagNames.Select; default: return null; } case 'v': if (!CharsAreEqual(builder, TagNames.Canvas)) { return null; } return TagNames.Canvas; case 'g': if (!CharsAreEqual(builder, TagNames.Keygen)) { return null; } return TagNames.Keygen; case 'o': switch (builder[0]) { case 's': if (!CharsAreEqual(builder, TagNames.Strong)) { return null; } return TagNames.Strong; case 'h': if (!CharsAreEqual(builder, TagNames.Hgroup)) { return null; } return TagNames.Hgroup; default: return null; } case 'a': if (!CharsAreEqual(builder, TagNames.Iframe)) { return null; } return TagNames.Iframe; case 'r': if (!CharsAreEqual(builder, TagNames.Source)) { return null; } return TagNames.Source; case 't': switch (builder[0]) { case 'b': if (!CharsAreEqual(builder, TagNames.Button)) { return null; } return TagNames.Button; case 'c': if (!CharsAreEqual(builder, TagNames.Center)) { return null; } return TagNames.Center; case 'f': if (!CharsAreEqual(builder, TagNames.Footer)) { return null; } return TagNames.Footer; default: return null; } case 'u': if (!CharsAreEqual(builder, TagNames.Figure)) { return null; } return TagNames.Figure; case 'd': if (!CharsAreEqual(builder, TagNames.Header)) { return null; } return TagNames.Header; case 'p': if (!CharsAreEqual(builder, TagNames.Output)) { return null; } return TagNames.Output; case 'c': if (!CharsAreEqual(builder, TagNames.Circle)) { return null; } return TagNames.Circle; default: return null; } case 7: switch (builder[0]) { case 'D': if (!CharsAreEqual(builder, TagNames.Doctype)) { return null; } return TagNames.Doctype; case 'b': if (!CharsAreEqual(builder, TagNames.Bgsound)) { return null; } return TagNames.Bgsound; case 'n': if (!CharsAreEqual(builder, TagNames.NoEmbed)) { return null; } return TagNames.NoEmbed; case 'm': if (!CharsAreEqual(builder, TagNames.Marquee)) { return null; } return TagNames.Marquee; case 'c': if (!CharsAreEqual(builder, TagNames.Caption)) { return null; } return TagNames.Caption; case 'd': if (!CharsAreEqual(builder, TagNames.Details)) { return null; } return TagNames.Details; case 'i': if (!CharsAreEqual(builder, TagNames.IsIndex)) { return null; } return TagNames.IsIndex; case 's': switch (builder[1]) { case 'u': if (!CharsAreEqual(builder, TagNames.Summary)) { return null; } return TagNames.Summary; case 'e': if (!CharsAreEqual(builder, TagNames.Section)) { return null; } return TagNames.Section; default: return null; } case 'l': if (!CharsAreEqual(builder, TagNames.Listing)) { return null; } return TagNames.Listing; case 'a': switch (builder[1]) { case 'd': if (!CharsAreEqual(builder, TagNames.Address)) { return null; } return TagNames.Address; case 'r': if (!CharsAreEqual(builder, TagNames.Article)) { return null; } return TagNames.Article; default: return null; } case 'p': if (!CharsAreEqual(builder, TagNames.Picture)) { return null; } return TagNames.Picture; default: return null; } case 8: switch (builder[2]) { case 's': switch (builder[0]) { case 'n': if (!CharsAreEqual(builder, TagNames.NoScript)) { return null; } return TagNames.NoScript; case 'b': if (!CharsAreEqual(builder, TagNames.BaseFont)) { return null; } return TagNames.BaseFont; default: return null; } case 'f': if (!CharsAreEqual(builder, TagNames.NoFrames)) { return null; } return TagNames.NoFrames; case 'n': if (!CharsAreEqual(builder, TagNames.MenuItem)) { return null; } return TagNames.MenuItem; case 'm': if (!CharsAreEqual(builder, TagNames.Template)) { return null; } return TagNames.Template; case 'l': if (!CharsAreEqual(builder, TagNames.Colgroup)) { return null; } return TagNames.Colgroup; case 'x': if (!CharsAreEqual(builder, TagNames.Textarea)) { return null; } return TagNames.Textarea; case 'e': if (!CharsAreEqual(builder, TagNames.Fieldset)) { return null; } return TagNames.Fieldset; case 't': switch (builder[0]) { case 'd': if (!CharsAreEqual(builder, TagNames.Datalist)) { return null; } return TagNames.Datalist; case 'o': if (!CharsAreEqual(builder, TagNames.Optgroup)) { return null; } return TagNames.Optgroup; default: return null; } case 'a': if (!CharsAreEqual(builder, TagNames.Frameset)) { return null; } return TagNames.Frameset; case 'o': if (!CharsAreEqual(builder, TagNames.Progress)) { return null; } return TagNames.Progress; default: return null; } case 9: if (!CharsAreEqual(builder, TagNames.Plaintext)) { return null; } return TagNames.Plaintext; case 10: switch (builder[0]) { case 'b': if (!CharsAreEqual(builder, TagNames.BlockQuote)) { return null; } return TagNames.BlockQuote; case 'f': if (!CharsAreEqual(builder, TagNames.Figcaption)) { return null; } return TagNames.Figcaption; default: return null; } case 13: if (!CharsAreEqual(builder, TagNames.ForeignObject)) { return null; } return TagNames.ForeignObject; case 14: if (!CharsAreEqual(builder, TagNames.AnnotationXml)) { return null; } return TagNames.AnnotationXml; default: return null; } } private static bool CharsAreEqual(ICharBuffer builder, string tagName) { for (int i = 0; i < tagName.Length; i++) { if (tagName[i] != builder[i]) { return false; } } return true; } } public delegate bool ShouldEmitAttribute(ref StructHtmlToken token, ReadOnlyMemory attributeName); public enum TokenConsumptionResult { Continue, Stop } public delegate void TokenConsumer(ref StructHtmlToken token); public delegate TokenConsumptionResult TokenizerMiddleware(ref StructHtmlToken token, TokenConsumer next); public sealed class HtmlTokenizer : BaseTokenizer { private enum AttributeState : byte { BeforeName, Name, AfterName, BeforeValue, QuotedValue, AfterValue, UnquotedValue, SelfClose } private enum ScriptState : byte { Normal, OpenTag, EndTag, StartEscape, Escaped, StartEscapeDash, EscapedDash, EscapedDashDash, EscapedOpenTag, EscapedEndTag, EscapedNameEndTag, StartDoubleEscape, EscapedDouble, EscapedDoubleDash, EscapedDoubleDashDash, EscapedDoubleOpenTag, EndDoubleEscape } private readonly struct EntityProvider { private readonly IEntityProviderExtended? _fast; private readonly IEntityProvider? _slow; public EntityProvider(IEntityProvider slow) { _fast = null; _slow = slow; } public EntityProvider(IEntityProviderExtended fast) { _slow = null; _fast = fast; } public string? GetSymbol(StringOrMemory name) { if (_fast != null) { return _fast.GetSymbol(name); } if (_slow != null) { return _slow.GetSymbol(name.ToString()); } throw new InvalidOperationException("Should not get there, please file a bug report."); } } private readonly EntityProvider _resolver; private StringOrMemory _lastStartTag; private TextPosition _position; private StructHtmlToken _token; private ShouldEmitAttribute _shouldEmitAttribute = delegate { return true; }; private char[]? _characterReferenceBuffer; public bool SkipDataText { get; set; } public bool SkipScriptText { get; set; } public bool SkipRawText { get; set; } public bool SkipComments { get; set; } public bool SkipPlaintext { get; set; } public bool SkipRCDataText { get; set; } public bool SkipCDATA { get; set; } public bool SkipProcessingInstructions { get; set; } public ShouldEmitAttribute ShouldEmitAttribute { get { return _shouldEmitAttribute; } set { if (value != null) { _shouldEmitAttribute = value; } } } public bool IsAcceptingCharacterData { get; set; } public bool IsPreservingAttributeNames { get; set; } public bool IsNotConsumingCharacterReferences { get; set; } public HtmlParseMode State { get; set; } public bool IsStrictMode { get; set; } public bool IsSupportingProcessingInstructions { get; set; } public event EventHandler? Error; public HtmlTokenizer(TextSource source, IEntityProvider resolver) : base(source) { State = HtmlParseMode.PCData; _lastStartTag = StringOrMemory.Empty; _resolver = new EntityProvider(resolver); } public HtmlTokenizer(TextSource source, IEntityProviderExtended resolver) : base(source) { State = HtmlParseMode.PCData; _lastStartTag = StringOrMemory.Empty; _resolver = new EntityProvider(resolver); } public HtmlToken Get() { return GetStructToken().ToHtmlToken(); } public ref StructHtmlToken GetStructToken() { char next = GetNext(); _position = GetCurrentPosition(); if (next != '\uffff') { switch (State) { case HtmlParseMode.PCData: return ref Data(next); case HtmlParseMode.RCData: return ref RCData(next); case HtmlParseMode.Plaintext: return ref Plaintext(next); case HtmlParseMode.Rawtext: return ref Rawtext(next); case HtmlParseMode.Script: return ref ScriptData(next); } } return ref NewEof(acceptable: true); } internal void RaiseErrorOccurred(HtmlParseError code, TextPosition position) { EventHandler eventHandler = this.Error; if (IsStrictMode) { string message = "Error while parsing the provided HTML document."; throw new HtmlParseException(code.GetCode(), message, position); } if (eventHandler != null) { HtmlErrorEvent e = new HtmlErrorEvent(code, position); eventHandler(this, e); } } private ref StructHtmlToken Data(char c) { if (c != '<') { return ref DataText(c); } return ref TagOpen(GetNext()); } private ref StructHtmlToken DataText(char c) { while (true) { switch (c) { case '<': case '\uffff': Back(); if (SkipDataText) { return ref NewSkippedContent(); } return ref NewCharacter(); case '&': AppendCharacterReference(GetNext()); break; case '\0': RaiseErrorOccurred(HtmlParseError.Null); break; default: Append(c); break; } c = GetNext(); } } private ref StructHtmlToken Plaintext(char c) { while (true) { switch (c) { case '\0': AppendReplacement(); break; case '\uffff': Back(); if (SkipPlaintext) { return ref NewSkippedContent(); } return ref NewCharacter(); default: Append(c); break; } c = GetNext(); } } private ref StructHtmlToken RCData(char c) { if (c != '<') { return ref RCDataText(c); } return ref RCDataLt(GetNext()); } private ref StructHtmlToken RCDataText(char c) { while (true) { switch (c) { case '&': AppendCharacterReference(GetNext()); break; case '<': case '\uffff': Back(); if (SkipRCDataText) { return ref NewSkippedContent(); } return ref NewCharacter(); case '\0': AppendReplacement(); break; default: Append(c); break; } c = GetNext(); } } private ref StructHtmlToken RCDataLt(char c) { if (c == '/') { c = GetNext(); if (c.IsUppercaseAscii()) { Append(char.ToLowerInvariant(c)); return ref RCDataNameEndTag(GetNext()); } if (c.IsLowercaseAscii()) { Append(c); return ref RCDataNameEndTag(GetNext()); } Append('<', '/'); return ref RCDataText(c); } Append('<'); return ref RCDataText(c); } private ref StructHtmlToken RCDataNameEndTag(char c) { while (true) { if (CreateIfAppropriate(c, ref _token)) { return ref _token; } if (c.IsUppercaseAscii()) { Append(char.ToLowerInvariant(c)); } else { if (!c.IsLowercaseAscii()) { break; } Append(c); } c = GetNext(); } base.CharBuffer.Insert(0, '<').Insert(1, '/'); return ref RCDataText(c); } private ref StructHtmlToken Rawtext(char c) { if (c != '<') { return ref RawtextText(c); } return ref RawtextLT(GetNext()); } private ref StructHtmlToken RawtextText(char c) { while (true) { switch (c) { case '<': case '\uffff': Back(); if (SkipRawText) { return ref NewSkippedContent(); } return ref NewCharacter(); case '\0': AppendReplacement(); break; default: Append(c); break; } c = GetNext(); } } private ref StructHtmlToken RawtextLT(char c) { if (c == '/') { c = GetNext(); if (c.IsUppercaseAscii()) { Append(char.ToLowerInvariant(c)); return ref RawtextNameEndTag(GetNext()); } if (c.IsLowercaseAscii()) { Append(c); return ref RawtextNameEndTag(GetNext()); } Append('<', '/'); return ref RawtextText(c); } Append('<'); return ref RawtextText(c); } private ref StructHtmlToken RawtextNameEndTag(char c) { while (true) { if (CreateIfAppropriate(c, ref _token)) { return ref _token; } if (c.IsUppercaseAscii()) { Append(char.ToLowerInvariant(c)); } else { if (!c.IsLowercaseAscii()) { break; } Append(c); } c = GetNext(); } base.CharBuffer.Insert(0, '<').Insert(1, '/'); return ref RawtextText(c); } private ref StructHtmlToken CharacterData(char c) { while (true) { switch (c) { case '\uffff': Back(); break; case ']': if (!ContinuesWithSensitive("]]>")) { goto IL_002b; } Advance(2); break; default: goto IL_002b; } break; IL_002b: Append(c); c = GetNext(); } if (SkipCDATA) { return ref NewSkippedContent(); } return ref NewCharacter(); } private void AppendCharacterReference(char c, char allowedCharacter = '\0', bool isAttribute = false) { if (IsNotConsumingCharacterReferences || c.IsSpaceCharacter() || c == '<' || c == '\uffff' || c == '&' || c == allowedCharacter) { Back(); Append('&'); return; } string text = null; text = ((c != '#') ? GetLookupCharacterReference(allowedCharacter, isAttribute) : GetNumericCharacterReference(GetNext(), isAttribute)); if (text == null) { Append('&'); } else { base.CharBuffer.Append(text.AsSpan()); } } private string? GetNumericCharacterReference(char c, bool isAttribute) { int num = 10; int num2 = 1; int num3 = 0; List list = new List(); bool flag = c == 'x' || c == 'X'; if (flag) { num = 16; while ((c = GetNext()).IsHex()) { list.Add(c.FromHex()); } } else { while (c.IsDigit()) { list.Add(c.FromHex()); c = GetNext(); } } for (int num4 = list.Count - 1; num4 >= 0; num4--) { num3 += list[num4] * num2; num2 *= num; } if (list.Count == 0) { Back(2); if (flag) { Back(); } if (!isAttribute) { RaiseErrorOccurred(HtmlParseError.CharacterReferenceWrongNumber); } return null; } if (c != ';') { RaiseErrorOccurred(HtmlParseError.CharacterReferenceSemicolonMissing); Back(); } if (HtmlEntityProvider.IsInCharacterTable(num3)) { RaiseErrorOccurred(HtmlParseError.CharacterReferenceInvalidCode); return HtmlEntityProvider.GetSymbolFromTable(num3); } if (HtmlEntityProvider.IsInvalidNumber(num3)) { RaiseErrorOccurred(HtmlParseError.CharacterReferenceInvalidNumber); return '\ufffd'.ToString(); } if (HtmlEntityProvider.IsInInvalidRange(num3)) { RaiseErrorOccurred(HtmlParseError.CharacterReferenceInvalidRange); } return char.ConvertFromUtf32(num3); } private string? GetLookupCharacterReference(char allowedCharacter, bool isAttribute) { string text = null; int insertionPoint = base.InsertionPoint - 1; if (_characterReferenceBuffer == null) { _characterReferenceBuffer = new char[32]; } int num = 0; char c = base.Current; while (c != ';' && c.IsName()) { _characterReferenceBuffer[num++] = c; c = GetNext(); if (c == '\uffff' || num >= 31) { break; } } if (c == ';') { _characterReferenceBuffer[num] = ';'; text = _resolver.GetSymbol(new StringOrMemory(_characterReferenceBuffer.AsMemory(0, num + 1))); } while (text == null && num > 0) { text = _resolver.GetSymbol(new StringOrMemory(_characterReferenceBuffer.AsMemory(0, num--))); if (text == null) { Back(); } } c = base.Current; if (c != ';') { if (allowedCharacter != 0 && (c == '=' || c.IsAlphanumericAscii())) { if (c == '=') { RaiseErrorOccurred(HtmlParseError.CharacterReferenceAttributeEqualsFound); } base.InsertionPoint = insertionPoint; return null; } Back(); if (!isAttribute) { RaiseErrorOccurred(HtmlParseError.CharacterReferenceNotTerminated); } } return text; } private ref StructHtmlToken TagOpen(char c) { if (c == '/') { return ref TagEnd(GetNext()); } if (c.IsLowercaseAscii()) { Append(c); return ref TagName(ref NewTagOpen()); } if (c.IsUppercaseAscii()) { Append(char.ToLowerInvariant(c)); return ref TagName(ref NewTagOpen()); } switch (c) { case '!': return ref MarkupDeclaration(GetNext()); case '?': if (IsSupportingProcessingInstructions) { return ref ProcessingInstruction(c); } break; } if (c != '?') { State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.AmbiguousOpenTag); Append('<'); return ref DataText(c); } RaiseErrorOccurred(HtmlParseError.BogusComment); return ref BogusComment(c); } private ref StructHtmlToken TagEnd(char c) { if (c.IsLowercaseAscii()) { Append(c); return ref TagName(ref NewTagClose()); } if (c.IsUppercaseAscii()) { Append(char.ToLowerInvariant(c)); return ref TagName(ref NewTagClose()); } switch (c) { case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); return ref Data(GetNext()); case '\uffff': Back(); RaiseErrorOccurred(HtmlParseError.EOF); Append('<', '/'); return ref NewCharacter(); default: RaiseErrorOccurred(HtmlParseError.BogusComment); return ref BogusComment(c); } } private ref StructHtmlToken TagName(ref StructHtmlToken tag) { while (true) { char next = GetNext(); if (next == '>') { tag.Name = FlushBufferFast(HtmlTagNameLookup.TryGetWellKnownTagName); return ref EmitTag(ref tag); } if (next.IsSpaceCharacter()) { tag.Name = FlushBufferFast(HtmlTagNameLookup.TryGetWellKnownTagName); return ref ParseAttributes(ref tag); } if (next == '/') { break; } if (next.IsUppercaseAscii()) { Append(char.ToLowerInvariant(next)); continue; } switch (next) { case '\0': AppendReplacement(); break; default: Append(next); break; case '\uffff': return ref NewEof(); } } tag.Name = FlushBufferFast(HtmlTagNameLookup.TryGetWellKnownTagName); return ref TagSelfClosing(ref tag); } private ref StructHtmlToken TagSelfClosing(ref StructHtmlToken tag) { if (TagSelfClosingInner(ref tag)) { return ref tag; } return ref ParseAttributes(ref tag); } private bool TagSelfClosingInner(ref StructHtmlToken tag) { while (true) { switch (GetNext()) { case '>': tag.IsSelfClosing = true; tag = EmitTag(ref tag); return true; case '\uffff': tag = NewEof(); return true; case '/': break; default: RaiseErrorOccurred(HtmlParseError.ClosingSlashMisplaced); Back(); return false; } RaiseErrorOccurred(HtmlParseError.ClosingSlashMisplaced); } } private ref StructHtmlToken MarkupDeclaration(char c) { if (ContinuesWithSensitive("--")) { Advance(); return ref CommentStart(GetNext()); } if (ContinuesWithInsensitive(TagNames.Doctype)) { Advance(6); return ref Doctype(GetNext()); } if (IsAcceptingCharacterData && ContinuesWithSensitive(Keywords.CData)) { Advance(6); return ref CharacterData(GetNext()); } RaiseErrorOccurred(HtmlParseError.UndefinedMarkupDeclaration); return ref BogusComment(c); } private ref StructHtmlToken ProcessingInstruction(char c) { base.CharBuffer.Discard(); while (true) { switch (c) { case '\uffff': Back(); break; case '\0': c = '\ufffd'; goto IL_002a; default: goto IL_002a; case '>': break; } break; IL_002a: Append(c); c = GetNext(); } State = HtmlParseMode.PCData; return ref NewProcessingInstruction(); } private ref StructHtmlToken BogusComment(char c) { base.CharBuffer.Discard(); while (true) { switch (c) { case '\uffff': Back(); break; case '\0': c = '\ufffd'; goto IL_002a; default: goto IL_002a; case '>': break; } break; IL_002a: Append(c); c = GetNext(); } State = HtmlParseMode.PCData; return ref NewComment(); } private ref StructHtmlToken CommentStart(char c) { base.CharBuffer.Discard(); switch (c) { case '-': if (CommentDashStart(GetNext(), ref _token)) { return ref _token; } return ref Comment(GetNext()); case '\0': AppendReplacement(); return ref Comment(GetNext()); case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); break; default: Append(c); return ref Comment(GetNext()); } return ref NewComment(); } private bool CommentDashStart(char c, ref StructHtmlToken token) { switch (c) { case '-': return CommentEnd(GetNext(), ref token); case '\0': RaiseErrorOccurred(HtmlParseError.Null); Append('-', '\ufffd'); token = ref Comment(GetNext()); return true; case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); break; default: Append('-', c); token = ref Comment(GetNext()); return true; } token = NewComment(); return true; } private ref StructHtmlToken Comment(char c) { while (true) { switch (c) { case '-': if (CommentDashEnd(GetNext(), ref _token)) { return ref _token; } break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); return ref NewComment(); case '\0': AppendReplacement(); break; default: Append(c); break; } c = GetNext(); } } private bool CommentDashEnd(char c, ref StructHtmlToken token) { switch (c) { case '-': return CommentEnd(GetNext(), ref token); case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); token = NewComment(); return true; case '\0': RaiseErrorOccurred(HtmlParseError.Null); c = '\ufffd'; break; } Append('-', c); return false; } private bool CommentEnd(char c, ref StructHtmlToken token) { while (true) { switch (c) { case '>': State = HtmlParseMode.PCData; token = NewComment(); return true; case '\0': RaiseErrorOccurred(HtmlParseError.Null); Append('-', '\ufffd'); return false; case '!': RaiseErrorOccurred(HtmlParseError.CommentEndedWithEM); return CommentBangEnd(GetNext(), ref token); case '-': break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); token = NewComment(); return true; default: RaiseErrorOccurred(HtmlParseError.CommentEndedUnexpected); Append('-', '-', c); return false; } RaiseErrorOccurred(HtmlParseError.CommentEndedWithDash); Append('-'); c = GetNext(); } } private bool CommentBangEnd(char c, ref StructHtmlToken token) { switch (c) { case '-': Append('-', '-', '!'); return CommentDashEnd(GetNext(), ref token); case '>': State = HtmlParseMode.PCData; break; case '\0': RaiseErrorOccurred(HtmlParseError.Null); Append('-', '-', '!', '\ufffd'); return false; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); break; default: Append('-', '-', '!', c); return false; } token = NewComment(); return true; } private ref StructHtmlToken Doctype(char c) { if (c.IsSpaceCharacter()) { return ref DoctypeNameBefore(GetNext()); } if (c == '\uffff') { RaiseErrorOccurred(HtmlParseError.EOF); Back(); return ref NewDoctype(quirksForced: true); } RaiseErrorOccurred(HtmlParseError.DoctypeUnexpected); return ref DoctypeNameBefore(c); } private ref StructHtmlToken DoctypeNameBefore(char c) { while (c.IsSpaceCharacter()) { c = GetNext(); } if (c.IsUppercaseAscii()) { ref StructHtmlToken doctype = ref NewDoctype(quirksForced: false); Append(char.ToLowerInvariant(c)); return ref DoctypeName(ref doctype); } switch (c) { case '\0': { ref StructHtmlToken doctype3 = ref NewDoctype(quirksForced: false); AppendReplacement(); return ref DoctypeName(ref doctype3); } case '>': { ref StructHtmlToken result2 = ref NewDoctype(quirksForced: true); State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); return ref result2; } case '\uffff': { ref StructHtmlToken result = ref NewDoctype(quirksForced: true); RaiseErrorOccurred(HtmlParseError.EOF); Back(); return ref result; } default: { ref StructHtmlToken doctype2 = ref NewDoctype(quirksForced: false); Append(c); return ref DoctypeName(ref doctype2); } } } private ref StructHtmlToken DoctypeName(ref StructHtmlToken doctype) { while (true) { char next = GetNext(); if (next.IsSpaceCharacter()) { doctype.Name = FlushBufferFast(); return ref DoctypeNameAfter(ref doctype); } if (next == '>') { State = HtmlParseMode.PCData; doctype.Name = FlushBufferFast(); break; } if (next.IsUppercaseAscii()) { Append(char.ToLowerInvariant(next)); continue; } switch (next) { case '\0': AppendReplacement(); continue; case '\uffff': break; default: Append(next); continue; } RaiseErrorOccurred(HtmlParseError.EOF); Back(); doctype.IsQuirksForced = true; doctype.Name = FlushBufferFast(); break; } return ref doctype; } private ref StructHtmlToken DoctypeNameAfter(ref StructHtmlToken doctype) { switch (SkipSpaces()) { case '>': State = HtmlParseMode.PCData; break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); doctype.IsQuirksForced = true; break; default: if (ContinuesWithInsensitive(Keywords.Public)) { Advance(5); return ref DoctypePublic(ref doctype); } if (ContinuesWithInsensitive(Keywords.System)) { Advance(5); return ref DoctypeSystem(ref doctype); } RaiseErrorOccurred(HtmlParseError.DoctypeUnexpectedAfterName); doctype.IsQuirksForced = true; return ref BogusDoctype(ref doctype); } return ref doctype; } private ref StructHtmlToken DoctypePublic(ref StructHtmlToken doctype) { char next = GetNext(); if (next.IsSpaceCharacter()) { return ref DoctypePublicIdentifierBefore(ref doctype); } switch (next) { case '"': RaiseErrorOccurred(HtmlParseError.DoubleQuotationMarkUnexpected); doctype.PublicIdentifier = StringOrMemory.Empty; return ref DoctypePublicIdentifierDoubleQuoted(ref doctype); case '\'': RaiseErrorOccurred(HtmlParseError.SingleQuotationMarkUnexpected); doctype.PublicIdentifier = StringOrMemory.Empty; return ref DoctypePublicIdentifierSingleQuoted(ref doctype); case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); doctype.IsQuirksForced = true; break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; Back(); break; default: RaiseErrorOccurred(HtmlParseError.DoctypePublicInvalid); doctype.IsQuirksForced = true; return ref BogusDoctype(ref doctype); } return ref doctype; } private ref StructHtmlToken DoctypePublicIdentifierBefore(ref StructHtmlToken doctype) { switch (SkipSpaces()) { case '"': doctype.PublicIdentifier = StringOrMemory.Empty; return ref DoctypePublicIdentifierDoubleQuoted(ref doctype); case '\'': doctype.PublicIdentifier = StringOrMemory.Empty; return ref DoctypePublicIdentifierSingleQuoted(ref doctype); case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); doctype.IsQuirksForced = true; break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; Back(); break; default: RaiseErrorOccurred(HtmlParseError.DoctypePublicInvalid); doctype.IsQuirksForced = true; return ref BogusDoctype(ref doctype); } return ref doctype; } private ref StructHtmlToken DoctypePublicIdentifierDoubleQuoted(ref StructHtmlToken doctype) { while (true) { char next = GetNext(); switch (next) { case '"': doctype.PublicIdentifier = FlushBufferFast(); return ref DoctypePublicIdentifierAfter(ref doctype); case '\0': AppendReplacement(); continue; case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); doctype.IsQuirksForced = true; doctype.PublicIdentifier = FlushBufferFast(); break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); doctype.IsQuirksForced = true; doctype.PublicIdentifier = FlushBufferFast(); break; default: Append(next); continue; } break; } return ref doctype; } private ref StructHtmlToken DoctypePublicIdentifierSingleQuoted(ref StructHtmlToken doctype) { while (true) { char next = GetNext(); switch (next) { case '\'': doctype.PublicIdentifier = FlushBufferFast(); return ref DoctypePublicIdentifierAfter(ref doctype); case '\0': AppendReplacement(); continue; case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); doctype.IsQuirksForced = true; doctype.PublicIdentifier = FlushBufferFast(); break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; doctype.PublicIdentifier = FlushBufferFast(); Back(); break; default: Append(next); continue; } break; } return ref doctype; } private ref StructHtmlToken DoctypePublicIdentifierAfter(ref StructHtmlToken doctype) { char next = GetNext(); if (next.IsSpaceCharacter()) { return ref DoctypeBetween(ref doctype); } switch (next) { case '>': State = HtmlParseMode.PCData; break; case '"': RaiseErrorOccurred(HtmlParseError.DoubleQuotationMarkUnexpected); doctype.SystemIdentifier = StringOrMemory.Empty; return ref DoctypeSystemIdentifierDoubleQuoted(ref doctype); case '\'': RaiseErrorOccurred(HtmlParseError.SingleQuotationMarkUnexpected); doctype.SystemIdentifier = StringOrMemory.Empty; return ref DoctypeSystemIdentifierSingleQuoted(ref doctype); case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; Back(); break; default: RaiseErrorOccurred(HtmlParseError.DoctypeInvalidCharacter); doctype.IsQuirksForced = true; return ref BogusDoctype(ref doctype); } return ref doctype; } private ref StructHtmlToken DoctypeBetween(ref StructHtmlToken doctype) { switch (SkipSpaces()) { case '>': State = HtmlParseMode.PCData; break; case '"': doctype.SystemIdentifier = StringOrMemory.Empty; return ref DoctypeSystemIdentifierDoubleQuoted(ref doctype); case '\'': doctype.SystemIdentifier = StringOrMemory.Empty; return ref DoctypeSystemIdentifierSingleQuoted(ref doctype); case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; Back(); break; default: RaiseErrorOccurred(HtmlParseError.DoctypeInvalidCharacter); doctype.IsQuirksForced = true; return ref BogusDoctype(ref doctype); } return ref doctype; } private ref StructHtmlToken DoctypeSystem(ref StructHtmlToken doctype) { char next = GetNext(); if (next.IsSpaceCharacter()) { State = HtmlParseMode.PCData; return ref DoctypeSystemIdentifierBefore(ref doctype); } switch (next) { case '"': RaiseErrorOccurred(HtmlParseError.DoubleQuotationMarkUnexpected); doctype.SystemIdentifier = StringOrMemory.Empty; return ref DoctypeSystemIdentifierDoubleQuoted(ref doctype); case '\'': RaiseErrorOccurred(HtmlParseError.SingleQuotationMarkUnexpected); doctype.SystemIdentifier = StringOrMemory.Empty; return ref DoctypeSystemIdentifierSingleQuoted(ref doctype); case '>': RaiseErrorOccurred(HtmlParseError.TagClosedWrong); doctype.SystemIdentifier = FlushBufferFast(); doctype.IsQuirksForced = true; break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; Back(); break; default: RaiseErrorOccurred(HtmlParseError.DoctypeSystemInvalid); doctype.IsQuirksForced = true; return ref BogusDoctype(ref doctype); } return ref doctype; } private ref StructHtmlToken DoctypeSystemIdentifierBefore(ref StructHtmlToken doctype) { switch (SkipSpaces()) { case '"': doctype.SystemIdentifier = StringOrMemory.Empty; return ref DoctypeSystemIdentifierDoubleQuoted(ref doctype); case '\'': doctype.SystemIdentifier = StringOrMemory.Empty; return ref DoctypeSystemIdentifierSingleQuoted(ref doctype); case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); doctype.IsQuirksForced = true; doctype.SystemIdentifier = FlushBufferFast(); break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; doctype.SystemIdentifier = FlushBufferFast(); Back(); break; default: RaiseErrorOccurred(HtmlParseError.DoctypeInvalidCharacter); doctype.IsQuirksForced = true; return ref BogusDoctype(ref doctype); } return ref doctype; } private ref StructHtmlToken DoctypeSystemIdentifierDoubleQuoted(ref StructHtmlToken doctype) { while (true) { char next = GetNext(); switch (next) { case '"': doctype.SystemIdentifier = FlushBufferFast(); return ref DoctypeSystemIdentifierAfter(ref doctype); case '\0': AppendReplacement(); continue; case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); doctype.IsQuirksForced = true; doctype.SystemIdentifier = FlushBufferFast(); break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; doctype.SystemIdentifier = FlushBufferFast(); Back(); break; default: Append(next); continue; } break; } return ref doctype; } private ref StructHtmlToken DoctypeSystemIdentifierSingleQuoted(ref StructHtmlToken doctype) { while (true) { char next = GetNext(); switch (next) { case '\'': doctype.SystemIdentifier = FlushBufferFast(); return ref DoctypeSystemIdentifierAfter(ref doctype); case '\0': AppendReplacement(); continue; case '>': State = HtmlParseMode.PCData; RaiseErrorOccurred(HtmlParseError.TagClosedWrong); doctype.IsQuirksForced = true; doctype.SystemIdentifier = FlushBufferFast(); break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; doctype.SystemIdentifier = FlushBufferFast(); Back(); break; default: Append(next); continue; } break; } return ref doctype; } private ref StructHtmlToken DoctypeSystemIdentifierAfter(ref StructHtmlToken doctype) { switch (SkipSpaces()) { case '>': State = HtmlParseMode.PCData; break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); doctype.IsQuirksForced = true; Back(); break; default: RaiseErrorOccurred(HtmlParseError.DoctypeInvalidCharacter); return ref BogusDoctype(ref doctype); } return ref doctype; } private ref StructHtmlToken BogusDoctype(ref StructHtmlToken doctype) { while (true) { switch (GetNext()) { default: continue; case '>': State = HtmlParseMode.PCData; break; case '\uffff': Back(); break; } break; } return ref doctype; } private ref StructHtmlToken ParseAttributes(ref StructHtmlToken tag) { AttributeState attributeState = AttributeState.BeforeName; char c = '"'; char c2 = '\0'; TextPosition currentPosition = GetCurrentPosition(); bool flag = false; while (true) { switch (attributeState) { case AttributeState.BeforeName: c2 = SkipSpaces(); switch (c2) { case '/': attributeState = AttributeState.SelfClose; break; case '>': return ref EmitTag(ref tag); default: if (c2.IsUppercaseAscii() && !IsPreservingAttributeNames) { Append(char.ToLowerInvariant(c2)); currentPosition = GetCurrentPosition(); attributeState = AttributeState.Name; break; } switch (c2) { case '\0': AppendReplacement(); currentPosition = GetCurrentPosition(); attributeState = AttributeState.Name; break; case '"': case '\'': case '<': case '=': RaiseErrorOccurred(HtmlParseError.AttributeNameInvalid); Append(c2); currentPosition = GetCurrentPosition(); attributeState = AttributeState.Name; break; default: Append(c2); currentPosition = GetCurrentPosition(); attributeState = AttributeState.Name; break; case '\uffff': return ref NewEof(); } break; } break; case AttributeState.Name: c2 = GetNext(); switch (c2) { case '=': { StringOrMemory name4 = FlushBufferFast(HtmlAttributesLookup.TryGetWellKnownAttributeName); flag = _shouldEmitAttribute(ref tag, name4.Memory); if (flag) { tag.AddAttribute(name4, currentPosition); } attributeState = AttributeState.BeforeValue; break; } case '>': { StringOrMemory name3 = FlushBufferFast(HtmlAttributesLookup.TryGetWellKnownAttributeName); if (_shouldEmitAttribute(ref tag, name3.Memory)) { tag.AddAttribute(name3, currentPosition); } return ref EmitTag(ref tag); } default: if (c2.IsSpaceCharacter()) { StringOrMemory name = FlushBufferFast(HtmlAttributesLookup.TryGetWellKnownAttributeName); flag = _shouldEmitAttribute(ref tag, name.Memory); if (flag) { tag.AddAttribute(name, currentPosition); } attributeState = AttributeState.AfterName; break; } if (c2 == '/') { StringOrMemory name2 = FlushBufferFast(HtmlAttributesLookup.TryGetWellKnownAttributeName); flag = _shouldEmitAttribute(ref tag, name2.Memory); if (flag) { tag.AddAttribute(name2, currentPosition); } attributeState = AttributeState.SelfClose; break; } if (c2.IsUppercaseAscii() && !IsPreservingAttributeNames) { Append(char.ToLowerInvariant(c2)); break; } switch (c2) { case '"': case '\'': case '<': RaiseErrorOccurred(HtmlParseError.AttributeNameInvalid); Append(c2); break; case '\0': AppendReplacement(); break; default: Append(c2); break; case '\uffff': return ref NewEof(); } break; } break; case AttributeState.AfterName: c2 = SkipSpaces(); switch (c2) { case '>': return ref EmitTag(ref tag); case '=': attributeState = AttributeState.BeforeValue; break; case '/': attributeState = AttributeState.SelfClose; break; default: if (c2.IsUppercaseAscii() && !IsPreservingAttributeNames) { Append(char.ToLowerInvariant(c2)); currentPosition = GetCurrentPosition(); attributeState = AttributeState.Name; break; } switch (c2) { case '"': case '\'': case '<': RaiseErrorOccurred(HtmlParseError.AttributeNameInvalid); Append(c2); currentPosition = GetCurrentPosition(); attributeState = AttributeState.Name; break; case '\0': AppendReplacement(); currentPosition = GetCurrentPosition(); attributeState = AttributeState.Name; break; default: Append(c2); currentPosition = GetCurrentPosition(); attributeState = AttributeState.Name; break; case '\uffff': return ref NewEof(); } break; } break; case AttributeState.BeforeValue: c2 = SkipSpaces(); switch (c2) { case '"': case '\'': attributeState = AttributeState.QuotedValue; c = c2; break; case '&': attributeState = AttributeState.UnquotedValue; break; case '>': RaiseErrorOccurred(HtmlParseError.TagClosedWrong); return ref EmitTag(ref tag); case '<': case '=': case '`': RaiseErrorOccurred(HtmlParseError.AttributeValueInvalid); Append(c2); attributeState = AttributeState.UnquotedValue; c2 = GetNext(); break; case '\0': AppendReplacement(); attributeState = AttributeState.UnquotedValue; c2 = GetNext(); break; default: Append(c2); attributeState = AttributeState.UnquotedValue; c2 = GetNext(); break; case '\uffff': return ref NewEof(); } break; case AttributeState.QuotedValue: c2 = GetNext(); if (c2 == c) { if (flag) { StringOrMemory attributeValue3 = FlushBufferFast(); tag.SetAttributeValue(attributeValue3); } else { base.CharBuffer.Discard(); } attributeState = AttributeState.AfterValue; break; } switch (c2) { case '&': AppendCharacterReference(GetNext(), c, isAttribute: true); break; case '\0': AppendReplacement(); break; default: Append(c2); break; case '\uffff': return ref NewEof(); } break; case AttributeState.UnquotedValue: if (c2 == '>') { if (flag) { StringOrMemory attributeValue = FlushBufferFast(); tag.SetAttributeValue(attributeValue); } else { base.CharBuffer.Discard(); } return ref EmitTag(ref tag); } if (c2.IsSpaceCharacter()) { if (flag) { StringOrMemory attributeValue2 = FlushBufferFast(); tag.SetAttributeValue(attributeValue2); } else { base.CharBuffer.Discard(); } attributeState = AttributeState.BeforeName; break; } switch (c2) { case '&': AppendCharacterReference(GetNext(), '>', isAttribute: true); c2 = GetNext(); break; case '\0': AppendReplacement(); c2 = GetNext(); break; case '"': case '\'': case '<': case '=': case '`': RaiseErrorOccurred(HtmlParseError.AttributeValueInvalid); Append(c2); c2 = GetNext(); break; default: Append(c2); c2 = GetNext(); break; case '\uffff': return ref NewEof(); } break; case AttributeState.AfterValue: c2 = GetNext(); if (c2 == '>') { return ref EmitTag(ref tag); } if (c2.IsSpaceCharacter()) { attributeState = AttributeState.BeforeName; break; } switch (c2) { case '/': attributeState = AttributeState.SelfClose; break; case '\uffff': return ref NewEof(); default: RaiseErrorOccurred(HtmlParseError.AttributeNameExpected); Back(); attributeState = AttributeState.BeforeName; break; } break; case AttributeState.SelfClose: if (!TagSelfClosingInner(ref tag)) { attributeState = AttributeState.BeforeName; break; } return ref tag; } } } private ref StructHtmlToken ScriptData(char c) { int length = _lastStartTag.Length; int length2 = TagNames.Script.Length; ScriptState scriptState = ScriptState.Normal; int num = 0; while (true) { switch (scriptState) { case ScriptState.Normal: switch (c) { case '\0': AppendReplacement(); break; case '<': Append('<'); scriptState = ScriptState.OpenTag; goto end_IL_001c; case '\uffff': Back(); if (SkipScriptText) { return ref NewSkippedContent(); } return ref NewCharacter(); default: Append(c); break; } c = GetNext(); break; case ScriptState.OpenTag: c = GetNext(); scriptState = c switch { '/' => ScriptState.EndTag, '!' => ScriptState.StartEscape, _ => ScriptState.Normal, }; break; case ScriptState.StartEscape: Append('!'); c = GetNext(); scriptState = ((c == '-') ? ScriptState.StartEscapeDash : ScriptState.Normal); break; case ScriptState.StartEscapeDash: c = GetNext(); Append('-'); if (c == '-') { Append('-'); scriptState = ScriptState.EscapedDashDash; } else { scriptState = ScriptState.Normal; } break; case ScriptState.EndTag: { c = GetNext(); Append('/'); num = base.CharBuffer.Length; ref StructHtmlToken reference = ref NewTagClose(); while (c.IsLetter()) { Append(c); c = GetNext(); bool flag = c.IsSpaceCharacter(); bool flag2 = c == '>'; bool flag3 = c == '/'; if (base.CharBuffer.Length - num != length || !(flag || flag2 || flag3) || !base.CharBuffer.HasTextAt(_lastStartTag.Memory.Span, num, length, StringComparison.OrdinalIgnoreCase)) { continue; } if (num > 2) { Back(3 + length); base.CharBuffer.Remove(num - 2, length + 2); if (SkipScriptText) { return ref NewSkippedContent(); } return ref NewCharacter(); } base.CharBuffer.Discard(); if (flag) { reference.Name = _lastStartTag; return ref ParseAttributes(ref reference); } if (flag3) { reference.Name = _lastStartTag; return ref TagSelfClosing(ref reference); } if (flag2) { reference.Name = _lastStartTag; return ref EmitTag(ref reference); } } scriptState = ScriptState.Normal; break; } case ScriptState.Escaped: switch (c) { case '-': Append('-'); c = GetNext(); scriptState = ScriptState.EscapedDash; break; case '<': c = GetNext(); scriptState = ScriptState.EscapedOpenTag; break; case '\0': AppendReplacement(); c = GetNext(); break; case '\uffff': Back(); if (SkipScriptText) { return ref NewSkippedContent(); } return ref NewCharacter(); default: scriptState = ScriptState.Normal; break; } break; case ScriptState.EscapedDash: switch (c) { case '-': Append('-'); scriptState = ScriptState.EscapedDashDash; goto end_IL_001c; case '<': c = GetNext(); scriptState = ScriptState.EscapedOpenTag; goto end_IL_001c; case '\0': AppendReplacement(); break; case '\uffff': Back(); if (SkipScriptText) { return ref NewSkippedContent(); } return ref NewCharacter(); default: Append(c); break; } c = GetNext(); scriptState = ScriptState.Escaped; break; case ScriptState.EscapedDashDash: c = GetNext(); switch (c) { case '-': Append('-'); break; case '<': c = GetNext(); scriptState = ScriptState.EscapedOpenTag; break; case '>': Append('>'); c = GetNext(); scriptState = ScriptState.Normal; break; case '\0': AppendReplacement(); c = GetNext(); scriptState = ScriptState.Escaped; break; case '\uffff': if (SkipScriptText) { return ref NewSkippedContent(); } return ref NewCharacter(); default: Append(c); c = GetNext(); scriptState = ScriptState.Escaped; break; } break; case ScriptState.EscapedOpenTag: if (c == '/') { c = GetNext(); scriptState = ScriptState.EscapedEndTag; } else if (c.IsLetter()) { Append('<'); num = base.CharBuffer.Length; Append(c); scriptState = ScriptState.StartDoubleEscape; } else { Append('<'); scriptState = ScriptState.Escaped; } break; case ScriptState.EscapedEndTag: Append('<', '/'); num = base.CharBuffer.Length; if (c.IsLetter()) { Append(c); scriptState = ScriptState.EscapedNameEndTag; } else { scriptState = ScriptState.Escaped; } break; case ScriptState.EscapedNameEndTag: c = GetNext(); if (base.CharBuffer.Length - num == length2 && (c == '/' || c == '>' || c.IsSpaceCharacter())) { if (base.CharBuffer.Isi(num, length2, TagNames.Script.AsSpan())) { Back(length2 + 3); base.CharBuffer.Remove(num - 2, length2 + 2); if (SkipScriptText) { return ref NewSkippedContent(); } return ref NewCharacter(); } } else if (!c.IsLetter()) { scriptState = ScriptState.Escaped; } else { Append(c); } break; case ScriptState.StartDoubleEscape: c = GetNext(); if (base.CharBuffer.Length - num == length2 && (c == '/' || c == '>' || c.IsSpaceCharacter())) { bool num3 = base.CharBuffer.Isi(num, length2, TagNames.Script.AsSpan()); Append(c); c = GetNext(); scriptState = (num3 ? ScriptState.EscapedDouble : ScriptState.Escaped); } else if (c.IsLetter()) { Append(c); } else { scriptState = ScriptState.Escaped; } break; case ScriptState.EscapedDouble: switch (c) { case '-': Append('-'); c = GetNext(); scriptState = ScriptState.EscapedDoubleDash; break; case '<': Append('<'); c = GetNext(); scriptState = ScriptState.EscapedDoubleOpenTag; break; case '\0': AppendReplacement(); c = GetNext(); break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); if (SkipScriptText) { return ref NewSkippedContent(); } return ref NewCharacter(); default: Append(c); c = GetNext(); break; } break; case ScriptState.EscapedDoubleDash: switch (c) { case '-': Append('-'); scriptState = ScriptState.EscapedDoubleDashDash; goto end_IL_001c; case '<': Append('<'); c = GetNext(); scriptState = ScriptState.EscapedDoubleOpenTag; goto end_IL_001c; case '\0': RaiseErrorOccurred(HtmlParseError.Null); c = '\ufffd'; break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); if (SkipScriptText) { return ref NewSkippedContent(); } return ref NewCharacter(); } scriptState = ScriptState.EscapedDouble; break; case ScriptState.EscapedDoubleDashDash: c = GetNext(); switch (c) { case '-': Append('-'); break; case '<': Append('<'); c = GetNext(); scriptState = ScriptState.EscapedDoubleOpenTag; break; case '>': Append('>'); c = GetNext(); scriptState = ScriptState.Normal; break; case '\0': AppendReplacement(); c = GetNext(); scriptState = ScriptState.EscapedDouble; break; case '\uffff': RaiseErrorOccurred(HtmlParseError.EOF); Back(); if (SkipScriptText) { return ref NewSkippedContent(); } return ref NewCharacter(); default: Append(c); c = GetNext(); scriptState = ScriptState.EscapedDouble; break; } break; case ScriptState.EscapedDoubleOpenTag: if (c == '/') { Append('/'); num = base.CharBuffer.Length; scriptState = ScriptState.EndDoubleEscape; } else { scriptState = ScriptState.EscapedDouble; } break; case ScriptState.EndDoubleEscape: { c = GetNext(); if (base.CharBuffer.Length - num == length2 && (c.IsSpaceCharacter() || c == '/' || c == '>')) { bool num2 = base.CharBuffer.Isi(num, length2, TagNames.Script.AsSpan()); Append(c); c = GetNext(); scriptState = (num2 ? ScriptState.Escaped : ScriptState.EscapedDouble); } else if (c.IsLetter()) { Append(c); } else { scriptState = ScriptState.EscapedDouble; } break; } end_IL_001c: break; } } } private ref StructHtmlToken NewSkippedContent(HtmlTokenType htmlTokenType = HtmlTokenType.Character) { base.CharBuffer.Discard(); _token = StructHtmlToken.Skipped(htmlTokenType, _position); return ref _token; } private ref StructHtmlToken NewCharacter() { StringOrMemory name = FlushBufferFast(); _token = StructHtmlToken.Character(name, _position); return ref _token; } private ref StructHtmlToken NewProcessingInstruction() { if (SkipProcessingInstructions) { return ref NewSkippedContent(HtmlTokenType.Comment); } StringOrMemory name = FlushBufferFast(); _token = StructHtmlToken.ProcessingInstruction(name, _position); return ref _token; } private ref StructHtmlToken NewComment() { if (SkipComments) { return ref NewSkippedContent(HtmlTokenType.Comment); } StringOrMemory name = FlushBufferFast(); _token = StructHtmlToken.Comment(name, _position); return ref _token; } private ref StructHtmlToken NewEof(bool acceptable = false) { if (!acceptable) { RaiseErrorOccurred(HtmlParseError.EOF); } _token = StructHtmlToken.EndOfFile(_position); return ref _token; } private ref StructHtmlToken NewDoctype(bool quirksForced) { _token = StructHtmlToken.Doctype(quirksForced, _position); return ref _token; } private ref StructHtmlToken NewTagOpen() { _token = StructHtmlToken.TagOpen(_position); return ref _token; } private ref StructHtmlToken NewTagClose() { _token = StructHtmlToken.TagClose(_position); return ref _token; } private void RaiseErrorOccurred(HtmlParseError code) { RaiseErrorOccurred(code, GetCurrentPosition()); } private void AppendReplacement() { RaiseErrorOccurred(HtmlParseError.Null); Append('\ufffd'); } private bool CreateIfAppropriate(char c, ref StructHtmlToken token) { bool flag = c.IsSpaceCharacter(); bool flag2 = c == '>'; bool flag3 = c == '/'; if (base.CharBuffer.Length == _lastStartTag.Length && (flag || flag2 || flag3) && base.CharBuffer.Is(_lastStartTag)) { ref StructHtmlToken reference = ref NewTagClose(); base.CharBuffer.Discard(); if (flag) { reference.Name = _lastStartTag; token = ParseAttributes(ref reference); return true; } if (flag3) { reference.Name = _lastStartTag; token = TagSelfClosing(ref reference); return true; } if (flag2) { reference.Name = _lastStartTag; token = EmitTag(ref reference); return true; } } return false; } private ref StructHtmlToken EmitTag(ref StructHtmlToken tag) { StructAttributes attributes = tag.Attributes; State = HtmlParseMode.PCData; switch (tag.Type) { case HtmlTokenType.StartTag: { for (int num = attributes.Count - 1; num > 0; num--) { for (int num2 = num - 1; num2 >= 0; num2--) { if (attributes[num2].Name.Is(attributes[num].Name)) { tag.RemoveAttributeAt(num); RaiseErrorOccurred(HtmlParseError.AttributeDuplicateOmitted, tag.Position); break; } } } _lastStartTag = tag.Name; break; } case HtmlTokenType.EndTag: if (tag.IsSelfClosing) { RaiseErrorOccurred(HtmlParseError.EndTagCannotBeSelfClosed, tag.Position); } if (attributes.Count != 0) { RaiseErrorOccurred(HtmlParseError.EndTagCannotHaveAttributes, tag.Position); } break; } return ref tag; } } public struct HtmlTokenizerOptions { public bool DisableElementPositionTracking { get; set; } public bool SkipComments { get; set; } public bool SkipPlaintext { get; set; } public bool SkipRCDataText { get; set; } public bool SkipCDATA { get; set; } public bool SkipProcessingInstructions { get; set; } public ShouldEmitAttribute ShouldEmitAttribute { get; set; } public bool SkipDataText { get; set; } public bool SkipScriptText { get; set; } public bool SkipRawText { get; set; } public bool IsPreservingAttributeNames { get; set; } public bool IsNotConsumingCharacterReferences { get; set; } public bool IsSupportingProcessingInstructions { get; set; } public bool IsStrictMode { get; set; } public HtmlTokenizerOptions(HtmlParserOptions htmlParserOptions) { IsStrictMode = htmlParserOptions.IsStrictMode; IsSupportingProcessingInstructions = htmlParserOptions.IsSupportingProcessingInstructions; IsNotConsumingCharacterReferences = htmlParserOptions.IsNotConsumingCharacterReferences; IsPreservingAttributeNames = htmlParserOptions.IsPreservingAttributeNames; SkipRawText = htmlParserOptions.SkipRawText; SkipScriptText = htmlParserOptions.SkipScriptText; SkipDataText = htmlParserOptions.SkipDataText; ShouldEmitAttribute = htmlParserOptions.ShouldEmitAttribute ?? ((ShouldEmitAttribute)delegate { return true; }); SkipDataText = htmlParserOptions.SkipDataText; SkipScriptText = htmlParserOptions.SkipScriptText; SkipRawText = htmlParserOptions.SkipRawText; SkipComments = htmlParserOptions.SkipComments; SkipPlaintext = htmlParserOptions.SkipPlaintext; SkipRCDataText = htmlParserOptions.SkipRCDataText; SkipCDATA = htmlParserOptions.SkipCDATA; SkipProcessingInstructions = htmlParserOptions.SkipProcessingInstructions; DisableElementPositionTracking = htmlParserOptions.DisableElementPositionTracking; } } public enum HtmlTokenType : byte { Doctype, StartTag, EndTag, Comment, Character, EndOfFile } internal enum HtmlTreeMode : byte { Initial, BeforeHtml, BeforeHead, InHead, InHeadNoScript, AfterHead, InBody, Text, InTable, InCaption, InColumnGroup, InTableBody, InRow, InCell, InSelect, InSelectInTable, InTemplate, AfterBody, InFrameset, AfterFrameset, AfterAfterBody, AfterAfterFrameset } public interface IHtmlParser : IParser, IEventTarget { IHtmlDocument ParseDocument(string source); IHtmlDocument ParseDocument(Stream source); INodeList ParseFragment(string source, IElement contextElement); INodeList ParseFragment(Stream source, IElement contextElement); IHtmlHeadElement? ParseHead(string source); IHtmlHeadElement? ParseHead(Stream source); Task ParseDocumentAsync(string source, CancellationToken cancel); Task ParseDocumentAsync(Stream source, CancellationToken cancel); Task ParseHeadAsync(string source, CancellationToken cancel); Task ParseHeadAsync(Stream source, CancellationToken cancel); Task ParseDocumentAsync(IDocument document, CancellationToken cancel); IHtmlDocument ParseDocument(char[] source, int length = 0); IHtmlDocument ParseDocument(TextSource source); IHtmlDocument ParseDocument(ReadOnlyMemory chars); TDocument ParseDocument(TextSource source, TokenizerMiddleware? middleware = null) where TDocument : class, IConstructableDocument where TElement : class, IConstructableElement; } public static class TokenizerExtensions { public static IEnumerable Tokenize(this TextSource source, IEntityProvider? provider = null, EventHandler? errorHandler = null) { return source.Tokenize(null, provider, errorHandler); } public static IEnumerable Tokenize(this TextSource source, HtmlTokenizerOptions? options = null, IEntityProvider? provider = null, EventHandler? errorHandler = null) { IEntityProvider resolver = provider ?? HtmlEntityProvider.Resolver; using HtmlTokenizer htmlTokenizer = new HtmlTokenizer(source, resolver); if (options.HasValue) { HtmlTokenizerOptions value = options.Value; htmlTokenizer.IsStrictMode = value.IsStrictMode; htmlTokenizer.IsSupportingProcessingInstructions = value.IsSupportingProcessingInstructions; htmlTokenizer.IsNotConsumingCharacterReferences = value.IsNotConsumingCharacterReferences; htmlTokenizer.IsPreservingAttributeNames = value.IsPreservingAttributeNames; htmlTokenizer.SkipRawText = value.SkipRawText; htmlTokenizer.SkipScriptText = value.SkipScriptText; htmlTokenizer.SkipDataText = value.SkipDataText; htmlTokenizer.ShouldEmitAttribute = value.ShouldEmitAttribute; htmlTokenizer.SkipDataText = value.SkipDataText; htmlTokenizer.SkipScriptText = value.SkipScriptText; htmlTokenizer.SkipRawText = value.SkipRawText; htmlTokenizer.SkipComments = value.SkipComments; htmlTokenizer.SkipPlaintext = value.SkipPlaintext; htmlTokenizer.SkipRCDataText = value.SkipRCDataText; htmlTokenizer.SkipCDATA = value.SkipCDATA; htmlTokenizer.SkipProcessingInstructions = value.SkipProcessingInstructions; htmlTokenizer.DisableElementPositionTracking = value.DisableElementPositionTracking; } if (errorHandler != null) { htmlTokenizer.Error += errorHandler; } HtmlToken token; do { token = htmlTokenizer.Get(); yield return token; } while (token.Type != HtmlTokenType.EndOfFile); } } } namespace AngleSharp.Html.Parser.Tokens { public readonly struct HtmlAttributeToken { public string Name { get; } public string Value { get; } public TextPosition Position { get; } public HtmlAttributeToken(TextPosition position, string name, string value) { Position = position; Name = name; Value = value; } } public sealed class HtmlDoctypeToken : HtmlToken { private bool _quirks; private string? _publicIdentifier; private string? _systemIdentifier; public bool IsQuirksForced { get { return _quirks; } set { _quirks = value; } } public bool IsPublicIdentifierMissing => _publicIdentifier == null; public bool IsSystemIdentifierMissing => _systemIdentifier == null; public string PublicIdentifier { get { return _publicIdentifier ?? string.Empty; } set { _publicIdentifier = value; } } public string SystemIdentifier { get { return _systemIdentifier ?? string.Empty; } set { _systemIdentifier = value; } } public bool IsLimitedQuirks { get { string publicIdentifier = PublicIdentifier; string systemIdentifier = SystemIdentifier; if (!publicIdentifier.StartsWith("-//W3C//DTD XHTML 1.0 Frameset//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD XHTML 1.0 Transitional//", StringComparison.OrdinalIgnoreCase) && !systemIdentifier.StartsWith("-//W3C//DTD HTML 4.01 Frameset//", StringComparison.OrdinalIgnoreCase)) { return systemIdentifier.StartsWith("-//W3C//DTD HTML 4.01 Transitional//", StringComparison.OrdinalIgnoreCase); } return true; } } public bool IsFullQuirks { get { string publicIdentifier = PublicIdentifier; if (!IsQuirksForced && base.Name == "html" && !publicIdentifier.StartsWith("+//Silmaril//dtd html Pro v0r11 19970101//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//AdvaSoft Ltd//DTD HTML 3.0 asWedit + extensions//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//AS//DTD HTML 3.0 asWedit + extensions//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Level 1//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Level 2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Strict Level 1//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Strict Level 2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Strict//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.1E//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 3.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 3.2 Final//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 3.2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 3//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Level 0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Level 1//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Level 2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Level 3//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict Level 0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict Level 1//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict Level 2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict Level 3//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Metrius//DTD Metrius Presentational//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 2.0 HTML Strict//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 2.0 HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 2.0 Tables//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 3.0 HTML Strict//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 3.0 HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 3.0 Tables//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Netscape Comm. Corp.//DTD HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Netscape Comm. Corp.//DTD Strict HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//O'Reilly and Associates//DTD HTML 2.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//O'Reilly and Associates//DTD HTML Extended 1.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//O'Reilly and Associates//DTD HTML Extended Relaxed 1.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//SoftQuad Software//DTD HoTMetaL PRO 6.0::19990601::extensions to HTML 4.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//SoftQuad//DTD HoTMetaL PRO 4.0::19971010::extensions to HTML 4.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Spyglass//DTD HTML 2.0 Extended//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//SQ//DTD HTML 2.0 HoTMetaL + extensions//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Sun Microsystems Corp.//DTD HotJava HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Sun Microsystems Corp.//DTD HotJava Strict HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3 1995-03-24//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3.2 Draft//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3.2 Final//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3.2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3.2S Draft//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 4.0 Frameset//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 4.0 Transitional//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML Experimental 19960712//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML Experimental 970421//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD W3 HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3O//DTD W3 HTML 3.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.Isi("-//W3O//DTD W3 HTML Strict 3.0//EN//") && !publicIdentifier.StartsWith("-//WebTechs//DTD Mozilla HTML 2.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//WebTechs//DTD Mozilla HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.Isi("-/W3C/DTD HTML 4.0 Transitional/EN") && !publicIdentifier.Isi("HTML") && !SystemIdentifier.Equals("http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd", StringComparison.OrdinalIgnoreCase) && (!IsSystemIdentifierMissing || !publicIdentifier.StartsWith("-//W3C//DTD HTML 4.01 Frameset//", StringComparison.OrdinalIgnoreCase))) { if (IsSystemIdentifierMissing) { return publicIdentifier.StartsWith("-//W3C//DTD HTML 4.01 Transitional//", StringComparison.OrdinalIgnoreCase); } return false; } return true; } } public bool IsValid { get { if (base.Name == "html") { if (!IsPublicIdentifierMissing) { switch (PublicIdentifier) { case "-//W3C//DTD HTML 4.0//EN": if (!IsSystemIdentifierMissing) { return SystemIdentifier == "http://www.w3.org/TR/REC-html40/strict.dtd"; } return true; case "-//W3C//DTD HTML 4.01//EN": if (!IsSystemIdentifierMissing) { return SystemIdentifier == "http://www.w3.org/TR/html4/strict.dtd"; } return true; case "-//W3C//DTD XHTML 1.0 Strict//EN": return SystemIdentifier == "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"; case "-//W3C//DTD XHTML 1.1//EN": return SystemIdentifier == "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"; } } if (!IsSystemIdentifierMissing) { return SystemIdentifier == "about:legacy-compat"; } return true; } return false; } } public HtmlDoctypeToken(bool quirksForced, TextPosition position) : base(HtmlTokenType.Doctype, position) { _publicIdentifier = null; _systemIdentifier = null; _quirks = quirksForced; } } public sealed class HtmlTagToken : HtmlToken { private readonly List _attributes = new List(); private bool _selfClosing; public bool IsSelfClosing { get { return _selfClosing; } set { _selfClosing = value; } } public List Attributes => _attributes; public HtmlTagToken(HtmlTokenType type, TextPosition position) : this(type, position, string.Empty) { } public HtmlTagToken(HtmlTokenType type, TextPosition position, string name) : base(type, position, name) { } public static HtmlTagToken Open(string name) { return new HtmlTagToken(HtmlTokenType.StartTag, TextPosition.Empty, name); } public static HtmlTagToken Close(string name) { return new HtmlTagToken(HtmlTokenType.EndTag, TextPosition.Empty, name); } public void AddAttribute(string name, TextPosition position) { _attributes.Add(new HtmlAttributeToken(position, name, string.Empty)); } public void AddAttribute(string name, string value) { _attributes.Add(new HtmlAttributeToken(TextPosition.Empty, name, value)); } public void SetAttributeValue(string value) { int index = _attributes.Count - 1; HtmlAttributeToken htmlAttributeToken = _attributes[index]; _attributes[index] = new HtmlAttributeToken(htmlAttributeToken.Position, htmlAttributeToken.Name, value); } public string GetAttribute(string name) { for (int i = 0; i != _attributes.Count; i++) { HtmlAttributeToken htmlAttributeToken = _attributes[i]; if (htmlAttributeToken.Name.Is(name)) { return htmlAttributeToken.Value; } } return string.Empty; } } public class HtmlToken : ISourceReference { private readonly HtmlTokenType _type; private readonly TextPosition _position; private string _name; public bool HasContent { get { for (int i = 0; i < _name.Length; i++) { if (!_name[i].IsSpaceCharacter()) { return true; } } return false; } } public string Name { get { return _name; } set { _name = value; } } public bool IsEmpty => string.IsNullOrEmpty(_name); public string Data => _name; public TextPosition Position => _position; public bool IsHtmlCompatible { get { if (_type != HtmlTokenType.StartTag) { return _type == HtmlTokenType.Character; } return true; } } public bool IsSvg => IsStartTag(TagNames.Svg); public bool IsMathCompatible { get { if (IsStartTag("mglyph") || IsStartTag("malignmark")) { return _type == HtmlTokenType.Character; } return true; } } public HtmlTokenType Type => _type; public bool IsProcessingInstruction { get; internal set; } public HtmlToken(HtmlTokenType type, TextPosition position, string? name = null) { _type = type; _position = position; _name = name; } public string TrimStart() { int i; for (i = 0; i < _name.Length && _name[i].IsSpaceCharacter(); i++) { } string result = _name.Substring(0, i); _name = _name.Substring(i); return result; } public void RemoveNewLine() { if (_name.Has('\n')) { _name = _name.Substring(1); } } public HtmlTagToken AsTag() { return (HtmlTagToken)this; } public bool IsStartTag(string name) { if (_type == HtmlTokenType.StartTag) { return _name.Is(name); } return false; } } } namespace AngleSharp.Html.Parser.Tokens.Struct { public readonly struct MemoryHtmlAttributeToken { public StringOrMemory Name { get; } public StringOrMemory Value { get; } public TextPosition Position { get; } public MemoryHtmlAttributeToken(TextPosition position, StringOrMemory name, StringOrMemory value) { Position = position; Name = name; Value = value; } } public struct StructAttributes { private int _count; private MemoryHtmlAttributeToken _t0; private MemoryHtmlAttributeToken _t1; private MemoryHtmlAttributeToken _t2; private MemoryHtmlAttributeToken _t3; private List _tail; public int Count => _count; public MemoryHtmlAttributeToken this[int id] { get { if (id >= _count) { throw new ArgumentOutOfRangeException("id"); } return id switch { 0 => _t0, 1 => _t1, 2 => _t2, 3 => _t3, _ => _tail[id - 4], }; } set { if (id >= _count) { throw new ArgumentOutOfRangeException("id"); } switch (id) { case 0: _t0 = value; break; case 1: _t1 = value; break; case 2: _t2 = value; break; case 3: _t3 = value; break; default: _tail[id - 4] = value; break; } } } public void Add(MemoryHtmlAttributeToken item) { int count = _count; if (count <= 3) { switch (count) { case 0: _t0 = item; _count = 1; break; case 1: _t1 = item; _count = 2; break; case 2: _t2 = item; _count = 3; break; case 3: _t3 = item; _count = 4; break; } } else { if (_tail == null) { _tail = new List(2); } _tail.Add(item); _count++; } } public void RemoveAt(int index) { if (index > _count) { throw new ArgumentOutOfRangeException("index"); } switch (_count) { case 1: _t0 = default(MemoryHtmlAttributeToken); break; case 2: if (index == 0) { _t0 = _t1; _t1 = default(MemoryHtmlAttributeToken); } else { _t1 = default(MemoryHtmlAttributeToken); } break; case 3: switch (index) { case 0: _t0 = _t1; _t1 = _t2; _t2 = default(MemoryHtmlAttributeToken); break; case 1: _t1 = _t2; _t2 = default(MemoryHtmlAttributeToken); break; default: _t2 = default(MemoryHtmlAttributeToken); break; } break; case 4: switch (index) { case 0: _t0 = _t1; _t1 = _t2; _t2 = _t3; _t3 = default(MemoryHtmlAttributeToken); break; case 1: _t1 = _t2; _t2 = _t3; _t3 = default(MemoryHtmlAttributeToken); break; case 2: _t2 = _t3; _t3 = default(MemoryHtmlAttributeToken); break; default: _t3 = default(MemoryHtmlAttributeToken); break; } break; default: switch (index) { case 0: _t0 = _t1; _t1 = _t2; _t2 = _t3; _t3 = _tail[0]; _tail.RemoveAt(0); break; case 1: _t1 = _t2; _t2 = _t3; _t3 = _tail[0]; _tail.RemoveAt(0); break; case 2: _t2 = _t3; _t3 = _tail[0]; _tail.RemoveAt(0); break; case 3: _t3 = _tail[0]; _tail.RemoveAt(0); break; default: _tail.RemoveAt(index - 4); break; } break; } _count--; } public bool HasAttribute(StringOrMemory name, StringOrMemory value) { for (int i = 0; i < _count; i++) { MemoryHtmlAttributeToken memoryHtmlAttributeToken = this[i]; if (memoryHtmlAttributeToken.Name.Equals(name) && memoryHtmlAttributeToken.Value.Equals(value)) { return true; } } return false; } } public struct StructHtmlToken { private sealed class StructTokenDoctypeData { public bool Quirks { get; set; } public StringOrMemory? PublicIdentifier { get; set; } public StringOrMemory? SystemIdentifier { get; set; } } private readonly HtmlTokenType _type; private readonly TextPosition _position; private StringOrMemory _name; private StructAttributes _attributes; private bool _selfClosing; private StructTokenDoctypeData? _structTokenDoctypeData; private static readonly char[] Spaces = new char[5] { ' ', '\t', '\n', '\r', '\f' }; public bool IsDoctype => _type == HtmlTokenType.Doctype; public bool IsTag { get { HtmlTokenType type = _type; if (type - 1 <= HtmlTokenType.StartTag) { return true; } return false; } } public bool HasContent { get { for (int i = 0; i < _name.Length; i++) { if (!_name[i].IsSpaceCharacter()) { return true; } } return false; } } public StringOrMemory Name { get { return _name; } set { _name = value; } } public bool IsEmpty => _name.Length == 0; public StringOrMemory Data => Name; public TextPosition Position => _position; public bool IsHtmlCompatible { get { if (_type != HtmlTokenType.StartTag) { return _type == HtmlTokenType.Character; } return true; } } public bool IsSvg => IsStartTag(TagNames.Svg); public bool IsMathCompatible { get { if (IsStartTag("mglyph") || IsStartTag("malignmark")) { return _type == HtmlTokenType.Character; } return true; } } public HtmlTokenType Type => _type; public bool IsProcessingInstruction { get; internal set; } public bool IsSelfClosing { get { return _selfClosing; } set { _selfClosing = value; } } public StructAttributes Attributes => _attributes; public bool IsQuirksForced { get { return _structTokenDoctypeData?.Quirks ?? false; } set { if (_structTokenDoctypeData == null) { _structTokenDoctypeData = new StructTokenDoctypeData(); } _structTokenDoctypeData.Quirks = value; } } public bool IsPublicIdentifierMissing { get { StructTokenDoctypeData? structTokenDoctypeData = _structTokenDoctypeData; if (structTokenDoctypeData == null) { return true; } return !structTokenDoctypeData.PublicIdentifier.HasValue; } } public bool IsSystemIdentifierMissing { get { StructTokenDoctypeData? structTokenDoctypeData = _structTokenDoctypeData; if (structTokenDoctypeData == null) { return true; } return !structTokenDoctypeData.SystemIdentifier.HasValue; } } public StringOrMemory PublicIdentifier { get { return (_structTokenDoctypeData?.PublicIdentifier).GetValueOrDefault(); } set { if (_structTokenDoctypeData == null) { _structTokenDoctypeData = new StructTokenDoctypeData(); } _structTokenDoctypeData.PublicIdentifier = value; } } public StringOrMemory SystemIdentifier { get { return (_structTokenDoctypeData?.SystemIdentifier).GetValueOrDefault(); } set { if (_structTokenDoctypeData == null) { _structTokenDoctypeData = new StructTokenDoctypeData(); } _structTokenDoctypeData.SystemIdentifier = value; } } public bool IsLimitedQuirks { get { StringOrMemory publicIdentifier = PublicIdentifier; StringOrMemory systemIdentifier = SystemIdentifier; if (!publicIdentifier.StartsWith("-//W3C//DTD XHTML 1.0 Frameset//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD XHTML 1.0 Transitional//", StringComparison.OrdinalIgnoreCase) && !systemIdentifier.StartsWith("-//W3C//DTD HTML 4.01 Frameset//", StringComparison.OrdinalIgnoreCase)) { return systemIdentifier.StartsWith("-//W3C//DTD HTML 4.01 Transitional//", StringComparison.OrdinalIgnoreCase); } return true; } } public bool IsFullQuirks { get { StringOrMemory publicIdentifier = PublicIdentifier; if (!IsQuirksForced && !(Name != "html") && !publicIdentifier.StartsWith("+//Silmaril//dtd html Pro v0r11 19970101//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//AdvaSoft Ltd//DTD HTML 3.0 asWedit + extensions//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//AS//DTD HTML 3.0 asWedit + extensions//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Level 1//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Level 2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Strict Level 1//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Strict Level 2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0 Strict//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 2.1E//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 3.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 3.2 Final//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 3.2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML 3//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Level 0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Level 1//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Level 2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Level 3//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict Level 0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict Level 1//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict Level 2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict Level 3//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML Strict//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//IETF//DTD HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Metrius//DTD Metrius Presentational//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 2.0 HTML Strict//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 2.0 HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 2.0 Tables//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 3.0 HTML Strict//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 3.0 HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Microsoft//DTD Internet Explorer 3.0 Tables//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Netscape Comm. Corp.//DTD HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Netscape Comm. Corp.//DTD Strict HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//O'Reilly and Associates//DTD HTML 2.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//O'Reilly and Associates//DTD HTML Extended 1.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//O'Reilly and Associates//DTD HTML Extended Relaxed 1.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//SoftQuad Software//DTD HoTMetaL PRO 6.0::19990601::extensions to HTML 4.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//SoftQuad//DTD HoTMetaL PRO 4.0::19971010::extensions to HTML 4.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Spyglass//DTD HTML 2.0 Extended//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//SQ//DTD HTML 2.0 HoTMetaL + extensions//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Sun Microsystems Corp.//DTD HotJava HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//Sun Microsystems Corp.//DTD HotJava Strict HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3 1995-03-24//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3.2 Draft//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3.2 Final//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3.2//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 3.2S Draft//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 4.0 Frameset//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML 4.0 Transitional//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML Experimental 19960712//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD HTML Experimental 970421//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3C//DTD W3 HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//W3O//DTD W3 HTML 3.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.Isi("-//W3O//DTD W3 HTML Strict 3.0//EN//") && !publicIdentifier.StartsWith("-//WebTechs//DTD Mozilla HTML 2.0//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.StartsWith("-//WebTechs//DTD Mozilla HTML//", StringComparison.OrdinalIgnoreCase) && !publicIdentifier.Isi("-/W3C/DTD HTML 4.0 Transitional/EN") && !publicIdentifier.Isi("HTML") && !StringOrMemoryExtensions.Equals(SystemIdentifier, "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd", StringComparison.OrdinalIgnoreCase) && (!IsSystemIdentifierMissing || !publicIdentifier.StartsWith("-//W3C//DTD HTML 4.01 Frameset//", StringComparison.OrdinalIgnoreCase))) { if (IsSystemIdentifierMissing) { return publicIdentifier.StartsWith("-//W3C//DTD HTML 4.01 Transitional//", StringComparison.OrdinalIgnoreCase); } return false; } return true; } } public bool IsValid { get { if (Name == "html") { if (!IsPublicIdentifierMissing) { StringOrMemory publicIdentifier = PublicIdentifier; if (publicIdentifier == "-//W3C//DTD HTML 4.0//EN") { if (!IsSystemIdentifierMissing) { return SystemIdentifier == "http://www.w3.org/TR/REC-html40/strict.dtd"; } return true; } if (publicIdentifier == "-//W3C//DTD HTML 4.01//EN") { if (!IsSystemIdentifierMissing) { return SystemIdentifier == "http://www.w3.org/TR/html4/strict.dtd"; } return true; } if (publicIdentifier == "-//W3C//DTD XHTML 1.0 Strict//EN") { return SystemIdentifier == "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"; } if (publicIdentifier == "-//W3C//DTD XHTML 1.1//EN") { return SystemIdentifier == "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"; } } if (!IsSystemIdentifierMissing) { return SystemIdentifier == "about:legacy-compat"; } return true; } return false; } } private StructHtmlToken(HtmlTokenType type, TextPosition position, StringOrMemory name = default(StringOrMemory)) { _attributes = default(StructAttributes); _selfClosing = false; _structTokenDoctypeData = null; IsProcessingInstruction = false; _type = type; _position = position; _name = name; } internal static StructHtmlToken Skipped(HtmlTokenType htmlTokenType, TextPosition position) { return new StructHtmlToken(htmlTokenType, position); } internal static StructHtmlToken Doctype(bool quirksForced, TextPosition position) { StructHtmlToken result = new StructHtmlToken(HtmlTokenType.Doctype, position); result._structTokenDoctypeData = new StructTokenDoctypeData { Quirks = quirksForced }; return result; } internal static StructHtmlToken TagOpen(TextPosition position) { return new StructHtmlToken(HtmlTokenType.StartTag, position); } internal static StructHtmlToken Open(StringOrMemory name) { return new StructHtmlToken(HtmlTokenType.StartTag, TextPosition.Empty, name); } internal static StructHtmlToken TagClose(TextPosition position) { return new StructHtmlToken(HtmlTokenType.EndTag, position); } internal static StructHtmlToken Close(StringOrMemory s) { return new StructHtmlToken(HtmlTokenType.EndTag, TextPosition.Empty, s); } internal static StructHtmlToken Character(StringOrMemory name, TextPosition position) { return new StructHtmlToken(HtmlTokenType.Character, position, name); } internal static StructHtmlToken Comment(StringOrMemory name, TextPosition position) { return new StructHtmlToken(HtmlTokenType.Comment, position, name); } internal static StructHtmlToken ProcessingInstruction(StringOrMemory name, TextPosition position) { StructHtmlToken result = new StructHtmlToken(HtmlTokenType.Comment, position, name); result.IsProcessingInstruction = true; return result; } internal static StructHtmlToken EndOfFile(TextPosition position) { return new StructHtmlToken(HtmlTokenType.EndOfFile, position); } public StringOrMemory TrimStart() { int i; ReadOnlyMemory memory; for (i = 0; i < _name.Length; i++) { memory = _name.Memory; if (!memory.Span[i].IsSpaceCharacter()) { break; } } memory = _name.Memory; ReadOnlyMemory memory2 = memory.Slice(0, i); memory = _name.Memory; _name = new StringOrMemory(memory.Slice(i)); return new StringOrMemory(memory2); } public void CleanStart() { ReadOnlyMemory memory = _name.Memory.TrimStart(Spaces); if (memory.Length != _name.Length) { _name = new StringOrMemory(memory); } } public void RemoveNewLine() { if (_name.Length > 0 && _name[0] == '\n') { _name = new StringOrMemory(_name.Memory.Slice(1)); } } public bool IsStartTag(string name) { if (_type == HtmlTokenType.StartTag) { return _name.Is(name); } return false; } public void AddAttribute(StringOrMemory name, TextPosition position) { _attributes.Add(new MemoryHtmlAttributeToken(position, name, StringOrMemory.Empty)); } public void AddAttribute(StringOrMemory name, StringOrMemory value) { _attributes.Add(new MemoryHtmlAttributeToken(TextPosition.Empty, name, value)); } public void SetAttributeValue(StringOrMemory value) { int id = _attributes.Count - 1; MemoryHtmlAttributeToken memoryHtmlAttributeToken = _attributes[id]; _attributes[id] = new MemoryHtmlAttributeToken(memoryHtmlAttributeToken.Position, memoryHtmlAttributeToken.Name, value); } public StringOrMemory GetAttribute(StringOrMemory name) { if (_attributes.Count == 0) { return StringOrMemory.Empty; } for (int i = 0; i != _attributes.Count; i++) { MemoryHtmlAttributeToken memoryHtmlAttributeToken = _attributes[i]; if (memoryHtmlAttributeToken.Name.Is(name)) { return memoryHtmlAttributeToken.Value; } } return StringOrMemory.Empty; } public void RemoveAttributeAt(int i) { if (i < _attributes.Count) { _attributes.RemoveAt(i); } } public HtmlToken ToHtmlToken() { switch (Type) { case HtmlTokenType.Doctype: { if (_structTokenDoctypeData == null) { return new HtmlDoctypeToken(quirksForced: false, _position) { IsProcessingInstruction = IsProcessingInstruction, Name = _name.ToString() }; } HtmlDoctypeToken htmlDoctypeToken = new HtmlDoctypeToken(_structTokenDoctypeData.Quirks, _position) { IsProcessingInstruction = IsProcessingInstruction, Name = _name.ToString() }; if (_structTokenDoctypeData.PublicIdentifier.HasValue) { htmlDoctypeToken.PublicIdentifier = _structTokenDoctypeData.PublicIdentifier.Value.ToString(); } if (_structTokenDoctypeData.SystemIdentifier.HasValue) { htmlDoctypeToken.SystemIdentifier = _structTokenDoctypeData.SystemIdentifier.Value.ToString(); } return htmlDoctypeToken; } case HtmlTokenType.StartTag: case HtmlTokenType.EndTag: { HtmlTagToken htmlTagToken = new HtmlTagToken(Type, _position, _name.ToString()) { IsSelfClosing = IsSelfClosing, IsProcessingInstruction = IsProcessingInstruction }; for (int i = 0; i < _attributes.Count; i++) { MemoryHtmlAttributeToken memoryHtmlAttributeToken = _attributes[i]; htmlTagToken.AddAttribute(memoryHtmlAttributeToken.Name.ToString(), memoryHtmlAttributeToken.Position); htmlTagToken.SetAttributeValue(memoryHtmlAttributeToken.Value.ToString()); } return htmlTagToken; } default: return new HtmlToken(Type, _position, _name.ToString()) { IsProcessingInstruction = IsProcessingInstruction }; } } } } namespace AngleSharp.Html.LinkRels { public abstract class BaseLinkRelation { private readonly IHtmlLinkElement _link; private readonly IRequestProcessor _processor; public IRequestProcessor Processor => _processor; public IHtmlLinkElement Link => _link; public Url? Url { get { string href = _link.Href; if (href == null || href.Length <= 0) { return null; } return new Url(_link.Href); } } public BaseLinkRelation(IHtmlLinkElement link, IRequestProcessor processor) { _link = link; _processor = processor; } public abstract Task LoadAsync(); } internal class ImportLinkRelation : BaseLinkRelation { private readonly ConditionalWeakTable> ImportLists = new ConditionalWeakTable>(); private bool _async; public IDocument? Import => (base.Processor as DocumentRequestProcessor)?.ChildDocument; public bool IsAsync => _async; public ImportLinkRelation(IHtmlLinkElement link) : base(link, new DocumentRequestProcessor(link?.Owner.Context)) { } public override Task LoadAsync() { IHtmlLinkElement link = base.Link; IDocument owner = link.Owner; Url url = base.Url; IRequestProcessor processor = base.Processor; if (owner != null && url != null && owner.AddImportUrl(url)) { ResourceRequest request = link.CreateRequestFor(url); _async = link.HasAttribute(AttributeNames.Async); return processor?.ProcessAsync(request); } return Task.CompletedTask; } private bool CheckCycle(IDocument document, Url location) { IDocument document2 = document; HashSet value; while (document2 != null && ImportLists.TryGetValue(document2, out value)) { if (value.Contains(location)) { return true; } document2 = document2.ImportAncestor; } return false; } } internal class StyleSheetLinkRelation : BaseLinkRelation { public IStyleSheet? Sheet => (base.Processor as StyleSheetRequestProcessor)?.Sheet; public StyleSheetLinkRelation(IHtmlLinkElement link) : base(link, new StyleSheetRequestProcessor(link.Owner.Context, link)) { } public override async Task LoadAsync() { if (base.Url != null) { ResourceRequest request = base.Link.CreateRequestFor(base.Url); await base.Processor.ProcessAsync(request).ConfigureAwait(continueOnCapturedContext: false); } } } } namespace AngleSharp.Html.InputTypes { public abstract class BaseInputType { protected static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); protected static readonly Regex NumberPattern = new Regex("^\\-?\\d+(\\.\\d+)?([eE][\\-\\+]?\\d+)?$", RegexOptions.Compiled); private readonly IHtmlInputElement _input; private readonly bool _validate; private readonly string _name; public string Name => _name; public bool CanBeValidated => _validate; public IHtmlInputElement Input => _input; public BaseInputType(IHtmlInputElement input, string name, bool validate) { _input = input; _validate = validate; _name = name; } public virtual bool IsAppendingData(IHtmlElement submitter) { return true; } public virtual ValidationErrors Check(IValidityState current) { return GetErrorsFrom(current); } public virtual double? ConvertToNumber(string? value) { return null; } public virtual string ConvertFromNumber(double value) { throw new DomException(DomError.InvalidState); } public virtual DateTime? ConvertToDate(string value) { return null; } public virtual string ConvertFromDate(DateTime value) { throw new DomException(DomError.InvalidState); } public virtual void ConstructDataSet(FormDataSet dataSet) { dataSet.Append(_input.Name, _input.Value, _input.Type); } public virtual void DoStep(int n) { throw new DomException(DomError.InvalidState); } protected bool IsStepMismatch() { double step = GetStep(); double? num = ConvertToNumber(_input.Value); double stepBase = GetStepBase(); if (step != 0.0) { return (num - stepBase) % step != 0.0; } return false; } protected double GetStep() { string step = _input.Step; if (string.IsNullOrEmpty(step)) { return GetDefaultStep() * GetStepScaleFactor(); } if (step.Isi(Keywords.Any)) { return 0.0; } double? num = ToNumber(step); if (!num.HasValue || num <= 0.0) { return GetDefaultStep() * GetStepScaleFactor(); } return num.Value * GetStepScaleFactor(); } private double GetStepBase() { double? num = ConvertToNumber(_input.Minimum); if (num.HasValue) { return num.Value; } num = ConvertToNumber(_input.DefaultValue); if (num.HasValue) { return num.Value; } return GetDefaultStepBase(); } protected virtual double GetDefaultStepBase() { return 0.0; } protected virtual double GetDefaultStep() { return 1.0; } protected virtual double GetStepScaleFactor() { return 1.0; } protected static ValidationErrors GetErrorsFrom(IValidityState state) { ValidationErrors validationErrors = ValidationErrors.None; if (state.IsBadInput) { validationErrors ^= ValidationErrors.BadInput; } if (state.IsTooShort) { validationErrors ^= ValidationErrors.TooShort; } if (state.IsTooLong) { validationErrors ^= ValidationErrors.TooLong; } if (state.IsValueMissing) { validationErrors ^= ValidationErrors.ValueMissing; } if (state.IsCustomError) { validationErrors ^= ValidationErrors.Custom; } return validationErrors; } protected ValidationErrors CheckTime(IValidityState state, string value, DateTime? date, DateTime? min, DateTime? max) { ValidationErrors validationErrors = (state.IsCustomError ? ValidationErrors.Custom : ValidationErrors.None); if (date.HasValue) { if (min.HasValue && date < min.Value) { validationErrors ^= ValidationErrors.RangeUnderflow; } if (max.HasValue && date > max.Value) { validationErrors ^= ValidationErrors.RangeOverflow; } if (IsStepMismatch()) { validationErrors ^= ValidationErrors.StepMismatch; } } else { if (Input.IsRequired) { validationErrors ^= ValidationErrors.ValueMissing; } if (!string.IsNullOrEmpty(value)) { validationErrors ^= ValidationErrors.BadInput; } } return validationErrors; } protected static bool IsInvalidPattern(string? pattern, string? value) { if (!string.IsNullOrEmpty(pattern) && !string.IsNullOrEmpty(value)) { try { return !new Regex(pattern, RegexOptions.ECMAScript | RegexOptions.CultureInvariant, TimeSpan.FromMilliseconds(100.0)).IsMatch(value); } catch (Exception) { } } return false; } protected static double? ToNumber(string? value) { if (!string.IsNullOrEmpty(value) && NumberPattern.IsMatch(value)) { return double.Parse(value, CultureInfo.InvariantCulture); } return null; } protected static TimeSpan? ToTime(string value, ref int position) { int num = position; int num2 = 0; int milliseconds = 0; if (value.Length >= 5 + num && value[position++].IsDigit() && value[position++].IsDigit() && value[position++] == ':') { int num3 = int.Parse(value.Substring(num, 2), CultureInfo.InvariantCulture); if (!IsLegalHour(num3) || !value[position++].IsDigit() || !value[position++].IsDigit()) { return null; } int num4 = int.Parse(value.Substring(3 + num, 2), CultureInfo.InvariantCulture); if (!IsLegalMinute(num4)) { return null; } if (value.Length >= 8 + num && value[position] == ':') { position++; if (!value[position++].IsDigit() || !value[position++].IsDigit()) { return null; } num2 = int.Parse(value.Substring(6 + num, 2), CultureInfo.InvariantCulture); if (!IsLegalSecond(num2)) { return null; } if (position + 1 < value.Length && value[position] == '.') { position++; int num5 = position; while (position < value.Length && value[position].IsDigit()) { position++; } string text = value.Substring(num5, position - num5); milliseconds = int.Parse(text, CultureInfo.InvariantCulture) * (int)Math.Pow(10.0, 3 - text.Length); } } return new TimeSpan(0, num3, num4, num2, milliseconds); } return null; } protected static int GetWeekOfYear(DateTime value) { return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(value, CalendarWeekRule.FirstDay, DayOfWeek.Monday); } protected static bool IsLegalHour(int value) { if (value >= 0) { return value <= 23; } return false; } protected static bool IsLegalSecond(int value) { if (value >= 0) { return value <= 59; } return false; } protected static bool IsLegalMinute(int value) { if (value >= 0) { return value <= 59; } return false; } protected static bool IsLegalMonth(int value) { if (value >= 1) { return value <= 12; } return false; } protected static bool IsLegalYear(int value) { if (value >= 0) { return value <= 9999; } return false; } protected static bool IsLegalDay(int day, int month, int year) { if (IsLegalYear(year) && IsLegalMonth(month)) { Calendar calendar = CultureInfo.InvariantCulture.Calendar; if (day >= 1) { return day <= calendar.GetDaysInMonth(year, month); } return false; } return false; } protected static bool IsLegalWeek(int week, int year) { if (IsLegalYear(year)) { int weekOfYear = GetWeekOfYear(new DateTime(year, 12, 31, 0, 0, 0, 0, DateTimeKind.Utc)); if (week >= 0) { return week < weekOfYear; } return false; } return false; } protected static bool IsTimeSeparator(char chr) { if (chr != ' ') { return chr == 'T'; } return true; } protected static int FetchDigits(string value) { int i; for (i = 0; i < value.Length && value[i].IsDigit(); i++) { } return i; } protected static bool PositionIsValidForDateTime(string value, int position) { if (position >= 4 && position <= value.Length - 13 && value[position] == '-' && value[position + 1].IsDigit() && value[position + 2].IsDigit() && value[position + 3] == '-' && value[position + 4].IsDigit()) { return value[position + 5].IsDigit(); } return false; } } internal class ButtonInputType : BaseInputType { public ButtonInputType(IHtmlInputElement input, string name) : base(input, name, validate: false) { } public override bool IsAppendingData(IHtmlElement submitter) { if (base.Name.Is(InputTypeNames.Reset)) { return submitter == base.Input; } return true; } } internal class CheckedInputType : BaseInputType { public CheckedInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { ValidationErrors errorsFrom = BaseInputType.GetErrorsFrom(current); errorsFrom &= ~ValidationErrors.ValueMissing; if (base.Input.IsRequired && !base.Input.IsChecked) { errorsFrom ^= ValidationErrors.ValueMissing; } return errorsFrom; } public override void ConstructDataSet(FormDataSet dataSet) { if (base.Input.IsChecked) { string value = (base.Input.HasValue ? base.Input.Value : Keywords.On); dataSet.Append(base.Input.Name, value, base.Input.Type); } } } internal class ColorInputType : BaseInputType { private static readonly Regex hexColorPattern = new Regex("^\\#[0-9A-Fa-f]{6}$", RegexOptions.Compiled); public ColorInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { ValidationErrors errorsFrom = BaseInputType.GetErrorsFrom(current); if (!hexColorPattern.IsMatch(base.Input.Value ?? string.Empty)) { errorsFrom ^= ValidationErrors.BadInput; if (base.Input.IsRequired) { errorsFrom ^= ValidationErrors.ValueMissing; } return errorsFrom; } return ValidationErrors.None; } } internal class DateInputType : BaseInputType { public DateInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { string value = base.Input.Value; DateTime? date = ConvertFromDate(value); DateTime? min = ConvertFromDate(base.Input.Minimum); DateTime? max = ConvertFromDate(base.Input.Maximum); return CheckTime(current, value, date, min, max); } public override double? ConvertToNumber(string? value) { DateTime? dateTime = ConvertFromDate(value); if (dateTime.HasValue) { return dateTime.Value.Subtract(BaseInputType.UnixEpoch).TotalMilliseconds; } return null; } public override string ConvertFromNumber(double value) { DateTime value2 = BaseInputType.UnixEpoch.AddMilliseconds(value); return ConvertFromDate(value2); } public override DateTime? ConvertToDate(string value) { return ConvertFromDate(value); } public override string ConvertFromDate(DateTime value) { return string.Format(CultureInfo.InvariantCulture, "{0:0000}-{1:00}-{2:00}", value.Year, value.Month, value.Day); } public override void DoStep(int n) { DateTime? dateTime = ConvertFromDate(base.Input.Value); if (dateTime.HasValue) { DateTime dateTime2 = dateTime.Value.AddMilliseconds(GetStep() * (double)n); DateTime? dateTime3 = ConvertFromDate(base.Input.Minimum); DateTime? dateTime4 = ConvertFromDate(base.Input.Maximum); if ((!dateTime3.HasValue || dateTime3.Value <= dateTime2) && (!dateTime4.HasValue || dateTime4.Value >= dateTime2)) { base.Input.ValueAsDate = dateTime2; } } } protected override double GetDefaultStepBase() { return 0.0; } protected override double GetDefaultStep() { return 1.0; } protected override double GetStepScaleFactor() { return 86400000.0; } protected static DateTime? ConvertFromDate(string? value) { if (value != null && value.Length > 0) { int num = BaseInputType.FetchDigits(value); if (IsLegalPosition(value, num)) { int year = int.Parse(value.Substring(0, num), CultureInfo.InvariantCulture); int month = int.Parse(value.Substring(num + 1, 2), CultureInfo.InvariantCulture); int day = int.Parse(value.Substring(num + 4, 2), CultureInfo.InvariantCulture); if (BaseInputType.IsLegalDay(day, month, year)) { return new DateTime(year, month, day, 0, 0, 0, 0, DateTimeKind.Utc); } } } return null; } private static bool IsLegalPosition(string value, int position) { if (position >= 4 && position == value.Length - 6 && value[position] == '-' && value[position + 1].IsDigit() && value[position + 2].IsDigit() && value[position + 3] == '-' && value[position + 4].IsDigit()) { return value[position + 5].IsDigit(); } return false; } } internal class DatetimeInputType : BaseInputType { public DatetimeInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { string value = base.Input.Value; DateTime? date = ConvertFromDateTime(value); DateTime? min = ConvertFromDateTime(base.Input.Minimum); DateTime? max = ConvertFromDateTime(base.Input.Maximum); return CheckTime(current, value, date, min, max); } public override double? ConvertToNumber(string? value) { DateTime? dateTime = ConvertFromDateTime(value); if (dateTime.HasValue) { return dateTime.Value.Subtract(BaseInputType.UnixEpoch).TotalMilliseconds; } return null; } public override string ConvertFromNumber(double value) { DateTime value2 = BaseInputType.UnixEpoch.AddMilliseconds(value); return ConvertFromDate(value2); } public override DateTime? ConvertToDate(string value) { return ConvertFromDateTime(value); } public override string ConvertFromDate(DateTime value) { string text = string.Format(CultureInfo.InvariantCulture, "{0:0000}-{1:00}-{2:00}", value.Year, value.Month, value.Day); string text2 = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00},{3:000}", value.Hour, value.Minute, value.Second, value.Millisecond); return text + "T" + text2 + "Z"; } public override void DoStep(int n) { DateTime? dateTime = ConvertFromDateTime(base.Input.Value); if (dateTime.HasValue) { DateTime dateTime2 = dateTime.Value.AddMilliseconds(GetStep() * (double)n); DateTime? dateTime3 = ConvertFromDateTime(base.Input.Minimum); DateTime? dateTime4 = ConvertFromDateTime(base.Input.Maximum); if ((!dateTime3.HasValue || dateTime3.Value <= dateTime2) && (!dateTime4.HasValue || dateTime4.Value >= dateTime2)) { base.Input.ValueAsDate = dateTime2; } } } protected override double GetDefaultStepBase() { return 0.0; } protected override double GetDefaultStep() { return 60.0; } protected override double GetStepScaleFactor() { return 1000.0; } protected static DateTime? ConvertFromDateTime(string? value) { if (value != null && value.Length > 0) { int num = BaseInputType.FetchDigits(value); if (BaseInputType.PositionIsValidForDateTime(value, num)) { int year = int.Parse(value.Substring(0, num), CultureInfo.InvariantCulture); int month = int.Parse(value.Substring(num + 1, 2), CultureInfo.InvariantCulture); int day = int.Parse(value.Substring(num + 4, 2), CultureInfo.InvariantCulture); num += 6; if (BaseInputType.IsLegalDay(day, month, year) && BaseInputType.IsTimeSeparator(value[num])) { bool flag = value[num++] == ' '; TimeSpan? timeSpan = BaseInputType.ToTime(value, ref num); DateTime dateTime = new DateTime(year, month, day, 0, 0, 0, DateTimeKind.Utc); if (timeSpan.HasValue) { dateTime = dateTime.Add(timeSpan.Value); if (num == value.Length) { if (flag) { return null; } return dateTime; } if (value[num] != 'Z') { if (!IsLegalPosition(value, num)) { return null; } int hours = int.Parse(value.Substring(num + 1, 2), CultureInfo.InvariantCulture); int minutes = int.Parse(value.Substring(num + 4, 2), CultureInfo.InvariantCulture); TimeSpan value2 = new TimeSpan(hours, minutes, 0); if (value[num] == '+') { dateTime = dateTime.Add(value2); } else { if (value[num] != '-') { return null; } dateTime = dateTime.Subtract(value2); } } else { if (num + 1 != value.Length) { return null; } dateTime = dateTime.ToUniversalTime(); } return dateTime; } } } } return null; } private static bool IsLegalPosition(string value, int position) { if (position == value.Length - 6 && value[position + 1].IsDigit() && value[position + 2].IsDigit() && value[position + 3] == ':' && value[position + 4].IsDigit()) { return value[position + 5].IsDigit(); } return false; } } internal class DatetimeLocalInputType : BaseInputType { public DatetimeLocalInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { string value = base.Input.Value; DateTime? date = ConvertFromDateTime(value); DateTime? min = ConvertFromDateTime(base.Input.Minimum); DateTime? max = ConvertFromDateTime(base.Input.Maximum); return CheckTime(current, value, date, min, max); } public override double? ConvertToNumber(string? value) { DateTime? dateTime = ConvertFromDateTime(value); if (dateTime.HasValue) { return dateTime.Value.ToUniversalTime().Subtract(BaseInputType.UnixEpoch).TotalMilliseconds; } return null; } public override string ConvertFromNumber(double value) { DateTime value2 = BaseInputType.UnixEpoch.AddMilliseconds(value); return ConvertFromDate(value2); } public override DateTime? ConvertToDate(string value) { return ConvertFromDateTime(value); } public override string ConvertFromDate(DateTime value) { value = value.ToLocalTime(); string text = string.Format(CultureInfo.InvariantCulture, "{0:0000}-{1:00}-{2:00}", value.Year, value.Month, value.Day); string text2 = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00},{3:000}", value.Hour, value.Minute, value.Second, value.Millisecond); return text + "T" + text2; } public override void DoStep(int n) { DateTime? dateTime = ConvertFromDateTime(base.Input.Value); if (dateTime.HasValue) { DateTime dateTime2 = dateTime.Value.AddMilliseconds(GetStep() * (double)n); DateTime? dateTime3 = ConvertFromDateTime(base.Input.Minimum); DateTime? dateTime4 = ConvertFromDateTime(base.Input.Maximum); if ((!dateTime3.HasValue || dateTime3.Value <= dateTime2) && (!dateTime4.HasValue || dateTime4.Value >= dateTime2)) { base.Input.ValueAsDate = dateTime2; } } } protected override double GetDefaultStepBase() { return 0.0; } protected override double GetDefaultStep() { return 60.0; } protected override double GetStepScaleFactor() { return 1000.0; } protected static DateTime? ConvertFromDateTime(string? value) { if (value != null && value.Length > 0) { int num = BaseInputType.FetchDigits(value); if (BaseInputType.PositionIsValidForDateTime(value, num)) { int year = int.Parse(value.Substring(0, num), CultureInfo.InvariantCulture); int month = int.Parse(value.Substring(num + 1, 2), CultureInfo.InvariantCulture); int day = int.Parse(value.Substring(num + 4, 2), CultureInfo.InvariantCulture); num += 6; if (BaseInputType.IsLegalDay(day, month, year) && BaseInputType.IsTimeSeparator(value[num])) { num++; TimeSpan? timeSpan = BaseInputType.ToTime(value, ref num); DateTime dateTime = new DateTime(year, month, day, 0, 0, 0, DateTimeKind.Local); if (timeSpan.HasValue) { dateTime = dateTime.Add(timeSpan.Value); if (num == value.Length) { return dateTime; } } } } } return null; } } internal class EmailInputType : BaseInputType { private static readonly Regex emailPattern = new Regex("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", RegexOptions.Compiled); public EmailInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { string value = base.Input.Value ?? string.Empty; ValidationErrors validationErrors = BaseInputType.GetErrorsFrom(current); if (BaseInputType.IsInvalidPattern(base.Input.Pattern, value)) { validationErrors ^= ValidationErrors.PatternMismatch; } if (IsInvalidEmail(base.Input.IsMultiple, value) && !string.IsNullOrEmpty(value)) { validationErrors ^= ValidationErrors.TypeMismatch | ValidationErrors.BadInput; } return validationErrors; } private static bool IsInvalidEmail(bool multiple, string value) { if (multiple) { string[] array = value.Split(','); foreach (string text in array) { if (!emailPattern.IsMatch(text.Trim())) { return true; } } return false; } return !emailPattern.IsMatch(value.Trim()); } } internal class FileInputType : BaseInputType { private readonly FileList _files; public FileList Files => _files; public FileInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { _files = new FileList(); } public override void ConstructDataSet(FormDataSet dataSet) { if (_files.Length == 0) { dataSet.Append(base.Input.Name, (IFile)null, base.Input.Type); } foreach (IFile file in _files) { dataSet.Append(base.Input.Name, file, base.Input.Type); } } } internal class ImageInputType : BaseInputType { private readonly ImageRequestProcessor? _request; public int Width => _request?.Width ?? 0; public int Height => _request?.Height ?? 0; public ImageInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { HtmlInputElement htmlInputElement = input as HtmlInputElement; string source = input.Source; if (source != null && htmlInputElement != null) { Url url = htmlInputElement.HyperReference(source); _request = new ImageRequestProcessor(htmlInputElement.Context); htmlInputElement.Process(_request, url); } } public override bool IsAppendingData(IHtmlElement submitter) { if (submitter == base.Input) { return !string.IsNullOrEmpty(base.Input.Name); } return false; } public override void ConstructDataSet(FormDataSet dataSet) { string name = base.Input.Name; string value = base.Input.Value; dataSet.Append(name + ".x", "0", base.Input.Type); dataSet.Append(name + ".y", "0", base.Input.Type); if (!string.IsNullOrEmpty(value)) { dataSet.Append(name, value, base.Input.Type); } } } internal class MonthInputType : BaseInputType { public MonthInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { string value = base.Input.Value; DateTime? date = ConvertFromMonth(value); DateTime? min = ConvertFromMonth(base.Input.Minimum); DateTime? max = ConvertFromMonth(base.Input.Maximum); return CheckTime(current, value, date, min, max); } public override double? ConvertToNumber(string? value) { DateTime? dateTime = ConvertFromMonth(value); if (dateTime.HasValue) { return (dateTime.Value.Year - 1970) * 12 + dateTime.Value.Month - 1; } return null; } public override string ConvertFromNumber(double value) { DateTime value2 = BaseInputType.UnixEpoch.AddMonths((int)value); return ConvertFromDate(value2); } public override DateTime? ConvertToDate(string value) { return ConvertFromMonth(value); } public override string ConvertFromDate(DateTime value) { return string.Format(CultureInfo.InvariantCulture, "{0:0000}-{1:00}", value.Year, value.Month); } public override void DoStep(int n) { DateTime? dateTime = ConvertFromMonth(base.Input.Value); if (dateTime.HasValue) { DateTime dateTime2 = dateTime.Value.AddMilliseconds(GetStep() * (double)n); DateTime? dateTime3 = ConvertFromMonth(base.Input.Minimum); DateTime? dateTime4 = ConvertFromMonth(base.Input.Maximum); if ((!dateTime3.HasValue || dateTime3.Value <= dateTime2) && (!dateTime4.HasValue || dateTime4.Value >= dateTime2)) { base.Input.ValueAsDate = dateTime2; } } } protected override double GetDefaultStepBase() { return 0.0; } protected override double GetDefaultStep() { return 1.0; } protected override double GetStepScaleFactor() { return 1.0; } protected static DateTime? ConvertFromMonth(string? value) { if (value != null && value.Length > 0) { int num = BaseInputType.FetchDigits(value); if (IsLegalPosition(value, num)) { int year = int.Parse(value.Substring(0, num), CultureInfo.InvariantCulture); int month = int.Parse(value.Substring(num + 1), CultureInfo.InvariantCulture); if (BaseInputType.IsLegalDay(1, month, year)) { return new DateTime(year, month, 1, 0, 0, 0, 0, DateTimeKind.Utc); } } } return null; } private static bool IsLegalPosition(string value, int position) { if (position >= 4 && position == value.Length - 3 && value[position] == '-' && value[position + 1].IsDigit()) { return value[position + 2].IsDigit(); } return false; } } internal class NumberInputType : BaseInputType { public NumberInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override double? ConvertToNumber(string? value) { return BaseInputType.ToNumber(value); } public override string ConvertFromNumber(double value) { return value.ToString(CultureInfo.InvariantCulture); } public override ValidationErrors Check(IValidityState current) { string value = base.Input.Value; double? num = ConvertToNumber(value); ValidationErrors validationErrors = (current.IsCustomError ? ValidationErrors.Custom : ValidationErrors.None); if (num.HasValue) { double? num2 = ConvertToNumber(base.Input.Minimum); double? num3 = ConvertToNumber(base.Input.Maximum); if (num2.HasValue && num < num2.Value) { validationErrors ^= ValidationErrors.RangeUnderflow; } if (num3.HasValue && num > num3.Value) { validationErrors ^= ValidationErrors.RangeOverflow; } if (IsStepMismatch()) { validationErrors ^= ValidationErrors.StepMismatch; } } else if (base.Input.IsRequired) { validationErrors ^= ValidationErrors.ValueMissing; } return validationErrors; } public override void DoStep(int n) { double? num = BaseInputType.ToNumber(base.Input.Value); if (num.HasValue) { double num2 = num.Value + GetStep() * (double)n; double? num3 = BaseInputType.ToNumber(base.Input.Minimum); double? num4 = BaseInputType.ToNumber(base.Input.Maximum); if ((!num3.HasValue || num3.Value <= num2) && (!num4.HasValue || num4.Value >= num2)) { base.Input.ValueAsNumber = num2; } } } protected override double GetDefaultStepBase() { return 0.0; } protected override double GetDefaultStep() { return 1.0; } protected override double GetStepScaleFactor() { return 1.0; } } internal class PatternInputType : BaseInputType { public PatternInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { ValidationErrors validationErrors = BaseInputType.GetErrorsFrom(current); if (BaseInputType.IsInvalidPattern(base.Input.Pattern, base.Input.Value ?? string.Empty)) { validationErrors ^= ValidationErrors.PatternMismatch; } return validationErrors; } } internal class SubmitInputType : BaseInputType { public SubmitInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override bool IsAppendingData(IHtmlElement submitter) { return submitter == base.Input; } } internal class TextInputType : BaseInputType { public TextInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { ValidationErrors validationErrors = BaseInputType.GetErrorsFrom(current); if (BaseInputType.IsInvalidPattern(base.Input.Pattern, base.Input.Value ?? string.Empty)) { validationErrors ^= ValidationErrors.PatternMismatch; } return validationErrors; } public override void ConstructDataSet(FormDataSet dataSet) { base.ConstructDataSet(dataSet); string attribute = base.Input.GetAttribute(null, AttributeNames.DirName); if (attribute != null && attribute.Length > 0) { dataSet.Append(attribute, base.Input.Direction?.ToLowerInvariant(), "Direction"); } } } internal class TimeInputType : BaseInputType { public TimeInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { string value = base.Input.Value; DateTime? date = ConvertFromTime(value); DateTime? min = ConvertFromTime(base.Input.Minimum); DateTime? max = ConvertFromTime(base.Input.Maximum); return CheckTime(current, value, date, min, max); } public override double? ConvertToNumber(string? value) { DateTime? dateTime = ConvertFromTime(value); if (dateTime.HasValue) { return dateTime.Value.Subtract(default(DateTime)).TotalMilliseconds; } return null; } public override string ConvertFromNumber(double value) { DateTime value2 = default(DateTime).AddMilliseconds(value); return ConvertFromDate(value2); } public override DateTime? ConvertToDate(string value) { DateTime? dateTime = ConvertFromTime(value); if (dateTime.HasValue) { return BaseInputType.UnixEpoch.Add(dateTime.Value.Subtract(default(DateTime))); } return null; } public override string ConvertFromDate(DateTime value) { return string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00},{3:000}", value.Hour, value.Minute, value.Second, value.Millisecond); } public override void DoStep(int n) { DateTime? dateTime = ConvertFromTime(base.Input.Value); if (dateTime.HasValue) { DateTime dateTime2 = dateTime.Value.AddMilliseconds(GetStep() * (double)n); DateTime? dateTime3 = ConvertFromTime(base.Input.Minimum); DateTime? dateTime4 = ConvertFromTime(base.Input.Maximum); if ((!dateTime3.HasValue || dateTime3.Value <= dateTime2) && (!dateTime4.HasValue || dateTime4.Value >= dateTime2)) { base.Input.ValueAsDate = dateTime2; } } } protected override double GetDefaultStepBase() { return 0.0; } protected override double GetDefaultStep() { return 60.0; } protected override double GetStepScaleFactor() { return 1000.0; } protected static DateTime? ConvertFromTime(string? value) { if (value != null && value.Length > 0) { int position = 0; TimeSpan? timeSpan = BaseInputType.ToTime(value, ref position); if (timeSpan.HasValue && position == value.Length) { return new DateTime(0L, DateTimeKind.Utc).Add(timeSpan.Value); } } return null; } } internal class UrlInputType : BaseInputType { public UrlInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { string value = base.Input.Value ?? string.Empty; ValidationErrors validationErrors = BaseInputType.GetErrorsFrom(current); if (BaseInputType.IsInvalidPattern(base.Input.Pattern, value)) { validationErrors ^= ValidationErrors.PatternMismatch; } if (IsInvalidUrl(value) && !string.IsNullOrEmpty(value)) { validationErrors ^= ValidationErrors.TypeMismatch | ValidationErrors.BadInput; } return validationErrors; } private static bool IsInvalidUrl(string value) { if (!string.IsNullOrEmpty(value)) { Url url = new Url(value); if (!url.IsInvalid) { return url.IsRelative; } return true; } return false; } } internal class WeekInputType : BaseInputType { public WeekInputType(IHtmlInputElement input, string name) : base(input, name, validate: true) { } public override ValidationErrors Check(IValidityState current) { string value = base.Input.Value; DateTime? date = ConvertFromWeek(value); DateTime? min = ConvertFromWeek(base.Input.Minimum); DateTime? max = ConvertFromWeek(base.Input.Maximum); return CheckTime(current, value, date, min, max); } public override double? ConvertToNumber(string? value) { DateTime? dateTime = ConvertFromWeek(value); if (dateTime.HasValue) { return dateTime.Value.Subtract(BaseInputType.UnixEpoch).TotalMilliseconds; } return null; } public override string ConvertFromNumber(double value) { DateTime value2 = BaseInputType.UnixEpoch.AddMilliseconds(value); return ConvertFromDate(value2); } public override DateTime? ConvertToDate(string value) { return ConvertFromWeek(value); } public override string ConvertFromDate(DateTime value) { int weekOfYear = BaseInputType.GetWeekOfYear(value); return string.Format(CultureInfo.InvariantCulture, "{0:0000}-W{1:00}", value.Year, weekOfYear); } public override void DoStep(int n) { DateTime? dateTime = ConvertFromWeek(base.Input.Value); if (dateTime.HasValue) { DateTime dateTime2 = dateTime.Value.AddMilliseconds(GetStep() * (double)n); DateTime? dateTime3 = ConvertFromWeek(base.Input.Minimum); DateTime? dateTime4 = ConvertFromWeek(base.Input.Maximum); if ((!dateTime3.HasValue || dateTime3.Value <= dateTime2) && (!dateTime4.HasValue || dateTime4.Value >= dateTime2)) { base.Input.ValueAsDate = dateTime2; } } } protected override double GetDefaultStepBase() { return -259200000.0; } protected override double GetDefaultStep() { return 1.0; } protected override double GetStepScaleFactor() { return 604800000.0; } protected static DateTime? ConvertFromWeek(string? value) { if (value != null && value.Length > 0) { int num = BaseInputType.FetchDigits(value); if (IsLegalPosition(value, num)) { int year = int.Parse(value.Substring(0, num)); int num2 = int.Parse(value.Substring(num + 2)) - 1; if (BaseInputType.IsLegalWeek(num2, year)) { DateTime dateTime = new DateTime(year, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); DayOfWeek dayOfWeek = dateTime.DayOfWeek; if (dayOfWeek == DayOfWeek.Sunday) { dateTime = dateTime.AddDays(-6.0); } else if (dayOfWeek > DayOfWeek.Monday) { dateTime = dateTime.AddDays((double)(1 - dayOfWeek)); } return dateTime.AddDays(7 * num2); } } } return null; } private static bool IsLegalPosition(string value, int position) { if (position >= 4 && position == value.Length - 4 && value[position] == '-' && value[position + 1] == 'W' && value[position + 2].IsDigit()) { return value[position + 3].IsDigit(); } return false; } } } namespace AngleSharp.Html.Forms { internal sealed class FileDataSetEntry : FormDataSetEntry { private readonly IFile _value; public string FileName => _value?.Name ?? string.Empty; public string ContentType => _value?.Type ?? MimeTypeNames.Binary; public FileDataSetEntry(string name, IFile value, string type) : base(name, type) { _value = value; } public override bool Contains(string boundary, Encoding encoding) { bool result = false; Stream stream = _value?.Body; if (stream != null && stream.CanSeek) { using (StreamReader streamReader = new StreamReader(stream, encoding, detectEncodingFromByteOrderMarks: false, 4096, leaveOpen: true)) { while (streamReader.Peek() != -1) { string text = streamReader.ReadLine(); if (text != null && text.Contains(boundary)) { result = true; break; } } } stream.Seek(0L, SeekOrigin.Begin); } return result; } public override void Accept(IFormDataSetVisitor visitor) { visitor.File(this, FileName, ContentType, _value); } } public abstract class FormDataSetEntry { private readonly string _name; private readonly string _type; public bool HasName => _name != null; public string Name => _name ?? string.Empty; public string Type => _type ?? InputTypeNames.Text; public FormDataSetEntry(string name, string type) { _name = name; _type = type; } public abstract void Accept(IFormDataSetVisitor visitor); public abstract bool Contains(string boundary, Encoding encoding); } internal static class FormDataSetExtensions { public static Stream CreateBody(this FormDataSet formDataSet, string enctype, string? charset, IHtmlEncoder? htmlEncoder) { Encoding encoding = TextEncoding.Resolve(charset); return formDataSet.CreateBody(enctype, encoding, htmlEncoder ?? new DefaultHtmlEncoder()); } public static Stream CreateBody(this FormDataSet formDataSet, string enctype, Encoding encoding, IHtmlEncoder htmlEncoder) { if (enctype.Isi(MimeTypeNames.UrlencodedForm)) { return formDataSet.AsUrlEncoded(encoding); } if (enctype.Isi(MimeTypeNames.MultipartForm)) { return formDataSet.AsMultipart(htmlEncoder, encoding); } if (enctype.Isi(MimeTypeNames.Plain)) { return formDataSet.AsPlaintext(encoding); } if (enctype.Isi(MimeTypeNames.ApplicationJson)) { return formDataSet.AsJson(); } return Stream.Null; } } public interface IFormDataSetVisitor { void Text(FormDataSetEntry entry, string value); void File(FormDataSetEntry entry, string fileName, string contentType, IFile content); } public interface IFormSubmitter : IFormDataSetVisitor { void Serialize(StreamWriter stream); } internal sealed class TextDataSetEntry : FormDataSetEntry { private readonly string _value; public TextDataSetEntry(string name, string value, string type) : base(name, type) { _value = value; } public override bool Contains(string boundary, Encoding encoding) { if (_value != null) { return _value.Contains(boundary); } return false; } public override void Accept(IFormDataSetVisitor visitor) { visitor.Text(this, _value); } } } namespace AngleSharp.Html.Forms.Submitters { public class DefaultHtmlEncoder : IHtmlEncoder { [MethodImpl(MethodImplOptions.AggressiveInlining)] public string Encode(string value, Encoding encoding) { return value.HtmlEncode(encoding); } } public interface IHtmlEncoder { string Encode(string value, Encoding encoding); } internal sealed class JsonFormDataSetVisitor : IFormSubmitter, IFormDataSetVisitor { private readonly JsonObject _context; public JsonFormDataSetVisitor() { _context = new JsonObject(); } public void Text(FormDataSetEntry entry, string value) { JsonValue value2 = CreateValue(entry.Type, value); IEnumerable enumerable = JsonStep.Parse(entry.Name); JsonElement context = _context; foreach (JsonStep item in enumerable) { context = item.Run(context, value2); } } public void File(FormDataSetEntry entry, string fileName, string contentType, IFile file) { JsonElement context = _context; Stream obj = ((file?.Body != null && file.Type != null) ? file.Body : Stream.Null); MemoryStream memoryStream = new MemoryStream(); obj.CopyTo(memoryStream); byte[] inArray = memoryStream.ToArray(); IEnumerable enumerable = JsonStep.Parse(entry.Name); JsonObject value = new JsonObject { [AttributeNames.Type] = new JsonValue(contentType), [AttributeNames.Name] = new JsonValue(fileName), [AttributeNames.Body] = new JsonValue(Convert.ToBase64String(inArray)) }; foreach (JsonStep item in enumerable) { context = item.Run(context, value, file: true); } } public void Serialize(StreamWriter stream) { string value = _context.ToString(); stream.Write(value); } private static JsonValue CreateValue(string type, string value) { if (type.Is(InputTypeNames.Checkbox)) { return new JsonValue(value.Is(Keywords.On)); } if (type.Is(InputTypeNames.Number)) { return new JsonValue(value.ToDouble()); } return new JsonValue(value); } } internal sealed class MultipartFormDataSetVisitor : IFormSubmitter, IFormDataSetVisitor { private static readonly string DashDash = "--"; private readonly IHtmlEncoder _htmlEncoder; private readonly Encoding _encoding; private readonly List> _writers; private readonly string _boundary; public MultipartFormDataSetVisitor(IHtmlEncoder htmlEncoder, Encoding encoding, string boundary) { _htmlEncoder = htmlEncoder; _encoding = encoding; _writers = new List>(); _boundary = boundary; } public void Text(FormDataSetEntry entry, string value) { if (entry.HasName && value != null) { _writers.Add(delegate(StreamWriter stream) { stream.WriteLine("Content-Disposition: form-data; name=\"{0}\"", _htmlEncoder.Encode(entry.Name, _encoding)); stream.WriteLine(); stream.WriteLine(_htmlEncoder.Encode(value, _encoding)); }); } } public void File(FormDataSetEntry entry, string fileName, string contentType, IFile content) { if (!entry.HasName) { return; } _writers.Add(delegate(StreamWriter stream) { bool num = content != null && content?.Name != null && content.Type != null && content.Body != null; stream.WriteLine("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"", _htmlEncoder.Encode(entry.Name, _encoding), _htmlEncoder.Encode(fileName, _encoding)); stream.WriteLine("Content-Type: {0}", contentType); stream.WriteLine(); if (num) { stream.Flush(); content.Body.CopyTo(stream.BaseStream); } stream.WriteLine(); }); } public void Serialize(StreamWriter stream) { stream.NewLine = "\r\n"; foreach (Action writer in _writers) { stream.Write(DashDash); stream.WriteLine(_boundary); writer(stream); } stream.Write(DashDash); stream.Write(_boundary); stream.Write(DashDash); } } internal sealed class PlaintextFormDataSetVisitor : IFormSubmitter, IFormDataSetVisitor { private readonly List _lines; public PlaintextFormDataSetVisitor() { _lines = new List(); } public void Text(FormDataSetEntry entry, string value) { if (entry.HasName && value != null) { Add(entry.Name, value); } } public void File(FormDataSetEntry entry, string fileName, string contentType, IFile content) { if (entry.HasName && content != null && content.Name != null) { Add(entry.Name, content.Name); } } public void Serialize(StreamWriter stream) { string value = string.Join("\r\n", _lines); stream.Write(value); } private void Add(string name, string value) { _lines.Add(name + "=" + value); } } internal sealed class UrlEncodedFormDataSetVisitor : IFormSubmitter, IFormDataSetVisitor { private readonly Encoding _encoding; private readonly List _lines; private bool _first; private string _index; public UrlEncodedFormDataSetVisitor(Encoding encoding) { _encoding = encoding; _lines = new List(); _first = true; _index = string.Empty; } public void Text(FormDataSetEntry entry, string value) { if (_first && entry.HasName && entry.Name.Is(TagNames.IsIndex) && entry.Type.Isi(InputTypeNames.Text)) { _index = value ?? string.Empty; } else if (entry.HasName && value != null) { byte[] bytes = _encoding.GetBytes(entry.Name); byte[] bytes2 = _encoding.GetBytes(value); Add(bytes, bytes2); } _first = false; } public void File(FormDataSetEntry entry, string fileName, string contentType, IFile content) { if (entry.HasName && content != null && content.Name != null) { byte[] bytes = _encoding.GetBytes(entry.Name); byte[] bytes2 = _encoding.GetBytes(content.Name); Add(bytes, bytes2); } _first = false; } public void Serialize(StreamWriter stream) { string value = string.Join("&", _lines); stream.Write(_index); stream.Write(value); } private void Add(byte[] name, byte[] value) { _lines.Add(name.UrlEncode() + "=" + value.UrlEncode()); } } } namespace AngleSharp.Html.Forms.Submitters.Json { internal sealed class JsonArray : JsonElement, IEnumerable, IEnumerable { private readonly List _elements; public int Length => _elements.Count; public JsonElement? this[int key] { get { return _elements.ElementAtOrDefault(key); } set { for (int i = _elements.Count; i <= key; i++) { _elements.Add(null); } _elements[key] = value; } } public JsonArray() { _elements = new List(); } public JsonArray(int capacity) { _elements = new List(capacity); } public void Push(JsonElement element) { _elements.Add(element); } public void Add(JsonElement element) { _elements.Add(element); } public override string ToString() { StringBuilder stringBuilder = StringBuilderPool.Obtain().Append('['); bool flag = false; foreach (JsonElement element in _elements) { if (flag) { stringBuilder.Append(','); } stringBuilder.Append(element?.ToString() ?? "null"); flag = true; } return stringBuilder.Append(']').ToPool(); } public IEnumerator GetEnumerator() { return _elements.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal abstract class JsonElement { public virtual JsonElement? this[string key] { get { throw new InvalidOperationException(); } set { throw new InvalidOperationException(); } } } internal sealed class JsonObject : JsonElement { private readonly Dictionary _properties = new Dictionary(); public override JsonElement? this[string key] { get { _properties.TryGetValue(key.ToString(), out JsonElement value); return value; } set { _properties[key] = value; } } public override string ToString() { StringBuilder stringBuilder = StringBuilderPool.Obtain().Append('{'); bool flag = false; foreach (KeyValuePair property in _properties) { if (flag) { stringBuilder.Append(','); } stringBuilder.Append('"').Append(property.Key).Append('"'); stringBuilder.Append(':').Append(property.Value.ToString()); flag = true; } return stringBuilder.Append('}').ToPool(); } } internal abstract class JsonStep { private sealed class ObjectStep : JsonStep { public string Key { get; } public ObjectStep(string key) { Key = key; } protected override JsonElement GetValue(JsonElement context) { return context[Key]; } protected override JsonElement SetValue(JsonElement context, JsonElement value) { context[Key] = value; return value; } protected override JsonElement CreateElement() { return new JsonObject(); } protected override JsonElement ConvertArray(JsonArray values) { JsonObject jsonObject = new JsonObject(); for (int i = 0; i < values.Length; i++) { JsonElement jsonElement = values[i]; if (jsonElement != null) { jsonObject[i.ToString()] = jsonElement; } } return jsonObject; } } private sealed class ArrayStep : JsonStep { public int Key { get; } public ArrayStep(int key) { Key = key; } protected override JsonElement GetValue(JsonElement context) { if (context is JsonArray jsonArray) { return jsonArray[Key]; } return context[Key.ToString()]; } protected override JsonElement SetValue(JsonElement context, JsonElement value) { if (context is JsonArray jsonArray) { jsonArray[Key] = value; } else { context[Key.ToString()] = value; } return value; } protected override JsonElement CreateElement() { return new JsonArray(); } protected override JsonElement ConvertArray(JsonArray value) { return value; } } public bool Append { get; set; } public JsonStep Next { get; set; } public static IEnumerable Parse(string path) { List list = new List(); int i; for (i = 0; i < path.Length && path[i] != '['; i++) { } if (i == 0) { return FailedJsonSteps(path); } list.Add(new ObjectStep(path.Substring(0, i))); while (i < path.Length) { if (i + 1 >= path.Length || path[i] != '[') { return FailedJsonSteps(path); } if (path[i + 1] == ']') { list[list.Count - 1].Append = true; i += 2; if (i < path.Length) { return FailedJsonSteps(path); } } else if (path[i + 1].IsDigit()) { int num = ++i; for (; i < path.Length && path[i] != ']'; i++) { if (!path[i].IsDigit()) { return FailedJsonSteps(path); } } if (i == path.Length) { return FailedJsonSteps(path); } list.Add(new ArrayStep(path.Substring(num, i - num).ToInteger(0))); i++; } else { int num2 = ++i; for (; i < path.Length && path[i] != ']'; i++) { } if (i == path.Length) { return FailedJsonSteps(path); } list.Add(new ObjectStep(path.Substring(num2, i - num2))); i++; } } int num3 = list.Count - 1; for (int j = 0; j < num3; j++) { list[j].Next = list[j + 1]; } return list; } private static IEnumerable FailedJsonSteps(string original) { return new ObjectStep[1] { new ObjectStep(original) }; } protected abstract JsonElement CreateElement(); protected abstract JsonElement SetValue(JsonElement context, JsonElement value); protected abstract JsonElement GetValue(JsonElement context); protected abstract JsonElement ConvertArray(JsonArray value); public JsonElement Run(JsonElement context, JsonElement value, bool file = false) { if (Next == null) { return JsonEncodeLastValue(context, value, file); } return JsonEncodeValue(context, value, file); } private JsonElement JsonEncodeValue(JsonElement context, JsonElement value, bool file) { JsonElement value2 = GetValue(context); if (value2 == null) { JsonElement value3 = Next.CreateElement(); return SetValue(context, value3); } if (value2 is JsonObject) { return value2; } if (value2 is JsonArray) { return SetValue(context, Next.ConvertArray((JsonArray)value2)); } JsonObject value4 = new JsonObject { [string.Empty] = value2 }; return SetValue(context, value4); } private JsonElement JsonEncodeLastValue(JsonElement context, JsonElement value, bool file) { JsonElement value2 = GetValue(context); if (value2 == null) { if (Append) { value = new JsonArray(1) { value }; } SetValue(context, value); } else if (value2 is JsonArray jsonArray) { jsonArray.Push(value); } else { if (value2 is JsonObject && !file) { return new ObjectStep(string.Empty).JsonEncodeLastValue(value2, value, file: true); } JsonArray value3 = new JsonArray(2) { value2, value }; SetValue(context, value3); } return context; } } internal sealed class JsonValue : JsonElement { private readonly string _value; public JsonValue(string value) { _value = value.CssString(); } public JsonValue(double value) { _value = value.ToString(CultureInfo.InvariantCulture); } public JsonValue(bool value) { _value = (value ? "true" : "false"); } public override string ToString() { return _value; } } } namespace AngleSharp.Html.Dom { public static class FormExtensions { public static IHtmlFormElement SetValues(this IHtmlFormElement form, IDictionary fields, bool createMissing = false) { if (form == null) { throw new ArgumentNullException("form"); } if (fields == null) { throw new ArgumentNullException("fields"); } IEnumerable source = form.Elements.OfType(); foreach (KeyValuePair field in fields) { HtmlFormControlElement targetInput = source.FirstOrDefault((HtmlFormControlElement e) => e.Name.Is(field.Key)); if (targetInput != null) { if (targetInput is IHtmlInputElement htmlInputElement) { if (htmlInputElement.Type.Is(InputTypeNames.Radio)) { foreach (IHtmlInputElement item in from i in source.OfType() where i.Name.Is(targetInput.Name) select i) { item.IsChecked = item.Value.Is(field.Value); } } else { htmlInputElement.Value = field.Value; } } else if (targetInput is IHtmlTextAreaElement htmlTextAreaElement) { htmlTextAreaElement.Value = field.Value; } else if (targetInput is IHtmlSelectElement htmlSelectElement) { htmlSelectElement.Value = field.Value; } } else { if (!createMissing) { throw new KeyNotFoundException("Field " + field.Key + " not found."); } IHtmlInputElement htmlInputElement2 = form.Owner.CreateElement(); htmlInputElement2.Type = InputTypeNames.Hidden; htmlInputElement2.Name = field.Key; htmlInputElement2.Value = field.Value; form.AppendChild(htmlInputElement2); } } return form; } public static Task SubmitAsync(this IHtmlFormElement form, object fields) { return form.SubmitAsync(fields.ToDictionary()); } public static Task SubmitAsync(this IHtmlFormElement form, IDictionary fields, bool createMissing = false) { form.SetValues(fields, createMissing); return form.SubmitAsync(); } public static Task SubmitAsync(this IHtmlElement element, object? fields = null) { return element.SubmitAsync(fields.ToDictionary()); } public static Task SubmitAsync(this IHtmlElement element, IDictionary fields, bool createMissing = false) { if (element is HtmlFormControlElement htmlFormControlElement) { IHtmlFormElement form = htmlFormControlElement.Form; if (form != null) { form.SetValues(fields, createMissing); return form.SubmitAsync(htmlFormControlElement); } return null; } throw new ArgumentException("element"); } } [DomName("HTMLAnchorElement")] public interface IHtmlAnchorElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IUrlUtilities { [DomName("target")] string? Target { get; set; } [DomName("download")] string? Download { get; set; } [DomName("ping")] ISettableTokenList Ping { get; } [DomName("rel")] string? Relation { get; set; } [DomName("relList")] ITokenList RelationList { get; } [DomName("hreflang")] string? TargetLanguage { get; set; } [DomName("type")] string? Type { get; } [DomName("text")] string Text { get; } } [DomName("HTMLAreaElement")] public interface IHtmlAreaElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IUrlUtilities { [DomName("alt")] string? AlternativeText { get; set; } [DomName("coords")] string? Coordinates { get; set; } [DomName("shape")] string? Shape { get; set; } [DomName("target")] string? Target { get; set; } [DomName("download")] string? Download { get; set; } [DomName("ping")] ISettableTokenList Ping { get; } [DomName("rel")] string? Relation { get; set; } [DomName("relList")] ITokenList RelationList { get; } [DomName("hreflang")] string? TargetLanguage { get; set; } [DomName("type")] string? Type { get; set; } } [DomName("HTMLAudioElement")] public interface IHtmlAudioElement : IHtmlMediaElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IMediaController, ILoadableElement { } [DomName("HTMLBaseElement")] public interface IHtmlBaseElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("href")] string? Href { get; set; } [DomName("target")] string? Target { get; set; } } [DomName("HTMLBodyElement")] public interface IHtmlBodyElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IWindowEventHandlers { } [DomName("HTMLBRElement")] public interface IHtmlBreakRowElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLButtonElement")] public interface IHtmlButtonElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { [DomName("autofocus")] bool Autofocus { get; set; } [DomName("disabled")] bool IsDisabled { get; set; } [DomName("form")] IHtmlFormElement? Form { get; } [DomName("labels")] INodeList Labels { get; } [DomName("name")] string? Name { get; set; } [DomName("type")] string Type { get; set; } [DomName("value")] string Value { get; set; } [DomName("formAction")] string? FormAction { get; set; } [DomName("formEncType")] string FormEncType { get; set; } [DomName("formMethod")] string FormMethod { get; set; } [DomName("formNoValidate")] bool FormNoValidate { get; set; } [DomName("formTarget")] string? FormTarget { get; set; } } [DomName("HTMLCanvasElement")] public interface IHtmlCanvasElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("width")] int Width { get; set; } [DomName("height")] int Height { get; set; } [DomName("toDataURL")] string ToDataUrl(string? type = null); [DomName("toBlob")] void ToBlob(Action callback, string? type = null); [DomName("getContext")] IRenderingContext GetContext(string contextId); [DomName("setContext")] void SetContext(IRenderingContext context); [DomName("probablySupportsContext")] bool IsSupportingContext(string contextId); } [DomName("HTMLCommandElement")] public interface IHtmlCommandElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("type")] string? Type { get; set; } [DomName("label")] string? Label { get; set; } [DomName("icon")] string? Icon { get; set; } [DomName("disabled")] bool IsDisabled { get; set; } [DomName("checked")] bool IsChecked { get; set; } [DomName("radiogroup")] string? RadioGroup { get; set; } [DomName("command")] IHtmlElement Command { get; } } [DomName("HTMLDataElement")] public interface IHtmlDataElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("value")] string? Value { get; set; } } [DomName("HTMLDataListElement")] public interface IHtmlDataListElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("options")] IHtmlCollection Options { get; } } [DomName("HTMLDetailsElement")] public interface IHtmlDetailsElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("open")] bool IsOpen { get; set; } } [DomName("HTMLDialogElement")] public interface IHtmlDialogElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("open")] bool Open { get; set; } [DomName("returnValue")] string? ReturnValue { get; set; } [DomName("show")] void Show(IElement? anchor = null); [DomName("showModal")] void ShowModal(IElement? anchor = null); [DomName("close")] void Close(string? returnValue = null); } [DomName("HTMLDivElement")] public interface IHtmlDivElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLDocument")] public interface IHtmlDocument : IDocument, INode, IEventTarget, IMarkupFormattable, IParentNode, IGlobalEventHandlers, IDocumentStyle, INonElementParentNode, IDisposable { } [DomName("HTMLElement")] public interface IHtmlElement : IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("lang")] string? Language { get; set; } [DomName("title")] string? Title { get; set; } [DomName("dir")] string? Direction { get; set; } [DomName("dataset")] IStringMap Dataset { get; } [DomName("translate")] bool IsTranslated { get; set; } [DomName("tabIndex")] int TabIndex { get; set; } [DomName("spellcheck")] bool IsSpellChecked { get; set; } [DomName("contentEditable")] string? ContentEditable { get; set; } [DomName("isContentEditable")] bool IsContentEditable { get; } [DomName("hidden")] bool IsHidden { get; set; } [DomName("draggable")] bool IsDraggable { get; set; } [DomName("accessKey")] string? AccessKey { get; set; } [DomName("accessKeyLabel")] string? AccessKeyLabel { get; } [DomName("contextMenu")] IHtmlMenuElement? ContextMenu { get; set; } [DomName("dropzone")] [DomPutForwards("value")] ISettableTokenList DropZone { get; } [DomName("click")] void DoClick(); [DomName("focus")] void DoFocus(); [DomName("blur")] void DoBlur(); [DomName("forceSpellCheck")] void DoSpellCheck(); } [DomName("HTMLEmbedElement")] public interface IHtmlEmbedElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILoadableElement { [DomName("src")] string? Source { get; set; } [DomName("type")] string? Type { get; set; } [DomName("width")] string? DisplayWidth { get; set; } [DomName("height")] string? DisplayHeight { get; set; } } [DomName("HTMLFieldSetElement")] public interface IHtmlFieldSetElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { [DomName("disabled")] bool IsDisabled { get; set; } [DomName("form")] IHtmlFormElement? Form { get; } [DomName("name")] string? Name { get; set; } [DomName("type")] string Type { get; } [DomName("elements")] IHtmlFormControlsCollection Elements { get; } } [DomName("HTMLFormControlsCollection")] public interface IHtmlFormControlsCollection : IHtmlCollection, IEnumerable, IEnumerable { } [DomName("HTMLFormElement")] public interface IHtmlFormElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("acceptCharset")] string? AcceptCharset { get; set; } [DomName("action")] string Action { get; set; } [DomName("autocomplete")] string? Autocomplete { get; set; } [DomName("enctype")] string? Enctype { get; set; } [DomName("encoding")] string Encoding { get; set; } [DomName("method")] string Method { get; set; } [DomName("name")] string? Name { get; set; } [DomName("noValidate")] bool NoValidate { get; set; } [DomName("target")] string Target { get; set; } [DomName("length")] int Length { get; } [DomName("elements")] IHtmlFormControlsCollection Elements { get; } [DomAccessor(Accessors.Getter)] IElement? this[int index] { get; } [DomAccessor(Accessors.Getter)] IElement? this[string name] { get; } [DomName("submit")] Task SubmitAsync(); Task SubmitAsync(IHtmlElement sourceElement); DocumentRequest? GetSubmission(); DocumentRequest? GetSubmission(IHtmlElement sourceElement); [DomName("reset")] void Reset(); [DomName("checkValidity")] bool CheckValidity(); [DomName("reportValidity")] bool ReportValidity(); [DomName("requestAutocomplete")] void RequestAutocomplete(); } [DomName("HTMLHeadElement")] public interface IHtmlHeadElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLHeadingElement")] public interface IHtmlHeadingElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLHRElement")] public interface IHtmlHrElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLHtmlElement")] public interface IHtmlHtmlElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("manifest")] string? Manifest { get; set; } } [DomName("HTMLImageElement")] public interface IHtmlImageElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILoadableElement { [DomName("alt")] string? AlternativeText { get; set; } [DomName("currentSrc")] string? ActualSource { get; } [DomName("src")] string? Source { get; set; } [DomName("srcset")] string? SourceSet { get; set; } [DomName("sizes")] string? Sizes { get; set; } [DomName("crossOrigin")] string? CrossOrigin { get; set; } [DomName("useMap")] string? UseMap { get; set; } [DomName("isMap")] bool IsMap { get; set; } [DomName("width")] int DisplayWidth { get; set; } [DomName("height")] int DisplayHeight { get; set; } [DomName("naturalWidth")] int OriginalWidth { get; } [DomName("naturalHeight")] int OriginalHeight { get; } [DomName("complete")] bool IsCompleted { get; } } [DomName("HTMLIFrameElement")] public interface IHtmlInlineFrameElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILoadableElement { [DomName("src")] string? Source { get; set; } [DomName("srcdoc")] string? ContentHtml { get; set; } [DomName("name")] string? Name { get; set; } [DomName("sandbox")] ISettableTokenList Sandbox { get; } [DomName("seamless")] bool IsSeamless { get; set; } [DomName("allowFullscreen")] bool IsFullscreenAllowed { get; set; } [DomName("allowPaymentRequest")] bool IsPaymentRequestAllowed { get; set; } [DomName("referrerPolicy")] string? ReferrerPolicy { get; set; } [DomName("width")] int DisplayWidth { get; set; } [DomName("height")] int DisplayHeight { get; set; } [DomName("contentDocument")] IDocument? ContentDocument { get; } [DomName("contentWindow")] IWindow? ContentWindow { get; } } [DomName("HTMLInputElement")] public interface IHtmlInputElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { [DomName("autofocus")] bool Autofocus { get; set; } [DomName("accept")] string? Accept { get; set; } [DomName("autocomplete")] string? Autocomplete { get; set; } [DomName("disabled")] bool IsDisabled { get; set; } [DomName("form")] IHtmlFormElement? Form { get; } [DomName("labels")] INodeList Labels { get; } [DomName("files")] IFileList? Files { get; } [DomName("name")] string? Name { get; set; } [DomName("type")] string Type { get; set; } [DomName("required")] bool IsRequired { get; set; } [DomName("readOnly")] bool IsReadOnly { get; set; } [DomName("alt")] string? AlternativeText { get; set; } [DomName("src")] string? Source { get; set; } [DomName("max")] string? Maximum { get; set; } [DomName("min")] string? Minimum { get; set; } [DomName("pattern")] string? Pattern { get; set; } [DomName("step")] string? Step { get; set; } [DomName("list")] IHtmlDataListElement? List { get; } [DomName("formAction")] string? FormAction { get; set; } [DomName("formEncType")] string FormEncType { get; set; } [DomName("formMethod")] string FormMethod { get; set; } [DomName("formNoValidate")] bool FormNoValidate { get; set; } [DomName("formTarget")] string? FormTarget { get; set; } [DomName("defaultValue")] string DefaultValue { get; set; } [DomName("value")] string Value { get; set; } bool HasValue { get; } [DomName("valueAsNumber")] double ValueAsNumber { get; set; } [DomName("valueAsDate")] DateTime? ValueAsDate { get; set; } [DomName("indeterminate")] bool IsIndeterminate { get; set; } [DomName("defaultChecked")] bool IsDefaultChecked { get; set; } [DomName("checked")] bool IsChecked { get; set; } [DomName("size")] int Size { get; set; } [DomName("multiple")] bool IsMultiple { get; set; } [DomName("maxLength")] int MaxLength { get; set; } [DomName("minLength")] int MinLength { get; set; } [DomName("placeholder")] string? Placeholder { get; set; } [DomName("width")] int DisplayWidth { get; set; } [DomName("height")] int DisplayHeight { get; set; } [DomName("selectionDirection")] string? SelectionDirection { get; } [DomName("dirName")] string? DirectionName { get; set; } [DomName("selectionStart")] int SelectionStart { get; set; } [DomName("selectionEnd")] int SelectionEnd { get; set; } [DomName("stepUp")] void StepUp(int n = 1); [DomName("stepDown")] void StepDown(int n = 1); [DomName("select")] void SelectAll(); [DomName("setSelectionRange")] void Select(int selectionStart, int selectionEnd, string? selectionDirection = null); } [DomName("HTMLKeygenElement")] public interface IHtmlKeygenElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { [DomName("autofocus")] bool Autofocus { get; set; } [DomName("labels")] INodeList Labels { get; } [DomName("disabled")] bool IsDisabled { get; set; } [DomName("form")] IHtmlFormElement? Form { get; } [DomName("name")] string? Name { get; set; } [DomName("type")] string Type { get; } [DomName("keytype")] string? KeyEncryption { get; set; } [DomName("challenge")] string? Challenge { get; set; } } [DomName("HTMLLabelElement")] public interface IHtmlLabelElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("form")] IHtmlFormElement? Form { get; } [DomName("htmlFor")] string? HtmlFor { get; set; } [DomName("control")] IHtmlElement? Control { get; } } [DomName("HTMLLegendElement")] public interface IHtmlLegendElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("form")] IHtmlFormElement? Form { get; } } [DomName("HTMLLinkElement")] public interface IHtmlLinkElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILinkStyle, ILinkImport, ILoadableElement { [DomName("disabled")] bool IsDisabled { get; set; } [DomName("href")] string? Href { get; set; } [DomName("rel")] string? Relation { get; set; } [DomName("rev")] string? ReverseRelation { get; set; } [DomName("relList")] ITokenList RelationList { get; } [DomName("media")] string? Media { get; set; } [DomName("hreflang")] string? TargetLanguage { get; set; } [DomName("type")] string? Type { get; set; } [DomName("sizes")] ISettableTokenList Sizes { get; } [DomName("integrity")] string? Integrity { get; set; } [DomName("crossOrigin")] string? CrossOrigin { get; set; } [DomName("nonce")] string? NumberUsedOnce { get; set; } } [DomName("HTMLLIElement")] public interface IHtmlListItemElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("value")] int? Value { get; set; } } [DomName("HTMLMapElement")] public interface IHtmlMapElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("name")] string? Name { get; set; } [DomName("areas")] IHtmlCollection Areas { get; } [DomName("images")] IHtmlCollection Images { get; } } [DomName("HTMLMarqueeElement")] public interface IHtmlMarqueeElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { int MinimumDelay { get; } [DomName("scrollamount")] int ScrollAmount { get; set; } [DomName("scrolldelay")] int ScrollDelay { get; set; } [DomName("loop")] int Loop { get; set; } } [DomName("HTMLMediaElement")] public interface IHtmlMediaElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IMediaController, ILoadableElement { [DomName("src")] string? Source { get; set; } [DomName("crossOrigin")] string? CrossOrigin { get; set; } [DomName("preload")] string? Preload { get; set; } [DomName("mediaGroup")] string? MediaGroup { get; set; } [DomName("networkState")] MediaNetworkState NetworkState { get; } [DomName("seeking")] bool IsSeeking { get; } [DomName("currentSrc")] string? CurrentSource { get; } [DomName("error")] IMediaError? MediaError { get; } [DomName("controller")] IMediaController? Controller { get; } [DomName("ended")] bool IsEnded { get; } [DomName("autoplay")] bool IsAutoplay { get; set; } [DomName("loop")] bool IsLoop { get; set; } [DomName("controls")] bool IsShowingControls { get; set; } [DomName("defaultMuted")] bool IsDefaultMuted { get; set; } [DomName("startDate")] DateTime StartDate { get; } [DomName("audioTracks")] IAudioTrackList? AudioTracks { get; } [DomName("videoTracks")] IVideoTrackList? VideoTracks { get; } [DomName("textTracks")] ITextTrackList? TextTracks { get; } [DomName("load")] void Load(); [DomName("canPlayType")] string CanPlayType(string type); [DomName("addTextTrack")] ITextTrack AddTextTrack(string kind, string? label = null, string? language = null); } [DomName("HTMLMenuElement")] public interface IHtmlMenuElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("label")] string? Label { get; set; } [DomName("type")] string? Type { get; set; } } [DomName("HTMLMenuItemElement")] public interface IHtmlMenuItemElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("command")] IHtmlElement? Command { get; } [DomName("type")] string? Type { get; set; } [DomName("label")] string? Label { get; set; } [DomName("icon")] string? Icon { get; set; } [DomName("disabled")] bool IsDisabled { get; set; } [DomName("checked")] bool IsChecked { get; set; } [DomName("default")] bool IsDefault { get; set; } [DomName("radiogroup")] string? RadioGroup { get; set; } } [DomName("HTMLMetaElement")] public interface IHtmlMetaElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("name")] string? Name { get; set; } [DomName("httpEquiv")] string? HttpEquivalent { get; set; } string? Charset { get; set; } [DomName("content")] string? Content { get; set; } } [DomName("HTMLMeterElement")] public interface IHtmlMeterElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILabelabelElement { [DomName("value")] double Value { get; set; } [DomName("min")] double Minimum { get; set; } [DomName("max")] double Maximum { get; set; } [DomName("low")] double Low { get; set; } [DomName("high")] double High { get; set; } [DomName("optimum")] double Optimum { get; set; } } [DomName("HTMLModElement")] public interface IHtmlModElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("cite")] string? Citation { get; set; } [DomName("datetime")] string? DateTime { get; set; } } [DomName("HTMLObjectElement")] public interface IHtmlObjectElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation, ILoadableElement { [DomName("data")] string? Source { get; set; } [DomName("type")] string? Type { get; set; } [DomName("typeMustMatch")] bool TypeMustMatch { get; set; } [DomName("name")] string? Name { get; set; } [DomName("useMap")] string? UseMap { get; set; } [DomName("form")] IHtmlFormElement? Form { get; } [DomName("width")] int DisplayWidth { get; set; } [DomName("height")] int DisplayHeight { get; set; } [DomName("contentDocument")] IDocument? ContentDocument { get; } [DomName("contentWindow")] IWindow? ContentWindow { get; } } [DomName("HTMLOptionElement")] public interface IHtmlOptionElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("disabled")] bool IsDisabled { get; set; } [DomName("form")] IHtmlFormElement? Form { get; } [DomName("label")] string? Label { get; set; } [DomName("defaultSelected")] bool IsDefaultSelected { get; set; } [DomName("selected")] bool IsSelected { get; set; } [DomName("value")] string Value { get; set; } [DomName("text")] string Text { get; set; } [DomName("index")] int Index { get; } } [DomName("HTMLOptionsCollection")] public interface IHtmlOptionsCollection : IHtmlCollection, IEnumerable, IEnumerable { [DomName("selectedIndex")] int SelectedIndex { get; set; } [DomAccessor(Accessors.Getter)] IHtmlOptionElement GetOptionAt(int index); [DomAccessor(Accessors.Setter)] void SetOptionAt(int index, IHtmlOptionElement option); [DomName("add")] void Add(IHtmlOptionElement element, IHtmlElement? before = null); [DomName("add")] void Add(IHtmlOptionsGroupElement element, IHtmlElement? before = null); [DomName("remove")] void Remove(int index); } [DomName("HTMLOptGroupElement")] public interface IHtmlOptionsGroupElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("disabled")] bool IsDisabled { get; set; } [DomName("label")] string? Label { get; set; } } [DomName("HTMLOListElement")] public interface IHtmlOrderedListElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("reversed")] bool IsReversed { get; set; } [DomName("start")] int Start { get; set; } [DomName("type")] string? Type { get; set; } } [DomName("HTMLOutputElement")] public interface IHtmlOutputElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { [DomName("htmlFor")] ISettableTokenList HtmlFor { get; } [DomName("defaultValue")] string DefaultValue { get; set; } [DomName("value")] string Value { get; set; } [DomName("labels")] INodeList Labels { get; } [DomName("type")] string Type { get; } [DomName("form")] IHtmlFormElement? Form { get; } [DomName("name")] string? Name { get; set; } } [DomName("HTMLParagraphElement")] public interface IHtmlParagraphElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLParamElement")] public interface IHtmlParamElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("name")] string? Name { get; set; } [DomName("value")] string? Value { get; set; } } [DomName("HTMLPictureElement")] public interface IHtmlPictureElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLPreElement")] public interface IHtmlPreElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLProgressElement")] public interface IHtmlProgressElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILabelabelElement { [DomName("value")] double Value { get; set; } [DomName("max")] double Maximum { get; set; } [DomName("position")] double Position { get; } } [DomName("HTMLQuoteElement")] public interface IHtmlQuoteElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("cite")] string? Citation { get; set; } } [DomName("HTMLScriptElement")] public interface IHtmlScriptElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILoadableElement { [DomName("src")] string? Source { get; set; } [DomName("async")] bool IsAsync { get; set; } [DomName("defer")] bool IsDeferred { get; set; } [DomName("type")] string? Type { get; set; } [DomName("charset")] string? CharacterSet { get; set; } [DomName("crossOrigin")] string? CrossOrigin { get; set; } [DomName("text")] string Text { get; set; } [DomName("integrity")] string? Integrity { get; set; } } [DomName("HTMLSelectElement")] public interface IHtmlSelectElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { [DomName("autofocus")] bool Autofocus { get; set; } [DomName("disabled")] bool IsDisabled { get; set; } [DomName("form")] IHtmlFormElement? Form { get; } [DomName("labels")] INodeList Labels { get; } [DomName("name")] string? Name { get; set; } [DomName("value")] string? Value { get; set; } [DomName("type")] string Type { get; } [DomName("required")] bool IsRequired { get; set; } [DomName("selectedOptions")] IHtmlCollection SelectedOptions { get; } [DomName("size")] int Size { get; set; } [DomName("options")] IHtmlOptionsCollection Options { get; } [DomName("length")] int Length { get; } [DomName("multiple")] bool IsMultiple { get; set; } [DomName("selectedIndex")] int SelectedIndex { get; } [DomAccessor(Accessors.Getter | Accessors.Setter)] IHtmlOptionElement this[int index] { get; set; } [DomName("add")] void AddOption(IHtmlOptionElement element, IHtmlElement? before = null); [DomName("add")] void AddOption(IHtmlOptionsGroupElement element, IHtmlElement? before = null); [DomName("remove")] void RemoveOptionAt(int index); } [DomName("HTMLSlotElement")] public interface IHtmlSlotElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("name")] string? Name { get; set; } [DomName("getDistributedNodes")] IEnumerable GetDistributedNodes(); } [DomName("HTMLSourceElement")] public interface IHtmlSourceElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("src")] string? Source { get; set; } [DomName("srcset")] string? SourceSet { get; set; } [DomName("sizes")] string? Sizes { get; set; } [DomName("type")] string? Type { get; set; } [DomName("media")] string? Media { get; set; } } [DomName("HTMLSpanElement")] public interface IHtmlSpanElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLStyleElement")] public interface IHtmlStyleElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILinkStyle { [DomName("disabled")] bool IsDisabled { get; set; } [DomName("media")] string? Media { get; set; } [DomName("type")] string? Type { get; set; } [DomName("scoped")] bool IsScoped { get; set; } } [DomName("HTMLTableCaptionElement")] public interface IHtmlTableCaptionElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLTableCellElement")] public interface IHtmlTableCellElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("colSpan")] int ColumnSpan { get; set; } [DomName("rowSpan")] int RowSpan { get; set; } [DomName("headers")] ISettableTokenList Headers { get; } [DomName("cellIndex")] int Index { get; } } [DomName("HTMLTableColElement")] public interface IHtmlTableColumnElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("span")] int Span { get; set; } } [DomName("HTMLTableDataCellElement")] public interface IHtmlTableDataCellElement : IHtmlTableCellElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLTableElement")] public interface IHtmlTableElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("caption")] IHtmlTableCaptionElement? Caption { get; set; } [DomName("tHead")] IHtmlTableSectionElement? Head { get; set; } [DomName("tFoot")] IHtmlTableSectionElement? Foot { get; set; } [DomName("tBodies")] IHtmlCollection Bodies { get; } [DomName("rows")] IHtmlCollection Rows { get; } [DomName("border")] uint Border { get; set; } [DomName("createCaption")] IHtmlTableCaptionElement CreateCaption(); [DomName("deleteCaption")] void DeleteCaption(); [DomName("createTHead")] IHtmlTableSectionElement CreateHead(); [DomName("deleteTHead")] void DeleteHead(); [DomName("createTFoot")] IHtmlTableSectionElement CreateFoot(); [DomName("deleteTFoot")] void DeleteFoot(); [DomName("createTBody")] IHtmlTableSectionElement CreateBody(); [DomName("insertRow")] IHtmlTableRowElement InsertRowAt(int index = -1); [DomName("deleteRow")] void RemoveRowAt(int index); } [DomName("HTMLTableHeaderCellElement")] public interface IHtmlTableHeaderCellElement : IHtmlTableCellElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("scope")] string? Scope { get; set; } } [DomName("HTMLTableRowElement")] public interface IHtmlTableRowElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("rowIndex")] int Index { get; } [DomName("sectionRowIndex")] int IndexInSection { get; } [DomName("cells")] IHtmlCollection Cells { get; } [DomName("insertCell")] IHtmlTableCellElement InsertCellAt(int index = -1, TableCellKind tableCellKind = TableCellKind.Td); [DomName("deleteCell")] void RemoveCellAt(int index); } [DomName("HTMLTableSectionElement")] public interface IHtmlTableSectionElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("rows")] IHtmlCollection Rows { get; } [DomName("insertRow")] IHtmlTableRowElement InsertRowAt(int index = -1); [DomName("deleteRow")] void RemoveRowAt(int index); } [DomName("HTMLTemplateElement")] public interface IHtmlTemplateElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("content")] IDocumentFragment Content { get; } } [DomName("HTMLTextAreaElement")] public interface IHtmlTextAreaElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { [DomName("autofocus")] bool Autofocus { get; set; } [DomName("disabled")] bool IsDisabled { get; set; } [DomName("form")] IHtmlFormElement? Form { get; } [DomName("labels")] INodeList Labels { get; } [DomName("name")] string? Name { get; set; } [DomName("type")] string Type { get; } [DomName("required")] bool IsRequired { get; set; } [DomName("readOnly")] bool IsReadOnly { get; set; } [DomName("defaultValue")] string DefaultValue { get; set; } [DomName("value")] string Value { get; set; } [DomName("wrap")] string? Wrap { get; set; } [DomName("textLength")] int TextLength { get; } [DomName("rows")] int Rows { get; set; } [DomName("cols")] int Columns { get; set; } [DomName("maxLength")] int MaxLength { get; set; } [DomName("placeholder")] string? Placeholder { get; set; } [DomName("selectionDirection")] string? SelectionDirection { get; } [DomName("dirName")] string? DirectionName { get; set; } [DomName("selectionStart")] int SelectionStart { get; set; } [DomName("selectionEnd")] int SelectionEnd { get; set; } [DomName("select")] void SelectAll(); [DomName("setSelectionRange")] void Select(int selectionStart, int selectionEnd, string? selectionDirection = null); } [DomName("HTMLTimeElement")] public interface IHtmlTimeElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("datetime")] string? DateTime { get; set; } } [DomName("HTMLTitleElement")] public interface IHtmlTitleElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("text")] string Text { get; set; } } [DomName("HTMLTrackElement")] public interface IHtmlTrackElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { [DomName("kind")] string? Kind { get; set; } [DomName("src")] string? Source { get; set; } [DomName("srclang")] string? SourceLanguage { get; set; } [DomName("label")] string? Label { get; set; } [DomName("default")] bool IsDefault { get; set; } [DomName("readyState")] TrackReadyState ReadyState { get; } [DomName("track")] ITextTrack? Track { get; } } [DomName("HTMLUnknownElement")] public interface IHtmlUnknownElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLUListElement")] public interface IHtmlUnorderedListElement : IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { } [DomName("HTMLVideoElement")] public interface IHtmlVideoElement : IHtmlMediaElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IMediaController, ILoadableElement { [DomName("width")] int DisplayWidth { get; set; } [DomName("height")] int DisplayHeight { get; set; } [DomName("videoWidth")] int OriginalWidth { get; } [DomName("videoHeight")] int OriginalHeight { get; } [DomName("poster")] string? Poster { get; set; } } [DomNoInterfaceObject] public interface ILabelabelElement { [DomName("labels")] INodeList Labels { get; } } public static class ImageExtensions { public static Stack GetSources(this IHtmlImageElement img) { IElement parentElement = img.ParentElement; Stack stack = new Stack(); 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; } } internal enum Alignment : byte { Bottom, Middle, Top, Left, Right } internal sealed class HtmlAddressElement : HtmlElement { public HtmlAddressElement(Document owner, string? prefix = null) : base(owner, TagNames.Address, prefix, NodeFlags.Special) { } } internal sealed class HtmlAnchorElement : HtmlUrlBaseElement, IHtmlAnchorElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IUrlUtilities { public string? Charset { get { return this.GetOwnAttribute(AttributeNames.Charset); } set { this.SetOwnAttribute(AttributeNames.Charset, value); } } public string? Name { get { return this.GetOwnAttribute(AttributeNames.Name); } set { this.SetOwnAttribute(AttributeNames.Name, value); } } public string Text { get { return TextContent; } set { TextContent = value; } } public HtmlAnchorElement(Document owner, string? prefix = null) : base(owner, TagNames.A, prefix, NodeFlags.HtmlFormatting) { } public override void DoFocus() { if (this.HasOwnAttribute(AttributeNames.Href)) { base.IsFocused = true; } } } [DomHistorical] internal sealed class HtmlAppletElement : HtmlElement { public HtmlAppletElement(Document owner, string? prefix = null) : base(owner, TagNames.Applet, prefix, NodeFlags.Special | NodeFlags.Scoped) { } } internal sealed class HtmlAreaElement : HtmlUrlBaseElement, IHtmlAreaElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IUrlUtilities { public string? AlternativeText { get { return this.GetOwnAttribute(AttributeNames.Alt); } set { this.SetOwnAttribute(AttributeNames.Alt, value); } } public string? Coordinates { get { return this.GetOwnAttribute(AttributeNames.Coords); } set { this.SetOwnAttribute(AttributeNames.Coords, value); } } public string? Shape { get { return this.GetOwnAttribute(AttributeNames.Shape); } set { this.SetOwnAttribute(AttributeNames.Shape, value); } } public HtmlAreaElement(Document owner, string? prefix = null) : base(owner, TagNames.Area, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } internal sealed class HtmlAudioElement : HtmlMediaElement, IHtmlAudioElement, IHtmlMediaElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IMediaController, ILoadableElement { private IAudioTrackList? _audios; public override IAudioTrackList? AudioTracks => _audios; public HtmlAudioElement(Document owner, string? prefix = null) : base(owner, TagNames.Audio, prefix) { _audios = null; } } internal sealed class HtmlBaseElement : HtmlElement, IHtmlBaseElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Href { get { return this.GetOwnAttribute(AttributeNames.Href); } set { this.SetOwnAttribute(AttributeNames.Href, value); } } public string? Target { get { return this.GetOwnAttribute(AttributeNames.Target); } set { this.SetOwnAttribute(AttributeNames.Target, value); } } public HtmlBaseElement(Document owner, string? prefix = null) : base(owner, TagNames.Base, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } internal override void SetupElement() { base.SetupElement(); string ownAttribute = this.GetOwnAttribute(AttributeNames.Href); if (ownAttribute != null) { UpdateUrl(ownAttribute); } } internal void UpdateUrl(string url) { base.Owner.BaseUrl = new Url(base.Owner.DocumentUrl, url ?? string.Empty); } } [DomHistorical] internal sealed class HtmlBaseFontElement : HtmlElement { public HtmlBaseFontElement(Document owner, string? prefix = null) : base(owner, TagNames.BaseFont, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } [DomHistorical] internal sealed class HtmlBgsoundElement : HtmlElement { public HtmlBgsoundElement(Document owner, string? prefix = null) : base(owner, TagNames.Bgsound, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } internal sealed class HtmlBigElement : HtmlElement { public HtmlBigElement(Document owner, string? prefix = null) : base(owner, TagNames.Big, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlBodyElement : HtmlElement, IHtmlBodyElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IWindowEventHandlers { public string? ALink { get { return this.GetOwnAttribute(AttributeNames.Alink); } set { this.SetOwnAttribute(AttributeNames.Alink, value); } } public string? Background { get { return this.GetOwnAttribute(AttributeNames.Background); } set { this.SetOwnAttribute(AttributeNames.Background, value); } } public string? BgColor { get { return this.GetOwnAttribute(AttributeNames.BgColor); } set { this.SetOwnAttribute(AttributeNames.BgColor, value); } } public string? Link { get { return this.GetOwnAttribute(AttributeNames.Link); } set { this.SetOwnAttribute(AttributeNames.Link, value); } } public string? Text { get { return this.GetOwnAttribute(AttributeNames.Text); } set { this.SetOwnAttribute(AttributeNames.Text, value); } } public string? VLink { get { return this.GetOwnAttribute(AttributeNames.Vlink); } set { this.SetOwnAttribute(AttributeNames.Vlink, value); } } public event DomEventHandler Printed { add { AddEventListener(EventNames.AfterPrint, value); } remove { RemoveEventListener(EventNames.AfterPrint, value); } } public event DomEventHandler Printing { add { AddEventListener(EventNames.BeforePrint, value); } remove { RemoveEventListener(EventNames.BeforePrint, value); } } public event DomEventHandler Unloading { add { AddEventListener(EventNames.Unloading, value); } remove { RemoveEventListener(EventNames.Unloading, value); } } public event DomEventHandler HashChanged { add { AddEventListener(EventNames.HashChange, value); } remove { RemoveEventListener(EventNames.HashChange, value); } } public event DomEventHandler MessageReceived { add { AddEventListener(EventNames.Message, value); } remove { RemoveEventListener(EventNames.Message, value); } } public event DomEventHandler WentOffline { add { AddEventListener(EventNames.Offline, value); } remove { RemoveEventListener(EventNames.Offline, value); } } public event DomEventHandler WentOnline { add { AddEventListener(EventNames.Online, value); } remove { RemoveEventListener(EventNames.Online, value); } } public event DomEventHandler PageHidden { add { AddEventListener(EventNames.PageHide, value); } remove { RemoveEventListener(EventNames.PageHide, value); } } public event DomEventHandler PageShown { add { AddEventListener(EventNames.PageShow, value); } remove { RemoveEventListener(EventNames.PageShow, value); } } public event DomEventHandler PopState { add { AddEventListener(EventNames.PopState, value); } remove { RemoveEventListener(EventNames.PopState, value); } } public event DomEventHandler Storage { add { AddEventListener(EventNames.Storage, value); } remove { RemoveEventListener(EventNames.Storage, value); } } public event DomEventHandler Unloaded { add { AddEventListener(EventNames.Unload, value); } remove { RemoveEventListener(EventNames.Unload, value); } } public HtmlBodyElement(Document owner, string? prefix = null) : base(owner, TagNames.Body, prefix, NodeFlags.Special | NodeFlags.ImplicitlyClosed) { } } internal sealed class HtmlBoldElement : HtmlElement { public HtmlBoldElement(Document owner, string? prefix = null) : base(owner, TagNames.B, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlBreakRowElement : HtmlElement, IHtmlBreakRowElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlBreakRowElement(Document owner, string? prefix = null) : base(owner, TagNames.Br, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } internal sealed class HtmlButtonElement : HtmlFormControlElement, IHtmlButtonElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { public string Type { get { return (this.GetOwnAttribute(AttributeNames.Type) ?? InputTypeNames.Submit).ToLowerInvariant(); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public string? FormAction { get { string text = this.GetOwnAttribute(AttributeNames.FormAction); if (text == null) { Document owner = base.Owner; if (owner == null) { return null; } text = owner.DocumentUri; } return text; } set { this.SetOwnAttribute(AttributeNames.FormAction, value); } } public string FormEncType { get { return this.GetOwnAttribute(AttributeNames.FormEncType).ToEncodingType() ?? string.Empty; } set { this.SetOwnAttribute(AttributeNames.FormEncType, value); } } public string FormMethod { get { return this.GetOwnAttribute(AttributeNames.FormMethod).ToFormMethod() ?? string.Empty; } set { this.SetOwnAttribute(AttributeNames.FormMethod, value); } } public bool FormNoValidate { get { return this.GetBoolAttribute(AttributeNames.FormNoValidate); } set { this.SetBoolAttribute(AttributeNames.FormNoValidate, value); } } public string FormTarget { get { return this.GetOwnAttribute(AttributeNames.FormTarget) ?? string.Empty; } [param: AllowNull] set { this.SetOwnAttribute(AttributeNames.FormTarget, value); } } public string Value { get { return this.GetOwnAttribute(AttributeNames.Value) ?? string.Empty; } set { this.SetOwnAttribute(AttributeNames.Value, value); } } internal bool IsVisited { get; set; } internal bool IsActive { get; set; } public HtmlButtonElement(Document owner, string? prefix = null) : base(owner, TagNames.Button, prefix) { } public override async void DoClick() { bool num = await IsClickedCancelled().ConfigureAwait(continueOnCapturedContext: false); IHtmlFormElement form = base.Form; if (!num && form != null) { string type = Type; if (type.Is(InputTypeNames.Submit)) { await form.SubmitAsync(this).ConfigureAwait(continueOnCapturedContext: false); } else if (type.Is(InputTypeNames.Reset)) { form.Reset(); } } } protected override bool CanBeValidated() { if (Type.Is(InputTypeNames.Submit)) { return !this.HasDataListAncestor(); } return false; } internal override void ConstructDataSet(FormDataSet dataSet, IHtmlElement submitter) { string type = Type; if (this == submitter && type.IsOneOf(InputTypeNames.Submit, InputTypeNames.Reset)) { dataSet.Append(base.Name, Value, type); } } } internal sealed class HtmlCanvasElement : HtmlElement, IHtmlCanvasElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private enum ContextMode : byte { None, Direct2d, DirectWebGl, Indirect, Proxied } private readonly IEnumerable _renderServices; private ContextMode _mode; private IRenderingContext? _current; public int Width { get { return this.GetOwnAttribute(AttributeNames.Width).ToInteger(300); } set { this.SetOwnAttribute(AttributeNames.Width, value.ToString()); } } public int Height { get { return this.GetOwnAttribute(AttributeNames.Height).ToInteger(150); } set { this.SetOwnAttribute(AttributeNames.Height, value.ToString()); } } public HtmlCanvasElement(Document owner, string? prefix = null) : base(owner, TagNames.Canvas, prefix) { _renderServices = owner.Context.GetServices(); _mode = ContextMode.None; } public IRenderingContext GetContext(string contextId) { if (_current == null || contextId.Isi(_current.ContextId)) { foreach (IRenderingService renderService in _renderServices) { if (renderService.IsSupportingContext(contextId)) { IRenderingContext renderingContext = renderService.CreateContext(this, contextId); if (renderingContext != null) { _mode = GetModeFrom(contextId); _current = renderingContext; } return renderingContext; } } return null; } return _current; } public bool IsSupportingContext(string contextId) { foreach (IRenderingService renderService in _renderServices) { if (renderService.IsSupportingContext(contextId)) { return true; } } return false; } public void SetContext(IRenderingContext context) { if (_mode != ContextMode.None && _mode != ContextMode.Indirect) { throw new DomException(DomError.InvalidState); } if (context.IsFixed) { throw new DomException(DomError.InvalidState); } if (context.Host != this) { throw new DomException(DomError.InUse); } _current = context; _mode = ContextMode.Indirect; } public string ToDataUrl(string? type = null) { return Convert.ToBase64String(GetImageData(type)); } public void ToBlob(Action callback, string? type = null) { MemoryStream obj = new MemoryStream(GetImageData(type)); callback(obj); } private byte[] GetImageData(string? type) { return _current?.ToImage(type ?? MimeTypeNames.Plain) ?? Array.Empty(); } private static ContextMode GetModeFrom(string contextId) { if (contextId.Isi(Keywords.TwoD)) { return ContextMode.Direct2d; } if (contextId.Isi(Keywords.WebGl)) { return ContextMode.DirectWebGl; } return ContextMode.None; } } internal sealed class HtmlCodeElement : HtmlElement { public HtmlCodeElement(Document owner, string? prefix = null) : base(owner, TagNames.Code, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlDataElement : HtmlElement, IHtmlDataElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Value { get { return this.GetOwnAttribute(AttributeNames.Value); } set { this.SetOwnAttribute(AttributeNames.Value, value); } } public HtmlDataElement(Document owner, string? prefix = null) : base(owner, TagNames.Data, prefix) { } } internal sealed class HtmlDataListElement : HtmlElement, IHtmlDataListElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private HtmlCollection? _options; public IHtmlCollection Options => _options ?? (_options = new HtmlCollection(this)); public HtmlDataListElement(Document owner, string? prefix = null) : base(owner, TagNames.Datalist, prefix) { } } internal sealed class HtmlDefinitionListElement : HtmlElement { public HtmlDefinitionListElement(Document owner, string? prefix = null) : base(owner, TagNames.Dl, prefix, NodeFlags.Special) { } } internal sealed class HtmlDetailsElement : HtmlElement, IHtmlDetailsElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public bool IsOpen { get { return this.GetBoolAttribute(AttributeNames.Open); } set { this.SetBoolAttribute(AttributeNames.Open, value); } } public HtmlDetailsElement(Document owner, string? prefix = null) : base(owner, TagNames.Details, prefix, NodeFlags.Special) { } } internal sealed class HtmlDialogElement : HtmlElement, IHtmlDialogElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private string? _returnValue; public bool Open { get { return this.GetBoolAttribute(AttributeNames.Open); } set { this.SetBoolAttribute(AttributeNames.Open, value); } } public string? ReturnValue { get { return _returnValue; } set { _returnValue = value; } } public HtmlDialogElement(Document owner, string? prefix = null) : base(owner, TagNames.Dialog, prefix) { } public void Show(IElement? anchor = null) { Open = true; } public void ShowModal(IElement? anchor = null) { Open = true; } public void Close(string? returnValue = null) { Open = false; ReturnValue = returnValue; } } [DomHistorical] internal sealed class HtmlDirectoryElement : HtmlElement { public HtmlDirectoryElement(Document owner, string? prefix = null) : base(owner, TagNames.Dir, prefix, NodeFlags.Special) { } } internal sealed class HtmlDivElement : HtmlElement, IHtmlDivElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlDivElement(Document owner, string? prefix = null) : base(owner, TagNames.Div, prefix, NodeFlags.Special) { } } internal sealed class HtmlDocument : Document, IHtmlDocument, IDocument, INode, IEventTarget, IMarkupFormattable, IParentNode, IGlobalEventHandlers, IDocumentStyle, INonElementParentNode, IDisposable { private readonly IElementFactory _htmlFactory; private readonly IElementFactory _mathFactory; private readonly IElementFactory _svgFactory; public override IElement DocumentElement => this.FindChild(); public override IEntityProvider Entities => base.Context.GetProvider() ?? HtmlEntityProvider.Resolver; internal HtmlDocument(IBrowsingContext? context, TextSource source) : base(context ?? BrowsingContext.New(), source) { base.ContentType = MimeTypeNames.Html; _htmlFactory = base.Context.GetFactory>(); _mathFactory = base.Context.GetFactory>(); _svgFactory = base.Context.GetFactory>(); } internal HtmlDocument(IBrowsingContext? context = null) : this(context, new TextSource(string.Empty)) { } public HtmlElement CreateHtmlElement(string name, string? prefix = null, NodeFlags flags = NodeFlags.None) { return _htmlFactory.Create(this, name, prefix, flags); } public MathElement CreateMathElement(string name, string? prefix = null, NodeFlags flags = NodeFlags.None) { return _mathFactory.Create(this, name, prefix, flags); } public SvgElement CreateSvgElement(string name, string? prefix = null, NodeFlags flags = NodeFlags.None) { return _svgFactory.Create(this, name, prefix, flags); } public override Element CreateElementFrom(string name, string? prefix, NodeFlags flags = NodeFlags.None) { return CreateHtmlElement(name, prefix, flags); } public override Node Clone(Document owner, bool deep) { TextSource source = new TextSource(base.Source.Text); HtmlDocument htmlDocument = new HtmlDocument(base.Context, source); CloneDocument(htmlDocument, deep); return htmlDocument; } protected override string GetTitle() { return DocumentElement.FindDescendant()?.TextContent.CollapseAndStrip() ?? base.GetTitle(); } protected override void SetTitle(string? value) { IHtmlTitleElement htmlTitleElement = DocumentElement.FindDescendant(); if (htmlTitleElement == null) { IHtmlHeadElement head = base.Head; if (head == null) { return; } htmlTitleElement = new HtmlTitleElement(this); head.AppendChild(htmlTitleElement); } htmlTitleElement.TextContent = value; } } public class HtmlElement : Element, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private StringMap? _dataset; private IHtmlMenuElement? _menu; private SettableTokenList? _dropZone; public bool IsHidden { get { return this.GetBoolAttribute(AttributeNames.Hidden); } set { this.SetBoolAttribute(AttributeNames.Hidden, value); } } public IHtmlMenuElement? ContextMenu { get { if (_menu == null) { string ownAttribute = this.GetOwnAttribute(AttributeNames.ContextMenu); if (ownAttribute != null && ownAttribute.Length > 0) { return base.Owner.GetElementById(ownAttribute) as IHtmlMenuElement; } } return _menu; } set { _menu = value; } } public ISettableTokenList DropZone { get { if (_dropZone == null) { _dropZone = new SettableTokenList(this.GetOwnAttribute(AttributeNames.DropZone)); _dropZone.Changed += delegate(string value) { UpdateAttribute(AttributeNames.DropZone, value); }; } return _dropZone; } } public bool IsDraggable { get { return this.GetOwnAttribute(AttributeNames.Draggable).ToBoolean(); } set { this.SetOwnAttribute(AttributeNames.Draggable, value.ToString()); } } public string? AccessKey { get { return this.GetOwnAttribute(AttributeNames.AccessKey) ?? string.Empty; } set { this.SetOwnAttribute(AttributeNames.AccessKey, value); } } public string? AccessKeyLabel => AccessKey; public string? Language { get { return this.GetOwnAttribute(AttributeNames.Lang) ?? GetDefaultLanguage(); } set { this.SetOwnAttribute(AttributeNames.Lang, value); } } public string? Title { get { return this.GetOwnAttribute(AttributeNames.Title); } set { this.SetOwnAttribute(AttributeNames.Title, value); } } public string? Direction { get { return this.GetOwnAttribute(AttributeNames.Dir); } set { this.SetOwnAttribute(AttributeNames.Dir, value); } } public bool IsSpellChecked { get { return this.GetOwnAttribute(AttributeNames.Spellcheck).ToBoolean(); } set { this.SetOwnAttribute(AttributeNames.Spellcheck, value.ToString()); } } public int TabIndex { get { return this.GetOwnAttribute(AttributeNames.TabIndex).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.TabIndex, value.ToString()); } } public IStringMap Dataset => _dataset ?? (_dataset = new StringMap("data-", this)); public string? ContentEditable { get { return this.GetOwnAttribute(AttributeNames.ContentEditable); } set { this.SetOwnAttribute(AttributeNames.ContentEditable, value); } } public bool IsContentEditable { get { ContentEditableMode contentEditableMode = ContentEditable.ToEnum(ContentEditableMode.Inherited); if (contentEditableMode != ContentEditableMode.True) { if (contentEditableMode == ContentEditableMode.Inherited && base.ParentElement is IHtmlElement htmlElement) { return htmlElement.IsContentEditable; } return false; } return true; } } public bool IsTranslated { get { return this.GetOwnAttribute(AttributeNames.Translate).ToEnum(SimpleChoice.Yes) == SimpleChoice.Yes; } set { this.SetOwnAttribute(AttributeNames.Translate, value ? Keywords.Yes : Keywords.No); } } public event DomEventHandler Aborted { add { AddEventListener(EventNames.Abort, value); } remove { RemoveEventListener(EventNames.Abort, value); } } public event DomEventHandler Blurred { add { AddEventListener(EventNames.Blur, value); } remove { RemoveEventListener(EventNames.Blur, value); } } public event DomEventHandler Cancelled { add { AddEventListener(EventNames.Cancel, value); } remove { RemoveEventListener(EventNames.Cancel, value); } } public event DomEventHandler CanPlay { add { AddEventListener(EventNames.CanPlay, value); } remove { RemoveEventListener(EventNames.CanPlay, value); } } public event DomEventHandler CanPlayThrough { add { AddEventListener(EventNames.CanPlayThrough, value); } remove { RemoveEventListener(EventNames.CanPlayThrough, value); } } public event DomEventHandler Changed { add { AddEventListener(EventNames.Change, value); } remove { RemoveEventListener(EventNames.Change, value); } } public event DomEventHandler Clicked { add { AddEventListener(EventNames.Click, value); } remove { RemoveEventListener(EventNames.Click, value); } } public event DomEventHandler CueChanged { add { AddEventListener(EventNames.CueChange, value); } remove { RemoveEventListener(EventNames.CueChange, value); } } public event DomEventHandler DoubleClick { add { AddEventListener(EventNames.DblClick, value); } remove { RemoveEventListener(EventNames.DblClick, value); } } public event DomEventHandler Drag { add { AddEventListener(EventNames.Drag, value); } remove { RemoveEventListener(EventNames.Drag, value); } } public event DomEventHandler DragEnd { add { AddEventListener(EventNames.DragEnd, value); } remove { RemoveEventListener(EventNames.DragEnd, value); } } public event DomEventHandler DragEnter { add { AddEventListener(EventNames.DragEnter, value); } remove { RemoveEventListener(EventNames.DragEnter, value); } } public event DomEventHandler DragExit { add { AddEventListener(EventNames.DragExit, value); } remove { RemoveEventListener(EventNames.DragExit, value); } } public event DomEventHandler DragLeave { add { AddEventListener(EventNames.DragLeave, value); } remove { RemoveEventListener(EventNames.DragLeave, value); } } public event DomEventHandler DragOver { add { AddEventListener(EventNames.DragOver, value); } remove { RemoveEventListener(EventNames.DragOver, value); } } public event DomEventHandler DragStart { add { AddEventListener(EventNames.DragStart, value); } remove { RemoveEventListener(EventNames.DragStart, value); } } public event DomEventHandler Dropped { add { AddEventListener(EventNames.Drop, value); } remove { RemoveEventListener(EventNames.Drop, value); } } public event DomEventHandler DurationChanged { add { AddEventListener(EventNames.DurationChange, value); } remove { RemoveEventListener(EventNames.DurationChange, value); } } public event DomEventHandler Emptied { add { AddEventListener(EventNames.Emptied, value); } remove { RemoveEventListener(EventNames.Emptied, value); } } public event DomEventHandler Ended { add { AddEventListener(EventNames.Ended, value); } remove { RemoveEventListener(EventNames.Ended, value); } } public event DomEventHandler Error { add { AddEventListener(EventNames.Error, value); } remove { RemoveEventListener(EventNames.Error, value); } } public event DomEventHandler Focused { add { AddEventListener(EventNames.Focus, value); } remove { RemoveEventListener(EventNames.Focus, value); } } public event DomEventHandler Input { add { AddEventListener(EventNames.Input, value); } remove { RemoveEventListener(EventNames.Input, value); } } public event DomEventHandler Invalid { add { AddEventListener(EventNames.Invalid, value); } remove { RemoveEventListener(EventNames.Invalid, value); } } public event DomEventHandler KeyDown { add { AddEventListener(EventNames.Keydown, value); } remove { RemoveEventListener(EventNames.Keydown, value); } } public event DomEventHandler KeyPress { add { AddEventListener(EventNames.Keypress, value); } remove { RemoveEventListener(EventNames.Keypress, value); } } public event DomEventHandler KeyUp { add { AddEventListener(EventNames.Keyup, value); } remove { RemoveEventListener(EventNames.Keyup, value); } } public event DomEventHandler Loaded { add { AddEventListener(EventNames.Load, value); } remove { RemoveEventListener(EventNames.Load, value); } } public event DomEventHandler LoadedData { add { AddEventListener(EventNames.LoadedData, value); } remove { RemoveEventListener(EventNames.LoadedData, value); } } public event DomEventHandler LoadedMetadata { add { AddEventListener(EventNames.LoadedMetaData, value); } remove { RemoveEventListener(EventNames.LoadedMetaData, value); } } public event DomEventHandler Loading { add { AddEventListener(EventNames.LoadStart, value); } remove { RemoveEventListener(EventNames.LoadStart, value); } } public event DomEventHandler MouseDown { add { AddEventListener(EventNames.Mousedown, value); } remove { RemoveEventListener(EventNames.Mousedown, value); } } public event DomEventHandler MouseEnter { add { AddEventListener(EventNames.Mouseenter, value); } remove { RemoveEventListener(EventNames.Mouseenter, value); } } public event DomEventHandler MouseLeave { add { AddEventListener(EventNames.Mouseleave, value); } remove { RemoveEventListener(EventNames.Mouseleave, value); } } public event DomEventHandler MouseMove { add { AddEventListener(EventNames.Mousemove, value); } remove { RemoveEventListener(EventNames.Mousemove, value); } } public event DomEventHandler MouseOut { add { AddEventListener(EventNames.Mouseout, value); } remove { RemoveEventListener(EventNames.Mouseout, value); } } public event DomEventHandler MouseOver { add { AddEventListener(EventNames.Mouseover, value); } remove { RemoveEventListener(EventNames.Mouseover, value); } } public event DomEventHandler MouseUp { add { AddEventListener(EventNames.Mouseup, value); } remove { RemoveEventListener(EventNames.Mouseup, value); } } public event DomEventHandler MouseWheel { add { AddEventListener(EventNames.Wheel, value); } remove { RemoveEventListener(EventNames.Wheel, value); } } public event DomEventHandler Paused { add { AddEventListener(EventNames.Pause, value); } remove { RemoveEventListener(EventNames.Pause, value); } } public event DomEventHandler Played { add { AddEventListener(EventNames.Play, value); } remove { RemoveEventListener(EventNames.Play, value); } } public event DomEventHandler Playing { add { AddEventListener(EventNames.Playing, value); } remove { RemoveEventListener(EventNames.Playing, value); } } public event DomEventHandler Progress { add { AddEventListener(EventNames.Progress, value); } remove { RemoveEventListener(EventNames.Progress, value); } } public event DomEventHandler RateChanged { add { AddEventListener(EventNames.RateChange, value); } remove { RemoveEventListener(EventNames.RateChange, value); } } public event DomEventHandler Resetted { add { AddEventListener(EventNames.Reset, value); } remove { RemoveEventListener(EventNames.Reset, value); } } public event DomEventHandler Resized { add { AddEventListener(EventNames.Resize, value); } remove { RemoveEventListener(EventNames.Resize, value); } } public event DomEventHandler Scrolled { add { AddEventListener(EventNames.Scroll, value); } remove { RemoveEventListener(EventNames.Scroll, value); } } public event DomEventHandler Seeked { add { AddEventListener(EventNames.Seeked, value); } remove { RemoveEventListener(EventNames.Seeked, value); } } public event DomEventHandler Seeking { add { AddEventListener(EventNames.Seeking, value); } remove { RemoveEventListener(EventNames.Seeking, value); } } public event DomEventHandler Selected { add { AddEventListener(EventNames.Select, value); } remove { RemoveEventListener(EventNames.Select, value); } } public event DomEventHandler Shown { add { AddEventListener(EventNames.Show, value); } remove { RemoveEventListener(EventNames.Show, value); } } public event DomEventHandler Stalled { add { AddEventListener(EventNames.Stalled, value); } remove { RemoveEventListener(EventNames.Stalled, value); } } public event DomEventHandler Submitted { add { AddEventListener(EventNames.Submit, value); } remove { RemoveEventListener(EventNames.Submit, value); } } public event DomEventHandler Suspended { add { AddEventListener(EventNames.Suspend, value); } remove { RemoveEventListener(EventNames.Suspend, value); } } public event DomEventHandler TimeUpdated { add { AddEventListener(EventNames.TimeUpdate, value); } remove { RemoveEventListener(EventNames.TimeUpdate, value); } } public event DomEventHandler Toggled { add { AddEventListener(EventNames.Toggle, value); } remove { RemoveEventListener(EventNames.Toggle, value); } } public event DomEventHandler VolumeChanged { add { AddEventListener(EventNames.VolumeChange, value); } remove { RemoveEventListener(EventNames.VolumeChange, value); } } public event DomEventHandler Waiting { add { AddEventListener(EventNames.Waiting, value); } remove { RemoveEventListener(EventNames.Waiting, value); } } public HtmlElement(Document owner, string localName, string? prefix = null, NodeFlags flags = NodeFlags.None) : base(owner, Combine(prefix, localName), localName, prefix, NamespaceNames.HtmlUri, flags | NodeFlags.HtmlMember) { } public override IElement ParseSubtree(string html) { return this.ParseHtmlSubtree(html); } public void DoSpellCheck() { base.Context?.GetSpellCheck(Language); } public virtual void DoClick() { IsClickedCancelled(); } public virtual void DoFocus() { } public virtual void DoBlur() { } public override Node Clone(Document owner, bool deep) { HtmlElement htmlElement = base.Context.GetFactory>().Create(owner, base.LocalName, base.Prefix); CloneElement(htmlElement, owner, deep); return htmlElement; } internal void UpdateDropZone(string value) { _dropZone?.Update(value); } protected Task IsClickedCancelled() { return base.Owner.QueueTaskAsync((CancellationToken _) => this.Fire(delegate(MouseEvent m) { m.Init(EventNames.Click, bubbles: true, cancelable: true, base.Owner.DefaultView, 0, 0, 0, 0, 0, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false, MouseButton.Primary, this); })); } protected IHtmlFormElement? GetAssignedForm() { INode node = base.Parent; while (node != null && !(node is IHtmlFormElement)) { node = node.ParentElement; } if (node == null) { string ownAttribute = this.GetOwnAttribute(AttributeNames.Form); Document owner = base.Owner; if (owner == null || string.IsNullOrEmpty(ownAttribute)) { return null; } node = owner.GetElementById(ownAttribute); } return node as IHtmlFormElement; } private string? GetDefaultLanguage() { if (!(base.ParentElement is IHtmlElement htmlElement)) { return base.Context.GetLanguage(); } return htmlElement.Language; } private static string Combine(string? prefix, string localName) { return ((prefix != null) ? (prefix + ":" + localName) : localName).ToUpperInvariant(); } } internal sealed class HtmlEmbedElement : HtmlElement, IHtmlEmbedElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILoadableElement { private readonly ObjectRequestProcessor _request; public IDownload? CurrentDownload => _request?.Download; public string? Source { get { return this.GetOwnAttribute(AttributeNames.Src); } set { this.SetOwnAttribute(AttributeNames.Src, value); } } public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public string? DisplayWidth { get { return this.GetOwnAttribute(AttributeNames.Width); } set { this.SetOwnAttribute(AttributeNames.Width, value); } } public string? DisplayHeight { get { return this.GetOwnAttribute(AttributeNames.Height); } set { this.SetOwnAttribute(AttributeNames.Height, value); } } public HtmlEmbedElement(Document owner, string? prefix = null) : base(owner, TagNames.Embed, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { _request = new ObjectRequestProcessor(owner.Context); } internal override void SetupElement() { base.SetupElement(); UpdateSource(this.GetOwnAttribute(AttributeNames.Src)); } internal void UpdateSource(string? value) { if (value != null) { Url url = new Url(Source); this.Process(_request, url); } } } internal sealed class HtmlEmphasizeElement : HtmlElement { public HtmlEmphasizeElement(Document owner, string? prefix = null) : base(owner, TagNames.Em, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlFieldSetElement : HtmlFormControlElement, IHtmlFieldSetElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { private HtmlFormControlsCollection? _elements; public string Type => TagNames.Fieldset; public IHtmlFormControlsCollection Elements => _elements ?? (_elements = new HtmlFormControlsCollection(base.Form, this)); public HtmlFieldSetElement(Document owner, string? prefix = null) : base(owner, TagNames.Fieldset, prefix) { } protected override bool IsFieldsetDisabled() { return false; } protected override bool CanBeValidated() { return true; } } [DomHistorical] internal sealed class HtmlFontElement : HtmlElement { public HtmlFontElement(Document owner, string? prefix = null) : base(owner, TagNames.Font, prefix, NodeFlags.HtmlFormatting) { } } internal abstract class HtmlFormControlElement : HtmlElement, ILabelabelElement, IValidation { private readonly NodeList _labels; private readonly ValidityState _vstate; private string? _error; public string? Name { get { return this.GetOwnAttribute(AttributeNames.Name); } set { this.SetOwnAttribute(AttributeNames.Name, value); } } public IHtmlFormElement? Form => GetAssignedForm(); public bool IsDisabled { get { if (!this.GetBoolAttribute(AttributeNames.Disabled)) { return IsFieldsetDisabled(); } return true; } set { this.SetBoolAttribute(AttributeNames.Disabled, value); } } public bool Autofocus { get { return this.GetBoolAttribute(AttributeNames.AutoFocus); } set { this.SetBoolAttribute(AttributeNames.AutoFocus, value); } } public INodeList Labels => _labels; public string? ValidationMessage { get { if (!_vstate.IsCustomError) { return string.Empty; } return _error; } } public bool WillValidate { get { if (!IsDisabled) { return CanBeValidated(); } return false; } } public IValidityState Validity { get { Check(_vstate); return _vstate; } } public HtmlFormControlElement(Document owner, string name, string? prefix, NodeFlags flags = NodeFlags.None) : base(owner, name, prefix, flags | NodeFlags.Special) { _vstate = new ValidityState(); _labels = new NodeList(); } public override Node Clone(Document owner, bool deep) { HtmlFormControlElement obj = (HtmlFormControlElement)base.Clone(owner, deep); obj.SetCustomValidity(_error); return obj; } public bool CheckValidity() { if (WillValidate) { return Validity.IsValid; } return false; } public void SetCustomValidity(string? error) { _error = error; ResetValidity(_vstate); } protected virtual bool IsFieldsetDisabled() { foreach (IHtmlFieldSetElement item in this.GetAncestors().OfType()) { if (item.IsDisabled) { INode node = item.ChildNodes.FirstOrDefault((INode m) => m is IHtmlLegendElement); return node == null || !this.IsDescendantOf(node); } } return false; } internal virtual void ConstructDataSet(FormDataSet dataSet, IHtmlElement submitter) { } internal virtual void Reset() { } protected virtual void Check(ValidityState state) { ResetValidity(state); } protected void ResetValidity(ValidityState state) { state.IsCustomError = !string.IsNullOrEmpty(_error); } protected abstract bool CanBeValidated(); } internal abstract class HtmlFormControlElementWithState : HtmlFormControlElement { internal bool CanContainRangeEndpoint { get; private set; } internal bool ShouldSaveAndRestoreFormControlState { get; private set; } public HtmlFormControlElementWithState(Document owner, string name, string? prefix, NodeFlags flags = NodeFlags.None) : base(owner, name, prefix, flags) { CanContainRangeEndpoint = false; } internal abstract FormControlState SaveControlState(); internal abstract void RestoreFormControlState(FormControlState state); } internal sealed class HtmlFormElement : HtmlElement, IHtmlFormElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IConstructableFormElement, IConstructableElement, IConstructableNode { private HtmlFormControlsCollection? _elements; public IElement? this[int index] => Elements[index]; public IElement? this[string name] => Elements[name]; public string? Name { get { return this.GetOwnAttribute(AttributeNames.Name); } set { this.SetOwnAttribute(AttributeNames.Name, value); } } public int Length => Elements.Length; public HtmlFormControlsCollection Elements => _elements ?? (_elements = new HtmlFormControlsCollection(this)); IHtmlFormControlsCollection IHtmlFormElement.Elements => Elements; public string? AcceptCharset { get { return this.GetOwnAttribute(AttributeNames.AcceptCharset); } set { this.SetOwnAttribute(AttributeNames.AcceptCharset, value); } } public string Action { get { return this.GetOwnAttribute(AttributeNames.Action) ?? base.Owner.DocumentUri; } set { this.SetOwnAttribute(AttributeNames.Action, value); } } public string? Autocomplete { get { return this.GetOwnAttribute(AttributeNames.AutoComplete); } set { this.SetOwnAttribute(AttributeNames.AutoComplete, value); } } public string Enctype { get { return this.GetOwnAttribute(AttributeNames.Enctype).ToEncodingType() ?? MimeTypeNames.UrlencodedForm; } [param: AllowNull] set { this.SetOwnAttribute(AttributeNames.Enctype, value); } } public string Encoding { get { return Enctype; } set { Enctype = value; } } public string Method { get { return this.GetOwnAttribute(AttributeNames.Method).ToFormMethod() ?? FormMethodNames.Get; } set { this.SetOwnAttribute(AttributeNames.Method, value); } } public bool NoValidate { get { return this.GetBoolAttribute(AttributeNames.NoValidate); } set { this.SetBoolAttribute(AttributeNames.NoValidate, value); } } public string Target { get { return this.GetOwnAttribute(AttributeNames.Target) ?? string.Empty; } set { this.SetOwnAttribute(AttributeNames.Target, value); } } public HtmlFormElement(Document owner, string? prefix = null) : base(owner, TagNames.Form, prefix, NodeFlags.Special) { } public Task SubmitAsync() { DocumentRequest submission = GetSubmission(); return base.Context.ResolveTargetContext(Target).NavigateToAsync(submission); } public Task SubmitAsync(IHtmlElement sourceElement) { DocumentRequest submission = GetSubmission(sourceElement); return base.Context.ResolveTargetContext(Target).NavigateToAsync(submission); } public DocumentRequest GetSubmission() { return SubmitForm(this, submittedFromSubmitMethod: true); } public DocumentRequest GetSubmission(IHtmlElement sourceElement) { return SubmitForm(sourceElement ?? this, submittedFromSubmitMethod: false); } public void Reset() { foreach (HtmlFormControlElement element in Elements) { element.Reset(); } } public bool CheckValidity() { IEnumerable invalidControls = GetInvalidControls(); bool result = true; foreach (HtmlFormControlElement item in invalidControls) { if (!item.FireSimpleEvent(EventNames.Invalid, bubble: false, cancelable: true)) { result = false; } } return result; } private IEnumerable GetInvalidControls() { foreach (HtmlFormControlElement element in Elements) { if (element.WillValidate && !element.CheckValidity()) { yield return element; } } } public bool ReportValidity() { IEnumerable invalidControls = GetInvalidControls(); bool result = true; bool flag = false; foreach (HtmlFormControlElement item in invalidControls) { if (!item.FireSimpleEvent(EventNames.Invalid, bubble: false, cancelable: true)) { if (!flag) { item.DoFocus(); flag = true; } result = false; } } return result; } public void RequestAutocomplete() { } private DocumentRequest? SubmitForm(IHtmlElement from, bool submittedFromSubmitMethod) { Document owner = base.Owner; if ((owner.ActiveSandboxing & Sandboxes.Forms) != Sandboxes.Forms) { if (submittedFromSubmitMethod || from.HasAttribute(AttributeNames.FormNoValidate) || NoValidate || CheckValidity()) { Url url = (string.IsNullOrEmpty(Action) ? new Url(owner.DocumentUri) : this.HyperReference(Action)); string scheme = url.Scheme; HttpMethod method = Method.ToEnum(HttpMethod.Get); return SubmitForm(method, scheme, url, from); } this.FireSimpleEvent(EventNames.Invalid); } return null; } private DocumentRequest SubmitForm(HttpMethod method, string scheme, Url action, IHtmlElement submitter) { if (scheme.IsOneOf(ProtocolNames.Http, ProtocolNames.Https)) { switch (method) { case HttpMethod.Get: return MutateActionUrl(action, submitter); case HttpMethod.Post: return SubmitAsEntityBody(action, submitter); } } else if (scheme.Is(ProtocolNames.Data)) { switch (method) { case HttpMethod.Get: return GetActionUrl(action); case HttpMethod.Post: return PostToData(action, submitter); } } else if (scheme.Is(ProtocolNames.Mailto)) { switch (method) { case HttpMethod.Get: return MailWithHeaders(action, submitter); case HttpMethod.Post: return MailAsBody(action, submitter); } } else if (scheme.IsOneOf(ProtocolNames.Ftp, ProtocolNames.JavaScript)) { return GetActionUrl(action); } return MutateActionUrl(action, submitter); } private DocumentRequest PostToData(Url action, IHtmlElement submitter) { string charset = (string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset); FormDataSet formDataSet = ConstructDataSet(submitter); string enctype = Enctype; IHtmlEncoder service = base.Owner.Context.GetService(); string s = string.Empty; using (StreamReader streamReader = new StreamReader(formDataSet.CreateBody(enctype, charset, service))) { s = streamReader.ReadToEnd(); } if (action.Href.Contains("%%%%")) { s = TextEncoding.UsAscii.GetBytes(s).UrlEncode(); action.Href = action.Href.ReplaceFirst("%%%%", s); } else if (action.Href.Contains("%%")) { s = TextEncoding.Utf8.GetBytes(s).UrlEncode(); action.Href = action.Href.ReplaceFirst("%%", s); } return GetActionUrl(action); } private DocumentRequest MailWithHeaders(Url action, IHtmlElement submitter) { Stream stream = ConstructDataSet(submitter).AsUrlEncoded(TextEncoding.UsAscii); string text = string.Empty; using (StreamReader streamReader = new StreamReader(stream)) { text = streamReader.ReadToEnd(); } action.Query = text.Replace("+", "%20"); return GetActionUrl(action); } private DocumentRequest MailAsBody(Url action, IHtmlElement submitter) { FormDataSet formDataSet = ConstructDataSet(submitter); string enctype = Enctype; Encoding usAscii = TextEncoding.UsAscii; IHtmlEncoder service = base.Owner.Context.GetService(); Stream stream = formDataSet.CreateBody(enctype, usAscii, service); string s = string.Empty; using (StreamReader streamReader = new StreamReader(stream)) { s = streamReader.ReadToEnd(); } action.Query = "body=" + usAscii.GetBytes(s).UrlEncode(); return GetActionUrl(action); } private DocumentRequest GetActionUrl(Url action) { return DocumentRequest.Get(action, this, base.Owner.DocumentUri); } private DocumentRequest SubmitAsEntityBody(Url url, IHtmlElement submitter) { string charset = (string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset); FormDataSet formDataSet = ConstructDataSet(submitter); string enctype = Enctype; IHtmlEncoder service = base.Owner.Context.GetService(); Stream stream = formDataSet.CreateBody(enctype, charset, service); if (enctype.Isi(MimeTypeNames.MultipartForm)) { return DocumentRequest.PostAsMultipart(url, stream, formDataSet.Boundary); } return DocumentRequest.Post(url, stream, enctype, this, base.Owner.DocumentUri); } private DocumentRequest MutateActionUrl(Url action, IHtmlElement submitter) { string charset = (string.IsNullOrEmpty(AcceptCharset) ? base.Owner.CharacterSet : AcceptCharset); FormDataSet formDataSet = ConstructDataSet(submitter); Encoding encoding = TextEncoding.Resolve(charset); using (StreamReader streamReader = new StreamReader(formDataSet.AsUrlEncoded(encoding))) { action.Query = streamReader.ReadToEnd(); } return GetActionUrl(action); } private FormDataSet ConstructDataSet(IHtmlElement submitter) { FormDataSet formDataSet = new FormDataSet(); foreach (HtmlFormControlElement node in this.GetNodes()) { if (!node.IsDisabled && !(node.ParentElement is IHtmlDataListElement) && node.Form == this) { node.ConstructDataSet(formDataSet, submitter); } } return formDataSet; } } internal sealed class HtmlFrameElement : HtmlFrameElementBase, IConstructableFrameElement, IConstructableElement, IConstructableNode { public bool NoResize { get { return this.GetOwnAttribute(AttributeNames.NoResize).ToBoolean(); } set { this.SetOwnAttribute(AttributeNames.NoResize, value.ToString()); } } public HtmlFrameElement(Document owner, string? prefix = null) : base(owner, TagNames.Frame, prefix, NodeFlags.SelfClosing) { } } internal abstract class HtmlFrameElementBase : HtmlFrameOwnerElement { private IBrowsingContext? _context; private FrameRequestProcessor _request; public IDownload? CurrentDownload => _request?.Download; public string? Name { get { return this.GetOwnAttribute(AttributeNames.Name); } set { this.SetOwnAttribute(AttributeNames.Name, value); } } public string? Source { get { return this.GetUrlAttribute(AttributeNames.Src); } set { this.SetOwnAttribute(AttributeNames.Src, value); } } public string? Scrolling { get { return this.GetOwnAttribute(AttributeNames.Scrolling); } set { this.SetOwnAttribute(AttributeNames.Scrolling, value); } } public IDocument? ContentDocument => _request?.Document; public string? LongDesc { get { return this.GetOwnAttribute(AttributeNames.LongDesc); } set { this.SetOwnAttribute(AttributeNames.LongDesc, value); } } public string? FrameBorder { get { return this.GetOwnAttribute(AttributeNames.FrameBorder); } set { this.SetOwnAttribute(AttributeNames.FrameBorder, value); } } public IBrowsingContext NestedContext => _context ?? (_context = NewChildContext()); public HtmlFrameElementBase(Document owner, string name, string? prefix, NodeFlags flags = NodeFlags.None) : base(owner, name, prefix, flags | NodeFlags.Special) { _request = new FrameRequestProcessor(owner.Context, this); } internal virtual string GetContentHtml() { return null; } internal override void SetupElement() { base.SetupElement(); if (this.GetOwnAttribute(AttributeNames.Src) != null) { UpdateSource(); } } internal void UpdateSource() { string contentHtml = GetContentHtml(); string source = Source; if ((source != null && source != base.Owner.DocumentUri) || contentHtml != null) { Url url = this.HyperReference(source); this.Process(_request, url); } } private IBrowsingContext NewChildContext() { IBrowsingContext browsingContext = base.Context.CreateChild(null, Sandboxes.None); base.Owner.AttachReference(browsingContext); return browsingContext; } } internal abstract class HtmlFrameOwnerElement : HtmlElement { public bool CanContainRangeEndpoint { get; private set; } public int DisplayWidth { get { return this.GetOwnAttribute(AttributeNames.Width).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.Width, value.ToString()); } } public int DisplayHeight { get { return this.GetOwnAttribute(AttributeNames.Height).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.Height, value.ToString()); } } public int MarginWidth { get { return this.GetOwnAttribute(AttributeNames.MarginWidth).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.MarginWidth, value.ToString()); } } public int MarginHeight { get { return this.GetOwnAttribute(AttributeNames.MarginHeight).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.MarginHeight, value.ToString()); } } public HtmlFrameOwnerElement(Document owner, string name, string? prefix, NodeFlags flags = NodeFlags.None) : base(owner, name, prefix, flags) { } } [DomHistorical] internal sealed class HtmlFrameSetElement : HtmlElement { public int Columns { get { return this.GetOwnAttribute(AttributeNames.Cols).ToInteger(1); } set { this.SetOwnAttribute(AttributeNames.Cols, value.ToString()); } } public int Rows { get { return this.GetOwnAttribute(AttributeNames.Rows).ToInteger(1); } set { this.SetOwnAttribute(AttributeNames.Rows, value.ToString()); } } public HtmlFrameSetElement(Document owner, string? prefix = null) : base(owner, TagNames.Frameset, prefix, NodeFlags.Special) { } } internal sealed class HtmlHeadElement : HtmlElement, IHtmlHeadElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlHeadElement(Document owner, string? prefix = null) : base(owner, TagNames.Head, prefix, NodeFlags.Special) { } } internal sealed class HtmlHeadingElement : HtmlElement, IHtmlHeadingElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlHeadingElement(Document owner, string? name = null, string? prefix = null) : base(owner, name ?? TagNames.H1, prefix, NodeFlags.Special) { } } internal sealed class HtmlHrElement : HtmlElement, IHtmlHrElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlHrElement(Document owner, string? prefix = null) : base(owner, TagNames.Hr, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } internal sealed class HtmlHtmlElement : HtmlElement, IHtmlHtmlElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Manifest { get { return this.GetOwnAttribute(AttributeNames.Manifest); } set { this.SetOwnAttribute(AttributeNames.Manifest, value); } } public HtmlHtmlElement(Document owner, string? prefix = null) : base(owner, TagNames.Html, prefix, NodeFlags.Special | NodeFlags.ImplicitlyClosed | NodeFlags.Scoped | NodeFlags.HtmlTableSectionScoped | NodeFlags.HtmlTableScoped) { } } internal sealed class HtmlIFrameElement : HtmlFrameElementBase, IHtmlInlineFrameElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILoadableElement { private SettableTokenList? _sandbox; public Alignment Align { get { return this.GetOwnAttribute(AttributeNames.Align).ToEnum(Alignment.Bottom); } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public string? ContentHtml { get { return this.GetOwnAttribute(AttributeNames.SrcDoc); } set { this.SetOwnAttribute(AttributeNames.SrcDoc, value); } } public ISettableTokenList Sandbox { get { if (_sandbox == null) { _sandbox = new SettableTokenList(this.GetOwnAttribute(AttributeNames.Sandbox)); _sandbox.Changed += delegate(string value) { UpdateAttribute(AttributeNames.Sandbox, value); }; } return _sandbox; } } public bool IsSeamless { get { return this.GetBoolAttribute(AttributeNames.SrcDoc); } set { this.SetBoolAttribute(AttributeNames.SrcDoc, value); } } public bool IsFullscreenAllowed { get { return this.GetBoolAttribute(AttributeNames.AllowFullscreen); } set { this.SetBoolAttribute(AttributeNames.AllowFullscreen, value); } } public bool IsPaymentRequestAllowed { get { return this.GetBoolAttribute(AttributeNames.AllowPaymentRequest); } set { this.SetBoolAttribute(AttributeNames.AllowPaymentRequest, value); } } public string? ReferrerPolicy { get { return this.GetOwnAttribute(AttributeNames.ReferrerPolicy); } set { this.SetOwnAttribute(AttributeNames.ReferrerPolicy, value); } } public IWindow? ContentWindow => base.NestedContext.Current; public HtmlIFrameElement(Document owner, string? prefix = null) : base(owner, TagNames.Iframe, prefix, NodeFlags.LiteralText) { } internal override string GetContentHtml() { return ContentHtml; } internal override void SetupElement() { base.SetupElement(); if (this.GetOwnAttribute(AttributeNames.SrcDoc) != null) { UpdateSource(); } } internal void UpdateSandbox(string value) { _sandbox?.Update(value); } } internal sealed class HtmlImageElement : HtmlElement, IHtmlImageElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILoadableElement { private readonly ImageRequestProcessor _request; public IDownload? CurrentDownload => _request?.Download; public string ActualSource { get { if (!IsCompleted) { return string.Empty; } return _request.Source; } } public string? SourceSet { get { return this.GetOwnAttribute(AttributeNames.SrcSet); } set { this.SetOwnAttribute(AttributeNames.SrcSet, value); } } public string? Sizes { get { return this.GetOwnAttribute(AttributeNames.Sizes); } set { this.SetOwnAttribute(AttributeNames.Sizes, value); } } public string? Source { get { return this.GetUrlAttribute(AttributeNames.Src); } set { this.SetOwnAttribute(AttributeNames.Src, value); } } public string? AlternativeText { get { return this.GetOwnAttribute(AttributeNames.Alt); } set { this.SetOwnAttribute(AttributeNames.Alt, value); } } public string? CrossOrigin { get { return this.GetOwnAttribute(AttributeNames.CrossOrigin); } set { this.SetOwnAttribute(AttributeNames.CrossOrigin, value); } } public string? UseMap { get { return this.GetOwnAttribute(AttributeNames.UseMap); } set { this.SetOwnAttribute(AttributeNames.UseMap, value); } } public int DisplayWidth { get { return this.GetOwnAttribute(AttributeNames.Width).ToInteger(OriginalWidth); } set { this.SetOwnAttribute(AttributeNames.Width, value.ToString()); } } public int DisplayHeight { get { return this.GetOwnAttribute(AttributeNames.Height).ToInteger(OriginalHeight); } set { this.SetOwnAttribute(AttributeNames.Height, value.ToString()); } } public int OriginalWidth => _request?.Width ?? 0; public int OriginalHeight => _request?.Height ?? 0; public bool IsCompleted => _request?.IsReady ?? false; public bool IsMap { get { return this.GetBoolAttribute(AttributeNames.IsMap); } set { this.SetBoolAttribute(AttributeNames.IsMap, value); } } public HtmlImageElement(Document owner, string? prefix = null) : base(owner, TagNames.Img, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { _request = new ImageRequestProcessor(owner.Context); } internal override void SetupElement() { base.SetupElement(); UpdateSource(); } internal void UpdateSource() { Url imageCandidate = this.GetImageCandidate(); if (imageCandidate != null) { this.Process(_request, imageCandidate); } } } internal sealed class HtmlInputElement : HtmlTextFormControlElement, IHtmlInputElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { private BaseInputType? _type; private bool? _checked; public override string DefaultValue { get { return this.GetOwnAttribute(AttributeNames.Value) ?? string.Empty; } set { this.SetOwnAttribute(AttributeNames.Value, value); } } public bool IsDefaultChecked { get { return this.GetBoolAttribute(AttributeNames.Checked); } set { this.SetBoolAttribute(AttributeNames.Checked, value); } } public bool IsChecked { get { return _checked ?? IsDefaultChecked; } set { _checked = value; } } public string Type { get { return _type.Name; } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public bool IsIndeterminate { get; set; } public bool IsMultiple { get { return this.GetBoolAttribute(AttributeNames.Multiple); } set { this.SetBoolAttribute(AttributeNames.Multiple, value); } } public DateTime? ValueAsDate { get { return _type.ConvertToDate(base.Value); } set { if (!value.HasValue) { base.Value = string.Empty; } else { base.Value = _type.ConvertFromDate(value.Value); } } } public double ValueAsNumber { get { return _type.ConvertToNumber(base.Value) ?? double.NaN; } set { if (double.IsInfinity(value)) { throw new DomException(DomError.TypeMismatch); } if (double.IsNaN(value)) { base.Value = string.Empty; } else { base.Value = _type.ConvertFromNumber(value); } } } public string? FormAction { get { string text = this.GetOwnAttribute(AttributeNames.FormAction); if (text == null) { Document owner = base.Owner; if (owner == null) { return null; } text = owner.DocumentUri; } return text; } set { this.SetOwnAttribute(AttributeNames.FormAction, value); } } public string FormEncType { get { return this.GetOwnAttribute(AttributeNames.FormEncType).ToEncodingType() ?? string.Empty; } set { this.SetOwnAttribute(AttributeNames.FormEncType, value); } } public string FormMethod { get { return this.GetOwnAttribute(AttributeNames.FormMethod).ToFormMethod() ?? string.Empty; } set { this.SetOwnAttribute(AttributeNames.FormMethod, value); } } public bool FormNoValidate { get { return this.GetBoolAttribute(AttributeNames.FormNoValidate); } set { this.SetBoolAttribute(AttributeNames.FormNoValidate, value); } } public string FormTarget { get { return this.GetOwnAttribute(AttributeNames.FormTarget) ?? string.Empty; } [param: AllowNull] set { this.SetOwnAttribute(AttributeNames.FormTarget, value); } } public string? Accept { get { return this.GetOwnAttribute(AttributeNames.Accept); } set { this.SetOwnAttribute(AttributeNames.Accept, value); } } public Alignment Align { get { return this.GetOwnAttribute(AttributeNames.Align).ToEnum(Alignment.Left); } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public string? AlternativeText { get { return this.GetOwnAttribute(AttributeNames.Alt); } set { this.SetOwnAttribute(AttributeNames.Alt, value); } } public string? Autocomplete { get { return this.GetOwnAttribute(AttributeNames.AutoComplete); } set { this.SetOwnAttribute(AttributeNames.AutoComplete, value); } } public IFileList? Files => (_type as FileInputType)?.Files; public IHtmlDataListElement? List { get { string ownAttribute = this.GetOwnAttribute(AttributeNames.List); if (ownAttribute != null && ownAttribute.Length > 0) { return base.Owner?.GetElementById(ownAttribute) as IHtmlDataListElement; } return null; } } public string? Maximum { get { return this.GetOwnAttribute(AttributeNames.Max); } set { this.SetOwnAttribute(AttributeNames.Max, value); } } public string? Minimum { get { return this.GetOwnAttribute(AttributeNames.Min); } set { this.SetOwnAttribute(AttributeNames.Min, value); } } public string? Pattern { get { return this.GetOwnAttribute(AttributeNames.Pattern); } set { this.SetOwnAttribute(AttributeNames.Pattern, value); } } public int Size { get { return this.GetOwnAttribute(AttributeNames.Size).ToInteger(20); } set { this.SetOwnAttribute(AttributeNames.Size, value.ToString()); } } public string? Source { get { return this.GetOwnAttribute(AttributeNames.Src); } set { this.SetOwnAttribute(AttributeNames.Src, value); } } public string? Step { get { return this.GetOwnAttribute(AttributeNames.Step); } set { this.SetOwnAttribute(AttributeNames.Step, value); } } public string? UseMap { get { return this.GetOwnAttribute(AttributeNames.UseMap); } set { this.SetOwnAttribute(AttributeNames.UseMap, value); } } public int DisplayWidth { get { return this.GetOwnAttribute(AttributeNames.Width).ToInteger(OriginalWidth); } set { this.SetOwnAttribute(AttributeNames.Width, value.ToString()); } } public int DisplayHeight { get { return this.GetOwnAttribute(AttributeNames.Height).ToInteger(OriginalHeight); } set { this.SetOwnAttribute(AttributeNames.Height, value.ToString()); } } public int OriginalWidth => (_type as ImageInputType)?.Width ?? 0; public int OriginalHeight => (_type as ImageInputType)?.Height ?? 0; internal bool IsVisited { get; set; } internal bool IsActive { get; set; } public HtmlInputElement(Document owner, string? prefix = null) : base(owner, TagNames.Input, prefix, NodeFlags.SelfClosing) { } public sealed override Node Clone(Document owner, bool deep) { HtmlInputElement obj = (HtmlInputElement)base.Clone(owner, deep); obj._checked = _checked; obj.UpdateType(_type.Name); return obj; } public override async void DoClick() { bool num = await IsClickedCancelled().ConfigureAwait(continueOnCapturedContext: false); IHtmlFormElement form = base.Form; if (!num && form != null) { string type = Type; if (type.Is(InputTypeNames.Submit)) { await form.SubmitAsync().ConfigureAwait(continueOnCapturedContext: false); } else if (type.Is(InputTypeNames.Reset)) { form.Reset(); } } } internal override FormControlState SaveControlState() { return new FormControlState(base.Name, Type, base.Value); } internal override void RestoreFormControlState(FormControlState state) { if (state.Type.Is(Type) && state.Name.Is(base.Name)) { base.Value = state.Value; } } public void StepUp(int n = 1) { _type.DoStep(n); } public void StepDown(int n = 1) { _type.DoStep(-n); } internal override void SetupElement() { base.SetupElement(); string ownAttribute = this.GetOwnAttribute(AttributeNames.Type); UpdateType(ownAttribute); } internal void UpdateType(string value) { _type = base.Context.GetFactory().Create(this, value); } internal override void ConstructDataSet(FormDataSet dataSet, IHtmlElement submitter) { if (_type.IsAppendingData(submitter)) { _type.ConstructDataSet(dataSet); } } internal override void Reset() { base.Reset(); _checked = null; UpdateType(Type); } protected override void Check(ValidityState state) { base.Check(state); ValidationErrors err = _type.Check(state); state.Reset(err); } protected override bool CanBeValidated() { if (_type.CanBeValidated) { return base.CanBeValidated(); } return false; } } internal sealed class HtmlIsIndexElement : HtmlElement { public IHtmlFormElement? Form { get; internal set; } public string? Prompt { get { return this.GetOwnAttribute(AttributeNames.Prompt); } set { this.SetOwnAttribute(AttributeNames.Prompt, value); } } public HtmlIsIndexElement(Document owner, string? prefix = null) : base(owner, TagNames.IsIndex, prefix, NodeFlags.Special) { } } internal sealed class HtmlItalicElement : HtmlElement { public HtmlItalicElement(Document owner, string? prefix = null) : base(owner, TagNames.I, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlKeygenElement : HtmlFormControlElementWithState, IHtmlKeygenElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { public string? Challenge { get { return this.GetOwnAttribute(AttributeNames.Challenge); } set { this.SetOwnAttribute(AttributeNames.Challenge, value); } } public string? KeyEncryption { get { return this.GetOwnAttribute(AttributeNames.Keytype); } set { this.SetOwnAttribute(AttributeNames.Keytype, value); } } public string Type => TagNames.Keygen; public HtmlKeygenElement(Document owner, string? prefix = null) : base(owner, TagNames.Keygen, prefix, NodeFlags.SelfClosing) { } internal override FormControlState SaveControlState() { return new FormControlState(base.Name, Type, Challenge); } internal override void RestoreFormControlState(FormControlState state) { if (state.Type.Is(Type) && state.Name.Is(base.Name)) { Challenge = state.Value; } } protected override bool CanBeValidated() { return false; } } internal sealed class HtmlLabelElement : HtmlElement, IHtmlLabelElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public IHtmlElement? Control { get { string htmlFor = HtmlFor; if (htmlFor != null && htmlFor.Length > 0) { IHtmlElement htmlElement = base.Owner.GetElementById(htmlFor) as IHtmlElement; if (htmlElement is ILabelabelElement) { return htmlElement; } } return null; } } public string? HtmlFor { get { return this.GetOwnAttribute(AttributeNames.For); } set { this.SetOwnAttribute(AttributeNames.For, value); } } public IHtmlFormElement? Form => GetAssignedForm(); public HtmlLabelElement(Document owner, string? prefix = null) : base(owner, TagNames.Label, prefix) { } } internal sealed class HtmlLegendElement : HtmlElement, IHtmlLegendElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public IHtmlFormElement? Form => (base.Parent as HtmlFieldSetElement)?.Form; public HtmlLegendElement(Document owner, string? prefix = null) : base(owner, TagNames.Legend, prefix) { } } internal sealed class HtmlLinkElement : HtmlElement, IHtmlLinkElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILinkStyle, ILinkImport, ILoadableElement { private BaseLinkRelation? _relation; private TokenList? _relList; private SettableTokenList? _sizes; internal bool IsVisited { get; set; } internal bool IsActive { get; set; } public IDownload? CurrentDownload => _relation?.Processor?.Download; public string? Href { get { return this.GetUrlAttribute(AttributeNames.Href); } set { this.SetOwnAttribute(AttributeNames.Href, value); } } public string? TargetLanguage { get { return this.GetOwnAttribute(AttributeNames.HrefLang); } set { this.SetOwnAttribute(AttributeNames.HrefLang, value); } } public string? Charset { get { return this.GetOwnAttribute(AttributeNames.Charset); } set { this.SetOwnAttribute(AttributeNames.Charset, value); } } public string? Relation { get { return this.GetOwnAttribute(AttributeNames.Rel); } set { this.SetOwnAttribute(AttributeNames.Rel, value); } } public string? ReverseRelation { get { return this.GetOwnAttribute(AttributeNames.Rev); } set { this.SetOwnAttribute(AttributeNames.Rev, value); } } public string? NumberUsedOnce { get { return this.GetOwnAttribute(AttributeNames.Nonce); } set { this.SetOwnAttribute(AttributeNames.Nonce, value); } } public ITokenList RelationList { get { if (_relList == null) { _relList = new TokenList(this.GetOwnAttribute(AttributeNames.Rel)); _relList.Changed += delegate(string value) { UpdateAttribute(AttributeNames.Rel, value); }; } return _relList; } } public ISettableTokenList Sizes { get { if (_sizes == null) { _sizes = new SettableTokenList(this.GetOwnAttribute(AttributeNames.Sizes)); _sizes.Changed += delegate(string value) { UpdateAttribute(AttributeNames.Sizes, value); }; } return _sizes; } } public string? Rev { get { return this.GetOwnAttribute(AttributeNames.Rev); } set { this.SetOwnAttribute(AttributeNames.Rev, value); } } public bool IsDisabled { get { return this.GetBoolAttribute(AttributeNames.Disabled); } set { this.SetBoolAttribute(AttributeNames.Disabled, value); } } public string? Target { get { return this.GetOwnAttribute(AttributeNames.Target); } set { this.SetOwnAttribute(AttributeNames.Target, value); } } public string? Media { get { return this.GetOwnAttribute(AttributeNames.Media); } set { this.SetOwnAttribute(AttributeNames.Media, value); } } public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public string? Integrity { get { return this.GetOwnAttribute(AttributeNames.Integrity); } set { this.SetOwnAttribute(AttributeNames.Integrity, value); } } public IStyleSheet? Sheet => (_relation as StyleSheetLinkRelation)?.Sheet; public IDocument? Import => (_relation as ImportLinkRelation)?.Import; public string? CrossOrigin { get { return this.GetOwnAttribute(AttributeNames.CrossOrigin); } set { this.SetOwnAttribute(AttributeNames.CrossOrigin, value); } } public HtmlLinkElement(Document owner, string? prefix = null) : base(owner, TagNames.Link, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } internal override void SetupElement() { string ownAttribute = this.GetOwnAttribute(AttributeNames.Rel); if (ownAttribute != null) { _relList?.Update(ownAttribute); _relation = CreateFirstLegalRelation(); } base.SetupElement(); } internal void UpdateSizes(string value) { _sizes?.Update(value); } internal void UpdateMedia(string value) { IStyleSheet sheet = Sheet; if (sheet != null) { sheet.Media.MediaText = value; } } internal void UpdateDisabled(string value) { IStyleSheet sheet = Sheet; if (sheet != null) { sheet.IsDisabled = value != null; } } internal void UpdateSource(string value) { Task task = _relation?.LoadAsync(); base.Owner?.DelayLoad(task); } private BaseLinkRelation? CreateFirstLegalRelation() { ITokenList relationList = RelationList; ILinkRelationFactory linkRelationFactory = base.Context?.GetFactory(); foreach (string item in relationList) { BaseLinkRelation baseLinkRelation = linkRelationFactory?.Create(this, item); if (baseLinkRelation != null) { return baseLinkRelation; } } return null; } } public static class HtmlLinkElementExtensions { public static bool IsPersistent(this IHtmlLinkElement link) { if (link.Relation.Isi(LinkRelNames.StyleSheet)) { return link.Title == null; } return false; } public static bool IsPreferred(this IHtmlLinkElement link) { if (link.Relation.Isi(LinkRelNames.StyleSheet)) { return link.Title != null; } return false; } public static bool IsAlternate(this IHtmlLinkElement link) { ITokenList relationList = link.RelationList; if (relationList.Contains(LinkRelNames.StyleSheet) && relationList.Contains(LinkRelNames.Alternate)) { return link.Title != null; } return false; } } internal sealed class HtmlListItemElement : HtmlElement, IHtmlListItemElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public int? Value { get { if (!int.TryParse(this.GetOwnAttribute(AttributeNames.Value), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return null; } return result; } set { this.SetOwnAttribute(AttributeNames.Value, value.HasValue ? value.Value.ToString() : null); } } public HtmlListItemElement(Document owner, string? name = null, string? prefix = null) : base(owner, name ?? TagNames.Li, prefix, NodeFlags.Special | NodeFlags.ImplicitlyClosed | NodeFlags.ImpliedEnd) { } } internal sealed class HtmlMapElement : HtmlElement, IHtmlMapElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private HtmlCollection? _areas; private HtmlCollection? _images; public string? Name { get { return this.GetOwnAttribute(AttributeNames.Name); } set { this.SetOwnAttribute(AttributeNames.Name, value); } } public IHtmlCollection Areas => _areas ?? (_areas = new HtmlCollection(this, deep: false)); public IHtmlCollection Images => _images ?? (_images = new HtmlCollection(base.Owner.DocumentElement, deep: true, IsAssociatedImage)); public HtmlMapElement(Document owner, string? prefix = null) : base(owner, TagNames.Map, prefix) { } private bool IsAssociatedImage(IHtmlImageElement image) { string useMap = image.UseMap; if (!string.IsNullOrEmpty(useMap)) { string other = (useMap.Has('#') ? ("#" + Name) : Name); return useMap.Is(other); } return false; } } [DomHistorical] internal sealed class HtmlMarqueeElement : HtmlElement, IHtmlMarqueeElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public int MinimumDelay { get; private set; } public int ScrollAmount { get; set; } public int ScrollDelay { get; set; } public int Loop { get; set; } public HtmlMarqueeElement(Document owner, string? prefix = null) : base(owner, TagNames.Marquee, prefix, NodeFlags.Special | NodeFlags.Scoped) { } public void Start() { base.Owner.QueueTask(delegate { this.FireSimpleEvent(EventNames.Play); }); } public void Stop() { base.Owner.QueueTask(delegate { this.FireSimpleEvent(EventNames.Pause); }); } } internal abstract class HtmlMediaElement : HtmlElement, IHtmlMediaElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IMediaController, ILoadableElement where TResource : class, IMediaInfo { private readonly MediaRequestProcessor _request; private ITextTrackList? _texts; public IDownload? CurrentDownload => _request?.Download; public string? Source { get { return this.GetUrlAttribute(AttributeNames.Src); } set { this.SetOwnAttribute(AttributeNames.Src, value); } } public string? CrossOrigin { get { return this.GetOwnAttribute(AttributeNames.CrossOrigin); } set { this.SetOwnAttribute(AttributeNames.CrossOrigin, value); } } public string? Preload { get { return this.GetOwnAttribute(AttributeNames.Preload); } set { this.SetOwnAttribute(AttributeNames.Preload, value); } } public MediaNetworkState NetworkState => _request?.NetworkState ?? MediaNetworkState.Empty; public TResource? Media { get { MediaRequestProcessor request = _request; if (request == null) { return null; } return request.Resource; } } public MediaReadyState ReadyState => Controller?.ReadyState ?? MediaReadyState.Nothing; public bool IsSeeking { get; protected set; } public string? CurrentSource => Source; public double Duration => Controller?.Duration ?? 0.0; public double CurrentTime { get { return Controller?.CurrentTime ?? 0.0; } set { IMediaController controller = Controller; if (controller != null) { controller.CurrentTime = value; } } } public bool IsAutoplay { get { return this.GetBoolAttribute(AttributeNames.Autoplay); } set { this.SetBoolAttribute(AttributeNames.Autoplay, value); } } public bool IsLoop { get { return this.GetBoolAttribute(AttributeNames.Loop); } set { this.SetBoolAttribute(AttributeNames.Loop, value); } } public bool IsShowingControls { get { return this.GetBoolAttribute(AttributeNames.Controls); } set { this.SetBoolAttribute(AttributeNames.Controls, value); } } public bool IsDefaultMuted { get { return this.GetBoolAttribute(AttributeNames.Muted); } set { this.SetBoolAttribute(AttributeNames.Muted, value); } } public bool IsPaused { get { if (PlaybackState == MediaControllerPlaybackState.Waiting) { return (int)ReadyState >= 2; } return false; } } public bool IsEnded => PlaybackState == MediaControllerPlaybackState.Ended; public DateTime StartDate => DateTime.Today; public ITimeRanges? BufferedTime => Controller?.BufferedTime; public ITimeRanges? SeekableTime => Controller?.SeekableTime; public ITimeRanges? PlayedTime => Controller?.PlayedTime; public string? MediaGroup { get { return this.GetOwnAttribute(AttributeNames.MediaGroup); } set { this.SetOwnAttribute(AttributeNames.MediaGroup, value); } } public double Volume { get { return Controller?.Volume ?? 1.0; } set { IMediaController controller = Controller; if (controller != null) { controller.Volume = value; } } } public bool IsMuted { get { return Controller?.IsMuted ?? false; } set { IMediaController controller = Controller; if (controller != null) { controller.IsMuted = value; } } } public IMediaController? Controller => _request?.Resource?.Controller; public double DefaultPlaybackRate { get { return Controller?.DefaultPlaybackRate ?? 1.0; } set { IMediaController controller = Controller; if (controller != null) { controller.DefaultPlaybackRate = value; } } } public double PlaybackRate { get { return Controller?.PlaybackRate ?? 1.0; } set { IMediaController controller = Controller; if (controller != null) { controller.PlaybackRate = value; } } } public MediaControllerPlaybackState PlaybackState => Controller?.PlaybackState ?? MediaControllerPlaybackState.Waiting; public IMediaError? MediaError { get; private set; } public virtual IAudioTrackList? AudioTracks => null; public virtual IVideoTrackList? VideoTracks => null; public ITextTrackList? TextTracks { get { return _texts; } protected set { _texts = value; } } public HtmlMediaElement(Document owner, string name, string? prefix) : base(owner, name, prefix) { _request = new MediaRequestProcessor(owner.Context); } public void Load() { string currentSource = CurrentSource; UpdateSource(currentSource); } public void Play() { Controller?.Play(); } public void Pause() { Controller?.Pause(); } public string CanPlayType(string type) { if (base.Context?.GetResourceService(type) == null) { return string.Empty; } return "maybe"; } public ITextTrack AddTextTrack(string kind, string? label = null, string? language = null) { return null; } internal override void SetupElement() { base.SetupElement(); UpdateSource(this.GetOwnAttribute(AttributeNames.Src)); } internal void UpdateSource(string? value) { if (value != null) { Url url = new Url(value); this.Process(_request, url); } } } internal sealed class HtmlMenuElement : HtmlElement, IHtmlMenuElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public string? Label { get { return this.GetOwnAttribute(AttributeNames.Label); } set { this.SetOwnAttribute(AttributeNames.Label, value); } } public HtmlMenuElement(Document owner, string? prefix = null) : base(owner, TagNames.Menu, prefix, NodeFlags.Special) { } } internal sealed class HtmlMenuItemElement : HtmlElement, IHtmlMenuItemElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public IHtmlElement? Command { get { string ownAttribute = this.GetOwnAttribute(AttributeNames.Command); if (ownAttribute != null && ownAttribute.Length > 0) { return base.Owner?.GetElementById(ownAttribute) as IHtmlElement; } return null; } } public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public string? Label { get { return this.GetOwnAttribute(AttributeNames.Label); } set { this.SetOwnAttribute(AttributeNames.Label, value); } } public string? Icon { get { return this.GetOwnAttribute(AttributeNames.Icon); } set { this.SetOwnAttribute(AttributeNames.Icon, value); } } public bool IsDisabled { get { return this.GetBoolAttribute(AttributeNames.Disabled); } set { this.SetBoolAttribute(AttributeNames.Disabled, value); } } public bool IsChecked { get { return this.GetBoolAttribute(AttributeNames.Checked); } set { this.SetBoolAttribute(AttributeNames.Checked, value); } } public bool IsDefault { get { return this.GetBoolAttribute(AttributeNames.Default); } set { this.SetBoolAttribute(AttributeNames.Default, value); } } public string? RadioGroup { get { return this.GetOwnAttribute(AttributeNames.Radiogroup); } set { this.SetOwnAttribute(AttributeNames.Radiogroup, value); } } public HtmlMenuItemElement(Document owner, string? prefix = null) : base(owner, TagNames.MenuItem, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } internal sealed class HtmlMetaElement : HtmlElement, IHtmlMetaElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IConstructableMetaElement, IConstructableElement, IConstructableNode { public string? Content { get { return this.GetOwnAttribute(AttributeNames.Content); } set { this.SetOwnAttribute(AttributeNames.Content, value); } } public string? Charset { get { return this.GetOwnAttribute(AttributeNames.Charset); } set { this.SetOwnAttribute(AttributeNames.Charset, value); } } public string? HttpEquivalent { get { return this.GetOwnAttribute(AttributeNames.HttpEquiv); } set { this.SetOwnAttribute(AttributeNames.HttpEquiv, value); } } public string? Scheme { get { return this.GetOwnAttribute(AttributeNames.Scheme); } set { this.SetOwnAttribute(AttributeNames.Scheme, value); } } public string? Name { get { return this.GetOwnAttribute(AttributeNames.Name); } set { this.SetOwnAttribute(AttributeNames.Name, value); } } public HtmlMetaElement(Document owner, string? prefix = null) : base(owner, TagNames.Meta, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } public void Handle() { foreach (IMetaHandler service in base.Owner.Context.GetServices()) { service.HandleContent(this); } } } internal sealed class HtmlMeterElement : HtmlElement, IHtmlMeterElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILabelabelElement { private readonly NodeList _labels; public INodeList Labels => _labels; public double Value { get { return this.GetOwnAttribute(AttributeNames.Value).ToDouble().Constraint(Minimum, Maximum); } set { this.SetOwnAttribute(AttributeNames.Value, value.ToString(NumberFormatInfo.InvariantInfo)); } } public double Maximum { get { return this.GetOwnAttribute(AttributeNames.Max).ToDouble(1.0).Constraint(Minimum, double.PositiveInfinity); } set { this.SetOwnAttribute(AttributeNames.Max, value.ToString(NumberFormatInfo.InvariantInfo)); } } public double Minimum { get { return this.GetOwnAttribute(AttributeNames.Min).ToDouble(); } set { this.SetOwnAttribute(AttributeNames.Min, value.ToString(NumberFormatInfo.InvariantInfo)); } } public double Low { get { return this.GetOwnAttribute(AttributeNames.Low).ToDouble(Minimum).Constraint(Minimum, Maximum); } set { this.SetOwnAttribute(AttributeNames.Low, value.ToString(NumberFormatInfo.InvariantInfo)); } } public double High { get { return this.GetOwnAttribute(AttributeNames.High).ToDouble(Maximum).Constraint(Low, Maximum); } set { this.SetOwnAttribute(AttributeNames.High, value.ToString(NumberFormatInfo.InvariantInfo)); } } public double Optimum { get { return this.GetOwnAttribute(AttributeNames.Optimum).ToDouble((Maximum + Minimum) * 0.5).Constraint(Minimum, Maximum); } set { this.SetOwnAttribute(AttributeNames.Optimum, value.ToString(NumberFormatInfo.InvariantInfo)); } } public HtmlMeterElement(Document owner, string? prefix = null) : base(owner, TagNames.Meter, prefix) { _labels = new NodeList(); } } internal sealed class HtmlModElement : HtmlElement, IHtmlModElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Citation { get { return this.GetOwnAttribute(AttributeNames.Cite); } set { this.SetOwnAttribute(AttributeNames.Cite, value); } } public string? DateTime { get { return this.GetOwnAttribute(AttributeNames.Datetime); } set { this.SetOwnAttribute(AttributeNames.Datetime, value); } } public HtmlModElement(Document owner, string? name = null, string? prefix = null) : base(owner, name ?? TagNames.Ins, prefix) { } } internal sealed class HtmlNoEmbedElement : HtmlElement { public HtmlNoEmbedElement(Document owner, string? prefix = null) : base(owner, TagNames.NoEmbed, prefix, NodeFlags.Special | NodeFlags.LiteralText) { } } internal sealed class HtmlNoFramesElement : HtmlElement { public HtmlNoFramesElement(Document owner, string? prefix = null) : base(owner, TagNames.NoFrames, prefix, NodeFlags.Special | NodeFlags.LiteralText) { } } internal sealed class HtmlNoNewlineElement : HtmlElement { public HtmlNoNewlineElement(Document owner, string? prefix = null) : base(owner, TagNames.NoBr, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlNoScriptElement : HtmlElement { public HtmlNoScriptElement(Document owner, string? prefix = null, bool? scripting = false) : base(owner, TagNames.NoScript, prefix, GetFlags(scripting ?? owner.Context.IsScripting())) { } private static NodeFlags GetFlags(bool scripting) { if (scripting) { return NodeFlags.Special | NodeFlags.LiteralText; } return NodeFlags.Special; } } internal sealed class HtmlObjectElement : HtmlFormControlElement, IHtmlObjectElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation, ILoadableElement { private readonly ObjectRequestProcessor _request; public IDownload? CurrentDownload => _request?.Download; public string? Source { get { return this.GetUrlAttribute(AttributeNames.Data); } set { this.SetOwnAttribute(AttributeNames.Data, value); } } public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public bool TypeMustMatch { get { return this.GetBoolAttribute(AttributeNames.TypeMustMatch); } set { this.SetBoolAttribute(AttributeNames.TypeMustMatch, value); } } public string? UseMap { get { return this.GetOwnAttribute(AttributeNames.UseMap); } set { this.SetOwnAttribute(AttributeNames.UseMap, value); } } public int DisplayWidth { get { return this.GetOwnAttribute(AttributeNames.Width).ToInteger(OriginalWidth); } set { this.SetOwnAttribute(AttributeNames.Width, value.ToString()); } } public int DisplayHeight { get { return this.GetOwnAttribute(AttributeNames.Height).ToInteger(OriginalHeight); } set { this.SetOwnAttribute(AttributeNames.Height, value.ToString()); } } public int OriginalWidth => _request?.Width ?? 0; public int OriginalHeight => _request?.Height ?? 0; public IDocument? ContentDocument => null; public IWindow? ContentWindow => null; public HtmlObjectElement(Document owner, string? prefix = null) : base(owner, TagNames.Object, prefix, NodeFlags.Scoped) { _request = new ObjectRequestProcessor(owner.Context); } protected override bool CanBeValidated() { return false; } internal override void SetupElement() { base.SetupElement(); UpdateSource(this.GetOwnAttribute(AttributeNames.Data)); } internal void UpdateSource(string? value) { if (value != null) { Url url = new Url(Source); this.Process(_request, url); } } } internal sealed class HtmlOptionElement : HtmlElement, IHtmlOptionElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private bool? _selected; public bool IsDisabled { get { return this.GetBoolAttribute(AttributeNames.Disabled); } set { this.SetBoolAttribute(AttributeNames.Disabled, value); } } public IHtmlFormElement? Form => GetAssignedForm(); public string Label { get { return this.GetOwnAttribute(AttributeNames.Label) ?? Text; } [param: AllowNull] set { this.SetOwnAttribute(AttributeNames.Label, value); } } public string Value { get { return this.GetOwnAttribute(AttributeNames.Value) ?? Text; } set { this.SetOwnAttribute(AttributeNames.Value, value); } } public int Index { get { if (base.Parent is HtmlOptionsGroupElement htmlOptionsGroupElement) { int num = 0; foreach (Node childNode in htmlOptionsGroupElement.ChildNodes) { if (childNode == this) { return num; } num++; } } return 0; } } public string Text { get { return TextContent.CollapseAndStrip(); } set { TextContent = value; } } public bool IsDefaultSelected { get { return this.GetBoolAttribute(AttributeNames.Selected); } set { this.SetBoolAttribute(AttributeNames.Selected, value); } } public bool IsSelected { get { return _selected ?? IsDefaultSelected; } set { _selected = value; } } public HtmlOptionElement(Document owner, string? prefix = null) : base(owner, TagNames.Option, prefix, NodeFlags.ImplicitlyClosed | NodeFlags.ImpliedEnd | NodeFlags.HtmlSelectScoped) { } } internal sealed class HtmlOptionsGroupElement : HtmlElement, IHtmlOptionsGroupElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Label { get { return this.GetOwnAttribute(AttributeNames.Label); } set { this.SetOwnAttribute(AttributeNames.Label, value); } } public bool IsDisabled { get { return this.GetBoolAttribute(AttributeNames.Disabled); } set { this.SetBoolAttribute(AttributeNames.Disabled, value); } } public HtmlOptionsGroupElement(Document owner, string? prefix = null) : base(owner, TagNames.Optgroup, prefix, NodeFlags.ImplicitlyClosed | NodeFlags.ImpliedEnd | NodeFlags.HtmlSelectScoped) { } } internal sealed class HtmlOrderedListElement : HtmlElement, IHtmlOrderedListElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public bool IsReversed { get { return this.GetBoolAttribute(AttributeNames.Reversed); } set { this.SetBoolAttribute(AttributeNames.Reversed, value); } } public int Start { get { return this.GetOwnAttribute(AttributeNames.Start).ToInteger(1); } set { this.SetOwnAttribute(AttributeNames.Start, value.ToString()); } } public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public HtmlOrderedListElement(Document owner, string? prefix = null) : base(owner, TagNames.Ol, prefix, NodeFlags.Special | NodeFlags.HtmlListScoped) { } } internal sealed class HtmlOutputElement : HtmlFormControlElement, IHtmlOutputElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { private string? _defaultValue; private string? _value; private SettableTokenList? _for; public string DefaultValue { get { return _defaultValue ?? TextContent; } set { _defaultValue = value; } } public override string TextContent { get { return _value ?? _defaultValue ?? base.TextContent; } set { base.TextContent = value; } } public string Value { get { return TextContent; } set { _value = value; } } public ISettableTokenList HtmlFor { get { if (_for == null) { _for = new SettableTokenList(this.GetOwnAttribute(AttributeNames.For)); _for.Changed += delegate(string value) { UpdateAttribute(AttributeNames.For, value); }; } return _for; } } public string Type => TagNames.Output; public HtmlOutputElement(Document owner, string? prefix = null) : base(owner, TagNames.Output, prefix) { } internal override void Reset() { _value = null; } internal void UpdateFor(string value) { _for?.Update(value); } protected override bool CanBeValidated() { return true; } } internal sealed class HtmlParagraphElement : HtmlElement, IHtmlParagraphElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HorizontalAlignment Align { get { return this.GetOwnAttribute(AttributeNames.Align).ToEnum(HorizontalAlignment.Left); } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public HtmlParagraphElement(Document owner, string? prefix = null) : base(owner, TagNames.P, prefix, NodeFlags.Special | NodeFlags.ImplicitlyClosed | NodeFlags.ImpliedEnd) { } } internal sealed class HtmlParamElement : HtmlElement, IHtmlParamElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Value { get { return this.GetOwnAttribute(AttributeNames.Value); } set { this.SetOwnAttribute(AttributeNames.Value, value); } } public string? Name { get { return this.GetOwnAttribute(AttributeNames.Name); } set { this.SetOwnAttribute(AttributeNames.Name, value); } } public HtmlParamElement(Document owner, string? prefix = null) : base(owner, TagNames.Param, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } internal sealed class HtmlPictureElement : HtmlElement, IHtmlPictureElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlPictureElement(Document owner, string? prefix = null) : base(owner, TagNames.Picture, prefix) { } } internal sealed class HtmlPlaintextElement : HtmlElement { public HtmlPlaintextElement(Document owner, string prefix) : base(owner, TagNames.Plaintext, prefix, NodeFlags.Special | NodeFlags.LiteralText) { } } internal sealed class HtmlPreElement : HtmlElement, IHtmlPreElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlPreElement(Document owner, string? prefix = null) : base(owner, TagNames.Pre, prefix, NodeFlags.Special | NodeFlags.LineTolerance) { } } internal sealed class HtmlProgressElement : HtmlElement, IHtmlProgressElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILabelabelElement { private readonly NodeList _labels; public INodeList Labels => _labels; public bool IsDeterminate => !string.IsNullOrEmpty(this.GetOwnAttribute(AttributeNames.Value)); public double Value { get { return this.GetOwnAttribute(AttributeNames.Value).ToDouble(); } set { this.SetOwnAttribute(AttributeNames.Value, value.ToString(NumberFormatInfo.InvariantInfo)); } } public double Maximum { get { return this.GetOwnAttribute(AttributeNames.Max).ToDouble(1.0); } set { this.SetOwnAttribute(AttributeNames.Max, value.ToString(NumberFormatInfo.InvariantInfo)); } } public double Position { get { if (!IsDeterminate) { return -1.0; } return Math.Max(Math.Min(Value / Maximum, 1.0), 0.0); } } public HtmlProgressElement(Document owner, string? prefix = null) : base(owner, TagNames.Progress, prefix) { _labels = new NodeList(); } } internal sealed class HtmlQuoteElement : HtmlElement, IHtmlQuoteElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Citation { get { return this.GetOwnAttribute(AttributeNames.Cite); } set { this.SetOwnAttribute(AttributeNames.Cite, value); } } public HtmlQuoteElement(Document owner, string? name = null, string? prefix = null) : base(owner, name ?? TagNames.Quote, prefix, name.Is(TagNames.BlockQuote) ? NodeFlags.Special : NodeFlags.None) { } } internal sealed class HtmlRbElement : HtmlElement { public HtmlRbElement(Document owner, string? prefix = null) : base(owner, TagNames.Rb, prefix, NodeFlags.ImplicitlyClosed | NodeFlags.ImpliedEnd) { } } internal sealed class HtmlRpElement : HtmlElement { public HtmlRpElement(Document owner, string? prefix = null) : base(owner, TagNames.Rp, prefix, NodeFlags.ImplicitlyClosed | NodeFlags.ImpliedEnd) { } } internal sealed class HtmlRtcElement : HtmlElement { public HtmlRtcElement(Document owner, string? prefix = null) : base(owner, TagNames.Rtc, prefix, NodeFlags.ImplicitlyClosed | NodeFlags.ImpliedEnd) { } } internal sealed class HtmlRtElement : HtmlElement { public HtmlRtElement(Document owner, string? prefix = null) : base(owner, TagNames.Rt, prefix, NodeFlags.ImplicitlyClosed | NodeFlags.ImpliedEnd) { } } internal sealed class HtmlRubyElement : HtmlElement { public HtmlRubyElement(Document owner, string? prefix = null) : base(owner, TagNames.Ruby, prefix) { } } internal sealed class HtmlScriptElement : HtmlElement, IHtmlScriptElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILoadableElement, IConstructableScriptElement, IConstructableElement, IConstructableNode { private readonly bool _parserInserted; private readonly ScriptRequestProcessor _request; private bool _started; private bool _forceAsync; public IDownload? CurrentDownload => _request?.Download; public string? Source { get { return this.GetOwnAttribute(AttributeNames.Src); } set { this.SetOwnAttribute(AttributeNames.Src, value); } } public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public string? CharacterSet { get { return this.GetOwnAttribute(AttributeNames.Charset); } set { this.SetOwnAttribute(AttributeNames.Charset, value); } } public string Text { get { return TextContent; } set { TextContent = value; } } public string? CrossOrigin { get { return this.GetOwnAttribute(AttributeNames.CrossOrigin); } set { this.SetOwnAttribute(AttributeNames.CrossOrigin, value); } } public bool IsDeferred { get { return this.GetBoolAttribute(AttributeNames.Defer); } set { this.SetBoolAttribute(AttributeNames.Defer, value); } } public bool IsAsync { get { return this.GetBoolAttribute(AttributeNames.Async); } set { this.SetBoolAttribute(AttributeNames.Async, value); } } public string? Integrity { get { return this.GetOwnAttribute(AttributeNames.Integrity); } set { this.SetOwnAttribute(AttributeNames.Integrity, value); } } public HtmlScriptElement(Document owner, string? prefix = null, bool parserInserted = false, bool started = false) : base(owner, TagNames.Script, prefix, NodeFlags.Special | NodeFlags.LiteralText) { _forceAsync = false; _started = started; _parserInserted = parserInserted; _request = new ScriptRequestProcessor(owner.Context, this); } public override Node Clone(Document owner, bool deep) { HtmlScriptElement htmlScriptElement = new HtmlScriptElement(owner, base.Prefix, _parserInserted, _started); CloneElement(htmlScriptElement, owner, deep); htmlScriptElement._forceAsync = _forceAsync; return htmlScriptElement; } protected override void OnParentChanged() { base.OnParentChanged(); if (!_parserInserted && Prepare(base.Owner)) { RunAsync(CancellationToken.None); } } internal Task RunAsync(CancellationToken cancel) { return _request?.RunAsync(cancel); } internal bool Prepare(Document document) { string ownAttribute = this.GetOwnAttribute(AttributeNames.Event); string ownAttribute2 = this.GetOwnAttribute(AttributeNames.For); string source = Source; bool parserInserted = _parserInserted; if (_started) { return false; } if (parserInserted) { _forceAsync = !IsAsync; } if (string.IsNullOrEmpty(source) && string.IsNullOrEmpty(Text)) { return false; } if (_request.Engine == null) { return false; } if (parserInserted) { _forceAsync = false; } _started = true; if (ownAttribute != null && ownAttribute.Length > 0 && ownAttribute2 != null && ownAttribute2.Length > 0) { ownAttribute = ownAttribute.Trim(); ownAttribute2 = ownAttribute2.Trim(); if (ownAttribute.EndsWith("()")) { ownAttribute = ownAttribute.Substring(0, ownAttribute.Length - 2); } bool num = ownAttribute2.Isi(AttributeNames.Window); bool flag = ownAttribute.Isi("onload"); if (!num || !flag) { return false; } } if (source != null) { if (source.Length != 0) { return InvokeLoadingScript(document, this.HyperReference(source)); } document.QueueTask(FireErrorEvent); return false; } _request.Process(Text); return true; } private bool InvokeLoadingScript(Document document, Url url) { bool result = true; if (_parserInserted && (IsDeferred || IsAsync)) { document.AddScript(this); result = false; } this.Process(_request, url); return result; } private void FireErrorEvent() { base.Owner.QueueTask(delegate { this.FireSimpleEvent(EventNames.Error); }); } Task IConstructableScriptElement.RunAsync(CancellationToken cancel) { return RunAsync(cancel); } bool IConstructableScriptElement.Prepare(IConstructableDocument document) { return Prepare((Document)document); } } internal sealed class HtmlSelectElement : HtmlFormControlElementWithState, IHtmlSelectElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { private OptionsCollection? _options; private HtmlCollection? _selected; public IHtmlOptionElement this[int index] { get { return Options.GetOptionAt(index); } set { Options.SetOptionAt(index, value); } } public int Size { get { return this.GetOwnAttribute(AttributeNames.Size).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.Size, value.ToString()); } } public bool IsRequired { get { return this.GetBoolAttribute(AttributeNames.Required); } set { this.SetBoolAttribute(AttributeNames.Required, value); } } public IHtmlCollection SelectedOptions => _selected ?? (_selected = new HtmlCollection(Options.Where((IHtmlOptionElement m) => m.IsSelected))); public int SelectedIndex => Options.SelectedIndex; public string? Value { get { foreach (IHtmlOptionElement option in Options) { if (option.IsSelected) { return option.Value; } } return null; } set { UpdateValue(value); } } public int Length => Options.Length; public bool IsMultiple { get { return this.GetBoolAttribute(AttributeNames.Multiple); } set { this.SetBoolAttribute(AttributeNames.Multiple, value); } } public IHtmlOptionsCollection Options => _options ?? (_options = new OptionsCollection(this)); public string Type { get { if (!IsMultiple) { return InputTypeNames.SelectOne; } return InputTypeNames.SelectMultiple; } } public HtmlSelectElement(Document owner, string? prefix = null) : base(owner, TagNames.Select, prefix) { } public void AddOption(IHtmlOptionElement element, IHtmlElement? before = null) { Options.Add(element, before); } public void AddOption(IHtmlOptionsGroupElement element, IHtmlElement? before = null) { Options.Add(element, before); } public void RemoveOptionAt(int index) { Options.Remove(index); } internal override FormControlState SaveControlState() { return new FormControlState(base.Name, Type, Value); } internal override void RestoreFormControlState(FormControlState state) { if (state.Type.Is(Type) && state.Name.Is(base.Name)) { Value = state.Value; } } internal override void ConstructDataSet(FormDataSet dataSet, IHtmlElement submitter) { IHtmlOptionsCollection options = Options; bool flag = false; for (int i = 0; i < options.Length; i++) { IHtmlOptionElement optionAt = options.GetOptionAt(i); if (optionAt.IsSelected && !optionAt.IsDisabled) { dataSet.Append(base.Name, optionAt.Value, Type); flag = true; } } if (!flag) { IHtmlOptionElement defaultOptionOrNull = GetDefaultOptionOrNull(); if (defaultOptionOrNull != null) { dataSet.Append(base.Name, defaultOptionOrNull.Value, Type); } } } private IHtmlOptionElement? GetDefaultOptionOrNull() { IHtmlOptionsCollection options = Options; for (int i = 0; i < options.Length; i++) { IHtmlOptionElement optionAt = options.GetOptionAt(i); if (!optionAt.IsDisabled) { return optionAt; } } return null; } internal override void SetupElement() { base.SetupElement(); string ownAttribute = this.GetOwnAttribute(AttributeNames.Value); if (ownAttribute != null) { UpdateValue(ownAttribute); } } internal override void Reset() { IHtmlOptionsCollection options = Options; int num = 0; int index = 0; for (int i = 0; i < options.Length; i++) { IHtmlOptionElement optionAt = options.GetOptionAt(i); optionAt.IsSelected = optionAt.IsDefaultSelected; if (optionAt.IsSelected) { index = i; num++; } } if (num == 1 || IsMultiple || options.Length <= 0) { return; } foreach (IHtmlOptionElement item in options) { item.IsSelected = false; } options[index].IsSelected = true; } internal void UpdateValue(string value) { foreach (IHtmlOptionElement option in Options) { bool isSelected = option.Value.Isi(value); option.IsSelected = isSelected; } } protected override bool CanBeValidated() { return !this.HasDataListAncestor(); } protected override void Check(ValidityState state) { base.Check(state); state.IsValueMissing = IsRequired && string.IsNullOrEmpty(Value); } } internal sealed class HtmlSemanticElement : HtmlElement { public HtmlSemanticElement(Document owner, string name, string? prefix = null) : base(owner, name, prefix, NodeFlags.Special) { } } internal sealed class HtmlSlotElement : HtmlElement, IHtmlSlotElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Name { get { return this.GetOwnAttribute(AttributeNames.Name); } set { this.SetOwnAttribute(AttributeNames.Name, value); } } public HtmlSlotElement(Document owner, string? prefix = null) : base(owner, TagNames.Slot, prefix) { } public IEnumerable GetDistributedNodes() { IElement element = this.GetAncestor()?.Host; if (element != null) { List list = new List(); { foreach (INode childNode in element.ChildNodes) { if (GetAssignedSlot(childNode) == this) { if (childNode is HtmlSlotElement htmlSlotElement) { list.AddRange(htmlSlotElement.GetDistributedNodes()); } else { list.Add(childNode); } } } return list; } } return Array.Empty(); } private static IElement? GetAssignedSlot(INode node) { return node.NodeType switch { NodeType.Text => ((IText)node).AssignedSlot, NodeType.Element => ((IElement)node).AssignedSlot, _ => null, }; } } internal sealed class HtmlSmallElement : HtmlElement { public HtmlSmallElement(Document owner, string? prefix = null) : base(owner, TagNames.Small, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlSourceElement : HtmlElement, IHtmlSourceElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? Source { get { return this.GetUrlAttribute(AttributeNames.Src); } set { this.SetOwnAttribute(AttributeNames.Src, value); } } public string? Media { get { return this.GetOwnAttribute(AttributeNames.Media); } set { this.SetOwnAttribute(AttributeNames.Media, value); } } public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public string? SourceSet { get { return this.GetOwnAttribute(AttributeNames.SrcSet); } set { this.SetOwnAttribute(AttributeNames.SrcSet, value); } } public string? Sizes { get { return this.GetOwnAttribute(AttributeNames.Sizes); } set { this.SetOwnAttribute(AttributeNames.Sizes, value); } } public HtmlSourceElement(Document owner, string? prefix = null) : base(owner, TagNames.Source, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } internal sealed class HtmlSpanElement : HtmlElement, IHtmlSpanElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlSpanElement(Document owner, string? prefix = null) : base(owner, TagNames.Span, prefix) { } } internal sealed class HtmlStrikeElement : HtmlElement { public HtmlStrikeElement(Document owner, string? prefix = null) : base(owner, TagNames.Strike, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlStrongElement : HtmlElement { public HtmlStrongElement(Document owner, string? prefix = null) : base(owner, TagNames.Strong, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlStruckElement : HtmlElement { public HtmlStruckElement(Document owner, string? prefix = null) : base(owner, TagNames.S, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlStyleElement : HtmlElement, IHtmlStyleElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, ILinkStyle { private IStyleSheet? _sheet; public bool IsScoped { get { return this.GetBoolAttribute(AttributeNames.Scoped); } set { this.SetBoolAttribute(AttributeNames.Scoped, value); } } public IStyleSheet? Sheet => _sheet; public bool IsDisabled { get { return this.GetBoolAttribute(AttributeNames.Disabled); } set { this.SetBoolAttribute(AttributeNames.Disabled, value); if (_sheet != null) { _sheet.IsDisabled = value; } } } public string? Media { get { return this.GetOwnAttribute(AttributeNames.Media); } set { this.SetOwnAttribute(AttributeNames.Media, value); } } public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public HtmlStyleElement(Document owner, string? prefix = null) : base(owner, TagNames.Style, prefix, NodeFlags.Special | NodeFlags.LiteralText) { } internal override void SetupElement() { base.SetupElement(); UpdateSheet(); } internal void UpdateMedia(string value) { if (_sheet != null) { _sheet.Media.MediaText = value; } } protected override void NodeIsInserted(Node newNode) { base.NodeIsInserted(newNode); UpdateSheet(); } protected override void NodeIsRemoved(Node removedNode, Node? oldPreviousSibling) { base.NodeIsRemoved(removedNode, oldPreviousSibling); UpdateSheet(); } private void UpdateSheet() { Document owner = base.Owner; if (owner != null) { IBrowsingContext context = base.Context; string type = Type ?? MimeTypeNames.Css; IStylingService styling = context.GetStyling(type); if (styling != null) { Task task = CreateSheetAsync(styling, owner); owner.DelayLoad(task); } } } private async Task CreateSheetAsync(IStylingService engine, IDocument document) { CancellationToken none = CancellationToken.None; IResponse response = VirtualResponse.Create(delegate(VirtualResponse res) { res.Content(TextContent).Address((Url)null); }); StyleOptions options = new StyleOptions(document) { Element = this, IsDisabled = IsDisabled, IsAlternate = false }; _sheet = await engine.ParseStylesheetAsync(response, options, none).ConfigureAwait(continueOnCapturedContext: false); UpdateMedia(Media); } } internal sealed class HtmlTableCaptionElement : HtmlElement, IHtmlTableCaptionElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string Align { get { return this.GetOwnAttribute(AttributeNames.Align) ?? Keywords.Top; } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public HtmlTableCaptionElement(Document owner, string? prefix = null) : base(owner, TagNames.Caption, prefix, NodeFlags.Special | NodeFlags.Scoped) { } } internal abstract class HtmlTableCellElement : HtmlElement, IHtmlTableCellElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private SettableTokenList? _headers; public int Index { get { IElement parentElement = base.ParentElement; while (parentElement != null && !(parentElement is IHtmlTableRowElement)) { parentElement = parentElement.ParentElement; } return (parentElement as HtmlTableRowElement)?.IndexOf(this) ?? (-1); } } public HorizontalAlignment Align { get { return this.GetOwnAttribute(AttributeNames.Align).ToEnum(HorizontalAlignment.Left); } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public VerticalAlignment VAlign { get { return this.GetOwnAttribute(AttributeNames.Valign).ToEnum(VerticalAlignment.Middle); } set { this.SetOwnAttribute(AttributeNames.Valign, value.ToString()); } } public string? BgColor { get { return this.GetOwnAttribute(AttributeNames.BgColor); } set { this.SetOwnAttribute(AttributeNames.BgColor, value); } } public string? Width { get { return this.GetOwnAttribute(AttributeNames.Width); } set { this.SetOwnAttribute(AttributeNames.Width, value); } } public string? Height { get { return this.GetOwnAttribute(AttributeNames.Height); } set { this.SetOwnAttribute(AttributeNames.Height, value); } } public int ColumnSpan { get { return LimitColSpan(this.GetOwnAttribute(AttributeNames.ColSpan).ToInteger(1)); } set { this.SetOwnAttribute(AttributeNames.ColSpan, value.ToString()); } } public int RowSpan { get { return LimitRowSpan(this.GetOwnAttribute(AttributeNames.RowSpan).ToInteger(1)); } set { this.SetOwnAttribute(AttributeNames.RowSpan, value.ToString()); } } public bool NoWrap { get { return this.GetOwnAttribute(AttributeNames.NoWrap).ToBoolean(); } set { this.SetOwnAttribute(AttributeNames.NoWrap, value.ToString()); } } public string? Abbr { get { return this.GetOwnAttribute(AttributeNames.Abbr); } set { this.SetOwnAttribute(AttributeNames.Abbr, value); } } public string? Scope { get { return this.GetOwnAttribute(AttributeNames.Scope); } set { this.SetOwnAttribute(AttributeNames.Scope, value); } } public ISettableTokenList Headers { get { if (_headers == null) { _headers = new SettableTokenList(this.GetOwnAttribute(AttributeNames.Headers)); _headers.Changed += delegate(string value) { UpdateAttribute(AttributeNames.Headers, value); }; } return _headers; } } public string? Axis { get { return this.GetOwnAttribute(AttributeNames.Axis); } set { this.SetOwnAttribute(AttributeNames.Axis, value); } } public HtmlTableCellElement(Document owner, string name, string? prefix) : base(owner, name, prefix, NodeFlags.Special | NodeFlags.ImplicitlyClosed | NodeFlags.Scoped) { } internal void UpdateHeaders(string value) { _headers?.Update(value); } private static int LimitColSpan(int value) { if (value < 1 || value > 1000) { return 1; } return value; } private static int LimitRowSpan(int value) { if (value < 0) { return 1; } return Math.Min(value, 65534); } } internal sealed class HtmlTableColElement : HtmlElement, IHtmlTableColumnElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HorizontalAlignment Align { get { return this.GetOwnAttribute(AttributeNames.Align).ToEnum(HorizontalAlignment.Center); } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public int Span { get { return this.GetOwnAttribute(AttributeNames.Span).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.Span, value.ToString()); } } public VerticalAlignment VAlign { get { return this.GetOwnAttribute(AttributeNames.Valign).ToEnum(VerticalAlignment.Middle); } set { this.SetOwnAttribute(AttributeNames.Valign, value.ToString()); } } public string? Width { get { return this.GetOwnAttribute(AttributeNames.Width); } set { this.SetOwnAttribute(AttributeNames.Width, value); } } public HtmlTableColElement(Document owner, string? prefix = null) : base(owner, TagNames.Col, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } internal sealed class HtmlTableColgroupElement : HtmlElement, IHtmlTableColumnElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HorizontalAlignment Align { get { return this.GetOwnAttribute(AttributeNames.Align).ToEnum(HorizontalAlignment.Center); } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public int Span { get { return this.GetOwnAttribute(AttributeNames.Span).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.Span, value.ToString()); } } public VerticalAlignment VAlign { get { return this.GetOwnAttribute(AttributeNames.Valign).ToEnum(VerticalAlignment.Middle); } set { this.SetOwnAttribute(AttributeNames.Valign, value.ToString()); } } public string? Width { get { return this.GetOwnAttribute(AttributeNames.Width); } set { this.SetOwnAttribute(AttributeNames.Width, value); } } public HtmlTableColgroupElement(Document owner, string? prefix = null) : base(owner, TagNames.Colgroup, prefix, NodeFlags.Special) { } } internal sealed class HtmlTableDataCellElement : HtmlTableCellElement, IHtmlTableDataCellElement, IHtmlTableCellElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlTableDataCellElement(Document owner, string? prefix = null) : base(owner, TagNames.Td, prefix) { } } internal sealed class HtmlTableElement : HtmlElement, IHtmlTableElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private HtmlCollection? _bodies; private HtmlCollection? _rows; public IHtmlTableCaptionElement? Caption { get { return base.ChildNodes.OfType().FirstOrDefault((IHtmlTableCaptionElement m) => m.LocalName.Is(TagNames.Caption)); } set { DeleteCaption(); if (value != null) { InsertChild(0, value); } } } public IHtmlTableSectionElement? Head { get { return base.ChildNodes.OfType().FirstOrDefault((IHtmlTableSectionElement m) => m.LocalName.Is(TagNames.Thead)); } set { DeleteHead(); if (value != null) { AppendChild(value); } } } public IHtmlCollection Bodies => _bodies ?? (_bodies = new HtmlCollection(this, deep: false, (IHtmlTableSectionElement m) => m.LocalName.Is(TagNames.Tbody))); public IHtmlTableSectionElement? Foot { get { return base.ChildNodes.OfType().FirstOrDefault((IHtmlTableSectionElement m) => m.LocalName.Is(TagNames.Tfoot)); } set { DeleteFoot(); if (value != null) { AppendChild(value); } } } public IEnumerable AllRows { get { IEnumerable enumerable = from m in base.ChildNodes.OfType() where m.LocalName.Is(TagNames.Thead) select m; IEnumerable foots = from m in base.ChildNodes.OfType() where m.LocalName.Is(TagNames.Tfoot) select m; foreach (IHtmlTableSectionElement item in enumerable) { foreach (IHtmlTableRowElement row in item.Rows) { yield return row; } } foreach (Node childNode in base.ChildNodes) { if (childNode is IHtmlTableSectionElement htmlTableSectionElement) { if (!htmlTableSectionElement.LocalName.Is(TagNames.Tbody)) { continue; } foreach (IHtmlTableRowElement row2 in htmlTableSectionElement.Rows) { yield return row2; } } else if (childNode is IHtmlTableRowElement htmlTableRowElement) { yield return htmlTableRowElement; } } foreach (IHtmlTableSectionElement item2 in foots) { foreach (IHtmlTableRowElement row3 in item2.Rows) { yield return row3; } } } } public IHtmlCollection Rows => _rows ?? (_rows = new HtmlCollection(AllRows)); public HorizontalAlignment Align { get { return this.GetOwnAttribute(AttributeNames.Align).ToEnum(HorizontalAlignment.Left); } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public string? BgColor { get { return this.GetOwnAttribute(AttributeNames.BgColor); } set { this.SetOwnAttribute(AttributeNames.BgColor, value); } } public uint Border { get { return this.GetOwnAttribute(AttributeNames.Border).ToInteger(0u); } set { this.SetOwnAttribute(AttributeNames.Border, value.ToString()); } } public int CellPadding { get { return this.GetOwnAttribute(AttributeNames.CellPadding).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.CellPadding, value.ToString()); } } public int CellSpacing { get { return this.GetOwnAttribute(AttributeNames.CellSpacing).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.CellSpacing, value.ToString()); } } public TableFrames Frame { get { return this.GetOwnAttribute(AttributeNames.Frame).ToEnum(TableFrames.Void); } set { this.SetOwnAttribute(AttributeNames.Frame, value.ToString()); } } public TableRules Rules { get { return this.GetOwnAttribute(AttributeNames.Rules).ToEnum(TableRules.All); } set { this.SetOwnAttribute(AttributeNames.Rules, value.ToString()); } } public string? Summary { get { return this.GetOwnAttribute(AttributeNames.Summary); } set { this.SetOwnAttribute(AttributeNames.Summary, value); } } public string? Width { get { return this.GetOwnAttribute(AttributeNames.Width); } set { this.SetOwnAttribute(AttributeNames.Width, value); } } public HtmlTableElement(Document owner, string? prefix = null) : base(owner, TagNames.Table, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.HtmlTableSectionScoped | NodeFlags.HtmlTableScoped) { } public IHtmlTableRowElement InsertRowAt(int index = -1) { IHtmlCollection rows = Rows; IHtmlTableRowElement htmlTableRowElement = (IHtmlTableRowElement)base.Owner.CreateElement(TagNames.Tr); if (index >= 0 && index < rows.Length) { IHtmlTableRowElement htmlTableRowElement2 = rows[index]; htmlTableRowElement2.ParentElement.InsertBefore(htmlTableRowElement, htmlTableRowElement2); } else if (rows.Length == 0) { IHtmlCollection bodies = Bodies; if (bodies.Length == 0) { IElement child = base.Owner.CreateElement(TagNames.Tbody); AppendChild(child); } bodies[bodies.Length - 1].AppendChild(htmlTableRowElement); } else { rows[rows.Length - 1].ParentElement.AppendChild(htmlTableRowElement); } return htmlTableRowElement; } public void RemoveRowAt(int index) { IHtmlCollection rows = Rows; if (index >= 0 && index < rows.Length) { rows[index].Remove(); } } public IHtmlTableSectionElement CreateHead() { IHtmlTableSectionElement htmlTableSectionElement = Head; if (htmlTableSectionElement == null) { htmlTableSectionElement = (IHtmlTableSectionElement)base.Owner.CreateElement(TagNames.Thead); AppendChild(htmlTableSectionElement); } return htmlTableSectionElement; } public IHtmlTableSectionElement CreateBody() { IHtmlTableSectionElement htmlTableSectionElement = Bodies.LastOrDefault(); IHtmlTableSectionElement htmlTableSectionElement2 = (IHtmlTableSectionElement)base.Owner.CreateElement(TagNames.Tbody); int length = base.ChildNodes.Length; int num = ((htmlTableSectionElement != null) ? (htmlTableSectionElement.Index() + 1) : length); if (num == length) { AppendChild(htmlTableSectionElement2); } else { InsertChild(num, htmlTableSectionElement2); } return htmlTableSectionElement2; } public void DeleteHead() { Head?.Remove(); } public IHtmlTableSectionElement CreateFoot() { IHtmlTableSectionElement htmlTableSectionElement = Foot; if (htmlTableSectionElement == null) { htmlTableSectionElement = (IHtmlTableSectionElement)base.Owner.CreateElement(TagNames.Tfoot); AppendChild(htmlTableSectionElement); } return htmlTableSectionElement; } public void DeleteFoot() { Foot?.Remove(); } public IHtmlTableCaptionElement CreateCaption() { IHtmlTableCaptionElement htmlTableCaptionElement = Caption; if (htmlTableCaptionElement == null) { htmlTableCaptionElement = (IHtmlTableCaptionElement)base.Owner.CreateElement(TagNames.Caption); InsertChild(0, htmlTableCaptionElement); } return htmlTableCaptionElement; } public void DeleteCaption() { Caption?.Remove(); } } internal sealed class HtmlTableHeaderCellElement : HtmlTableCellElement, IHtmlTableHeaderCellElement, IHtmlTableCellElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlTableHeaderCellElement(Document owner, string? prefix = null) : base(owner, TagNames.Th, prefix) { } } internal sealed class HtmlTableRowElement : HtmlElement, IHtmlTableRowElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private HtmlCollection? _cells; public HorizontalAlignment Align { get { return this.GetOwnAttribute(AttributeNames.Align).ToEnum(HorizontalAlignment.Left); } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public VerticalAlignment VAlign { get { return this.GetOwnAttribute(AttributeNames.Valign).ToEnum(VerticalAlignment.Middle); } set { this.SetOwnAttribute(AttributeNames.Valign, value.ToString()); } } public string? BgColor { get { return this.GetOwnAttribute(AttributeNames.BgColor); } set { this.SetOwnAttribute(AttributeNames.BgColor, value); } } public IHtmlCollection Cells => _cells ?? (_cells = new HtmlCollection(this, deep: false)); public int Index => this.GetAncestor()?.Rows.Index(this) ?? (-1); public int IndexInSection => (base.ParentElement as IHtmlTableSectionElement)?.Rows.Index(this) ?? Index; public HtmlTableRowElement(Document owner, string? prefix = null) : base(owner, TagNames.Tr, prefix, NodeFlags.Special | NodeFlags.ImplicitlyClosed) { } public IHtmlTableCellElement InsertCellAt(int index = -1, TableCellKind tableCellKind = TableCellKind.Td) { IHtmlCollection cells = Cells; IHtmlTableCellElement htmlTableCellElement = (IHtmlTableCellElement)base.Owner.CreateElement((tableCellKind == TableCellKind.Td) ? TagNames.Td : TagNames.Th); if (index >= 0 && index < cells.Length) { InsertBefore(htmlTableCellElement, cells[index]); } else { AppendChild(htmlTableCellElement); } return htmlTableCellElement; } public void RemoveCellAt(int index) { IHtmlCollection cells = Cells; if (index < 0) { index = cells.Length + index; } if (index >= 0 && index < cells.Length) { cells[index].Remove(); } } } internal sealed class HtmlTableSectionElement : HtmlElement, IHtmlTableSectionElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private HtmlCollection? _rows; public HorizontalAlignment Align { get { return this.GetOwnAttribute(AttributeNames.Align).ToEnum(HorizontalAlignment.Center); } set { this.SetOwnAttribute(AttributeNames.Align, value.ToString()); } } public IHtmlCollection Rows => _rows ?? (_rows = new HtmlCollection(this, deep: false)); public VerticalAlignment VAlign { get { return this.GetOwnAttribute(AttributeNames.Valign).ToEnum(VerticalAlignment.Middle); } set { this.SetOwnAttribute(AttributeNames.Valign, value.ToString()); } } public HtmlTableSectionElement(Document owner, string? name = null, string? prefix = null) : base(owner, name ?? TagNames.Tbody, prefix, NodeFlags.Special | NodeFlags.ImplicitlyClosed | NodeFlags.HtmlTableSectionScoped) { } public IHtmlTableRowElement InsertRowAt(int index = -1) { IHtmlCollection rows = Rows; IHtmlTableRowElement htmlTableRowElement = (IHtmlTableRowElement)base.Owner.CreateElement(TagNames.Tr); if (index >= 0 && index < rows.Length) { InsertBefore(htmlTableRowElement, rows[index]); } else { AppendChild(htmlTableRowElement); } return htmlTableRowElement; } public void RemoveRowAt(int index) { IHtmlCollection rows = Rows; if (index >= 0 && index < rows.Length) { rows[index].Remove(); } } } internal sealed class HtmlTeletypeTextElement : HtmlElement { public HtmlTeletypeTextElement(Document owner, string? prefix = null) : base(owner, TagNames.Tt, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlTemplateElement : HtmlElement, IHtmlTemplateElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IConstructableTemplateElement, IConstructableElement, IConstructableNode { private readonly DocumentFragment _content; public IDocumentFragment Content => _content; public HtmlTemplateElement(Document owner, string? prefix = null) : base(owner, TagNames.Template, prefix, NodeFlags.Special | NodeFlags.Scoped | NodeFlags.HtmlTableSectionScoped | NodeFlags.HtmlTableScoped) { _content = new DocumentFragment(owner); } public override Node Clone(Document owner, bool deep) { HtmlTemplateElement htmlTemplateElement = new HtmlTemplateElement(owner); CloneElement(htmlTemplateElement, owner, deep); DocumentFragment content = htmlTemplateElement._content; foreach (Node childNode in _content.ChildNodes) { if (childNode != null) { Node node = childNode; Node node2 = node.Clone(owner, deep); content.AddNode(node2); } } return htmlTemplateElement; } public void PopulateFragment() { while (base.HasChildNodes) { Node node = base.ChildNodes[0]; RemoveNode(0, node); _content.AddNode(node); } } protected override void ReplacedAll() { PopulateFragment(); } protected override void NodeIsAdopted(Document oldDocument) { _content.Owner = oldDocument; } } internal sealed class HtmlTextAreaElement : HtmlTextFormControlElement, IHtmlTextAreaElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IValidation { public string? Wrap { get { return this.GetOwnAttribute(AttributeNames.Wrap); } set { this.SetOwnAttribute(AttributeNames.Wrap, value); } } public override string DefaultValue { get { return TextContent; } set { TextContent = value; } } public int TextLength => base.Value.Length; public int Rows { get { return this.GetOwnAttribute(AttributeNames.Rows).ToInteger(2); } set { this.SetOwnAttribute(AttributeNames.Rows, value.ToString()); } } public int Columns { get { return this.GetOwnAttribute(AttributeNames.Cols).ToInteger(20); } set { this.SetOwnAttribute(AttributeNames.Cols, value.ToString()); } } public string Type => TagNames.Textarea; public HtmlTextAreaElement(Document owner, string? prefix = null) : base(owner, TagNames.Textarea, prefix, NodeFlags.LineTolerance) { } internal override void ConstructDataSet(FormDataSet dataSet, IHtmlElement submitter) { ConstructDataSet(dataSet, Type); } internal override FormControlState SaveControlState() { return new FormControlState(base.Name, Type, base.Value); } internal override void RestoreFormControlState(FormControlState state) { if (state.Type.Is(Type) && state.Name.Is(base.Name)) { base.Value = state.Value; } } } internal abstract class HtmlTextFormControlElement : HtmlFormControlElementWithState { public enum SelectionType : byte { None, Forward, Backward } private bool _dirty; private string? _value; private SelectionType _direction; private int _start; private int _end; public bool IsDirty { get { return _dirty; } set { _dirty = value; } } public string? DirectionName { get { return this.GetOwnAttribute(AttributeNames.DirName); } set { this.SetOwnAttribute(AttributeNames.DirName, value); } } public int MaxLength { get { return this.GetOwnAttribute(AttributeNames.MaxLength).ToInteger(-1); } set { this.SetOwnAttribute(AttributeNames.MaxLength, value.ToString()); } } public int MinLength { get { return this.GetOwnAttribute(AttributeNames.MinLength).ToInteger(0); } set { this.SetOwnAttribute(AttributeNames.MinLength, value.ToString()); } } public abstract string DefaultValue { get; set; } public bool HasValue { get { if (_value == null) { return this.HasOwnAttribute(AttributeNames.Value); } return true; } } public string Value { get { return _value ?? DefaultValue; } [param: AllowNull] set { _value = value; } } public string? Placeholder { get { return this.GetOwnAttribute(AttributeNames.Placeholder); } set { this.SetOwnAttribute(AttributeNames.Placeholder, value); } } public bool IsRequired { get { return this.GetBoolAttribute(AttributeNames.Required); } set { this.SetBoolAttribute(AttributeNames.Required, value); } } public bool IsReadOnly { get { return this.GetBoolAttribute(AttributeNames.Readonly); } set { this.SetBoolAttribute(AttributeNames.Readonly, value); } } public int SelectionStart { get { return _start; } set { SetSelectionRange(value, _end, _direction); } } public int SelectionEnd { get { return _end; } set { SetSelectionRange(_start, value, _direction); } } public string? SelectionDirection => _direction.ToString().ToLowerInvariant(); public HtmlTextFormControlElement(Document owner, string name, string? prefix, NodeFlags flags = NodeFlags.None) : base(owner, name, prefix, flags) { } public override Node Clone(Document owner, bool deep) { HtmlTextFormControlElement obj = (HtmlTextFormControlElement)base.Clone(owner, deep); obj._dirty = _dirty; obj._value = _value; obj._direction = _direction; obj._start = _start; obj._end = _end; return obj; } public void Select(int selectionStart, int selectionEnd, string? selectionDirection = null) { SetSelectionRange(selectionStart, selectionEnd, selectionDirection.ToEnum(SelectionType.Forward)); } public void SelectAll() { SetSelectionRange(0, Value.Length, SelectionType.Forward); } protected override void Check(ValidityState state) { int length = (Value ?? string.Empty).Length; int maxLength = MaxLength; int minLength = MinLength; state.IsValueMissing = IsRequired && length == 0; state.IsTooLong = _dirty && maxLength > -1 && length > maxLength; state.IsTooShort = _dirty && length > 0 && length < minLength; base.Check(state); } protected override bool CanBeValidated() { if (!IsReadOnly) { return !this.HasDataListAncestor(); } return false; } protected void ConstructDataSet(FormDataSet dataSet, string type) { dataSet.Append(base.Name, Value, type); string ownAttribute = this.GetOwnAttribute(AttributeNames.DirName); if (ownAttribute != null && ownAttribute.Length > 0) { dataSet.Append(ownAttribute, base.Direction.ToString().ToLowerInvariant(), "Direction"); } } private void SetSelectionRange(int selectionStart, int selectionEnd, SelectionType selectionType) { int length = (Value ?? string.Empty).Length; if (selectionEnd > length) { selectionEnd = length; } if (selectionEnd < selectionStart) { selectionStart = selectionEnd; } _start = selectionStart; _end = selectionEnd; _direction = selectionType; } internal override void Reset() { Value = null; Select(int.MaxValue, int.MaxValue); } } internal sealed class HtmlTimeElement : HtmlElement, IHtmlTimeElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string? DateTime { get { return this.GetOwnAttribute(AttributeNames.Datetime); } set { this.SetOwnAttribute(AttributeNames.Datetime, value); } } public HtmlTimeElement(Document owner, string? prefix = null) : base(owner, TagNames.Time, prefix, NodeFlags.Special) { } } internal sealed class HtmlTitleElement : HtmlElement, IHtmlTitleElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public string Text { get { return TextContent; } set { TextContent = value; } } public HtmlTitleElement(Document owner, string? prefix = null) : base(owner, TagNames.Title, prefix, NodeFlags.Special) { } } internal sealed class HtmlTrackElement : HtmlElement, IHtmlTrackElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { private TrackReadyState _ready; public string? Kind { get { return this.GetOwnAttribute(AttributeNames.Kind); } set { this.SetOwnAttribute(AttributeNames.Kind, value); } } public string? Source { get { return this.GetUrlAttribute(AttributeNames.Src); } set { this.SetOwnAttribute(AttributeNames.Src, value); } } public string? SourceLanguage { get { return this.GetOwnAttribute(AttributeNames.SrcLang); } set { this.SetOwnAttribute(AttributeNames.SrcLang, value); } } public string? Label { get { return this.GetOwnAttribute(AttributeNames.Label); } set { this.SetOwnAttribute(AttributeNames.Label, value); } } public bool IsDefault { get { return this.GetBoolAttribute(AttributeNames.Default); } set { this.SetBoolAttribute(AttributeNames.Default, value); } } public TrackReadyState ReadyState => _ready; public ITextTrack? Track => null; public HtmlTrackElement(Document owner, string? prefix = null) : base(owner, TagNames.Track, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { _ready = TrackReadyState.None; } } internal sealed class HtmlUnderlineElement : HtmlElement { public HtmlUnderlineElement(Document owner, string? prefix = null) : base(owner, TagNames.U, prefix, NodeFlags.HtmlFormatting) { } } internal sealed class HtmlUnknownElement : HtmlElement, IHtmlUnknownElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlUnknownElement(Document owner, string localName, string? prefix = null, NodeFlags flags = NodeFlags.None) : base(owner, localName, prefix, flags) { } } internal sealed class HtmlUnorderedListElement : HtmlElement, IHtmlUnorderedListElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers { public HtmlUnorderedListElement(Document owner, string? prefix = null) : base(owner, TagNames.Ul, prefix, NodeFlags.Special | NodeFlags.HtmlListScoped) { } } internal abstract class HtmlUrlBaseElement : HtmlElement, IUrlUtilities { private TokenList? _relList; private SettableTokenList? _ping; public string? Download { get { return this.GetOwnAttribute(AttributeNames.Download); } set { this.SetOwnAttribute(AttributeNames.Download, value); } } public string Href { get { return this.GetUrlAttribute(AttributeNames.Href); } set { SetAttribute(AttributeNames.Href, value); } } public string Hash { get { return GetLocationPart((ILocation m) => m.Hash); } set { SetLocationPart(delegate(ILocation m) { m.Hash = value; }); } } public string Host { get { return GetLocationPart((ILocation m) => m.Host); } set { SetLocationPart(delegate(ILocation m) { m.Host = value; }); } } public string HostName { get { return GetLocationPart((ILocation m) => m.HostName); } set { SetLocationPart(delegate(ILocation m) { m.HostName = value; }); } } public string PathName { get { return GetLocationPart((ILocation m) => m.PathName); } set { SetLocationPart(delegate(ILocation m) { m.PathName = value; }); } } public string Port { get { return GetLocationPart((ILocation m) => m.Port); } set { SetLocationPart(delegate(ILocation m) { m.Port = value; }); } } public string Protocol { get { return GetLocationPart((ILocation m) => m.Protocol); } set { SetLocationPart(delegate(ILocation m) { m.Protocol = value; }); } } public string? UserName { get { return GetLocationPart((ILocation m) => m.UserName); } set { SetLocationPart(delegate(ILocation m) { m.UserName = value; }); } } public string? Password { get { return GetLocationPart((ILocation m) => m.Password); } set { SetLocationPart(delegate(ILocation m) { m.Password = value; }); } } public string Search { get { return GetLocationPart((ILocation m) => m.Search); } set { SetLocationPart(delegate(ILocation m) { m.Search = value; }); } } public string? Origin => GetLocationPart((ILocation m) => m.Origin); public string? TargetLanguage { get { return this.GetOwnAttribute(AttributeNames.HrefLang); } set { this.SetOwnAttribute(AttributeNames.HrefLang, value); } } public string? Media { get { return this.GetOwnAttribute(AttributeNames.Media); } set { this.SetOwnAttribute(AttributeNames.Media, value); } } public string? Relation { get { return this.GetOwnAttribute(AttributeNames.Rel); } set { this.SetOwnAttribute(AttributeNames.Rel, value); } } public ITokenList RelationList { get { if (_relList == null) { _relList = new TokenList(this.GetOwnAttribute(AttributeNames.Rel)); _relList.Changed += delegate(string value) { UpdateAttribute(AttributeNames.Rel, value); }; } return _relList; } } public ISettableTokenList Ping { get { if (_ping == null) { _ping = new SettableTokenList(this.GetOwnAttribute(AttributeNames.Ping)); _ping.Changed += delegate(string value) { UpdateAttribute(AttributeNames.Ping, value); }; } return _ping; } } public string? Target { get { return this.GetOwnAttribute(AttributeNames.Target); } set { this.SetOwnAttribute(AttributeNames.Target, value); } } public string? Type { get { return this.GetOwnAttribute(AttributeNames.Type); } set { this.SetOwnAttribute(AttributeNames.Type, value); } } public HtmlUrlBaseElement(Document owner, string name, string? prefix, NodeFlags flags) : base(owner, name, prefix, flags) { } public override async void DoClick() { if (!(await IsClickedCancelled().ConfigureAwait(continueOnCapturedContext: false))) { await this.NavigateAsync().ConfigureAwait(continueOnCapturedContext: false); } } internal void UpdateRel(string value) { _relList?.Update(value); } internal void UpdatePing(string value) { _ping?.Update(value); } private string? GetLocationPart(Func getter) { string ownAttribute = this.GetOwnAttribute(AttributeNames.Href); Url url = ((ownAttribute != null) ? new Url(base.BaseUrl, ownAttribute) : null); if (url != null && !url.IsInvalid) { Location arg = new Location(url); return getter(arg); } return string.Empty; } private void SetLocationPart(Action setter) { string ownAttribute = this.GetOwnAttribute(AttributeNames.Href); Url url = ((ownAttribute != null) ? new Url(base.BaseUrl, ownAttribute) : null); if (url == null || url.IsInvalid) { url = new Url(base.BaseUrl); } Location location = new Location(url); setter(location); this.SetOwnAttribute(AttributeNames.Href, location.Href); } } internal sealed class HtmlVideoElement : HtmlMediaElement, IHtmlVideoElement, IHtmlMediaElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IGlobalEventHandlers, IMediaController, ILoadableElement { private IVideoTrackList? _videos; public override IVideoTrackList? VideoTracks => _videos; public int DisplayWidth { get { return this.GetOwnAttribute(AttributeNames.Width).ToInteger(OriginalWidth); } set { this.SetOwnAttribute(AttributeNames.Width, value.ToString()); } } public int DisplayHeight { get { return this.GetOwnAttribute(AttributeNames.Height).ToInteger(OriginalHeight); } set { this.SetOwnAttribute(AttributeNames.Height, value.ToString()); } } public int OriginalWidth => base.Media?.Width ?? 0; public int OriginalHeight => base.Media?.Height ?? 0; public string? Poster { get { return this.GetUrlAttribute(AttributeNames.Poster); } set { this.SetOwnAttribute(AttributeNames.Poster, value); } } public HtmlVideoElement(Document owner, string? prefix = null) : base(owner, TagNames.Video, prefix) { _videos = null; } } internal sealed class HtmlWbrElement : HtmlElement { public HtmlWbrElement(Document owner, string? prefix = null) : base(owner, TagNames.Wbr, prefix, NodeFlags.SelfClosing | NodeFlags.Special) { } } internal sealed class HtmlXmpElement : HtmlElement { public HtmlXmpElement(Document owner, string? prefix = null) : base(owner, TagNames.Xmp, prefix, NodeFlags.Special | NodeFlags.LiteralText) { } } internal sealed class ValidityState : IValidityState { private ValidationErrors _err; public bool IsValueMissing { get { return _err.HasFlag(ValidationErrors.ValueMissing); } set { Set(IsValueMissing, value, ValidationErrors.ValueMissing); } } public bool IsTypeMismatch { get { return _err.HasFlag(ValidationErrors.TypeMismatch); } set { Set(IsTypeMismatch, value, ValidationErrors.TypeMismatch); } } public bool IsPatternMismatch { get { return _err.HasFlag(ValidationErrors.PatternMismatch); } set { Set(IsPatternMismatch, value, ValidationErrors.PatternMismatch); } } public bool IsBadInput { get { return _err.HasFlag(ValidationErrors.BadInput); } set { Set(IsBadInput, value, ValidationErrors.BadInput); } } public bool IsTooLong { get { return _err.HasFlag(ValidationErrors.TooLong); } set { Set(IsTooLong, value, ValidationErrors.TooLong); } } public bool IsTooShort { get { return _err.HasFlag(ValidationErrors.TooShort); } set { Set(IsTooShort, value, ValidationErrors.TooShort); } } public bool IsRangeUnderflow { get { return _err.HasFlag(ValidationErrors.RangeUnderflow); } set { Set(IsRangeUnderflow, value, ValidationErrors.RangeUnderflow); } } public bool IsRangeOverflow { get { return _err.HasFlag(ValidationErrors.RangeOverflow); } set { Set(IsRangeOverflow, value, ValidationErrors.RangeOverflow); } } public bool IsStepMismatch { get { return _err.HasFlag(ValidationErrors.StepMismatch); } set { Set(IsStepMismatch, value, ValidationErrors.StepMismatch); } } public bool IsCustomError { get { return _err.HasFlag(ValidationErrors.Custom); } set { Set(IsCustomError, value, ValidationErrors.Custom); } } public bool IsValid => _err == ValidationErrors.None; internal ValidityState() { _err = ValidationErrors.None; } public void Reset(ValidationErrors err = ValidationErrors.None) { _err = err; } private void Set(bool oldValue, bool newValue, ValidationErrors err) { if (newValue != oldValue) { _err ^= err; } } } [DomNoInterfaceObject] public interface IValidation { [DomName("willValidate")] bool WillValidate { get; } [DomName("validity")] IValidityState Validity { get; } [DomName("validationMessage")] string? ValidationMessage { get; } [DomName("checkValidity")] bool CheckValidity(); [DomName("setCustomValidity")] void SetCustomValidity(string error); } [DomName("ValidityState")] public interface IValidityState { [DomName("valueMissing")] bool IsValueMissing { get; } [DomName("typeMismatch")] bool IsTypeMismatch { get; } [DomName("patternMismatch")] bool IsPatternMismatch { get; } [DomName("tooLong")] bool IsTooLong { get; } [DomName("tooShort")] bool IsTooShort { get; } [DomName("badInput")] bool IsBadInput { get; } [DomName("rangeUnderflow")] bool IsRangeUnderflow { get; } [DomName("rangeOverflow")] bool IsRangeOverflow { get; } [DomName("stepMismatch")] bool IsStepMismatch { get; } [DomName("customError")] bool IsCustomError { get; } [DomName("valid")] bool IsValid { get; } } public enum TableCellKind { Td, Th } public enum TableFrames : byte { Void, Box, Above, Below, HSides, VSides, LHS, RHS, Border } public enum TableRules : byte { None, Rows, Cols, Groups, All } [DomName("HTMLTrackElement")] public enum TrackReadyState : byte { [DomName("NONE")] None, [DomName("LOADING")] Loading, [DomName("LOADED")] Loaded, [DomName("ERROR")] Error } } namespace AngleSharp.Html.Dom.Events { [DomName("CompositionEvent")] public class CompositionEvent : UiEvent { [DomName("data")] public string? Data { get; private set; } public CompositionEvent() { } [DomConstructor] [DomInitDict(1, true)] public CompositionEvent(string type, bool bubbles = false, bool cancelable = false, IWindow? view = null, string? data = null) { Init(type, bubbles, cancelable, view, data ?? string.Empty); } [DomName("initCompositionEvent")] public void Init(string type, bool bubbles, bool cancelable, IWindow? view, string data) { Init(type, bubbles, cancelable, view, 0); Data = data; } } public class HtmlErrorEvent : Event { private readonly HtmlParseError _code; private readonly TextPosition _position; public TextPosition Position => _position; public int Code => _code.GetCode(); public string Message => _code.GetMessage(); public HtmlErrorEvent(HtmlParseError code, TextPosition position) : base(EventNames.Error) { _code = code; _position = position; } } public class HtmlParseEvent : Event { public IHtmlDocument Document { get; private set; } public HtmlParseEvent(IHtmlDocument document, bool completed) : base(completed ? EventNames.Parsed : EventNames.Parsing) { Document = document; } } [DomName("InputEvent")] public class InputEvent : Event { [DomName("data")] public string? Data { get; private set; } public InputEvent() { } [DomConstructor] [DomInitDict(1, true)] public InputEvent(string type, bool bubbles = false, bool cancelable = false, string? data = null) { Init(type, bubbles, cancelable, data ?? string.Empty); } [DomName("initInputEvent")] public void Init(string type, bool bubbles, bool cancelable, string data) { Init(type, bubbles, cancelable); Data = data; } } [DomName("TouchList")] public interface ITouchList { [DomName("length")] int Length { get; } [DomAccessor(Accessors.Getter)] [DomName("item")] ITouchPoint this[int index] { get; } } [DomName("Touch")] public interface ITouchPoint { [DomName("identifier")] int Id { get; } [DomName("target")] IEventTarget Target { get; } [DomName("screenX")] int ScreenX { get; } [DomName("screenY")] int ScreenY { get; } [DomName("clientX")] int ClientX { get; } [DomName("clientY")] int ClientY { get; } [DomName("pageX")] int PageX { get; } [DomName("pageY")] int PageY { get; } } [DomName("KeyboardEvent")] public class KeyboardEvent : UiEvent { private string _modifiers; [DomName("key")] public string? Key { get; private set; } [DomName("location")] public KeyboardLocation Location { get; private set; } [DomName("ctrlKey")] public bool IsCtrlPressed => _modifiers.IsCtrlPressed(); [DomName("shiftKey")] public bool IsShiftPressed => _modifiers.IsShiftPressed(); [DomName("altKey")] public bool IsAltPressed => _modifiers.IsAltPressed(); [DomName("metaKey")] public bool IsMetaPressed => _modifiers.IsMetaPressed(); [DomName("repeat")] public bool IsRepeated { get; private set; } [DomName("locale")] public string? Locale { get { if (!base.IsTrusted) { return null; } return string.Empty; } } public KeyboardEvent() { } [DomConstructor] [DomInitDict(1, true)] public KeyboardEvent(string type, bool bubbles = false, bool cancelable = false, IWindow? view = null, int detail = 0, string? key = null, KeyboardLocation location = KeyboardLocation.Standard, string? modifiersList = null, bool repeat = false) { Init(type, bubbles, cancelable, view, detail, key ?? string.Empty, location, modifiersList ?? string.Empty, repeat); } [DomName("getModifierState")] public bool GetModifierState(string key) { return _modifiers.ContainsKey(key); } [DomName("initKeyboardEvent")] [MemberNotNull(new string[] { "Key", "Location", "_modifiers" })] public void Init(string type, bool bubbles, bool cancelable, IWindow? view, int detail, string key, KeyboardLocation location, string modifiersList, bool repeat) { Init(type, bubbles, cancelable, view, detail); Key = key; Location = location; IsRepeated = repeat; _modifiers = modifiersList; } } [DomName("KeyboardEvent")] public enum KeyboardLocation : byte { [DomName("DOM_KEY_LOCATION_STANDARD")] Standard, [DomName("DOM_KEY_LOCATION_LEFT")] Left, [DomName("DOM_KEY_LOCATION_RIGHT")] Right, [DomName("DOM_KEY_LOCATION_NUMPAD")] NumPad } internal static class ModifierExtensions { public static bool IsCtrlPressed(this string modifierList) { return false; } public static bool IsMetaPressed(this string modifierList) { return false; } public static bool IsShiftPressed(this string modifierList) { return false; } public static bool IsAltPressed(this string modifierList) { return false; } public static bool ContainsKey(this string modifierList, string key) { return modifierList.Contains(key); } } public enum MouseButton : byte { Primary, Auxiliary, Secondary } [Flags] public enum MouseButtons : byte { None = 0, Primary = 0, Secondary = 2, Auxiliary = 4 } [DomName("MouseEvent")] public class MouseEvent : UiEvent { [DomName("screenX")] public int ScreenX { get; private set; } [DomName("screenY")] public int ScreenY { get; private set; } [DomName("clientX")] public int ClientX { get; private set; } [DomName("clientY")] public int ClientY { get; private set; } [DomName("ctrlKey")] public bool IsCtrlPressed { get; private set; } [DomName("shiftKey")] public bool IsShiftPressed { get; private set; } [DomName("altKey")] public bool IsAltPressed { get; private set; } [DomName("metaKey")] public bool IsMetaPressed { get; private set; } [DomName("button")] public MouseButton Button { get; private set; } [DomName("buttons")] public MouseButtons Buttons { get; private set; } [DomName("relatedTarget")] public IEventTarget? Target { get; private set; } public MouseEvent() { } [DomConstructor] [DomInitDict(1, true)] public MouseEvent(string type, bool bubbles = false, bool cancelable = false, IWindow? view = null, int detail = 0, int screenX = 0, int screenY = 0, int clientX = 0, int clientY = 0, bool ctrlKey = false, bool altKey = false, bool shiftKey = false, bool metaKey = false, MouseButton button = MouseButton.Primary, IEventTarget? relatedTarget = null) { Init(type, bubbles, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget); } [DomName("getModifierState")] public bool GetModifierState(string key) { return false; } [DomName("initMouseEvent")] public void Init(string type, bool bubbles, bool cancelable, IWindow? view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, MouseButton button, IEventTarget? target) { Init(type, bubbles, cancelable, view, detail); ScreenX = screenX; ScreenY = screenY; ClientX = clientX; ClientY = clientY; IsCtrlPressed = ctrlKey; IsMetaPressed = metaKey; IsShiftPressed = shiftKey; IsAltPressed = altKey; Button = button; Target = target; } } [DomName("TouchEvent")] public class TouchEvent : UiEvent { [DomName("touches")] public ITouchList? Touches { get; private set; } [DomName("targetTouches")] public ITouchList? TargetTouches { get; private set; } [DomName("changedTouches")] public ITouchList? ChangedTouches { get; private set; } [DomName("altKey")] public bool IsAltPressed { get; private set; } [DomName("metaKey")] public bool IsMetaPressed { get; private set; } [DomName("ctrlKey")] public bool IsCtrlPressed { get; private set; } [DomName("shiftKey")] public bool IsShiftPressed { get; private set; } public TouchEvent() { } [DomConstructor] [DomInitDict(1, true)] public TouchEvent(string type, bool bubbles = false, bool cancelable = false, IWindow? view = null, int detail = 0, ITouchList? touches = null, ITouchList? targetTouches = null, ITouchList? changedTouches = null, bool ctrlKey = false, bool altKey = false, bool shiftKey = false, bool metaKey = false) { Init(type, bubbles, cancelable, view, detail); } [DomName("initTouchEvent")] public void Init(string type, bool bubbles, bool cancelable, IWindow? view, int detail, ITouchList? touches, ITouchList? targetTouches, ITouchList? changedTouches, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) { Init(type, bubbles, cancelable, view, detail); Touches = touches; TargetTouches = targetTouches; ChangedTouches = changedTouches; IsCtrlPressed = ctrlKey; IsShiftPressed = shiftKey; IsMetaPressed = metaKey; IsAltPressed = altKey; } } [DomName("TrackEvent")] public class TrackEvent : Event { [DomName("track")] public object? Track { get; private set; } public TrackEvent() { } [DomConstructor] [DomInitDict(1, true)] public TrackEvent(string type, bool bubbles = false, bool cancelable = false, object? track = null) { Init(type, bubbles, cancelable, track); } [DomName("initTrackEvent")] public void Init(string type, bool bubbles, bool cancelable, object? track) { Init(type, bubbles, cancelable); Track = track; } } [DomName("WheelEvent")] public class WheelEvent : MouseEvent { [DomName("deltaX")] public double DeltaX { get; private set; } [DomName("deltaY")] public double DeltaY { get; private set; } [DomName("deltaZ")] public double DeltaZ { get; private set; } [DomName("deltaMode")] public WheelMode DeltaMode { get; private set; } public WheelEvent() { } [DomConstructor] [DomInitDict(1, true)] public WheelEvent(string type, bool bubbles = false, bool cancelable = false, IWindow? view = null, int detail = 0, int screenX = 0, int screenY = 0, int clientX = 0, int clientY = 0, MouseButton button = MouseButton.Primary, IEventTarget? target = null, string? modifiersList = null, double deltaX = 0.0, double deltaY = 0.0, double deltaZ = 0.0, WheelMode deltaMode = WheelMode.Pixel) { Init(type, bubbles, cancelable, view, detail, screenX, screenY, clientX, clientY, button, target, modifiersList ?? string.Empty, deltaX, deltaY, deltaZ, deltaMode); } [DomName("initWheelEvent")] public void Init(string type, bool bubbles, bool cancelable, IWindow? view, int detail, int screenX, int screenY, int clientX, int clientY, MouseButton button, IEventTarget? target, string modifiersList, double deltaX, double deltaY, double deltaZ, WheelMode deltaMode) { Init(type, bubbles, cancelable, view, detail, screenX, screenY, clientX, clientY, modifiersList.IsCtrlPressed(), modifiersList.IsAltPressed(), modifiersList.IsShiftPressed(), modifiersList.IsMetaPressed(), button, target); DeltaX = deltaX; DeltaY = deltaY; DeltaZ = deltaZ; DeltaMode = deltaMode; } } [DomName("WheelEvent")] public enum WheelMode : byte { [DomName("DOM_DELTA_PIXEL")] Pixel, [DomName("DOM_DELTA_LINE")] Line, [DomName("DOM_DELTA_PAGE")] Page } } namespace AngleSharp.Html.Construction { public interface IHtmlElementConstructionFactory : IDomConstructionElementFactory { } internal sealed class HtmlDomConstructionFactory : IHtmlElementConstructionFactory, IDomConstructionElementFactory { public static readonly IHtmlElementConstructionFactory Instance = new HtmlDomConstructionFactory(HtmlElementFactory.Instance, MathElementFactory.Instance, SvgElementFactory.Instance); private readonly IElementFactory _html; private readonly IElementFactory _math; private readonly IElementFactory _svg; public HtmlDomConstructionFactory(IBrowsingContext context) { _html = context.GetService>(); _math = context.GetService>(); _svg = context.GetService>(); } public HtmlDomConstructionFactory(IElementFactory html, IElementFactory math, IElementFactory svg) { _html = html; _math = math; _svg = svg; } public Element Create(Document document, StringOrMemory localName, StringOrMemory prefix = default(StringOrMemory), NodeFlags flags = NodeFlags.None) { return _html.Create(document, localName.ToString(), prefix.IsNullOrEmpty ? null : prefix.ToString(), flags); } public IConstructableMetaElement CreateMeta(Document document) { return new HtmlMetaElement(document); } public IConstructableScriptElement CreateScript(Document document, bool parserInserted, bool started) { return new HtmlScriptElement(document, null, parserInserted, started); } public IConstructableFrameElement CreateFrame(Document document) { return new HtmlFrameElement(document); } public IConstructableTemplateElement CreateTemplate(Document document) { return new HtmlTemplateElement(document); } public IConstructableFormElement CreateForm(Document document) { return new HtmlFormElement(document); } public Element CreateNoScript(Document document, bool scripting) { return new HtmlNoScriptElement(document, null, scripting); } public IConstructableMathElement CreateMath(Document document, StringOrMemory name = default(StringOrMemory)) { return _math.Create(document, name.ToString()); } public IConstructableSvgElement CreateSvg(Document document, StringOrMemory name = default(StringOrMemory)) { return _svg.Create(document, name.ToString()); } public Element CreateUnknown(Document document, StringOrMemory tagName) { return new HtmlUnknownElement(document, tagName.ToString()); } public Document CreateDocument(TextSource source, IBrowsingContext? context = null) { return new HtmlDocument(context, source); } public IConstructableNode CreateDocumentType(Document document, StringOrMemory name, StringOrMemory publicIdentifier, StringOrMemory systemIdentifier) { return new DocumentType(document, name.ToString()) { SystemIdentifier = systemIdentifier.ToString(), PublicIdentifier = publicIdentifier.ToString() }; } } public interface IConstructableAttr { StringOrMemory Name { get; } StringOrMemory Value { get; set; } } public interface IConstructableDocument : IConstructableNode { TextSource Source { get; } IDisposable? Builder { get; set; } QuirksMode QuirksMode { get; set; } IConstructableElement? Head { get; } IConstructableElement DocumentElement { get; } bool IsLoading { get; } void PerformMicrotaskCheckpoint(); void ProvideStableState(); void AddComment(ref StructHtmlToken token); void TrackError(Exception exception); Task WaitForReadyAsync(CancellationToken cancelToken); Task FinishLoadingAsync(); void ApplyManifest(); void Clear(); } public interface IConstructableElement : IConstructableNode { StringOrMemory NamespaceUri { get; } StringOrMemory LocalName { get; } StringOrMemory Prefix { get; } IConstructableNamedNodeMap Attributes { get; } ISourceReference? SourceReference { get; set; } void SetAttribute(string? namespaceUri, StringOrMemory name, StringOrMemory value); void SetOwnAttribute(StringOrMemory name, StringOrMemory value); StringOrMemory GetAttribute(StringOrMemory namespaceUri, StringOrMemory localName); void SetAttributes(StructAttributes tagAttributes); bool HasAttribute(StringOrMemory name); void SetupElement(); void AddComment(ref StructHtmlToken token); IConstructableNode ShallowCopy(); } public interface IConstructableNamedNodeMap { IConstructableAttr? this[StringOrMemory name] { get; } int Length { get; } bool SameAs(IConstructableNamedNodeMap? attributes); } public interface IConstructableNode { StringOrMemory NodeName { get; } NodeFlags Flags { get; } IConstructableNode? Parent { get; set; } IConstructableNodeList ChildNodes { get; } void RemoveFromParent(); void RemoveChild(IConstructableNode childNode); void RemoveNode(int idx, IConstructableNode childNode); void InsertNode(int idx, IConstructableNode childNode); void AddNode(IConstructableNode node); void AppendText(StringOrMemory text, bool emitWhiteSpaceOnly = false); void InsertText(int idx, StringOrMemory text, bool emitWhiteSpaceOnly = false); } public interface IConstructableNodeList : IEnumerable, IEnumerable { IConstructableNode this[int index] { get; } int Length { get; } void Clear(); } public interface IDomConstructionElementFactory where TDocument : class, IConstructableDocument where TElement : class, IConstructableElement { TElement Create(TDocument document, StringOrMemory localName, StringOrMemory prefix = default(StringOrMemory), NodeFlags flags = NodeFlags.None); TElement CreateNoScript(TDocument document, bool scripting); IConstructableNode CreateDocumentType(TDocument document, StringOrMemory name, StringOrMemory publicIdentifier, StringOrMemory systemIdentifier); IConstructableMathElement CreateMath(TDocument document, StringOrMemory name = default(StringOrMemory)); IConstructableSvgElement CreateSvg(TDocument document, StringOrMemory name = default(StringOrMemory)); IConstructableMetaElement CreateMeta(TDocument document); IConstructableScriptElement CreateScript(TDocument document, bool parserInserted, bool started); IConstructableFrameElement CreateFrame(TDocument document); IConstructableTemplateElement CreateTemplate(TDocument document); IConstructableFormElement CreateForm(TDocument document); TElement CreateUnknown(TDocument document, StringOrMemory tagName); TDocument CreateDocument(TextSource source, IBrowsingContext? context = null); } public interface IConstructableTemplateElement : IConstructableElement, IConstructableNode { void PopulateFragment(); } public interface IConstructableSvgElement : IConstructableElement, IConstructableNode { } public interface IConstructableScriptElement : IConstructableElement, IConstructableNode { Task RunAsync(CancellationToken cancel); bool Prepare(IConstructableDocument document); } public interface IConstructableMetaElement : IConstructableElement, IConstructableNode { void Handle(); } public interface IConstructableMathElement : IConstructableElement, IConstructableNode { } public interface IConstructableFrameElement : IConstructableElement, IConstructableNode { } public interface IConstructableFormElement : IConstructableElement, IConstructableNode { } } namespace AngleSharp.Common { internal sealed class ArrayPoolBuffer : IMutableCharBuffer, ICharBuffer, IDisposable { private char[] _buffer = ArrayPool.Shared.Rent(length); private int _start; private int _idx; private bool _disposed; private int Pointer => _start + _idx; public int Length => _idx; public int Capacity => _buffer.Length; public char this[int i] => _buffer[_start + i]; public ArrayPoolBuffer(int length) { } public void Append(char c) { _buffer[_start + _idx] = c; _idx++; } public void Discard() { Clear(commit: false); } private void Clear(bool commit) { if (commit) { _start += _idx; } _idx = 0; } public IMutableCharBuffer Remove(int startIndex, int length) { Span span = _buffer.AsSpan(_start + startIndex + length, length); Span destination = _buffer.AsSpan(_start + startIndex, length); span.CopyTo(destination); _idx -= length; return this; } public void ReturnToPool() { if (!_disposed) { ArrayPool.Shared.Return(_buffer); _buffer = null; _disposed = true; } } public IMutableCharBuffer Insert(int idx, char c) { if ((uint)idx > Length) { throw new ArgumentOutOfRangeException("idx"); } if (Pointer + 1 > Capacity) { throw new InvalidOperationException("Buffer is full."); } Array.Copy(_buffer, _start + idx, _buffer, _start + idx + 1, Length - idx); _buffer[_start + idx] = c; _idx++; return this; } public IMutableCharBuffer Append(ReadOnlySpan str) { if (Pointer + str.Length > Capacity) { throw new InvalidOperationException("Buffer is full."); } str.CopyTo(_buffer.AsSpan(Pointer)); _idx += str.Length; return this; } public ReadOnlyMemory? TryCopyTo(char[] buffer) { StringOrMemory data = GetData(); if (data.Length > buffer.Length) { return null; } data.Memory.Span.CopyTo(buffer); return buffer.AsMemory(0, data.Length); } private StringOrMemory GetData() { return new StringOrMemory(_buffer.AsMemory(_start, Length)); } public StringOrMemory GetDataAndClear() { StringOrMemory data = GetData(); Clear(commit: true); return data; } public bool HasText(ReadOnlySpan test, StringComparison comparison = StringComparison.Ordinal) { return MemoryExtensions.Equals(_buffer.AsSpan(_start, Length), test, comparison); } public bool HasTextAt(ReadOnlySpan test, int offset, int length, StringComparison comparison = StringComparison.Ordinal) { return MemoryExtensions.Equals(_buffer.AsSpan(_start + offset, length), test, comparison); } string IMutableCharBuffer.ToString() { return _buffer.AsMemory(_start, Length).ToString(); } public void Dispose() { ReturnToPool(); } } internal static class ArrayPoolExtensions { internal readonly struct Lease : IDisposable { private readonly ArrayPool _owner; private readonly T[] _data; private readonly int _requestedLength; public int RequestedLength => _requestedLength; public T[] Data => _data; public Span Span => Data.AsSpan(0, RequestedLength); public Memory Memory => Data.AsMemory(0, RequestedLength); public Lease(ArrayPool owner, T[] data, int requestedLength) { _owner = owner; _data = data; _requestedLength = requestedLength; } public void Dispose() { _owner.Return(_data); } } internal static Lease Borrow(this ArrayPool pool, int length) { T[] data = ArrayPool.Shared.Rent(length); return new Lease(ArrayPool.Shared, data, length); } } public abstract class BaseTokenizer : IDisposable { private readonly Stack _columns; private readonly IReadOnlyTextSource _source; private readonly WritableTextSource? _wts; private readonly CharArrayTextSource? _cats; private StringBuilder _stringBuilder; private IMutableCharBuffer _charBuffer; private readonly ArrayPoolBuffer? _apb; private readonly StringBuilderBuffer? _sbb; private ushort _column; private ushort _row; private char _current; private bool _normalized; private bool _disableElementPositionTracking; public int InsertionPoint { get { return _source.Index; } protected set { int i; for (i = _source.Index - value; i > 0; i--) { BackUnsafe(); } for (; i < 0; i++) { AdvanceUnsafe(); } } } public int Position => _source.Index - (_normalized ? 1 : 0); protected char Current => _current; protected StringBuilder StringBuffer => _stringBuilder; private protected IMutableCharBuffer CharBuffer => _charBuffer; protected bool IsNormalized => _normalized; public bool DisableElementPositionTracking { get { return _disableElementPositionTracking; } set { _disableElementPositionTracking = value; } } public BaseTokenizer(TextSource source) { _stringBuilder = StringBuilderPool.Obtain(); if (source.TryGetContentLength(out var length)) { _charBuffer = (_apb = new ArrayPoolBuffer(length)); } else { _charBuffer = (_sbb = new StringBuilderBuffer()); } _source = source.GetUnderlyingTextSource(); if (_source is WritableTextSource wts) { _wts = wts; } else if (_source is CharArrayTextSource cats) { _cats = cats; } _current = '\0'; _column = 0; _row = 1; _columns = new Stack(); } public string FlushBuffer() { string result = StringBuffer.ToString(); StringBuffer.Clear(); return result; } internal StringOrMemory FlushBufferFast() { return _charBuffer.GetDataAndClear(); } internal StringOrMemory FlushBufferFast(Func stringResolver) { string text = stringResolver(CharBuffer); if (text != null) { _charBuffer.Discard(); return new StringOrMemory(text); } return _charBuffer.GetDataAndClear(); } public void Dispose() { if (_charBuffer != null) { _source.Dispose(); _stringBuilder.Clear(); _stringBuilder.ReturnToPool(); _stringBuilder = null; _charBuffer.Discard(); _charBuffer.Dispose(); _charBuffer = null; } } public TextPosition GetCurrentPosition() { return new TextPosition(_row, _column, Position); } protected bool ContinuesWithInsensitive(string s) { StringOrMemory str = PeekStringFast(s.Length); if (str.Length == s.Length) { return str.Isi(s); } return false; } protected bool ContinuesWithSensitive(string s) { StringOrMemory str = PeekStringFast(s.Length); if (str.Length == s.Length) { return str.Is(s); } return false; } protected string PeekString(int length) { int index = _source.Index; _source.Index--; string result = _source.ReadCharacters(length); _source.Index = index; return result; } protected StringOrMemory PeekStringFast(int length) { int index = _source.Index; _source.Index--; StringOrMemory result = _source.ReadMemory(length); _source.Index = index; return result; } protected char SkipSpaces() { char next = GetNext(); while (next.IsSpaceCharacter()) { next = GetNext(); } return next; } protected char GetNext() { Advance(); return _current; } protected char GetPrevious() { Back(); return _current; } protected void Advance() { if (_current != '\uffff') { AdvanceUnsafe(); } } protected void Advance(int n) { while (n-- > 0 && _current != '\uffff') { AdvanceUnsafe(); } } protected void Back() { if (InsertionPoint > 0) { BackUnsafe(); } } protected void Back(int n) { while (n-- > 0 && InsertionPoint > 0) { BackUnsafe(); } } private protected void Append(char c) { if (_sbb != null) { _sbb._sb.Append(c); } else { _apb.Append(c); } } private protected void Append(char a, char b) { if (_sbb != null) { _sbb._sb.Append(a).Append(b); return; } _apb.Append(a); _apb.Append(b); } private protected void Append(char a, char b, char c) { if (_sbb != null) { _sbb._sb.Append(a).Append(b).Append(c); return; } _apb.Append(a); _apb.Append(b); _apb.Append(c); } private protected void Append(char a, char b, char c, char d) { if (_sbb != null) { _sbb._sb.Append(a).Append(b).Append(c) .Append(d); return; } _apb.Append(a); _apb.Append(b); _apb.Append(c); _apb.Append(d); } private void AdvanceUnsafe() { if (!_disableElementPositionTracking) { Track(); } char p = ReadCharFromSource(); _current = NormalizeForward(p); void Track() { if (_current == '\n') { _columns.Push(_column); _column = 1; _row++; } else { _column++; } } } private void BackUnsafe() { _source.Index--; if (_source.Index == 0) { _column = 0; _current = '\0'; return; } char c = (_current = NormalizeBackward(_source[_source.Index - 1])); if (!_disableElementPositionTracking) { switch (c) { case '\n': _column = (ushort)((_columns.Count == 0) ? 1 : _columns.Pop()); _row--; break; default: _column--; break; case '\0': break; } } } private char NormalizeForward(char p) { if (p != '\r') { _normalized = false; return p; } if (ReadCharFromSource() != '\n') { _source.Index--; } else { _normalized = true; } return '\n'; } private char NormalizeBackward(char p) { if (p != '\r') { _normalized = false; return p; } if (_source.Index < _source.Length && _source[_source.Index] == '\n') { _normalized = false; BackUnsafe(); return '\0'; } _normalized = true; return '\n'; } private char ReadCharFromSource() { if (_wts != null) { return _wts.ReadCharacter(); } if (_cats != null) { return _cats.ReadCharacter(); } return _source.ReadCharacter(); } } internal static class BufferExtensions { public static bool Is(this IMutableCharBuffer buffer, string test) { return buffer.HasText(test.AsSpan()); } public static bool Is(this IMutableCharBuffer buffer, int start, int length, string test) { return buffer.HasTextAt(test.AsSpan(), start, length); } public static bool Isi(this IMutableCharBuffer buffer, string test) { return buffer.HasText(test.AsSpan(), StringComparison.OrdinalIgnoreCase); } public static bool Isi(this IMutableCharBuffer buffer, int start, int length, string test) { return buffer.HasTextAt(test.AsSpan(), start, length, StringComparison.OrdinalIgnoreCase); } public static bool Is(this IMutableCharBuffer buffer, StringOrMemory test) { return buffer.HasText(test.Memory.Span); } public static bool Is(this IMutableCharBuffer buffer, int start, int length, StringOrMemory test) { return buffer.HasTextAt(test.Memory.Span, start, length); } public static bool Isi(this IMutableCharBuffer buffer, StringOrMemory test) { return buffer.HasText(test.Memory.Span, StringComparison.OrdinalIgnoreCase); } public static bool Isi(this IMutableCharBuffer buffer, int start, int length, StringOrMemory test) { return buffer.HasTextAt(test.Memory.Span, start, length, StringComparison.OrdinalIgnoreCase); } public static bool Isi(this IMutableCharBuffer buffer, ReadOnlyMemory test) { return buffer.HasText(test.Span, StringComparison.OrdinalIgnoreCase); } public static bool Isi(this IMutableCharBuffer buffer, int start, int length, ReadOnlyMemory test) { return buffer.HasTextAt(test.Span, start, length, StringComparison.OrdinalIgnoreCase); } public static bool Is(this IMutableCharBuffer buffer, ReadOnlyMemory test) { return buffer.HasText(test.Span); } public static bool Is(this IMutableCharBuffer buffer, int start, int length, ReadOnlyMemory test) { return buffer.HasTextAt(test.Span, start, length); } public static bool Is(this IMutableCharBuffer buffer, ReadOnlySpan test) { return buffer.HasText(test); } public static bool Is(this IMutableCharBuffer buffer, int start, int length, ReadOnlySpan test) { return buffer.HasTextAt(test, start, length); } public static bool Isi(this IMutableCharBuffer buffer, ReadOnlySpan test) { return buffer.HasText(test, StringComparison.OrdinalIgnoreCase); } public static bool Isi(this IMutableCharBuffer buffer, int start, int length, ReadOnlySpan test) { return buffer.HasTextAt(test, start, length, StringComparison.OrdinalIgnoreCase); } } public interface IBindable { event Action Changed; void Update(string value); } public interface ICancellable : ICancellable { Task Task { get; } } public interface ICancellable { bool IsCompleted { get; } bool IsRunning { get; } void Cancel(); } public interface ICharBuffer { int Length { get; } char this[int i] { get; } ReadOnlyMemory? TryCopyTo(char[] buffer); } internal interface IMutableCharBuffer : ICharBuffer, IDisposable { int Capacity { get; } void Append(char c); void Discard(); IMutableCharBuffer Remove(int start, int length); void ReturnToPool(); IMutableCharBuffer Insert(int index, char c); IMutableCharBuffer Append(ReadOnlySpan str); StringOrMemory GetDataAndClear(); bool HasText(ReadOnlySpan test, StringComparison comparison = StringComparison.Ordinal); bool HasTextAt(ReadOnlySpan test, int offset, int length, StringComparison comparison = StringComparison.Ordinal); new string ToString(); } public static class Keywords { public static readonly string Url = "url"; public static readonly string On = "on"; public static readonly string Off = "off"; public static readonly string Of = "of"; public static readonly string Yes = "yes"; public static readonly string No = "no"; public static readonly string Top = "top"; public static readonly string Any = "any"; public static readonly string Public = "PUBLIC"; public static readonly string System = "SYSTEM"; public static readonly string CData = "[CDATA["; public static readonly string Replace = "replace"; public static readonly string Alternate = "alternate"; public static readonly string Odd = "odd"; public static readonly string Even = "even"; public static readonly string TwoD = "2d"; public static readonly string WebGl = "webgl"; } public static class ObjectExtensions { public static Dictionary ToDictionary(this object? values) { Dictionary dictionary = new Dictionary(); if (values != null) { PropertyInfo[] properties = values.GetType().GetProperties(); foreach (PropertyInfo propertyInfo in properties) { object obj = propertyInfo.GetValue(values, null) ?? string.Empty; dictionary.Add(propertyInfo.Name, obj.ToString() ?? string.Empty); } } return dictionary; } public static T GetItemByIndex(this IEnumerable items, int index) { if (items is IReadOnlyList readOnlyList) { return readOnlyList[index]; } if (index >= 0) { int num = 0; foreach (T item in items) { if (num++ == index) { return item; } } } throw new ArgumentOutOfRangeException("index"); } public static IEnumerable Concat(this IEnumerable items, T element) { yield return element; foreach (T item in items) { yield return item; } } public static IEnumerable Except(this IEnumerable items, T element) { foreach (T item in items) { if ((object)item != (object)element) { yield return item; } } } public static T? TryGet(this IDictionary values, string key) where T : struct { if (values.TryGetValue(key, out object value) && value is T) { return (T)value; } return null; } public static object? TryGet(this IDictionary values, string key) { values.TryGetValue(key, out object value); return value; } [return: NotNullIfNotNull("defaultValue")] public static U? GetOrDefault(this IDictionary values, T key, U? defaultValue) where T : notnull where U : notnull { if (!values.TryGetValue(key, out U value)) { return defaultValue; } return value; } public static double Constraint(this double value, double min, double max) { if (!(value < min)) { if (!(value > max)) { return value; } return max; } return min; } public static string GetMessage<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(this T code) where T : Enum { return typeof(T).GetField(code.ToString())?.GetCustomAttribute()?.Description ?? "An unknown error occurred."; } } internal sealed class StringBuilderBuffer : IMutableCharBuffer, ICharBuffer, IDisposable { private bool _disposed; internal StringBuilder _sb = StringBuilderPool.Obtain(); public int Length => _sb.Length; public int Capacity => _sb.Capacity; public char this[int i] => _sb[i]; public void Append(char c) { _sb.Append(c); } public void Discard() { _sb.Clear(); } public IMutableCharBuffer Remove(int startIndex, int length) { _sb.Remove(startIndex, length); return this; } public void ReturnToPool() { if (_disposed) { _sb.ReturnToPool(); _sb = null; _disposed = true; } } public void Dispose() { ReturnToPool(); } public IMutableCharBuffer Insert(int index, char c) { _sb.Insert(index, c); return this; } public IMutableCharBuffer Append(ReadOnlySpan str) { _sb.Append(str); return this; } public ReadOnlyMemory? TryCopyTo(char[] buffer) { if (_sb.Length > buffer.Length) { return null; } _sb.CopyTo(0, buffer, 0, _sb.Length); return buffer.AsMemory(0, _sb.Length); } private StringOrMemory GetData() { return new StringOrMemory(_sb.ToString()); } public StringOrMemory GetDataAndClear() { StringOrMemory data = GetData(); Discard(); return data; } public bool HasText(ReadOnlySpan test, StringComparison comparison) { int length = _sb.Length; using ArrayPoolExtensions.Lease lease = ArrayPool.Shared.Borrow(length); _sb.CopyTo(0, lease.Data, 0, length); return MemoryExtensions.Equals(lease.Span.Slice(0, length), test, comparison); } public bool HasTextAt(ReadOnlySpan test, int offset, int length, StringComparison comparison = StringComparison.Ordinal) { using ArrayPoolExtensions.Lease lease = ArrayPool.Shared.Borrow(length); _sb.CopyTo(offset, lease.Data, 0, length); return MemoryExtensions.Equals(lease.Span.Slice(0, length), test, comparison); } public override string ToString() { return _sb.ToString(); } } public struct StringOrMemory { private readonly ReadOnlyMemory _memory; public readonly ReadOnlyMemory Memory => _memory; public int Length => _memory.Length; public char this[int i] => _memory.Span[i]; public bool IsNullOrEmpty => _memory.IsEmpty; public static StringOrMemory Empty => new StringOrMemory(string.Empty); public StringOrMemory(string str) { _memory = str.AsMemory(); } public StringOrMemory(ReadOnlyMemory memory) { _memory = memory; } public static implicit operator StringOrMemory(string str) { return new StringOrMemory(str); } public static implicit operator StringOrMemory(ReadOnlyMemory memory) { return new StringOrMemory(memory); } public static implicit operator ReadOnlyMemory(StringOrMemory str) { return str.Memory; } public static implicit operator ReadOnlySpan(StringOrMemory str) { return str.Memory.Span; } public static bool operator ==(StringOrMemory left, string right) { return left.Memory.Span.SequenceEqual(right.AsSpan()); } public static bool operator ==(StringOrMemory left, StringOrMemory right) { ReadOnlyMemory memory = left.Memory; ReadOnlySpan span = memory.Span; memory = right.Memory; return span.SequenceEqual(memory.Span); } public static bool operator ==(StringOrMemory left, ReadOnlyMemory right) { return left.Memory.Span.SequenceEqual(right.Span); } public static bool operator ==(StringOrMemory left, ReadOnlySpan right) { return left.Memory.Span.SequenceEqual(right); } public static bool operator !=(StringOrMemory left, string right) { return !(left == right); } public static bool operator !=(StringOrMemory left, StringOrMemory right) { return !(left == right); } public static bool operator !=(StringOrMemory left, ReadOnlyMemory right) { return !(left == right); } public static bool operator !=(StringOrMemory left, ReadOnlySpan right) { return !(left == right); } public bool Equals(StringOrMemory other) { if (!_memory.Equals(other._memory)) { return _memory.Span.SequenceEqual(other._memory.Span); } return true; } public override bool Equals(object? obj) { if (obj is StringOrMemory other) { return Equals(other); } return false; } public override int GetHashCode() { return GetHashCode(_memory.Span); } public StringOrMemory Replace(char target, char replacement) { return new StringOrMemory(ToString().Replace(target, replacement)); } public override string ToString() { if (_memory.IsEmpty) { return string.Empty; } return _memory.ToString(); } private static int GetHashCode(ReadOnlySpan span) { int num = 352654597; for (int i = 0; i < span.Length; i++) { num = ((num << 5) + num + (num >> 27)) ^ span[i]; } return num * 1566083941; } } internal static class StringOrMemoryExtensions { public static bool Is(this StringOrMemory str, StringOrMemory other) { return str == other; } public static bool Is(this StringOrMemory str, string other) { return str == other; } public static bool Isi(this StringOrMemory str, StringOrMemory other) { ReadOnlyMemory memory = str.Memory; ReadOnlySpan span = memory.Span; memory = other.Memory; return MemoryExtensions.Equals(span, memory.Span, StringComparison.OrdinalIgnoreCase); } public static bool Isi(this StringOrMemory str, string other) { return MemoryExtensions.Equals(str.Memory.Span, other.AsSpan(), StringComparison.OrdinalIgnoreCase); } public static bool IsOneOf(this StringOrMemory str, StringOrMemory a, StringOrMemory b, StringOrMemory c, StringOrMemory d) { if (!str.Is(a) && !str.Is(b) && !str.Is(c)) { return str.Is(d); } return true; } public static bool IsOneOf(this StringOrMemory str, StringOrMemory a, StringOrMemory b, StringOrMemory c) { if (!str.Is(a) && !str.Is(b)) { return str.Is(c); } return true; } public static bool IsOneOf(this StringOrMemory str, StringOrMemory a, StringOrMemory b) { if (!str.Is(a)) { return str.Is(b); } return true; } public static bool StartsWith(this StringOrMemory str, string test, StringComparison comparison) { return str.Memory.Span.StartsWith(test.AsSpan(), comparison); } public static bool Equals(this StringOrMemory str, string test, StringComparison comparison) { return MemoryExtensions.Equals(str.Memory.Span, test.AsSpan(), comparison); } } } namespace AngleSharp.Browser { internal sealed class DefaultNavigationHandler(IBrowsingContext context) : INavigationHandler { private readonly IBrowsingContext _context = context; public async Task NavigateAsync(DocumentRequest request, CancellationToken cancel) { string target = ((request.Source is HtmlUrlBaseElement htmlUrlBaseElement) ? htmlUrlBaseElement.Target : null); IBrowsingContext context = context.ResolveTargetContext(target); IDocumentLoader service = context.GetService(); if (service != null) { IDownload download = service.FetchAsync(request); cancel.Register(download.Cancel); using IResponse response = await download.Task.ConfigureAwait(continueOnCapturedContext: false); if (response != null) { return await context.OpenAsync(response, cancel).ConfigureAwait(continueOnCapturedContext: false); } } return await context.OpenNewAsync(request.Target.Href, cancel).ConfigureAwait(continueOnCapturedContext: false); } public bool SupportsProtocol(string protocol) { return context.GetServices().Any((IRequester m) => m.SupportsProtocol(protocol)); } } public class EncodingMetaHandler : IMetaHandler { public EncodingMetaHandler() { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); } void IMetaHandler.HandleContent(IHtmlMetaElement element) { Encoding encoding = GetEncoding(element); if (encoding != null) { element.Owner.Source.CurrentEncoding = encoding; } } protected virtual Encoding? GetEncoding(IHtmlMetaElement element) { string charset = element.Charset; if (charset != null) { charset = charset.Trim(); if (TextEncoding.IsSupported(charset)) { return TextEncoding.Resolve(charset); } } if (!element.HttpEquivalent.Isi(HeaderNames.ContentType)) { return null; } return TextEncoding.Parse(element.Content ?? string.Empty); } } public static class EventLoopExtensions { public static void Enqueue(this IEventLoop? loop, Action action, TaskPriority priority = TaskPriority.Normal) { if (loop != null) { loop.Enqueue(delegate { action(); }, priority); } else { action(); } } public static Task EnqueueAsync(this IEventLoop? loop, Func action, TaskPriority priority = TaskPriority.Normal) { if (loop != null) { TaskCompletionSource tcs = new TaskCompletionSource(); loop.Enqueue(delegate(CancellationToken c) { try { tcs.SetResult(action(c)); } catch (Exception exception2) { tcs.SetException(exception2); } }, priority); return tcs.Task; } try { return Task.FromResult(action(default(CancellationToken))); } catch (Exception exception) { return Task.FromException(exception); } } } public interface ICommand { string CommandId { get; } bool Execute(IDocument document, bool showUserInterface, string value); bool IsEnabled(IDocument document); bool IsIndeterminate(IDocument document); bool IsExecuted(IDocument document); bool IsSupported(IDocument document); string GetValue(IDocument document); } public interface ICommandProvider { ICommand GetCommand(string name); } public interface IEncodingProvider { Encoding Suggest(string locale); } public interface IEventLoop { ICancellable Enqueue(Action action, TaskPriority priority); void Spin(); void CancelAll(); } public interface IMetaHandler { void HandleContent(IHtmlMetaElement element); } public interface INavigationHandler { bool SupportsProtocol(string protocol); Task NavigateAsync(DocumentRequest request, CancellationToken token); } public interface IParser : IEventTarget { event DomEventHandler Parsing; event DomEventHandler Parsed; event DomEventHandler Error; } public interface ISpellCheckService { CultureInfo Culture { get; } void Ignore(string word, bool persistent); bool IsCorrect(string word); IEnumerable SuggestFor(string word); } public class LocaleEncodingProvider : IEncodingProvider { private static readonly Dictionary suggestions = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "ar", TextEncoding.Utf8 }, { "cy", TextEncoding.Utf8 }, { "fa", TextEncoding.Utf8 }, { "hr", TextEncoding.Utf8 }, { "kk", TextEncoding.Utf8 }, { "mk", TextEncoding.Utf8 }, { "or", TextEncoding.Utf8 }, { "ro", TextEncoding.Utf8 }, { "sr", TextEncoding.Utf8 }, { "vi", TextEncoding.Utf8 }, { "be", TextEncoding.Latin5 }, { "bg", TextEncoding.Windows1251 }, { "ru", TextEncoding.Windows1251 }, { "uk", TextEncoding.Windows1251 }, { "cs", TextEncoding.Latin2 }, { "hu", TextEncoding.Latin2 }, { "pl", TextEncoding.Latin2 }, { "sl", TextEncoding.Latin2 }, { "tr", TextEncoding.Windows1254 }, { "ku", TextEncoding.Windows1254 }, { "he", TextEncoding.Windows1255 }, { "lv", TextEncoding.Latin13 }, { "ja", TextEncoding.Utf8 }, { "ko", TextEncoding.Korean }, { "lt", TextEncoding.Windows1257 }, { "sk", TextEncoding.Windows1250 }, { "th", TextEncoding.Windows874 } }; public virtual Encoding Suggest(string locale) { if (!string.IsNullOrEmpty(locale) && locale.Length > 1) { string key = locale.Substring(0, 2); if (suggestions.TryGetValue(key, out Encoding value)) { return value; } if (locale.Isi("zh-cn")) { return TextEncoding.Gb18030; } if (locale.Isi("zh-tw")) { return TextEncoding.Big5; } } return TextEncoding.Windows1252; } } public class RefreshMetaHandler : IMetaHandler { private readonly Predicate _shouldRefresh; public RefreshMetaHandler(Predicate? shouldRefresh = null) { _shouldRefresh = shouldRefresh ?? new Predicate(AlwaysRefresh); } void IMetaHandler.HandleContent(IHtmlMetaElement element) { if (!element.HttpEquivalent.Isi("refresh")) { return; } IDocument document = element.Owner; string content = element.Content; Url redirectUrl; Url baseAddress = (redirectUrl = new Url(document.DocumentUri)); string s = content; int num = content.IndexOf(';'); if (num >= 0) { s = content.Substring(0, num); string text = content.Substring(num + 1).Trim(); if (text.StartsWith("url=", StringComparison.OrdinalIgnoreCase)) { string text2 = text.Substring(4); if (text2.Length > 0) { redirectUrl = new Url(baseAddress, text2); } } } if (int.TryParse(s, out var result)) { Task.Delay(TimeSpan.FromSeconds(result)).ContinueWith(delegate { document.Location.Assign(redirectUrl.Href); }); } } private static bool AlwaysRefresh(Url url) { return true; } } [Flags] public enum Sandboxes : ushort { None = 0, Navigation = 1, AuxiliaryNavigation = 2, TopLevelNavigation = 4, Plugins = 8, Origin = 0x10, Forms = 0x20, PointerLock = 0x40, Scripts = 0x80, AutomaticFeatures = 0x100, Fullscreen = 0x200, DocumentDomain = 0x400, Presentation = 0x800 } public enum TaskPriority : byte { None, Normal, Microtask, Critical } } namespace AngleSharp.Browser.Dom { [DomName("ApplicationCache")] public enum CacheStatus : byte { [DomName("UNCACHED")] Uncached, [DomName("IDLE")] Idle, [DomName("CHECKING")] Checking, [DomName("DOWNLOADING")] Downloading, [DomName("UPDATEREADY")] UpdateReady, [DomName("OBSOLETE")] Obsolete } [DomName("ApplicationCache")] public interface IApplicationCache : IEventTarget { [DomName("status")] CacheStatus Status { get; } [DomName("onchecking")] event DomEventHandler Checking; [DomName("onerror")] event DomEventHandler Error; [DomName("onnoupdate")] event DomEventHandler NoUpdate; [DomName("ondownloading")] event DomEventHandler Downloading; [DomName("onprogress")] event DomEventHandler Progress; [DomName("onupdateready")] event DomEventHandler UpdateReady; [DomName("oncached")] event DomEventHandler Cached; [DomName("onobsolete")] event DomEventHandler Obsolete; [DomName("update")] void Update(); [DomName("abort")] void Abort(); [DomName("swapCache")] void Swap(); } [DomName("History")] public interface IHistory { [DomName("length")] int Length { get; } int Index { get; } IDocument this[int index] { get; } [DomName("state")] object State { get; } [DomName("go")] void Go(int delta = 0); [DomName("back")] void Back(); [DomName("forward")] void Forward(); [DomName("pushState")] void PushState(object data, string? title, string? url = null); [DomName("replaceState")] void ReplaceState(object data, string? title, string? url = null); } [DomName("Navigator")] public interface INavigator : INavigatorId, INavigatorContentUtilities, INavigatorStorageUtilities, INavigatorOnline { } [DomName("NavigatorContentUtils")] [DomNoInterfaceObject] public interface INavigatorContentUtilities { [DomName("registerProtocolHandler")] void RegisterProtocolHandler(string scheme, string url, string title); [DomName("registerContentHandler")] void RegisterContentHandler(string mimeType, string url, string title); [DomName("isProtocolHandlerRegistered")] bool IsProtocolHandlerRegistered(string scheme, string url); [DomName("isContentHandlerRegistered")] bool IsContentHandlerRegistered(string mimeType, string url); [DomName("unregisterProtocolHandler")] void UnregisterProtocolHandler(string scheme, string url); [DomName("unregisterContentHandler")] void UnregisterContentHandler(string mimeType, string url); } [DomName("NavigatorID")] [DomNoInterfaceObject] public interface INavigatorId { [DomName("appName")] string Name { get; } [DomName("appVersion")] string Version { get; } [DomName("platform")] string Platform { get; } [DomName("userAgent")] string UserAgent { get; } } [DomName("NavigatorOnLine")] [DomNoInterfaceObject] public interface INavigatorOnline { [DomName("onLine")] bool IsOnline { get; } } [DomName("NavigatorStorageUtils")] [DomNoInterfaceObject] public interface INavigatorStorageUtilities { [DomName("yieldForStorageUpdates")] void WaitForStorageUpdates(); } } namespace AngleSharp.Browser.Dom.Events { public class InteractivityEvent : Event { private Task? _result; public Task? Result => _result; public T Data { get; } public InteractivityEvent(string eventName, T data) : base(eventName) { Data = data; } [MemberNotNull("_result")] public void SetResult(Task value) { if (_result != null) { _result = Task.WhenAll(_result, value); } else { _result = value; } } } public class TrackEvent : Event { public Exception Error { get; } public TrackEvent(string eventName, Exception error) : base(eventName) { Error = error; } } } namespace AngleSharp.Attributes { [Flags] public enum Accessors : byte { None = 0, Getter = 1, Setter = 2, Deleter = 4, Adder = 8, Remover = 0x10 } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)] public sealed class DomAccessorAttribute : Attribute { public Accessors Type { get; } public DomAccessorAttribute(Accessors type) { Type = type; } } [AttributeUsage(AttributeTargets.Constructor, Inherited = false)] public sealed class DomConstructorAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] public sealed class DomDescriptionAttribute : Attribute { public string Description { get; } public DomDescriptionAttribute(string description) { Description = description; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] public sealed class DomExposedAttribute : Attribute { public string Target { get; } public DomExposedAttribute(string target) { Target = target; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate)] public sealed class DomHistoricalAttribute : Attribute { } [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)] public sealed class DomInitDictAttribute : Attribute { public int Offset { get; } public bool IsOptional { get; } public DomInitDictAttribute(int offset = 0, bool optional = false) { Offset = offset; IsOptional = optional; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] public sealed class DomInstanceAttribute : Attribute { public string Name { get; } public DomInstanceAttribute(string name) { Name = name; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Event, Inherited = false)] public sealed class DomLenientThisAttribute : Attribute { } [AttributeUsage(AttributeTargets.Enum)] public sealed class DomLiteralsAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] public sealed class DomNameAttribute : Attribute { public string OfficialName { get; } public DomNameAttribute(string officialName) { OfficialName = officialName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)] public sealed class DomNoInterfaceObjectAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property, Inherited = false)] public sealed class DomPutForwardsAttribute : Attribute { public string PropertyName { get; } public DomPutForwardsAttribute(string propertyName) { PropertyName = propertyName; } } }