Adds limited support for window.open. This leverages the new page container and
behaves similarly to an iframe. There are many things not implemented, but the
most significant are:
1- target=window_name or target=_blank don't work (but this could be added
pretty easily I think)
2- Windows (which are is just a Frame) are shutdown when the Page is shutdown.
They would need to be owned by the Session (rather than the Page), but I'm
not really confident in that right now.
3- No CDP testing. There are maybe CDP-specific messages we need to emit (or
maybe messages that we shouldn't emit).
As-is, this should help with common cases where:
1. window.open is called but doesn't matter (won't give a JS error)
2. window.open is short-lived, or, more specifically, lives only for the
duration of the page that opened it (e.g. a login popup).
3. WPT tests! (because most of these fit in #2).
This possibly addresses some release overflows that could happen during various
failures. For example, if Frame.init fails during a navigation event, this will
make sure to remove the frame from the parent list preventing a double-free
on the frame.
functions should be defined directly on the window.console (and window.CSS)
instances. This is necessary for being able to iterate their "own" properties.
businessinsider.com has code that proxies console via such an iterator (through
Object.entries(console)). This commit allows types to declare that they own
their properties (as opposed to the prototype).
Also fixed HTMLDocument.location. This was using Document._location, but that
field wasn't always set. The new code removes the _location field and changes
the getter to get window._location. (Also an issue on businessinsider.com)
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