Loading pages
editA parsed document is only a tree. A BrowsingContext turns it into a page, as a tab of a browser: it has a Window, a viewport, an event loop, a session history, and, when you allow it, the network, the cookies, the scripts and the rendering. Navigate it to a URL to load a document:
using var context = new BrowsingContext();
// The callback returns the response, as a DocumentLoader would: here, an XML document
var document = context.Navigate("https://example.com/feed.xml", url => new DocumentResource("<feed><title>News</title></feed>")
{
Headers = [new("Content-Type", "application/xml")],
});
Assert.Equal("application/xml", document.ContentType);
Assert.Equal("https://example.com/feed.xml", document.Url);
Assert.Equal("News", document.QuerySelector("title")!.TextContent);Navigate
| Method | Loads |
|---|---|
Navigate(url, url => html) | An HTML document from its text, synchronously |
Navigate(url, url => new DocumentResource(...)) | A document from a response: HTML, XML or text, from its text or its bytes, with its status and headers. A null resource is a network error |
NavigateAsync(url, ...) | The same, and waits until the parser has finished (when a script engine makes it wait for a script) |
Navigate(url) | The document returned by the document loader, from a task of the event loop |
The URL of the document resolves its relative URLs and gives its origin, which the cookies, the storage and the security checks use. The navigation adds an entry to the session history, and the loaded document becomes BrowsingContext.Document. Before the first navigation, a browsing context has an about:blank document.
Run the event loop
The DOMContentLoaded and load events, the documents of the iframe elements, the style sheets and the images are loaded by the tasks of the event loop of the page. Run them:
using var context = new BrowsingContext(new BrowsingContextOptions
{
DocumentLoader = DocumentLoader.Create(), // HTTP GET requests with a shared HttpClient (or pass your own)
CookieJar = new CookieJar(), // optional: the cookies (RFC 6265bis, document.cookie, cookieStore)
});
context.Navigate("https://example.com/");
await context.EventLoop.RunUntilIdleAsync(); // runs the tasks until the document and its resources are loaded
var document = context.Document;EventLoop.RunUntilIdleAsync()runs the tasks until nothing is left, including the resources that are still loading.EventLoop.RunUntilIdle()runs the tasks that are already queued, without waiting.- These methods do not wait for the timers that are not due yet (
setTimeout,setInterval) nor for the animation frames: see Time and the event loop.
Use a browsing context from one thread at a time, the thread that runs its event loop.
Options
BrowsingContextOptions decides what the pages can do. Everything is off by default:
| Option | Allows |
|---|---|
| DocumentLoader | Network requests: documents, style sheets, images, frames, scripts, fetch() (see Network requests) |
| CookieJar, LocalStorage | Cookies and storage (see Cookies and storage) |
| Viewport, UserAgent | The size of the viewport and the emulated device (see Viewport and devices) |
| ScriptEngine, WebAssemblyRuntime | Scripts and WebAssembly (see Scripting) |
| RenderingBackend | Screenshots, printing, canvases and image decoding (see Rendering) |
| TimeProvider | The clock of the event loop (see Time and the event loop) |
| UseSystemFonts | The fonts installed on the machine (see Fonts) |
| Permissions, Geolocation, ShowNotification... | The permissions, the clipboard, sharing, vibration, geolocation, notifications, the badge, the battery, the wake lock, the keyboard lock, the keyboard layout, the media session, the screen orientation, the virtual keyboard, the viewport segments, the compute pressure, the idle state and the device posture (see Permissions and devices) |
The callbacks of the options report what happens in the pages: ConsoleMessage and UnhandledScriptError for the scripts, BrowsingContextCreated and BrowsingContextDestroyed for the frames and the popups, DocumentActivated for the navigations, and UserPromptHandler answers alert(), confirm() and prompt().
The first argument of every callback is a CallbackContext: where the callback was raised. It has the BrowsingContext, the Global object (a window, a worker or a worklet), and the Window and Document when the global object is a window. Use it to know which page or frame a message comes from:
var log = new List<string>();
using var context = new BrowsingContext(new BrowsingContextOptions
{
// The first argument of every callback is a CallbackContext: the browsing context, the window or the worker,
// and the document where the callback was raised
DocumentActivated = (callbackContext, document) => log.Add((callbackContext.BrowsingContext!.Parent is null ? "page " : "frame ") + document.Url),
BrowsingContextCreated = callbackContext => log.Add("created a frame in " + callbackContext.BrowsingContext!.Parent!.Document.Url),
});
context.Navigate("https://example.com/", _ => "<iframe srcdoc='<p>x'></iframe>");
context.EventLoop.RunUntilIdle();The callbacks raised by a browsing context (its creation, its navigations, the downloads, fullscreen and pointer lock) always have a BrowsingContext. The callbacks raised by scripts (the console messages, the unhandled errors and the content security policy violations) can come from a worker or a worklet: their BrowsingContext is null, and Global is the worker or worklet global scope.
Frames and popups
The iframe elements get nested browsing contexts (BrowsingContext.Children, HtmlIFrameElement.ContentDocument), which share the event loop and the options of their page. window.open() creates a popup: another top-level browsing context of the same group.
Dispose the page
BrowsingContext.Dispose() discards the page: its documents and the documents of its frames are destroyed, the pending requests are canceled, and the pending tasks and timers are dropped. No event is fired: to run the pagehide and unload handlers first, call TryClose(), which closes the page as a user closes a tab.
In this section
- Network requests: load pages and resources from the network, from memory or from the disk, and filter the requests.
- Cookies and storage: share and persist the cookies, the local storage and the other stores.
- Viewport and devices: the size of the viewport, the device pixel ratio, mobile devices, the color scheme.
- Layout and geometry: the positions and sizes of the elements, hit testing and scrolling.
- User input: click, tap, scroll and type as a user.
- Time and the event loop: timers, animations and fake clocks.
- Permissions and devices: answer the permission prompts, and simulate the clipboard, sharing, vibration, geolocation, notifications, the badge, the battery, the wake lock, the keyboard lock, the keyboard layout, the media session, the screen orientation, the virtual keyboard, the viewport segments, the compute pressure, the idle state and the device posture.