From 457dad14f1149999b70b1f83c45d7030efbf5e82 Mon Sep 17 00:00:00 2001 From: Wayne Sebbens Date: Sun, 11 Jun 2023 09:50:24 +1000 Subject: [PATCH 1/4] Use DomName in enum JsValues --- src/AngleSharp.Js/Extensions/EngineExtensions.cs | 6 ++++++ .../Extensions/ReflectionExtensions.cs | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/AngleSharp.Js/Extensions/EngineExtensions.cs b/src/AngleSharp.Js/Extensions/EngineExtensions.cs index 37c7417..c8958eb 100644 --- a/src/AngleSharp.Js/Extensions/EngineExtensions.cs +++ b/src/AngleSharp.Js/Extensions/EngineExtensions.cs @@ -45,6 +45,12 @@ public static JsValue ToJsValue(this Object obj, EngineInstance engine) } else if (obj is Enum) { + string name = ((Enum)obj).GetOfficialName(); + if (name != null) + { + return new JsValue(name); + } + return new JsValue(Convert.ToInt32(obj)); } diff --git a/src/AngleSharp.Js/Extensions/ReflectionExtensions.cs b/src/AngleSharp.Js/Extensions/ReflectionExtensions.cs index 164068c..fded50b 100644 --- a/src/AngleSharp.Js/Extensions/ReflectionExtensions.cs +++ b/src/AngleSharp.Js/Extensions/ReflectionExtensions.cs @@ -55,8 +55,8 @@ public static MethodInfo PrepareConvert(this Type fromType, Type toType) public static String GetOfficialName(this MemberInfo member) { var names = member.GetCustomAttributes(); - 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) @@ -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 + IEnumerable names = member.GetCustomAttributes(); + 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) From 2829487ef774a0b8e7253e396fe842defad0f13b Mon Sep 17 00:00:00 2001 From: Wayne Sebbens Date: Sun, 11 Jun 2023 11:16:28 +1000 Subject: [PATCH 2/4] Only use DomName for certain enum types --- src/AngleSharp.Js/Extensions/EngineExtensions.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/AngleSharp.Js/Extensions/EngineExtensions.cs b/src/AngleSharp.Js/Extensions/EngineExtensions.cs index c8958eb..f9c124c 100644 --- a/src/AngleSharp.Js/Extensions/EngineExtensions.cs +++ b/src/AngleSharp.Js/Extensions/EngineExtensions.cs @@ -45,12 +45,16 @@ public static JsValue ToJsValue(this Object obj, EngineInstance engine) } else if (obj is Enum) { - string name = ((Enum)obj).GetOfficialName(); - if (name != null) + switch (obj) { - return new JsValue(name); + case DocumentReadyState _: + string name = ((Enum)obj).GetOfficialName(); + if (name != null) + { + return new JsValue(name); + } + break; } - return new JsValue(Convert.ToInt32(obj)); } From efb949ea33486d477b09c89368473a2b1a0ab4cd Mon Sep 17 00:00:00 2001 From: Wayne Sebbens Date: Sun, 11 Jun 2023 11:25:09 +1000 Subject: [PATCH 3/4] Updates to follow style conventions --- src/AngleSharp.Js/Extensions/EngineExtensions.cs | 2 +- src/AngleSharp.Js/Extensions/ReflectionExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AngleSharp.Js/Extensions/EngineExtensions.cs b/src/AngleSharp.Js/Extensions/EngineExtensions.cs index f9c124c..180236a 100644 --- a/src/AngleSharp.Js/Extensions/EngineExtensions.cs +++ b/src/AngleSharp.Js/Extensions/EngineExtensions.cs @@ -48,7 +48,7 @@ public static JsValue ToJsValue(this Object obj, EngineInstance engine) switch (obj) { case DocumentReadyState _: - string name = ((Enum)obj).GetOfficialName(); + var name = ((Enum)obj).GetOfficialName(); if (name != null) { return new JsValue(name); diff --git a/src/AngleSharp.Js/Extensions/ReflectionExtensions.cs b/src/AngleSharp.Js/Extensions/ReflectionExtensions.cs index fded50b..3a309ea 100644 --- a/src/AngleSharp.Js/Extensions/ReflectionExtensions.cs +++ b/src/AngleSharp.Js/Extensions/ReflectionExtensions.cs @@ -94,7 +94,7 @@ public static String GetOfficialName(this Enum value) // 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 - IEnumerable names = member.GetCustomAttributes(); + var names = member.GetCustomAttributes(); var officialNameAttribute = names.FirstOrDefault(); return officialNameAttribute?.OfficialName; } From 3fb3c454d8527fb1558635c387030677d8151c99 Mon Sep 17 00:00:00 2001 From: Wayne Sebbens Date: Sun, 11 Jun 2023 11:56:41 +1000 Subject: [PATCH 4/4] Added unit test to check expected DocumentReadyState values --- src/AngleSharp.Js.Tests/FireEventTests.cs | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/AngleSharp.Js.Tests/FireEventTests.cs b/src/AngleSharp.Js.Tests/FireEventTests.cs index e468a1f..eac505c 100644 --- a/src/AngleSharp.Js.Tests/FireEventTests.cs +++ b/src/AngleSharp.Js.Tests/FireEventTests.cs @@ -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] @@ -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 = @" + + + +"; + 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() {