This change creates a new "type bundle" trait, which holds all of the
concrete implementations of the layout DOM types. The benefit here is
that each implementation of a layout DOM type needs a single associated
type. In addition, and most importantly, `Layout` itself only needs to
parameterized over a single type (the concrete type bundle). This will
make parameterizing layout a lot friendlier.
The downside is that extracting the concrete type from the type bundle
is a bit ugly in Rust, so the change also exposes some type aliases to
make this nicer. In the future, default associated types can make
things a bit simpler as well.
Testing: This should not change behavior so no new tests are necessary.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Adds a profiling event at the startup of servoshell, right after
initializing the tracing subsystem. To support this, add macro
abstractions for tracing events.
The existing span (macros) have a start and an end, but for one-off
events, we don't need a span and hence it make sense to also add the
event macros.
The new event at startup is useful when measuring / optimizing general
startup time. Adding a timestamp as field, allows us to ground the
measurement and compare it against time measured outside of servo,
regardless of how the profiling backend (tracing-perfetto,
tracing-hitrace, future backends) save timestamps.
Testing: Build-testing: the HarmonyOS build enables the tracing feature.
On other platforms this is not the case in CI.
---------
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
ResourceFetchTimings are set throughout the methods in http_loader.rs.
These methods are already very complicated, so having multiple times
`context.timings.lock().set_attribute()` can be quite distracting to
understanding.
This introduces ResourceFetchTimingsContainer structure which has the
lock inside and allows setting multiple attributes to clean up the code
in http_loader.
Testing: This is a refactor and does not change functionality.
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Add the Storage Standard WebIDL for NavigatorStorage and StorageManager,
wire navigator.storage on Window and Worker, and implement persisted(),
persist(), and estimate().
Testing: covered by WP test.
part of #39100fixes#39101
---------
Signed-off-by: Taym Haddadi <haddadi.taym@gmail.com>
This introduces a mechanism that let script threads register and
unregister themselves from receiving messages from the constellation.
This is useful when only globals with event listeners or callbacks will
process some message types.
The first migrated API is the webstorage 'storage' event. This patch
ensures that we only send IPC to same origin globals that have an event
handler set.
While we use it for an event here, this is also usable for DOM callbacks
such as the ones used in the Geolocation API.
Testing: optimization with no tests regression:
https://github.com/webbeef/servo/actions/runs/22880845745
---------
Signed-off-by: webbeef <me@webbeef.org>
Instead of walking the entire fragment tree to find nodes for which
animations and image animations need to be cancelled, this change moves
that logic to `script`. Now, for each animating node the animation
managers will explicitly ask `layout` if the node is being rendered (or
delegating rendering in the case of CSS animations and transitions).
The main goal here is a performance improvement, elimating roughly 1% of
layout time from the profiler when running the
`flexbox-deeply-nested-column-flow.html` test case. This will almost
certainly be an even better improvement on more complex pages as we are
no longer doing things once per fragment tree entry, but once per
animating node.
There is also a subtle behavior improvement here. Before nodes with
`display: contents` had their animations canceled, but now they are not.
For instance, this test case now works properly:
```html
<!DOCTYPE html>
<style>
@keyframes anim {
from { color: cyan }
to { color: magenta }
}
div {
display: contents;
animation: anim 1s infinite alternate linear;
}
</style>
```
The new layout query will additionally be useful for other parts of
script that need to answer the same "being rendered" or "delegates
rendering to children" question.
Testing: This change adds a new test and gets one more subtest passing.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Support applications to get cookies asynchronously from embedder.
Testing:
`servo/components/servo/tests/site_data_manager.rs::test_get_cookie_async`
---------
Signed-off-by: batu_hoang <longvatrong111@gmail.com>
Integrate client storage into indexeddb for the creation and deletion of
databases.
Testing: Existing WPT tests.
Fixes: None
---------
Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
Add a cache for `SameFormattingContextBlock`s: A new kind of cache
is added which allows reusing fragments for
`SameFormattingContextBlock` (the majority of block level elements).
This can reduce the amount of fragment tree construction during
incremental layout (although with a 40 byte overhead per
`SameFormattingContextBlock`).
Testing: This change adds a new Servo-specific WPT test that verifies
that
the minimal number of `Fragment`s are rebuilt after an incremental
layout.
Previously, when running `flexbox-deeply-nested-column-flow.html` from
`tests/blink_perf_tests/perf_tests/layout/`, performance would degrade
with successive test runs. This is due to how slow inline layout is.
This change
removes that progressive degradation, though we may be able to remove
this cache with improvements to inline layout.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Luke Warlow <lwarlow@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Depends on #42251 for the overflow query.
Use containing block queries to implement the iteration of step [3.2.7.
Compute the Intersection of a Target Element and the
Root](https://w3c.github.io/IntersectionObserver/#compute-the-intersection)
within `IntersectionObserver` algorithm.
Contrary to the algorithm in the spec that maps the coordinate space of
the element for each iteration, we uses bounding client rect queries to
get the appropriate clip rect. And, to handle the mapping between
different coordinate spaces of iframes, we use a simple translation.
Due to the platform limitation, currently it would only handle the same
`ScriptThread` browsing context. Therefore innaccuracy any usage with
cross origin iframes is expected.
Testing: Existing and new WPTs.
Part of: https://github.com/servo/servo/issues/35767
Co-authored-by: Josh Matthews
[josh@joshmatthews.net](josh@joshmatthews.net)
---------
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This introduces a `ScriptToEmbedderChan` property on `LayoutThread`,
which is used to send accessibility updates directly to the embedder.
Follow-up to https://github.com/servo/servo/pull/42338.
Testing: Covered by existing tests.
Signed-off-by: Alice Boxhall <alice@igalia.com>
This change introduces the `accessibility_tree` module, containing code
to build an in-memory representation of a very basic accessibility tree
for web contents. Currently, the tree for a given document contains:
- a `RootWebArea` which has the document root node as its sole child,
- an `Unknown` node for the root DOM node,
- a `GenericContainer` node for each DOM element, and
- a `TextRun` node for each text node.
This allows us to make basic assertions about the tree contents in the
`accessibility` test by doing a tree walk to find text nodes and
checking their contents.
Right now, the tree is rebuilt from scratch when accessibility is
enabled and when a navigation occurs (via
`Constellation::set_frame_tree_for_webview()` sending
`ScriptThreadMessage::SetAccessibilityActive`); it's not responsive to
changes in the page.
This change also changes the way we handle updating the graft node
between the webview's accessibility tree and its top level pipeline's
accessibility tree.
Previously, `Constellation::set_frame_tree_for_webview()` would send a
`ConstellationToEmbedderMsg::DocumentAccessibilityTreeIdChange` method
informing the webview of the accesskit TreeId of the top-level pipeline.
However, this resulted in flaky timing as we couldn't depend on that
message being handled before the message containing the TreeUpdate from
the WebContents, which would lead to a panic as the new TreeId wasn't
grafted into the combined tree yet.
This change introduces an epoch value which flows from the
ConstellationWebview, where it's updated every time the
`active_top_level_pipeline_id` changes, to the layout accessibility
tree, and finally to the webview with each TreeUpdate. Whenever a
TreeUpdate arrives at the webview which has a newer epoch than the last
known epoch, the webview-to-contents graft node is updated before the
TreeUpdate is forwarded. If a TreeUpdate arrives at the webview with an
epoch _older_ than the last known epoch, it's dropped, as it must be for
a no-longer-active pipeline.
Fixes: Part of #4344
---------
Signed-off-by: delan azabani <dazabani@igalia.com>
Signed-off-by: Alice Boxhall <alice@igalia.com>
Co-authored-by: delan azabani <dazabani@igalia.com>
Co-authored-by: Luke Warlow <lwarlow@igalia.com>
The main goal here is to have layout not depend on `ServoLayoutElement`
directly and instead use the layout DOM interface exposed by
`layout-api`.
This change allows layout to determine if replaced content
is the root of a user agent widget without having to access
`ServoDangerousStyleShadowRoot` which isn't really safe to use in layout
code. `LayoutElement::shadow_root()` is now no longer exposed to layout.
Testing: This should not change behavior, so should be covered by
existing test.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
In https://github.com/servo/servo/pull/43600, we introduce the new
`CoreResourceMsg::GetCookiesForUrl`.
However after some updates, it is exactly the same with an existing one
`CoreResourceMsg::GetCookiesDataForUrl` which is used by `webdriver`.
This PR removes the duplication.
Signed-off-by: batu_hoang <longvatrong111@gmail.com>
This change reworks the layout DOM wrappers so that they are simpler and
easier to reason about. The main changes here:
**Combine layout wrappers into one interface:**
- `LayoutNode`/`ThreadSafeLayoutNode` is combined into `LayoutNode`:
The idea here is that `LayoutNode` is always thread-safe when used in
layout as long as no `unsafe` calls are used. These interfaces
only expose what is necessary for layout.
- `LayoutElement`/`ThreadSafeLayoutElement` is combined into
`LayoutElement`: See above.
**Expose two new interfaces to be used *only* with `stylo` and
`selectors`:**
`DangerousStyleNode` and `DangerousStyleElement`. `stylo`
and `selectors` have a different way of ensuring safety that is
incompatible with Servo's layout (access all of the DOM tree anywhere,
but ensure that writing only happens from a single-thread). These types
only implement things like `TElement`, `TNode` and are not intended to
be used by layout at all.
All traits and implementations are moved to files that are named after
the struct or trait inside them, in order to better understand what one
is looking at.
The main goals here are:
- Make it easier to reason about the safe use of the DOM APIs.
- Remove the interdependencies between the `stylo` and `selectors`
interface implementations and the layout interface. This helps
with the first point as well and makes it simpler to know where
a method is implemented.
- Reduce the amount of code.
- Make it possible to eliminate `TrustedNodeAddress` in the future.
- Document and bring the method naming up to modern Rust conventions.
This is a lot of code changes, but is very well tested by the WPT tests.
Unfortunately, it is difficult to make a change like this iteratively.
In addition, this new design comes with new documentation at
servo/book#225.
Testing: This should not change behavior so should be covered by
existing
WPT tests.
Signed-off-by: Martin Robinson <mrobinson@fastmail.fm>
Many things are nodes, such as `CharacterData` and attributes. They
don't need style data at all. This saves 16 bytes on every attribute and
text node.
Testing: This should not change testable behavior (only save some
memory),
so it should be covered by existing tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Changes all the uses of `ServoUrl` to `ImmutableOrigin` in
`WebStorageThreadMsg`
Testing: Adds a test case as described in the issue.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<main>
<h1>Tab and Program crashes!</h1>
<iframe srcdoc="
<body>
<p>Hello Web users! <br/> I am an iframe, <br /> I set a key and then retreive it. </p>
<script>
for (let i = 0; i < 1000; i++) {
window.localStorage.setItem('truth', 'Servo is awesome! 🌐')
const example = window.localStorage.getItem('truth')
console.log(example === 'Servo is awesome! 🌐')
}
</script>
</body>
"></iframe>
</main>
</body>
</html>
```
Fixes: #44001
---------
Signed-off-by: Niya Gupta <niyabits@disroot.org>
`dom_count` was used to determine whether it is worth it to run layout
parallel algorithm.
Now this is based on `layout_threads` pref.
Testing: Just removing dead code.
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Implement drop-down select multiple:
- Updates the embedder API to support multi-selects.
- Updates the select element to correctly reset when multiple attribute
is removed.
- Select now renders "n selected" as button text when more than 1, or 0
options are selected.
Note that listbox selects are not yet supported, once they are these new
features will be for `<select multiple size=1>`.
Testing: WPTs and also manually using
https://demo.lukewarlow.dev/css-forms.html. The two test regressions are
due to the lack of listbox support rather than an issue with this PR.
Fixes: #38509
---------
Signed-off-by: Luke Warlow <lwarlow@igalia.com>
Signed-off-by: Martin Robinson <martin@abandonedwig.info>
Co-authored-by: Martin Robinson <martin@abandonedwig.info>
Make `isAsync` and `isGenerator` optional
Testing: Current tests as passing
Fixes: part of #36027
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
Signed-off-by: eri <eri@igalia.com>
Co-authored-by: eri <eri@igalia.com>
There are two times that Servo needs to ask other `Document`s to either
focus or blur.
- During processing of the "focusing steps". When a new element gains
focus this may cause focus to be lost or gained in parent `<iframe>`s.
- When calling `focus()` on a DOM Window from another origin.
In both of these cases we need to request that a `Document` gain or lose
focus via the Constellation, but in the second case we may have a
`BrowsingContextId` of the `<iframe>` gaining focus and a
`FocusSequence`. This change splits those cases into two kinds of
messages.
Finally, run the entire focusing steps when calling `window.focus()`
instead of going to the constellation immediately. This will be
important in a followup changes where messaging order is made more
consistent.
Testing: This should not change behavior so is covered by existing
tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Returns an error on `RenderingContext` constructors when size is 0 in
either dimension. Also adds panics to resize functions in the same case.
Testing: Added a unit test for the new error on
`SoftwareRenderingContext::new()`.
Fixes: https://github.com/servo/servo/issues/36061
Signed-off-by: Freya Arbjerg <git@arbjerg.dev>
Co-authored-by: Martin Robinson <martin@abandonedwig.info>
`global.api_base_url().origin()` returns a unique opaque origin when the
base URL is an opaque origin. When we use the global's origin instead,
requests for claimed blobs can now pass the same-origin check.
Testing: Newly passing tests.
Fixes: #43326Fixes: #43973
---------
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
The origin of a `file` URL is unspecified. Engines act like they're
opaque except in a few special cases - one of which is the "is
potentially trustworthy" algorithm. This change allows consumers of
`servo-url` to distinguish between regular opaque origins and file
origins. Then we use that to mark file origins as "potentially
trustworthy" which is what the spec wants.
For now we can get away without changes to the `url` crate (the one used
in the wider ecosystem, not just servo), but I'm unsure if that will be
the case in the future.
Testing: This change adds a test
Fixes: https://github.com/servo/servo/issues/42540
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
DevTools was collecting CSS rules by walking stylesheets and matching
selector text. This ignored cascade order and did not correctly handle
rules inside layer blocks.
This change uses computed values (rule tree) to get the actual applied
rules in cascade order. It then maps those rules back to CSSStyleRule
using the declaration block identity, and walks the CSSOM to get
selector text and layer ancestry.
This fills ancestor_data with layer names and lets the inspector show
layered rules correctly.
Testing:
- Verified using the minimized testcase from the issue
- Verified on https://www.sharyap.com/
- Confirmed that rules inside layer blocks are now shown with correct
order and hierarchy.
Fixes: #43541
Signed-off-by: arabson99 <arabiusman99@gmail.com>
Add an internal macro to avoid duplication, and use that to implement
the existing two `trace` and `info` macros and add `debug_span`. We skip
`warn` and `error` (from the tracing-rs library), since those names
don't fit our profiling usage too well, and 3 different levels should
also be enough. If we need more levels in the future we could still add
more macros than (after deciding on better names than warn and error)
Testing: Servo is built with the tracing feature in CI (for HarmonyOS)
---------
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
`blob` URLs have a implicit blob URL entry attached, which stores the
data contained in the blob. The specification requires this entry to be
resolved as the URL is parsed. We only resolve it inside `net` when
loading the URL. That causes problems if the blob entry has been revoked
in the meantime - see https://github.com/servo/servo/issues/25226.
Ideally we would want to resolve blobs at parse-time as required. But
because `ServoUrl` is such a fundamental type, I've not managed to do
this change without having to touch hundreds of files at once.
Thus, we now require passing a `UrlWithBlobClaim` instead of a
`ServoUrl` when `fetch`-ing. This type proves that the caller has
acquired the blob beforehand.
As a temporary escape hatch, I've added
`UrlWithBlobClaim::from_url_without_having_claimed_blob`. That method
logs a warning if its used unsafely. This method is currently used in
most places to keep this change small. Only workers now acquire the blob
beforehand.
Testing: A new test starts to pass
Part of https://github.com/servo/servo/issues/43326
Part of https://github.com/servo/servo/issues/25226
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This continues #43045
Changelog:
- Upstream:
74ddab4091...6de1071549
- Servo fixups:
9f2f4f3f1b...6cfce6f329
Stylo tracking issue: https://github.com/servo/stylo/issues/347
Summary of improvements:
- Adding support for the CSS-wide `revert-rule` keyword
- `::details-content` becomes element-backed, thus accepting nested
pseudo-elements like `::details-content::before`.
- Custom properties can now be registered using dashed idents in their
syntax
- Various `attr()` improvements
Testing: Various WPT improvements
---------
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This implements MallocSizeOf for a couple more types and removes some
"ignore_malloc_size_of" throughout the codebase.
- std::path::PathBuf
- tokio::sync::oneshot::Sender
- http::HeaderMap (with a reasonable approximation of iterating over all
headers)
- data_url::Mime by looking at the inner type
- http::Method: Is an enum internally
- urlpattern::Urlpattern: Iterating over all public fields that are
strings as an approximation.
Testing: We cannot test if MallocSizeOf is correct currently.
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Remove the dependency on the `webgpu` crate if the feature is disabled.
Note: This doesn't seem to improve the binary size in production mode,
so presumably dead code elimination is already working well.
Nevertheless, it's preferable to correctly feature guard and it should
save a bit of compile-time (when not building with the webgpu feature).
Testing: `webgpu` feature is enabled by default in CI, and we test
`--no-default-features` too in the HOS build in CI. `cargo tree -p servo
--no-default-features` does not show webgpu anymore after this change.
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This PR considers the following constraints:
- Resources must be available when building servo via a published
crates.io package (i.e. no `../../../resources/<file>` file references).
- Minimal setup when writing tests (`nextest` spawns each test in its
own process, so we don't want to explicitly initialize the resource
handler for every `#[test]` fn)
- Use local resources when developing locally
- Support loading the resources from a proper resource directory if the
embedder wishes so, including via a custom mechanism, not necessarily as
files
(File) Resources that are only accessed from servoshell are out of scope
of this PR, since it mainly focusses on unblocking publishing `libservo`
to crates.io.
Baking the resources into the binary by default simplifies the setup a
lot. We already supported that before, but only for testing purposes and
explicitly not for production builds.
Using [`inventory`](https://crates.io/crates/inventory) adds a simple
way for the embedder to replace the default baked in resources, while
also keeping the test usage of baked in resources simple.
rippy.png is also referenced from image_cache - We simply duplicate it,
since the image is small, to avoid adding unnecessarily complex
solutions like adding a dedicated crate.
Testing: Covered by existing tests. [mach try
full](https://github.com/jschwe/servo/actions/runs/23811669469)
Fixes: Part of #43145
---------
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This set of changes introduces a type matching the spec's "target
snapshot params" and uses it as part of determining the origin of new
documents. This has a side benefit of making our sandbox flag
determination more accurate, which leads to a bunch of sandboxing tests
passing as well as some new failures due to spec confusion about
origins.
Testing: Many new passing tests.
Part of the long road to #43149
---------
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Add the minimum amount of FreeBSD-specific code to Servo, where no
platform-neutral fallback exists.
Testing: I've succesfully built and run Servo on FreeBSD with these
changes (and some fixes to dependencies). There's no functional change
to any other targets. This pull request was created with Servo running
on FreeBSD.
Fixes: #11625
---------
Signed-off-by: Juhani Krekelä <juhani@krekelä.fi>
Co-authored-by: Juhani Krekelä <juhani@krekelä.fi>
Use constant variable to define the `PipelineNamespaceId` for
`Constellation` and `Embedder`, and fix the comment describing the
declaration `next_pipeline_namespace_id`.
Testing: A successful build should be enough for the minimal
refactoring.
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
In general, for a normal `BoxFragment`, a `ExternalScrollId` is created
by directly using the `OpaqueNode::id` which is the heap address of the
`Node`. But for a `BoxFragment` from a `::before` or `::after` pseudo
element, we are using the next unused id (starting from zero) with an
increment of two.
This patch modifies so that we are using the bitwise or of
`OpaqueNode::id` and `FragmentType` as the `ExternalScrollId`. With
these changes, the `ExternalScrollId` for the pseudo elements would
remain the same after reflow (instead of getting a new scroll id).
Testing: New WPT test
Fixes: #43308
---------
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>