Skip to content

Commit 9712d2e

Browse files
committed
Added ability for direct evaluation
1 parent 844ccce commit 9712d2e

File tree

5 files changed

+69
-4
lines changed

5 files changed

+69
-4
lines changed

src/AngleSharp.Scripting.JavaScript/AngleSharp.Scripting.JavaScript.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
<Reference Include="System.Xml" />
5151
</ItemGroup>
5252
<ItemGroup>
53+
<Compile Include="ApiExtensions.cs" />
5354
<Compile Include="Attributes\DomInstanceAttribute.cs" />
5455
<Compile Include="JsConfigurationExtensions.cs" />
5556
<Compile Include="ConsoleInstance.cs" />
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
namespace AngleSharp.Scripting.JavaScript
2+
{
3+
using AngleSharp.Dom;
4+
using AngleSharp.Scripting.JavaScript.Services;
5+
using System;
6+
using System.Linq;
7+
8+
/// <summary>
9+
/// Useful extensions for the DOM.
10+
/// </summary>
11+
public static class ApiExtensions
12+
{
13+
/// <summary>
14+
/// Executes the given script code in the context of the provided node.
15+
/// </summary>
16+
/// <param name="node">The node acting as context.</param>
17+
/// <param name="scriptCode">The script to run.</param>
18+
/// <returns>The result of running the script, if any.</returns>
19+
public static Object Execute(this INode node, String scriptCode)
20+
{
21+
if (node == null)
22+
throw new ArgumentNullException(nameof(node));
23+
24+
var document = node.Owner;
25+
var options = document?.Context.Configuration;
26+
var providers = options?.Services.OfType<JavaScriptProvider>();
27+
var engine = providers?.FirstOrDefault()?.Engine;
28+
return engine?.EvaluateScript(node, scriptCode);
29+
}
30+
}
31+
}

src/AngleSharp.Scripting.JavaScript/EngineInstance.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
{
33
using AngleSharp.Dom;
44
using Jint;
5+
using Jint.Native;
56
using Jint.Runtime.Environments;
67
using Services;
78
using System;
89
using System.Collections.Generic;
910
using System.Linq;
11+
using System.Runtime.CompilerServices;
1012

1113
sealed class EngineInstance
1214
{
1315
#region Fields
1416

15-
private readonly Dictionary<Object, DomNodeInstance> _objects;
17+
private readonly ConditionalWeakTable<Object, DomNodeInstance> _objects;
1618
private readonly Engine _engine;
1719
private readonly LexicalEnvironment _lexicals;
1820
private readonly LexicalEnvironment _variables;
@@ -34,7 +36,7 @@ public EngineInstance(IWindow window, IDictionary<String, Object> assignments)
3436
logger = createLogger.Invoke(context);
3537
}
3638

37-
_objects = new Dictionary<Object, DomNodeInstance>();
39+
_objects = new ConditionalWeakTable<Object, DomNodeInstance>();
3840
_engine = new Engine();
3941
_engine.SetValue("console", new ConsoleInstance(_engine, logger));
4042

@@ -99,11 +101,12 @@ public DomNodeInstance GetDomNode(Object obj)
99101
return domNodeInstance;
100102
}
101103

102-
public void RunScript(String source)
104+
public Object RunScript(String source, JsValue context)
103105
{
104-
_engine.EnterExecutionContext(Lexicals, Variables, _window);
106+
_engine.EnterExecutionContext(Lexicals, Variables, context);
105107
_engine.Execute(source);
106108
_engine.LeaveExecutionContext();
109+
return _engine.GetCompletionValue().FromJsValue();
107110
}
108111

109112
#endregion

src/AngleSharp.Scripting.JavaScript/Extensions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ public static JsValue ToJsValue(this Object obj, EngineInstance engine)
5555
return JsValue.Null;
5656
}
5757

58+
public static Object RunScript(this EngineInstance engine, String source)
59+
{
60+
return engine.RunScript(source, engine.Window);
61+
}
62+
63+
public static Object RunScript(this EngineInstance engine, String source, INode context)
64+
{
65+
return engine.RunScript(source, context.ToJsValue(engine));
66+
}
67+
5868
public static ClrFunctionInstance AsValue(this Engine engine, Func<JsValue, JsValue[], JsValue> func)
5969
{
6070
return new ClrFunctionInstance(engine, func);

src/AngleSharp.Scripting.JavaScript/JavaScriptEngine.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,26 @@ public async Task EvaluateScriptAsync(IResponse response, ScriptOptions options,
8484
}
8585
}
8686

87+
/// <summary>
88+
/// Evaluates the given script source in the provided context.
89+
/// </summary>
90+
/// <param name="context">The context of the evaluation.</param>
91+
/// <param name="source">The source of the script.</param>
92+
/// <returns>The result of the evaluation.</returns>
93+
public Object EvaluateScript(INode context, String source)
94+
{
95+
if (context == null)
96+
throw new ArgumentNullException(nameof(context));
97+
98+
var document = context.Owner;
99+
100+
if (document == null)
101+
throw new ArgumentException("The context has to be attached to a document.");
102+
103+
var instance = GetOrCreateInstance(document);
104+
return instance.RunScript(source, context);
105+
}
106+
87107
#endregion
88108

89109
#region Helpers

0 commit comments

Comments
 (0)