ScriptRequestProcessor
using AngleSharp.Dom;
using AngleSharp.Dom.Html;
using AngleSharp.Extensions;
using AngleSharp.Html;
using AngleSharp.Services.Scripting;
using System.Threading;
using System.Threading.Tasks;
namespace AngleSharp.Network.RequestProcessors
{
internal class ScriptRequestProcessor : IRequestProcessor
{
private readonly HtmlScriptElement _script;
private readonly Document _document;
private readonly IResourceLoader _loader;
private IDownload _download;
private IResponse _response;
private IScriptEngine _engine;
public IDownload Download => _download;
public IScriptEngine Engine => _engine ?? (_engine = _document.Options.GetScriptEngine(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 (!string.IsNullOrEmpty(text))
return text;
return MimeTypeNames.DefaultJavaScript;
}
}
private ScriptRequestProcessor(HtmlScriptElement script, IResourceLoader loader)
{
_script = script;
_document = script.Owner;
_loader = loader;
}
internal static ScriptRequestProcessor Create(HtmlScriptElement script)
{
Document owner = script.Owner;
IResourceLoader loader = owner.Loader;
return new ScriptRequestProcessor(script, loader);
}
public async Task RunAsync(CancellationToken cancel)
{
if (_download != null)
_response = await _download.Task.ConfigureAwait(false);
if (_response != null && !_script.FireSimpleEvent(EventNames.BeforeScriptExecute, false, true)) {
ScriptOptions options = CreateOptions();
int insert = _document.Source.Index;
try {
await _engine.EvaluateScriptAsync(_response, options, cancel).ConfigureAwait(false);
} catch {
}
_document.Source.Index = insert;
FireAfterScriptExecuteEvent();
_document.QueueTask(FireLoadEvent);
_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 Process(ResourceRequest request)
{
if (_loader != null && Engine != null) {
CorsSetting setting = _script.CrossOrigin.ToEnum(CorsSetting.None);
OriginBehavior behavior = OriginBehavior.Taint;
_download = _loader.FetchWithCors(request, setting, behavior);
return _download.Task;
}
return null;
}
private ScriptOptions CreateOptions()
{
ScriptOptions scriptOptions = new ScriptOptions();
scriptOptions.Context = _document.DefaultView;
scriptOptions.Document = _document;
scriptOptions.Element = _script;
scriptOptions.Encoding = TextEncoding.Resolve(_script.CharacterSet);
return scriptOptions;
}
private void FireLoadEvent()
{
_script.FireSimpleEvent(EventNames.Load, false, false);
}
private void FireAfterScriptExecuteEvent()
{
_script.FireSimpleEvent(EventNames.AfterScriptExecute, true, false);
}
}
}