Scripting
editThe library never runs scripts by itself. Give a script engine to a browsing context, and the pages run their scripts as in a browser: the script elements, the modules, the event handlers, the timers, the javascript: URLs, the workers. The Meziantou.Framework.WebPlatform.JavaScript package provides the engine, based on Meziantou.Framework.JavaScriptEngine, an ECMAScript engine written in .NET.
dotnet package add Meziantou.Framework.WebPlatform.JavaScriptusing var engine = new JavaScriptScriptEngine(new JavaScriptScriptEngineOptions
{
Timeout = TimeSpan.FromSeconds(5), // per script or callback
});
using var context = new BrowsingContext(new BrowsingContextOptions
{
ScriptEngine = engine,
DocumentLoader = DocumentLoader.Create(), // optional: external scripts, modules, fetch, XMLHttpRequest, WebSocket, EventSource...
UnhandledScriptError = (_, error) => Console.Error.WriteLine(error),
ConsoleMessage = (_, message) => Console.WriteLine(message.Text), // console.log(), console.count()...
});
var document = await context.NavigateAsync("https://example.com/", _ => """
<title>Example</title>
<ul id=list></ul>
<script>
setTimeout(() => document.getElementById('list').innerHTML = '<li>a<li>b', 100);
</script>
""");
// Run the tasks and the timers until there is nothing left
do { await context.EventLoop.RunUntilIdleAsync(); } while (await context.EventLoop.WaitForNextTimerAsync());
Assert.Equal("<li>a</li><li>b</li>", document.GetElementById("list")!.InnerHtml);
// Evaluate code in the realm of a window
var title = engine.Evaluate(context.Window, "document.title");
Assert.Equal("Example", title.AsString());Without a script engine
Without an engine, the scripts are never fetched or run, the event handler attributes (onclick="...") have no effect, and the javascript: URLs are ignored. The DOM, the styles and the layout work the same: a page without scripts is often all you need to read server-rendered HTML.
What the scripts can use
The scripts see the DOM and the web APIs implemented by the library, through the bindings of the browsers: the DOM and the events, fetch() and XMLHttpRequest (with a document loader), the timers, the storage, the module scripts and the import maps, the workers, the custom elements, the canvases (with a rendering backend), Web Crypto, the streams, and WebAssembly (with a WebAssembly runtime). The scripts have no access to .NET: they only see what a page sees in a browser, and the functions that you add.
In this section
- Running JavaScript: the engine, its options, the console and the errors of the scripts.
- Calling JavaScript from .NET: evaluate code, call functions, convert values, and add .NET functions to the pages.
- Running untrusted pages: the limits of the engine and the requests of the pages.
- WebAssembly: run the WebAssembly modules of the pages with Wasmtime.