Events, custom form controls, fonts and navigation work the way the web standards say: the Web APIs score rises from 53 to 59
This release is the first wave of the Web APIs and DOM plan: it adds the parts of the platform that pages use every day and that Floati answered only in outline. Events now follow the DOM standard from end to end: a click activates exactly one element (a checkbox inside a link toggles and follows nothing), a cancelled click puts a checkbox back, passive listeners cannot cancel scrolling, and the window, the document and every element share one dispatch. Custom form controls built as web components join their form, submit their value and style themselves with :state(). Fonts a script loads are used for text, document.fonts reports them, and style sheets read through script show nested rules, @layer, @container, @property and more. The Navigation API, XPath, Observable, Touch events and 26 Navigator members are new, URL objects keep every part in sync, and blob URLs load in fetch, workers, modules and images. Measured against the reference browser, the platform surface rose from 52.8 to 59.3 percent and the DOM web-platform tests from 94.2 to 95.2 (DOM events 227 -> 617 of 662), with every test site still free of script errors the reference browser does not also show. One fix matters for security: random numbers for keys and IDs now come from the operating system.
Events by the standard
Floati had three separate copies of event dispatch (a script's dispatchEvent, an element's click(), and the events the browser fires itself), each covering part of the standard. There is now one, written from the DOM standard's algorithm. An event being dispatched cannot be dispatched again; one made by document.createEvent waits for initEvent; stopping or cancelling an event is reset when dispatch ends, so it can be sent again; cancelBubble, returnValue and window.event work. A click chooses one element to activate, the innermost one that has a click behaviour: a checkbox, a radio button, a label (which forwards the click to its control), a summary (which opens its details), a submit or reset button, or a link. A listener that cancels the click puts the checkbox or radio back as it was. Listeners can be passive, and touch and wheel listeners on the window, the document and the body are passive unless the page says otherwise, so they cannot hold up scrolling. Handler attributes such as onclick="..." compile on their own (a typo in one breaks only that one) and read back as functions, the load and DOMContentLoaded events reach listeners as real events, and nothing runs for a frame that has been removed. On the DOM events part of the web-platform tests, Floati passes 617 of the 662 tests the reference browser passes, up from 227.
Custom form controls that are real form controls



A web component can declare itself form-associated and take an ElementInternals object. Floati now gives it the whole contract: the control finds its form (or the one its form attribute names), appears in form.elements, submits its value with the form and through FormData, takes part in validation (setValidity, checkValidity, :invalid and :valid), gets labels, follows a disabled fieldset, and hears its form being reset or disabled. Its custom states are exposed as a CustomStateSet and styled with the :state() selector, which is how switches, ratings and toggles built as components show that they are on. Before, the switch in the picture never turned green and an empty required control showed as valid.
Fonts loaded by script, and style rules script can read






The CSS Font Loading API is real: new FontFace(...) loads and decodes a font, the face is used for the page's text as soon as it is added to document.fonts, and document.fonts lists the page's own @font-face faces with their status, so code that waits for fonts.ready before measuring text gets the right width. Style sheets read through script now give each kind of rule its own interface: nested style rules, @layer, @container, @scope, @property, @page, @counter-style, @font-palette-values, @starting-style and more, and editing a rule through script no longer drops the rules nested inside it from the page. The newer parts load on first use, so a page that never asks for them pays nothing.
Navigation, XPath, Observable and URLs
The Navigation API lets single-page apps see every navigation as an event they can take over: window.navigation lists the session's entries, navigate() and back() report when they commit and finish, and links, location changes and history moves all go through it (fragment changes fire hashchange and popstate as they should). document.evaluate runs XPath 1.0 natively, faster than the reference browser on 7 of 12 typical queries. Observable, the new streams-of-events API, works with all its operators, and Touch events can be constructed. 26 more Navigator members answer the standard way, honestly: geolocation and wake lock are refused without your permission, and no credential is handed out. A URL object now keeps its parts in sync (setting its hash or a search parameter changes its href), and blob URLs made from data in memory load in fetch, workers, modules and images.
Random numbers for keys come from the operating system
crypto.getRandomValues, crypto.randomUUID and generated encryption keys were drawn from the same predictable number sequence as Math.random, starting from the same seed in every page. Pages use these for keys, tokens and IDs, so this was a security bug. They now come from the operating system's cryptographic random source, as in every other browser, and follow the standard's limits on size and array type. Math.random still uses its fast sequence, which is what it is for.
What changed 9 changes
Try it in your browser
Each check runs live in the browser you are reading with. Nothing is sent anywhere.