Skip to content

Commit 9563ba5

Browse files
committed
Added special dom event instance
1 parent 1b7a86c commit 9563ba5

File tree

3 files changed

+65
-11
lines changed

3 files changed

+65
-11
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
<Compile Include="ConsoleInstance.cs" />
5555
<Compile Include="DomConstructorInstance.cs" />
5656
<Compile Include="DomConstructors.cs" />
57+
<Compile Include="DomEventInstance.cs" />
5758
<Compile Include="Dom\RequesterState.cs" />
5859
<Compile Include="Dom\XmlHttpRequest.cs" />
5960
<Compile Include="Dom\XmlHttpRequestEventTarget.cs" />
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
namespace AngleSharp.Scripting.JavaScript
2+
{
3+
using AngleSharp.Dom;
4+
using Jint.Native;
5+
using Jint.Native.Function;
6+
using Jint.Runtime.Interop;
7+
using System.Reflection;
8+
9+
sealed class DomEventInstance
10+
{
11+
DomEventHandler _handler;
12+
FunctionInstance _function;
13+
14+
public DomEventInstance(DomNodeInstance node, EventInfo eventInfo)
15+
{
16+
Getter = new ClrFunctionInstance(node.Engine, (thisObject, arguments) => _function ?? JsValue.Null);
17+
Setter = new ClrFunctionInstance(node.Engine, (thisObject, arguments) =>
18+
{
19+
if (_handler != null)
20+
{
21+
eventInfo.RemoveEventHandler(node.Value, _handler);
22+
_handler = null;
23+
_function = null;
24+
}
25+
26+
if (arguments[0].Is<FunctionInstance>())
27+
{
28+
_function = arguments[0].As<FunctionInstance>();
29+
_handler = (s, ev) =>
30+
{
31+
var sender = s.ToJsValue(node.Context);
32+
var args = ev.ToJsValue(node.Context);
33+
_function.Call(sender, new [] { args });
34+
};
35+
eventInfo.AddEventHandler(node.Value, _handler);
36+
}
37+
38+
return arguments[0];
39+
});
40+
}
41+
42+
public ClrFunctionInstance Getter
43+
{
44+
get;
45+
private set;
46+
}
47+
48+
public ClrFunctionInstance Setter
49+
{
50+
get;
51+
private set;
52+
}
53+
}
54+
}

AngleSharp.Scripting.JavaScript/DomNodeInstance.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ public EngineInstance Context
3535
public override PropertyDescriptor GetOwnProperty(String propertyName)
3636
{
3737
// If we have a numeric indexer and the property is numeric
38-
int numericIndex;
38+
var numericIndex = default(Int32);
3939

40-
if (_numericIndexer != null && int.TryParse(propertyName, out numericIndex))
40+
if (_numericIndexer != null && Int32.TryParse(propertyName, out numericIndex))
4141
return new PropertyDescriptor(_numericIndexer.GetMethod.Invoke(_value, new Object[] { numericIndex }).ToJsValue(_engine), false, false, false);
4242

4343
// Else a string property
@@ -46,8 +46,8 @@ public override PropertyDescriptor GetOwnProperty(String propertyName)
4646
// Eg. object.callMethod1() vs object['callMethod1'] is not necessarily the same if the object has a string indexer?? (I'm not an ECMA expert!)
4747
// node.attributes is one such object - has both a string and numeric indexer
4848
// This GetOwnProperty override might need an additional parameter to let us know this was called via an indexer
49-
if (_stringIndexer != null && Properties.ContainsKey(propertyName) == false)
50-
return new PropertyDescriptor(_stringIndexer.GetMethod.Invoke(_value, new Object[] {propertyName}).ToJsValue(_engine), false, false, false);
49+
if (_stringIndexer != null && !Properties.ContainsKey(propertyName))
50+
return new PropertyDescriptor(_stringIndexer.GetMethod.Invoke(_value, new Object[] { propertyName }).ToJsValue(_engine), false, false, false);
5151

5252
// Else try to return a registered property
5353
return base.GetOwnProperty(propertyName);
@@ -85,9 +85,8 @@ void SetEvents(EventInfo[] eventInfos)
8585

8686
foreach (var name in names.Select(m => m.OfficialName))
8787
{
88-
FastSetProperty(name, new PropertyDescriptor(
89-
new DomFunctionInstance(this, eventInfo.RaiseMethod),
90-
new DomFunctionInstance(this, eventInfo.AddMethod), false, false));
88+
var eventInstance = new DomEventInstance(this, eventInfo);
89+
FastSetProperty(name, new PropertyDescriptor(eventInstance.Getter, eventInstance.Setter, false, false));
9190
}
9291
}
9392
}
@@ -116,8 +115,8 @@ void SetProperties(IEnumerable<PropertyInfo> properties)
116115
foreach (var name in names.Select(m => m.OfficialName))
117116
{
118117
FastSetProperty(name, new PropertyDescriptor(
119-
new DomFunctionInstance(this, property.GetMethod),
120-
new DomFunctionInstance(this, property.SetMethod), false, false));
118+
new DomFunctionInstance(_engine, property.GetMethod),
119+
new DomFunctionInstance(_engine, property.SetMethod), false, false));
121120
}
122121
}
123122
}
@@ -136,8 +135,8 @@ void SetMethods(IEnumerable<MethodInfo> methods)
136135
// to pick depending on the number (and probably types) of arguments.
137136
if (Properties.ContainsKey(name))
138137
continue;
139-
140-
FastAddProperty(name, new DomFunctionInstance(this, method), false, false, false);
138+
139+
FastAddProperty(name, new DomFunctionInstance(_engine, method), false, false, false);
141140
}
142141
}
143142
}

0 commit comments

Comments
 (0)