AngleSharp by Florian Rappl

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

.NET API 1,189,376 bytes

 HtmlScriptElement

Represents an HTML script element.
using AngleSharp.Dom.Css; using AngleSharp.Extensions; using AngleSharp.Html; using AngleSharp.Network; using AngleSharp.Scripting; using System; using System.Threading; using System.Threading.Tasks; namespace AngleSharp.Dom.Html { internal sealed class HtmlScriptElement : HtmlElement, IHtmlScriptElement, IHtmlElement, IElement, INode, IEventTarget, IMarkupFormattable, IParentNode, IChildNode, INonDocumentTypeChildNode, IElementCssInlineStyle, IDisposable { private bool _started; private bool _parserInserted; private bool _wasParserInserted; private bool _forceAsync; private bool _readyToBeExecuted; private CancellationTokenSource _cts; private Task<IResponse> _loadingTask; internal bool IsReady => _readyToBeExecuted; internal bool IsParserInserted { get { return _parserInserted; } set { _parserInserted = value; } } internal bool IsAlreadyStarted { get { return _started; } set { _started = value; } } public string ScriptLanguage { get { string ownAttribute = GetOwnAttribute(AttributeNames.Language); string text = Type ?? ((ownAttribute != null) ? ("text/" + ownAttribute) : null); if (!string.IsNullOrEmpty(text)) return text; return MimeTypes.DefaultJavaScript; } } public string Source { get { return GetOwnAttribute(AttributeNames.Src); } set { SetOwnAttribute(AttributeNames.Src, value); } } public string Type { get { return GetOwnAttribute(AttributeNames.Type); } set { SetOwnAttribute(AttributeNames.Type, value); } } public string CharacterSet { get { return GetOwnAttribute(AttributeNames.Charset); } set { SetOwnAttribute(AttributeNames.Charset, value); } } public string Text { get { return TextContent; } set { TextContent = value; } } public string CrossOrigin { get { return GetOwnAttribute(AttributeNames.CrossOrigin); } set { SetOwnAttribute(AttributeNames.CrossOrigin, value); } } public bool IsDeferred { get { return GetOwnAttribute(AttributeNames.Defer) != null; } set { SetOwnAttribute(AttributeNames.Defer, value ? string.Empty : null); } } public bool IsAsync { get { return GetOwnAttribute(AttributeNames.Async) != null; } set { SetOwnAttribute(AttributeNames.Async, value ? string.Empty : null); } } public HtmlScriptElement(Document owner, string prefix = null) : base(owner, Tags.Script, prefix, NodeFlags.Special | NodeFlags.LiteralText) { } internal void Run() { if (_loadingTask != null) { if (_loadingTask.Exception != null || _loadingTask.IsFaulted) Error(); else if (!CancelledBeforeScriptExecute()) { using (IResponse response = _loadingTask.Result) base.Owner.Options.RunScript(response, CreateOptions(), ScriptLanguage); AfterScriptExecute(); if (Source != null) Load(); else base.Owner.QueueTask(Load); } } } internal void Prepare() { if (!_started && base.Owner != null) { IConfiguration options = base.Owner.Options; _wasParserInserted = _parserInserted; _parserInserted = false; _forceAsync = (_wasParserInserted && !IsAsync); if ((!string.IsNullOrEmpty(Source) || !string.IsNullOrEmpty(Text)) && options.GetScriptEngine(ScriptLanguage) != null) { if (_wasParserInserted) { _parserInserted = true; _forceAsync = false; } _started = true; if (base.Owner.Options.IsScripting()) { string ownAttribute = GetOwnAttribute(AttributeNames.Event); string ownAttribute2 = GetOwnAttribute(AttributeNames.For); if (!string.IsNullOrEmpty(ownAttribute) && !string.IsNullOrEmpty(ownAttribute2)) { ownAttribute = ownAttribute.Trim(); ownAttribute2 = ownAttribute2.Trim(); if (ownAttribute.EndsWith("()")) ownAttribute = ownAttribute.Substring(0, ownAttribute.Length - 2); if (!ownAttribute2.Equals(AttributeNames.Window, StringComparison.OrdinalIgnoreCase) || !ownAttribute.Equals("onload", StringComparison.OrdinalIgnoreCase)) return; } string source = Source; if (source != null) { if (source == string.Empty) base.Owner.QueueTask(Error); else { Url url = this.HyperReference(source); _cts = new CancellationTokenSource(); _loadingTask = PrepareAsync(url, _cts.Token); } } else if (_parserInserted && base.Owner.HasScriptBlockingStyleSheet()) { _readyToBeExecuted = true; } else { options.RunScript(Text, CreateOptions(), ScriptLanguage); } } } } } private async Task<IResponse> PrepareAsync(Url url, CancellationToken cancel) { if (_parserInserted && !IsAsync) { if (IsDeferred) Owner.AddScript(this); } else if (!IsAsync && !_forceAsync) { Owner.AddScript(this); } else { Owner.AddScript(this); } ResourceRequest request = this.CreateRequestFor(url); CorsSetting setting = CrossOrigin.ToEnum(CorsSetting.None); IResponse result = await AwaitExtensions.ConfigureAwait(Owner.Loader.FetchWithCorsAsync(request, setting, OriginBehavior.Taint, cancel), false); if (_parserInserted && !IsAsync) _readyToBeExecuted = true; return result; } private void Load() { this.FireSimpleEvent(EventNames.Load, false, false); } private void Error() { this.FireSimpleEvent(EventNames.Error, false, false); } private bool CancelledBeforeScriptExecute() { return this.FireSimpleEvent(EventNames.BeforeScriptExecute, false, true); } private void AfterScriptExecute() { this.FireSimpleEvent(EventNames.AfterScriptExecute, true, false); } private ScriptOptions CreateOptions() { return new ScriptOptions { Context = base.Owner.DefaultView, Document = base.Owner, Element = this, Encoding = TextEncoding.Resolve(CharacterSet) }; } public void Dispose() { if (_cts != null) _cts.Cancel(); _cts = null; _loadingTask = null; } } }