Events, form controls, performance timing, URL patterns, live streams and the newest JavaScript: the Web APIs score rises from 59 to 62
The second wave of the Web APIs and DOM plan. Event objects carry the members the standard gives them, select boxes and form collections behave like the real thing, the page can see its own long frames and slow scripts, and URLPattern, server-sent events, Cache Storage and the Cookie Store API are built on Floati's own network stack. JavaScript gains the newest built-ins (iterator helpers, Promise.try, base64 on Uint8Array, JSON.rawJSON and more), and loops that test instanceof or in now run compiled. Measured against the reference browser, the Web APIs surface goes from 59.3 to 62.5 percent.
Events that carry what the standard says




Every event interface now converts its init dictionary the way the standard's types say: numbers are rounded the way the reference browser rounds them, a missing required member throws, and an event a page builds with new MouseEvent('click', {clientX: 5}) reads back clientX, pageX, offsetX (measured against the laid-out target), getModifierState and the rest. Pointer, wheel, focus, input, toggle, submit, close, command and device motion events are all real interfaces. The events the browser fires itself carry the same members: a click from script is a PointerEvent, focus() and blur() fire focus, blur, focusin and focusout with relatedTarget (they fired nothing before), a WebSocket close is a CloseEvent, and buttons with commandfor open and close dialogs and popovers.
Form controls and collections




select.options is a live HTMLOptionsCollection you can add to, remove from and shorten, form.elements is a live HTMLFormControlsCollection, and a name shared by several radio buttons gives a RadioNodeList whose value reads and sets the checked one. A select remembers which option it shows, so inserting an option before it no longer changes the selection. A checkbox set to indeterminate matches :indeterminate and paints its bar, a click clears it and a cancelled click puts it back. Images answer naturalWidth, complete and decode(), and dialog.requestClose() asks first.
Content placed by hand in a web component




A web component that attaches its shadow tree with slotAssignment set to manual chooses which of its children each slot shows by calling slot.assign(). Floati recorded the choice but laid the page out with its own copy of the automatic rule, so every child showed at once: a tab component displayed all its panels. The page is now laid out from the same assignment the DOM keeps, so only the chosen panel shows.
The page can see its own slow frames
Every task the page runs is timed. A frame that takes longer than 50 ms becomes a long-animation-frame entry naming the scripts that ran in it (a timer, an animation frame callback, a click handler on a named element), with their source position and the time spent forcing layout; long tasks are reported too. Images and text marked with elementtiming report when they painted, performance.eventCounts counts the events the user caused, and a navigation's Server-Timing header shows up in its entry. Counting events happens inside the engine, so it costs nothing per event.
URL patterns, live streams, caches and cookies
URLPattern matches and captures URLs natively and passes all 369 of the standard's own test cases. EventSource streams server-sent events off the main thread and reconnects with the last event id after the server's retry time. Cache Storage keeps responses per site on the device, and the Cookie Store API reads, writes and watches the same cookies as document.cookie, under the same rules. XMLHttpRequest fires its progress events in the standard's order, and WebSocket sends and receives binary messages, reports a real close and offers WebSocketStream. On Windows a WebSocket or event stream could wait up to ten seconds before a message sent after it opened left the machine; that is fixed.
The newest JavaScript, and faster loops
Iterator helpers (map, filter, take, drop, flatMap, reduce and the rest, lazy and closing as they should), Iterator.from and concat, Map.groupBy, getOrInsert, Promise.try, Error.isError, RegExp.escape, Math.sumPrecise and f16round, base64 and hex on Uint8Array, float16 on DataView, JSON.rawJSON (numbers too big for a double written exactly) and the source text a JSON reviver can read, RegExp.$1 and the other legacy statics, and Function.prototype[Symbol.hasInstance]. Reflect.get and Reflect.set now run getters and setters with the receiver they are given, which is what proxy based state libraries rely on. Loops that test instanceof or in used to run uncompiled, about 120 times slower than the reference engine; they now run on the loop compiler, and a regex replace with a replacer function is linear in the length of the text.
What changed 10 changes
Try it in your browser
Each check runs live in the browser you are reading with. Nothing is sent anywhere.