Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/AngleSharp.Js.Tests/FireEventTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ namespace AngleSharp.Js.Tests
using AngleSharp.Dom.Events;
using AngleSharp.Scripting;
using NUnit.Framework;

using System;
using System.Linq;
using System.Threading.Tasks;

[TestFixture]
Expand Down Expand Up @@ -256,6 +259,35 @@ public async Task DocumentLoadEventIsFired_Issue42()
Assert.AreEqual("Success!", div?.TextContent);
}

[Test]
public async Task DocumentReadyStateIsComplete_Issue86()
{
var cfg = Configuration.Default.WithJs().WithEventLoop();
var html = @"<!doctype html>
<html>
<body>
<script>
document.onreadystatechange = function() {
var element = document.createElement('div');
element.textContent = document.readyState;
document.body.appendChild(element);
};
</script>
</body>";
var context = BrowsingContext.New(cfg);
var document = await context.OpenAsync(m => m.Content(html))
.WhenStable();

var divs = document.GetElementsByTagName("div");

// expected value will vary depending on AngleSharp package version
// 1.0.2 and greater, expected value will be { "interactive", "complete"
// prior to 1.0.2, expected value will be { "1", "2" }
var expected = new[] { DocumentReadyState.Interactive, DocumentReadyState.Complete }
.Select(e => e.GetOfficialName() ?? Convert.ToInt32(e).ToString());
CollectionAssert.AreEqual(expected, divs.Select(d => d.TextContent));
}

[Test]
public async Task SetTimeoutWithStringAsFunction()
{
Expand Down
10 changes: 10 additions & 0 deletions src/AngleSharp.Js/Extensions/EngineExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ public static JsValue ToJsValue(this Object obj, EngineInstance engine)
}
else if (obj is Enum)
{
switch (obj)
{
case DocumentReadyState _:
var name = ((Enum)obj).GetOfficialName();
if (name != null)
{
return new JsValue(name);
}
break;
}
return new JsValue(Convert.ToInt32(obj));
}

Expand Down
16 changes: 14 additions & 2 deletions src/AngleSharp.Js/Extensions/ReflectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ public static MethodInfo PrepareConvert(this Type fromType, Type toType)
public static String GetOfficialName(this MemberInfo member)
{
var names = member.GetCustomAttributes<DomNameAttribute>();
var officalNameAttribute = names.FirstOrDefault();
return officalNameAttribute?.OfficialName ?? member.Name;
var officialNameAttribute = names.FirstOrDefault();
return officialNameAttribute?.OfficialName ?? member.Name;
}

public static String GetOfficialName(this Type currentType, Type baseType)
Expand Down Expand Up @@ -87,6 +87,18 @@ public static String GetOfficialName(this Type currentType, Type baseType)
return name;
}

public static String GetOfficialName(this Enum value)
{
var enumType = value.GetType();
var member = enumType.GetMember(value.ToString()).FirstOrDefault();

// if the enum value does not have a DomNameAttribute, calling member.GetOfficialName() would return the value name
// to allow previous behaviour to be preserved, if the DomNameAttribute is not present then null will be returned
var names = member.GetCustomAttributes<DomNameAttribute>();
var officialNameAttribute = names.FirstOrDefault();
return officialNameAttribute?.OfficialName;
}

public static PropertyInfo GetInheritedProperty(this Type type, String propertyName, BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.Instance)
{
if (type.GetTypeInfo().IsInterface)
Expand Down