HTMLScriptElement
sealed class HTMLScriptElement : HTMLElement, IHtmlScriptElement, IHtmlElement, IElement, INode, IEventTarget, IParentNode, IChildNode, INonDocumentTypeChildNode, IElementCssInlineStyle
Represents an HTML script element.
using AngleSharp.DOM.Css;
using AngleSharp.Infrastructure;
using AngleSharp.Network;
using System;
using System.IO;
using System.Threading.Tasks;
namespace AngleSharp.DOM.Html
{
internal sealed class HTMLScriptElement : HTMLElement, IHtmlScriptElement, IHtmlElement, IElement, INode, IEventTarget, IParentNode, IChildNode, INonDocumentTypeChildNode, IElementCssInlineStyle
{
private bool _started;
private bool _parserInserted;
private bool _wasParserInserted;
private bool _forceAsync;
private bool _readyToBeExecuted;
private Task<Stream> _load;
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 text = Type ?? ((GetAttribute(AttributeNames.Language) != null) ? ("text/" + GetAttribute(AttributeNames.Language)) : null);
if (string.IsNullOrEmpty(text))
return MimeTypes.DefaultJavaScript;
return text;
}
}
public string Source {
get {
return GetAttribute(AttributeNames.Src);
}
set {
SetAttribute(AttributeNames.Src, value);
}
}
public string Type {
get {
return GetAttribute(AttributeNames.Type);
}
set {
SetAttribute(AttributeNames.Type, value);
}
}
public string CharacterSet {
get {
return GetAttribute(AttributeNames.Charset);
}
set {
SetAttribute(AttributeNames.Charset, value);
}
}
public string Text {
get {
return TextContent;
}
set {
TextContent = value;
}
}
public string CrossOrigin {
get {
return GetAttribute(AttributeNames.CrossOrigin);
}
set {
SetAttribute(AttributeNames.CrossOrigin, value);
}
}
public bool IsDeferred {
get {
return GetAttribute(AttributeNames.Defer) != null;
}
set {
SetAttribute(AttributeNames.Defer, value ? string.Empty : null);
}
}
public bool IsAsync {
get {
return GetAttribute(AttributeNames.Async) != null;
}
set {
SetAttribute(AttributeNames.Async, value ? string.Empty : null);
}
}
public HTMLScriptElement()
: base(Tags.Script, NodeFlags.Special | NodeFlags.LiteralText)
{
}
internal void Run()
{
if (_load != null) {
if (_load.Exception != null || _load.IsFaulted)
FireSimpleEvent(EventNames.Error, false, false);
else if (!FireSimpleEvent(EventNames.BeforeScriptExecute, false, true)) {
base.Owner.Options.RunScript(_load.Result, CreateOptions(), ScriptLanguage);
FireSimpleEvent(EventNames.AfterScriptExecute, true, false);
if (Source != null)
FireSimpleEvent(EventNames.Load, false, false);
else
base.Owner.QueueTask(delegate {
FireSimpleEvent(EventNames.Load, false, false);
});
}
}
}
internal void Prepare()
{
IConfiguration configuration = base.Owner.Options ?? Configuration.Default;
if (!_started) {
_wasParserInserted = _parserInserted;
_parserInserted = false;
_forceAsync = (_wasParserInserted && !IsAsync);
if ((!string.IsNullOrEmpty(Source) || !string.IsNullOrEmpty(Text)) && base.Owner != null && configuration.GetScriptEngine(ScriptLanguage) != null) {
if (_wasParserInserted) {
_parserInserted = true;
_forceAsync = false;
}
_started = true;
if (base.Owner.Options.IsScripting) {
string attribute = GetAttribute(AttributeNames.Event);
string attribute2 = GetAttribute(AttributeNames.For);
if (!string.IsNullOrEmpty(attribute) && !string.IsNullOrEmpty(attribute2)) {
attribute = attribute.Trim();
attribute2 = attribute2.Trim();
if (attribute.EndsWith("()"))
attribute = attribute.Substring(0, attribute.Length - 2);
if (!attribute2.Equals("window", StringComparison.OrdinalIgnoreCase) || !attribute.Equals("onload", StringComparison.OrdinalIgnoreCase))
return;
}
string source = Source;
if (source != null) {
if (source == string.Empty)
base.Owner.QueueTask(delegate {
FireSimpleEvent(EventNames.Error, false, false);
});
else {
Url url = HyperRef(source);
_load = configuration.LoadWithCorsAsync(url, CrossOrigin.ToEnum(CorsSetting.None), base.Owner.Origin, OriginBehavior.Taint);
if (_parserInserted && !IsAsync) {
if (IsDeferred)
base.Owner.AddScript(this);
_load.ContinueWith((Task<Stream> task) => _readyToBeExecuted = true);
} else if (!IsAsync && !_forceAsync) {
base.Owner.AddScript(this);
} else {
base.Owner.AddScript(this);
}
}
} else if (_parserInserted) {
_readyToBeExecuted = true;
configuration.RunScript(Text, CreateOptions(), ScriptLanguage);
} else {
configuration.RunScript(Text, CreateOptions(), ScriptLanguage);
}
}
}
}
}
private ScriptOptions CreateOptions()
{
ScriptOptions scriptOptions = new ScriptOptions();
scriptOptions.Context = base.Owner.DefaultView;
scriptOptions.Document = base.Owner;
scriptOptions.Element = this;
scriptOptions.BaseUri = base.BaseUri;
scriptOptions.Encoding = DocumentEncoding.Resolve(CharacterSet);
return scriptOptions;
}
}
}