When an ancestor document is unloaded, its child documents are unloaded
(and destroyed) first, which leaves their navigable's active document
null. If the ancestor's pagehide handler then removes a subtree
containing one of those iframe containers, destroy_the_child_navigable
crashed dereferencing the null active document.
Treat the "destroy a document and its descendants" step as a no-op when
there is no document left to destroy, and still run the remaining
post-destruction cleanup.
This fixes a crash when closing a GMail tab.
Previously this walked up the parent chain on every call, which shows
up as a 2.5% item in the profile while watching YouTube videos.
Cache an m_is_connected bit on Node instead, maintained by the DOM
insertion and removal steps.
NativeFunction previously stored an AK::Function for every builtin,
even when the callable was just a plain C++ entry point. That mixed
together two different representations, made simple builtins carry
capture storage they did not need, and forced the GC to treat every
native function as if it might contain captured JS values.
Introduce RawNativeFunction for plain NativeFunctionPointer callees
and keep AK::Function-backed callables on a CapturingNativeFunction
subclass. Update the straightforward native registrations in LibJS
and LibWeb to use the raw representation, while leaving exported
Wasm functions on the capturing path because they still capture
state.
Wrap UniversalGlobalScope's byte-length strategy lambda in
Function<...> explicitly so it keeps selecting the capturing
NativeFunction::create overload.
This corresponds with the editorial change to the HTML standard
introducing the parsing mode enum of:
01c45cede
And a follow up normative change of:
508706c80
Making fragment parsing derive its scripting mode from the context
document.
The initial about:blank document inherits sandbox flags when the
child navigable is created. Parse the iframe sandbox attribute first
so the initial child document gets the correct sandbox state.
Fixed in the HTML spec with:
3fd7f35
Route BroadcastChannel messages over IPC so matching channels can
receive them across WebContent and WebWorker processes, rather than only
within a single process.
Each channel now serializes its payload, sends it upward over IPC, and
receiving processes deliver it locally after matching by storage key and
channel name.
Inline JS-to-JS frames no longer live in the raw execution context
vector, so LibWeb callers that need to inspect or pop contexts now go
through VM helpers instead of peeking into that storage directly.
This keeps the execution context bookkeeping encapsulated while
preserving existing microtask and realm-entry checks.
The bytecode interpreter only needed the running execution context,
but still threaded a separate Interpreter object through both the C++
and asm entry points. Move that state and the bytecode execution
helpers onto VM instead, and teach the asm generator and slow paths to
use VM directly.
Lock the shared Skia backend context before clearing an external
content back store.
Nested navigables render through PublishToExternalContent, and that
clear ran outside the locking used by normal display list playback.
This allowed multiple renderer threads to enter the same Ganesh
context concurrently and trip Skia's SingleOwner checks during
painting.
Don't rewrite text input 'width: auto' to 'size()ch' in
'HTMLInputElement::adjust_computed_style()'. That turns the control into
a definite-width flex item and prevents 'align-items: stretch' from
expanding it across the flex container.
Fixes the layout of the input element on the element matrix login page.
Prevents ancestors of the `<video>` element from moving the bar around.
For example, `<center><video></center>` would cause the progress bar to
start in the center and expand outwards.
This ensures that when we're switching from one video track to another,
we don't end up exiting buffering/seeking early due to no tracks being
enabled.
We could apparently update the ready state within time_marches_on()
called by set_ready_state(), which could result in triggering autoplay
twice for the same state transition.
Previously, `CheckUnloadingCanceledState::start_phase2()` used
`queue_global_task()` to fire `beforeunload` on each relevant document.
However, tasks associated with a document are only runnable when the
document is fully active and it is possible for the document to become
not fully-active before the task is run. This caused a 15 second delay
in `CheckUnloadingCanceledState` while we waited for a timeout, which
could cause test timeouts when under heavy load.
A MessagePort can be transferred while it already has local queued
state such as incoming messages drained from its transport,
outgoing messages posted before a transport exists, and a pending
shutdown to apply once the port is enabled.
Serialize and restore that state as part of transfer so it moves with
the port instead of being left behind on the old transport.
Also mark transports that are being transferred so shutdown of the old
endpoint during handoff is not reported as peer EOF. That shutdown is
part of moving the transport to the new owner, not peer disconnected.
Co-Authored-By: Alexander Kalenik <kalenik.aliaksandr@gmail.com>
Let's not have to know off-hand that we need to update Environments.cpp
when adding a new WebUI. It's more obvious just below where we define
the URLs.
Split JS::ErrorData out of JS::Error so that it can be used both
by JS::Error and WebIDL::DOMException. This adds support for
Error.isError to DOMException, also letting us report DOMException
stack information to the console.
Canvases belonging to `OffscreenCanvas` and disconnected
`HTMLCanvasElement`s use a LRC based on the initial canvas context font
size of 10px.
This will be covered by WPT tests in a later commit once we expose the
absolutized value in the font getter
This introduces two new top-level `ValueParsingContext`s,
`OnScreenCanvasContextFontValue` and `CanvasContextGenericValue`, while
these are handled the same for now, there is a distinction is whether or
not they allow tree counting functions (which will come in a later
commit)
Previously we simply serialized a concatenation of the longhand
properties, now we use the correct `font` serialization logic
implemented within `ShorthandStyleValue::serialize`
When setting to a non-string value (i.e. a `CanvasGradient` or
`CanvasPattern`) we would accidentally update the fill style instead of
the stroke style.
The case of an unsupported format error wasn't covered for this,
meaning that it could crash if the fetch completed successfully after
the fetch was cancelled due to such an error.
A crash test is included for this issue, using an echo of a large
corrupted WebM file to ensure that the fetch completes after media
init.
This fixes a timeout in WPT's abort-in-initial-upgradeneeded.any.html
test. The timeout was a rare one, caused by idbfactory_open.any.html
leaving the second connection in the final test open, since support.js
only tracks the connection created by the first createdb call. By
leaving the connection open, the harness's deleteDatabase() call would
never take effect. This in turn meant that the upgradeneeded test would
fail an assertion on the number of databases. That assertion was also
uncaught by the harness, turning it into a timeout instead of a fail.
By closing the connections when a document is destroyed, we can ensure
that the connection doesn't leak over to the next test and cause the
exception to be thrown.
Cleanup following the per-Navigable rasterization split: since each
Navigable now rasterizes its own display list independently, the HashMap
keyed on display list was always populated with exactly one entry. Pass
the ScrollStateSnapshot directly through the display list player and
rendering thread instead.
Previously, iframes were rasterized synchronously as nested display
lists inside their parent's display list: the parent's paint walk called
record_display_list() on each hosted iframe document and emitted a
PaintNestedDisplayList command that the player would recurse into. Only
the top-level traversable's RenderingThread was ever active, even though
every Navigable already owned one.
The motivation for splitting this apart:
- Work in the outer document no longer has to be re-recorded when only
an iframe changes. The parent's cached display list now references the
iframe's rasterized output live via an ExternalContentSource, so an
iframe invalidation just needs the parent's display list replayed, not
re-recorded.
- Each iframe now has a self-contained rasterization pipeline, which is
prep work for moving iframes into separate sandboxed processes.
Prep for rasterizing each Navigable independently, where children must
paint before their parents — the event loop needs to walk documents in
an order where every child comes after its container. The HTML spec
already mandates such an order for the "docs" list: each document
appears after its container, with siblings in shadow-including tree
order.
Maintain m_documents in that sorted order, re-sorting lazily when a
document is registered or its navigable is reassigned.
When a dedicated worker has an unhandled exception, we should propogate
that exception to be fired at the parent global. Fixes a timeout
in the included WPT test.
The proposal has not seemed to progress for a while, and there is
a open issue about module imports which breaks HTML integration.
While we could probably make an AD-HOC change to fix that issue,
it is deep enough in the JS engine that I am not particularly
keen on making that change.
Until other browsers begin to make positive signals about shipping
ShadowRealms, let's remove our implementation for now.
There is still some cleanup that can be done with regard to the
HTML integration, but there are a few more items that need to be
untangled there.
We should not throw exception types that are not dictated by the spec.
This is observable. This was preventing login on strava.com from
working.
Let's mark this feature as experimental as well, since it is just a stub
and was only added for a WPT score increase.
The spec's "not completely loaded" check in navigate_an_iframe_or_frame
was applied to all navigations, including attribute-driven src changes.
This caused navigations triggered before the previous page's load event
(e.g. via postMessage during parsing) to replace the history entry
instead of pushing a new one.
Restrict the check to initial insertion only. For subsequent src
attribute changes, always use "auto" so the navigate algorithm's own
logic (navigation_must_be_a_replace) decides the history handling.