This API isn't supported by FireFox (yet), so it isn't a huge priority, but I
did notice that its used across many Google properties. It uses the same value
as Sec-Ch-Ua (https://github.com/lightpanda-io/browser/pull/2100) to provide
consistent data.
Smaller changes:
1 - Allow `OffscreenCanvas` to be used with Worker (noticed this error too)
2 - Don't like JS execution errors at "error" level for "load" and
"DOMContentLoaded". "error" should be reserved for things we can fix and
should never be triggered from invalid a bug in JavaScript.
Follow up to https://github.com/lightpanda-io/browser/pull/2200
This change is actually pretty mundane, but a bunch of files that used to
take a *Session (e.g. every WebAPI releaseRef and deinit) now take a *Page.
This aims to separate the 2 lifetimes currently managed by Session by moving
the "Page" lifetime to a dedicated container: Page. Ultimately, the goal is to
remove the 1-page-per-session limit of the current design. Not to explicitly
support multiple pages per session (though, that's more possible now), but
in order to better emulate Chrome where, during a navigation event, the old and
new page both exist.
Because we don't fully process CSS, indexes that code expect might be out of
bounds. The specific case comes from https://github.com/lightpanda-io/browser/issues/2214
which uses fullcalender library. This library uses a @font-face which we do not
process and thus end up with incorrect indexes. As a quick workaround aligned
with previous fixes for these types of cases (and what the original issue
recommended), we simply clamp the index.
Chromium's accessibility tree prunes elements hidden via `display:none`,
`visibility:hidden`, the `hidden` attribute, `inert`, or `aria-hidden="true"`
and we match this behavior. It's correct for most elements, but it breaks
a common form pattern: CSS-only toggle switches and custom radio groups
hide the real `<input>` and style the `<label>` as the interactive surface.
Before, an agent walking the AX tree for a toggle switch saw:
{role: "none", name: "Enable feature", ignored: false}
a generic element with no indication it's interactive and no exposure of
the underlying `checked` state. The input was pruned and the label had no
intrinsic role.
Now, when a `<label>` is associated (via `for=` or by wrapping) with a
hidden checkbox or radio input, the label is promoted to the input's role
and state:
{role: "checkbox", name: "Enable feature",
properties: [..., {checked: "true"}, {focusable: true}, ...]}
Native browsers already forward label clicks to the associated input, so
the label's `backendDOMNodeId` remains a valid click target — no action-
side changes needed.
Scope is intentionally narrow:
- Only checkbox and radio inputs. Other labelable controls (textarea,
select, etc.) don't have the "visible label as interactive surface"
idiom.
- Skipped when the label has an explicit `role=` attribute, to respect
the page's declared semantics.
- Skipped when the input is visible: normal AX tree flow already
surfaces it, and promoting would double-count.
The fixture `src/browser/tests/cdp/ax_tree.html` covers:
- `display:none` checkbox, checked, referenced by `<label for=id>`
- `display:none` radio, checked, referenced by `<label for=id>`
- `visibility:hidden` radio, unchecked, referenced by `<label for=id>`
- Wrapping `<label>` containing a `display:none` checkbox