Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding ClearScript Engine Integration #964

Open
vuminhquang opened this issue May 3, 2021 · 8 comments
Open

Adding ClearScript Engine Integration #964

vuminhquang opened this issue May 3, 2021 · 8 comments

Comments

@vuminhquang
Copy link

New Feature Proposal

Adding ClearScript Engine Integration

Description

Currently, there are many modern web pages which Jint can't not handle.
ClearScript7 is supporting newest JavaScript.
ClearScript7 is easy to apply into a project.
ClearScript7 is backed up by Microsoft, easier up-to-date than Jint.

Background

Please follow the link
https://microsoft.github.io/ClearScript/Examples/Examples.html

Specification

No

@FlorianRappl
Copy link
Contributor

Yeah definitely - just like the Jint integration that would be another plugin library.

Feel free to contribute and start it! We can help / guide you if you have questions.

@vuminhquang
Copy link
Author

Yes, I need some help. Could you provide some quick start or some integration point into AngleSharp?
Reading whole AngleSharp.Js will be pain now, since I have only little time at the weekend.

@FlorianRappl
Copy link
Contributor

AngleSharp.Js is actually not that large.

The main point is to have the configuration extension ready, such as the WithJs from AngleSharp.Js.
https://github.com/AngleSharp/AngleSharp.Js/blob/master/src/AngleSharp.Js/JsConfigurationExtensions.cs#L66

For this the IScriptingService interface needs to be implemented: https://github.com/AngleSharp/AngleSharp.Js/blob/master/src/AngleSharp.Js/JsScriptingService.cs#L21

@vuminhquang
Copy link
Author

Hello, me again
Seems that Devel and Master are in 2 branches now.
image

What's the branch recommended to begin?

@FlorianRappl
Copy link
Contributor

Hm for what?

devel should always be the base branch - master reflects the latest full release (non-preview).

But for the ClearScript integration a new project should be started. It should not be in the core.

@vuminhquang
Copy link
Author

ok, thanks

@hjlld
Copy link

hjlld commented Aug 19, 2022

Any news?

I've tried to combine AngleSharp and ClearScript but I encountered a problem.

Document.CreateElement() method is defined in sealed class AngleSharp.Html.Dom.HtmlDocument, because it's sealed, it cannot be exposed to JavaScript, so ClearScript will throw method not defined exception, whatever restrict type in use, like:

Exception has occurred: Error: “AngleSharp.Html.Dom.IHtmlDocument” does not contain a definition for “createElement”
Exception has occurred: Error: “AngleSharp.Dom.Document” does not contain a definition for “createElement”
Exception has occurred: Error: “AngleSharp.Dom.IDocument” does not contain a definition for “createElement”

ps: I use V8ScriptEngineFlags.UseCaseInsensitiveMemberBinding to construct the engine, so the methods name started with Uppercase in C# will be recognized as lowercase in JavaScript.

this is my code

            var engine = new V8ScriptEngine(
                  V8ScriptEngineFlags.UseCaseInsensitiveMemberBinding
                | V8ScriptEngineFlags.EnableDebugging 
                | V8ScriptEngineFlags.AwaitDebuggerAndPauseOnStart
            );

            engine.AccessContext = typeof(HTMLParser);

            var raw = File.ReadAllText(@"D:\Vue\dist\assets\index.eb41276c.js");

            var config = AngleSharp.Configuration.Default
                .WithCss()
                .WithDefaultLoader();

            var address = "http://127.0.0.1:8080";
            var context = BrowsingContext.New(config);
            var document = await context.OpenAsync(address) as AngleSharp.Html.Dom.IHtmlDocument;

            IEnumerable<Assembly> assemblies = context
                .GetServices<Object>()
                .Select(m => m.GetType().GetAssembly())
                .Distinct()
                .Where(m => m.FullName.StartsWith("AngleSharp"));

            foreach (Assembly assembly in assemblies)
            {
                foreach (var exportedType in assembly.ExportedTypes)
                {
                    var ti = exportedType.GetTypeInfo();
                    var names = ti.GetCustomAttributes<DomNameAttribute>();
                    var name = names.FirstOrDefault();

                    if (name == null)
                    {
                        continue;
                    }

                    engine.AddHostType(name.OfficialName, exportedType);

                }

            }
            engine.AddRestrictedHostObject("document", document);
            engine.AddHostType("MutationCallback", typeof(AngleSharp.Dom.MutationCallback));

            try
            {
                engine.Execute(raw);

                foreach (var el in document.All)
                {
                    Debug.WriteLine($"{el.TagName}");
                }

                foreach (var style in document.StyleSheets)
                {
                    Debug.WriteLine(style.Source.Text);
                }
            }
            catch (Exception)
            {
            }

@ClearScriptLib
Copy link

Hi @hjlld,

because it's sealed, it cannot be exposed to JavaScript

The sealed modifier controls neither visibility nor access, so it shouldn't be relevant here. The class HtmlDocument isn't public, but you're using AddRestrictedHostObject to expose a public interface, which should be usable from JavaScript.

Due to its dependencies, we can't test your code as is, but the following works as expected (.NET Fiddle):

using var engine = new V8ScriptEngine(V8ScriptEngineFlags.UseCaseInsensitiveMemberBinding);
var config = Configuration.Default.WithCss().WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync("http://dictionary.com");
engine.AddRestrictedHostObject("document", document);
Console.WriteLine(engine.Evaluate("document.title"));
Console.WriteLine(engine.Evaluate("document.createElement(null, 'FooBar').tagName"));

Output:

Dictionary.com | Meanings and Definitions of Words at Dictionary.com
FooBar

If you can share a complete minimal sample that reproduces your issue, we'll be happy to take a look.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants