Put the Gamepad API and its supporting infrastructure behind a `gamepad`
feature flag. This allows embedders to opt-out of gamepad support at
compile time to save on binary size and reduce dependencies.
Testing:
1. `./mach build -d` (Gamepad enabled by default)
2. `cargo build -p servoshell --no-default-features --features
"libservo/clipboard,js_jit,max_log_level,webgpu"` (Gamepad Disabled)
3. `cargo build -p servoshell --features "gamepad,webxr,..."` (Gamepad &
WebXR Enabled)
Fixes: #40897
Signed-off-by: WaterWhisperer <waterwhisperer24@qq.com>
Another step towards being spec-compatible. Right now
we can't destroy an unsalvagable document during unloading,
as that breaks all kinds of tests. Before that, we need
to update various machinery to handle destroying correctly.
The first one is a top-level navigable, which explicitly
destroys a document after it is unloaded.
Part of #31973
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
For all upcoming and already-processed deferred fetches, we now
implement a quota. We don't support policy headers yet to configure the
quota, hence we use the default quota. That's why we have some tests
failing again.
It involves computing which document to compute the quota for, as well
as computing total length of requests. Additionally, the DevTools
computation for headers now uses the same logic for headers as deferred
fetches.
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
Servo currently completely ignores `<meta charset>` tags. When we find
one with an encoding that is incompatible to the current one, then we
should reload the page and start over with the new encoding. A common
optimization that has even made its way into the specification is to
wait for a few bytes to arrive and inspect them for `meta` tags, so the
browser is able to use the correct encoding from the very beginng.
In practice, I've run into problems with our WPT harness when reloading
the page after `meta` tags. Therefore, this change implement the
optimization first, so we never have to reload when running WPT. I've
implemented prescanning in a way where we wait for 1024 bytes to arrive
or for one second to pass, whichever one happens first.
This causes a large number of web platform tests to flip around. I've
looked at most of the new failures and I believe they're reasonable.
Testing: New tests start to pass.
Part of https://github.com/servo/servo/issues/6414
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This method now allows you to pass in a custom registry. The registry
isn't used yet for callers, since we don't support scoped registries.
However, as we now pass in the registry to `Node::clone`, we set the
registry when creating elements and cloning them.
As such, various tests start passing where we set the registry. Some
tests started failing, but they rely on scoped registries which we don't
support yet. These tests thus flipped: those that were erroneously
failing are now passing and vice versa.
Part of #34319
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
The specification has a dedicated method for destroying
documents. Parts of that method were scattered around
various parts of Servo machinery.
This patch consolidates these steps and follow the spec.
Additionally, it now correctly unloads iframes when
they are removed from a parent document.
As a result, the fetch-later WPT test now passes, as
it relies on the correct ordering of iframe unloading
to verify the fetch-later requests are sent.
Part of #31973
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This is the first part of preparation for implementing the keepalive
flag for requests. It requires implementation of the concept of a task
group, which we already sort of have with `DocumentLoader`. Therefore,
we currently already cancel any loads, which should be updated to
ignored kept-alive requests.
However, termination also requires storing of deferred fetches, which
are also kept-alive. Therefore, to distinguish the two, we need to store
them separately as stated with the TODO.
In a follow-up, we can then skip canceling keep-alive requests for both
`navigator.sendBeacon` (which aren't deferred) and `fetchLater` (which
are deferred).
Part of #41230
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
For a long time, the "Compositor" hasn't done any compositing. This is
handled by WebRender. In addition the "Compositor" does many other
tasks. This change renames `IOCompositor` to `Paint`.
`Paint` is Servo's paint subsystem and contains multiple `Painter`s.
This change does not rename the crate; that will be done in a
followup change.
Testing: This just renames types and updates comments, so no new tests
are necessary.
---------
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Changed some allow to expects and removed the unfulfilled expectations.
Testing: Refactor
Part of: #40383
Signed-off-by: anonmiraj <nabilmalek48@gmail.com>
Currently when we call a `Focus` we always scroll a focusable element to
the center of the container. However, this would causes a different
behavior where UAs wouldn't scroll when a focus is called to a visible
element. This PR add implementations following the behavior of Firefox
[nsFocusManager::ScrollIntoView](e613f4df35/dom/base/nsFocusManager.cpp (L3121)),
where we are scrolling to the element if it is not visible.
This would enhance the user experience of focusing an input element,
where we should avoid moving the element if it is visible.
Incidentally fix a calculation bug for the calculation of
`ScrollIntoView` with `nearest` block or inline option.
Testing: Private WPT for the implementation defined behavior and public
WPT for the bug.
---------
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
We were trying to update the dirty root to be the common ancestor of the
old dirty root and the element noted with dirty descendants. But that
would panic if when the old dirty root had been disconnected.
In that case, just set the dirty root to be the element, as if the old
dirty root was None.
Testing: Adding a crashtest, and one existing test now fails instead of
crashing
Fixes: #40920
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Rebase of #37021 with review comments applied. These changes bundle up
the required information from the relevant global when a stylesheet is
added so that any requests for web fonts match the specification.
Testing: Newly passing tests.
Fixes: #36590
---------
Signed-off-by: Uthman Yahaya Baba <uthmanyahayababa@gmail.com>
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Uthman Yahaya Baba <uthmanyahayababa@gmail.com>
The current implementation doesn't match the specification and is broken
in a way that makes nytimes.com endlessly attempt to enqueue resource
timing entries, making the page completely unresposive to user input.
This PR makes some surgical changes that fix the NYTimes behaviour and
add some comments to make it easier to further improve the
implementation in the future.
Testing: Various WPT that used to timeout now fail instead.
Fixes: #40808
---------
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Currently, only the first `Painter` is used for all operations in the
`Compositor`. This change modifies the compositor API and message
handling to allow routing the operations to the correct `Painter` via a
provided `PainterId` or `WebViewId`.
This change is to enable support for per-`WebView`s `RenderingContext`s.
Testing: This change shouldn't change behavior, so existing WPT tests
should cover it.
---------
Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
I used find and replace to finish the job. All this PR does is replace
all `Error::<error_name>` occurrences with `Error::<error_name>(None)`.
Testing: Refactor
Fixes: #39053
Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
The tests now start running rather than erroring, but they aren't
working yet as we don't currently use protocol handlers yet. That's for
follow-up PRs, as that requires more plumbing.
Part of #40615
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
The two are semantically equivalent, but `find_map` is more concise.
Testing: Covered by existing tests
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Adds an optional error message to HierarchyRequestError
Testing: refactor
Fixes: one item in #39053
---------
Signed-off-by: Austin Willis <austinwillis8@gmail.com>
The goal of this change is to prevent having to copy so much data out of
listeners when a fetch completes, which will be particularly important
for off-the-main thread parsing of CSS (see #22478). This change has
pros and cons:
Pros:
- This makes the design of the `FetchResponseListener` a great deal
simpler.
They no longer individually store a dummy `ResourceFetchTiming` that is
only replaced right before `process_response_eof`.
- The creation of the `Arc<Mutex<FetchResponseListener>>` in the
`NetworkListener` is abstracted away from clients and now they just
pass the `FetchResponseListener` to the fetch methods in the global.
Cons:
- Now each `FetchResponseListener` must explicitly call `submit_timing`
instead of having the `NetworkListener` do it. This is arguably a bit
easier to follow in the code.
- Since the internal data of the `NetworkListener` is now an
`Arc<Mutex<Option<FetchResponseListener>>>`, when the fetching code
needs to share state with the `NetworkListener` it either needs to
share an `Option` or some sort of internal state. In one case I've
stored the `Option` and in another case, I've stored a new inner
shared value.
Testing: This should not change observable behavior and is thus covered
by existing tests.
Fixes: #22550
---------
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
The result of an xpath query can depend on whether or not the document
is a HTMLDocument. We should always use the document that
`document.evaluate` was called on. Instead, we were using the document
of the relevant window. This makes a difference when a script creates a
document and calls `document.evaluate` on that.
Testing: New tests start to pass
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This implements character set restrictions both for the DOM API and when
getting cookies from http/ws headers. This is a local workaround for
https://github.com/rwf2/cookie-rs/issues/243
We still fail some tests because hyper errors out when parsing headers
with %x1 characters.
This patch also makes a minor change to
'ServoCookie::from_cookie_string()' to avoid some string cloning when
possible.
Testing: wpt tests expectations are updated
Signed-off-by: webbeef <me@webbeef.org>
Follow the specification and allow to render media controls (expose a
user interface to the user) without any HTMLMediaElement `readyState`
precondition.
The media controls be shown for the following examples without specified
media source (e.g. without `src` attribute).
```
<audio controls></audio>
<video controls>/<video>
```
See https://html.spec.whatwg.org/multipage/media.html#user-interface
For media controls UI don't define root `div` element's style `width`
property from the video natural size (`videoWidth/Height` IDL attributes
which return `0` if `readyState` is `HAVE_NOTHING`).
When the `media` element is adopted between different documents need
adopt the media controls id, so media controls UI
will keep access to the whilelist of media controls identifiers via
`document.servoGetMediaControls(id)` API.
Testing: Improvements in the following tests
-
html/rendering/replaced-elements/embedded-content-rendering-rules/audio-controls-00*
-
html/semantics/the-button-element/command-and-commandfor/on-audio-behavior.tentative.html
-
html/semantics/the-button-element/command-and-commandfor/on-audio-invalid-behavior.tentative.html
Note that `Invoker Commands` API is not yet supported so these `command
and commandfor` tests should fail, but due to previous bug with delayed
media controls shown up. The invoker `onClick` function send actions
with mouse events
(move/up/down) to the test driver at the position of the button element
(via getBoundingClientRect), but before test driver
will handle these actions the mediadata is received and media controls
are shown up with "play" button at this position.
So the media control "play" button is clicked instead of the button, and
it triggers media element `pause` state change.
See https://open-ui.org/components/invokers.explainer/
Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
`FetchReponseListener` has traditionally lived in `net` even though it
is only used in `script` currently. Because of the two way dependency,
it has also use a lot of templating to implement something pretty basic
(call methods on a trait object).
This change moves the trait to `script` and removes several levels of
templating, making the code quite a bit shorter and easier to
understand.
This change is preparation for fixing #22550 and implementing
off-the-main-thread CSS parsing.
Testing: This should not change any behavior so is covered by existing
tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Removes some unneeded lints, especially `#[allow(unsafe_code)]`.
Testing: Refactor
Part of: #40383
Signed-off-by: WaterWhisperer <waterwhisperer24@qq.com>
Within the same tree, only one `<details>` element with the same name
may be open at a time. Before this change, this invariant was not
enforced.
I've added a `HashMap` to `Document` and `ShadowRoot` which maps from a
name to the a list of details elements with the same name. This map
allows us to find conflicting details elements without having to
traverse the whole tree. Of course this only works when the tree is a
document tree or a shadow tree, so we still have to fall back to
`traverse_preorder` in some cases (which I believe to be uncommon).
This is ready for review, but I'd like to wait until
https://github.com/servo/servo/pull/40271 is merged to not cause
unnecessary merge conflicts.
Testing: New web platform tests start to pass
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This removes some unneeded lints, especially `#[allow(unsafe_code)]`.
Testing: Refactor
Part of: #40383
Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
This change makes it so that the `HTMLCanvasElement` is responsible for
managing the `ImageKey` for associated `RenderingContext`s. Only
canvases display their contents into WebRender directly, so this makes
it so that keys are not generated for `OffscreenCanvas`.
The main goal here is that `ImageKey`s are always associated with a
particular `WebView`, which isn't possible in the various canvas
backends yet. This is important because each `WebView` may soon have a
different WebRender instance entirely with its own set of `ImageKey`s.
This also allows for clearing `ImageKey`s when canvases are disconnected
from the DOM in a future change. One tricky thing here is placeholder
canvases, which are meant to be driven from workers.
It seems that the implementation isn't correct for these at the moment
as they need to be updated to the specification. Instead, what is
happening is that any existing context / image is completely lost when
converting to an `OffscreenCanvas`.
Testing: This shouldn't change observable behavior, so is covered by
existing tests.
Fixes: This is part of #40261.
---------
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Remove the microtask queue from `GlobalScope`. The queue is moved inside
worker global scopes, while for window globals the script thread's queue
is accessed.
Testing: Covered by existing tests
Fixes: #20908
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
Servo has a lot of comments like this:
```rust
// https://example-spec.com/#do-the-thing
fn do_the_thing() {}
```
and I keep turning these into doc comments whenever I'm working close to
one of them. Doing so allows me to hover over a function call in an IDE
and open its specification without having to jump to the function
definition first. This change fixes all of these comments at once.
This was done using `find components -name '*.rs' -exec perl -i -0777
-pe 's|^([ \t]*)// (https?://.*)\n\1(fn )|\1/// <$2>\n\1$3|mg' {} +`.
Note that these comments should be doc comments even within trait `impl`
blocks, because rustdoc will use them as fallback documentation when the
method definition on the trait does not have documentation.
Testing: Comments only, no testing required
Preparation for https://github.com/servo/servo/pull/39552
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Steps for calculating LCP:
1. When the pref for `largest_contentful_paint_enabled` is enabled,
`LargestContentfulPaintCandidateCollector` is created once per
LayoutThread using `viewport_size`.
2. While building the `display_list`, it send the pre-calculated
`clip_rect` and `bounds` to `LCPCollector` along with `transform` and
`LCPCandidateType` for `visual_rect` calculation for `LCPCandidates`.
3. After `visual_rect` calculation, update the `lcp_candidate` based on
`area` of `visual_rect` and send it to `compositor`.
4. Then among `lcp_candidates`, we find out the
`largest_contentful_paint` and send it to `paint_metric`
5. In addition to above `LCP` also uses `PaintMetricState` to save
console from spamming with duplicate entries.
This PR includes following commits better segregation of code
1. Add `LargestContentfulPaintCandidate` struct
2. Add `LargestContentfulPaintCandidateCollector`
6. Collect the `LargestContentfulPaintCandidates`when feature is
enabled.
7. Send the `LargestContentfulPaintCandidates` to compositor
8. Add `LargestContentfulPaintCalculator`
9. Calculates the `LargestContentfulPaint`
10. Send `LCP` to `PaintMetrics`
11. Disable `LCP` feature on user interaction
Elements considered for LCP in this PR:
- Image element
- An element with background image
Reference: https://github.com/servo/servo/pull/38041
Testing: Tested using
[perf-analysis-tools](https://github.com/servo/perf-analysis-tools) See
attached screenshot.
Fixes: None
Perfetto
<img width="2566" height="1151" alt="Screenshot from 2025-10-16
11-37-41"
src="https://github.com/user-attachments/assets/96e4f933-b39c-4ac7-833c-46dcc0c1671e"
/>
Console Output of Metric
<img width="1784" height="282" alt="Screenshot from 2025-10-16 11-33-16"
src="https://github.com/user-attachments/assets/441746a5-92ae-47c6-9022-f49114f23a2d"
/>
---------
Signed-off-by: Shubham Gupta <shubham.gupta@chromium.org>
Co-authored-by: boluochoufeng <1355990831@qq.com>
Moves interfaces defined by the performance spec to the
`script/dom/performance/` module from `script/dom/`.
Testing: Just a refactor shouldn't need any testing
Fixes: Partially #38901
Signed-off-by: WaterWhisperer <waterwhisperer24@qq.com>
Implement `Document.parseHTMLUnsafe`
Testing: Covered by existing WPTs, expectations have been updated.
Fixes: #40245
---------
Signed-off-by: Luke Warlow <lwarlow@igalia.com>
Moves interfaces defined by the CSS spec to the `script/dom/css/` module
from `script/dom/`.
Testing: Just a refactor shouldn't need any testing
Fixes: Partially #38901
Signed-off-by: WaterWhisperer <waterwhisperer24@qq.com>
Adds an optional message to be attached to an InvalidCharacterError.
Testing: simple refactor
Fixes: one of the items of #39053
---------
Signed-off-by: Alessandro Vannini <alessandrovnnn@gmail.com>
Input methods are very similar to other kinds of embedder controls such
as file selection boxes, so merge them into the same libservo API. This
simplfiies the API surface a bit.
Testing: This change comes with a new unit test.
---------
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This aligns the request object more with the specification,
since the spec now has a `traversable_for_user_prompts` and
a separate field for the client. Before, they were present
in the same enum.
In doing so, new structs are added that are all required in
the new spec. With this we can add support for preloaded
resources in this client, which are only populated when
we have an applicable Global.
Since the spec moved things around a bit, it now has a
dedicated method to populate the client from the request.
Unfortunately none of the WPT preload tests pass, since
the requests are received out-of-order. The specification
requires us to wait for that to settle, but I haven't figured
out yet how to do that. Given that this PR is already quite
large, opted to do that in a follow-up.
Part of #35035
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
Observers should trigger an observation when they are installed, but
this can only happen if a rendering update happens. This change makes
sure that a rendering opportunity is triggered. This isn't discused in
the specification because we only triggering rendering updates when
necessary for performance reasons.
Testing: This fixes a timeout in
`/intersection-observer/cross-origin-tall-iframe.sub.html`.
Fixes#39831.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This fixes a regression (likely from #39583) that made the result of
many font loading
tests intermittent. The issues here is that the count of fonts loading
is decremented synchronously in the `FontContext`, but the notification
to the `ScriptThread` happens asynchronously. In between the time the
decrement happens and the `ScriptThread` is notified, a rendering update
could happen which could mark a screenshot as ready to take too soon.
The solution here is to wait until the `fonts.ready` promise is
resolved, which is guaranteed to fire after all fonts have loaded. In
addition, a rendering update is queued after this happens. This means
that the screenshot will wait until that final rendering update to be
ready.
This should remove the flakiness of font load tests.
Testing: This should fix many flaky tests.
Fixes: #39953.
Fixes: #39951.
Fixes#38956.
Fixes#39408.
Fixes#39429.
Fixes#39592.
Fixes#39636.
Fixes#39650.
Fixes#39666.
Fixes#39667.
Fixes#39706.
Fixes#39750.
Fixes#39801.
Fixes#39853.
Fixes#39881.
Fixes#39950.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
The renderer needs needs to know when touch events processing has
finished in the DOM in order to properly handle them. This was
previously done using the `CompositorMsg::TouchEventProcessed` message.
This message is now redudant with the general-purpose
`EmbedderMsg::InputEventHandled` message.
This change removes the former message and instead, has the
`TouchHandler` keep a `HashMap` of pending touch events which is uses to
finish their processing when they come back from script. The goal here
is reduce the number of messages sent and to keep the complexity of
touch handling more centered in the `TouchHandler`.
Testing: This should not change observable behavior, so is covered by
existing tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This implements LazyDOMString (from now on DOMString) as outlined in
https://github.com/servo/servo/issues/39479.
Constructing from a *mut JSString we keep the in a
RootedTraceableBox<Heap<*mut JSString>> and transform
the string into a rust string if necessary via the `make_rust_string`
method.
Methods used in script are implemented on this string. Currently we
transform the string at all times.
But in the future more efficient implementations are possible.
We implement the safety critical sections in a separate module
DOMStringInner which allows simple constructors, `make_rust_string` and
the `bytes` method.
This method returns the new type `EncodedBytes` which contains the
reference to the underlying string in either format.
Testing: WPT tests still seem to work, so this should test this
functionality.
---------
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
We were previously using the unsound `StylesheetContents::from_data()`
to create a dummy stylesheet, which we were later replacing with the
actual imported stylesheet once it loaded.
This patch changes that to use `ImportSheet::Pending` instead. But then:
- We need to store the `MediaList` in `StylesheetContextSource`.
Previosuly we stored it in the dummy stylesheet.
- We also need to store an Arc pointer to the `ImportRule`, in order to
update its stylesheet to `ImportSheet::Sheet(stylesheet)` later on.
Testing: Unnecessary, there should be no behavior change
Fixes: #39710
Stylo PR: https://github.com/servo/stylo/pull/250
Signed-off-by: Oriol Brufau <obrufau@igalia.com>