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>
Instead of panicking when pressing a keyboard shortcut for an uknown
WebView, just silently ignore the request. This code path is only
followed when using keyboard shortcuts, so this isn't going to hide any
unexpected behavior.
Testing: We do not have testing at this level of servoshell.
Fixes: #44056.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
this patch plumbs the webview accessibility trees (#43029, #43556) into
servoshell. we add a global flag in servoshell, which is set when the
platform activates accessibility and cleared when the platform
deactivates accessibility. the flag in turn [activates
accessibility](https://doc.servo.org/servo/struct.WebView.html#method.set_accessibility_active)
in existing and new webviews.
Testing: none in this patch, but will be covered by end-to-end platform
a11y tests in WPT
Fixes: part of #4344, extracted from our work in #42338
Signed-off-by: delan azabani <dazabani@igalia.com>
Co-authored-by: Luke Warlow <lwarlow@igalia.com>
Co-authored-by: Alice Boxhall <alice@igalia.com>
This change has 2 parts:
- adding `BluetoothPickDeviceRequest`, similar to other request structs
used to communicate with the embedder.
- switch from a `Vec<String>` that expected 2 * <device count> strings
to `Vec<BluetoothDeviceDescription>` which is easier to reason about.
Testing: Manual testing with a build that has the `native-bluetooth`
feature enabled.
---------
Signed-off-by: webbeef <me@webbeef.org>
This makes the name of the `GamepadDelegate` consistent with the other
delegates.
Testing: No tests necessary as this is just renaming some structs and
members. Compilation should be enough.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This message appeared in a backtrace without any format replacement
taking place.
Testing: No tests for error messages.
---------
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This adds a `cfg` to servo that uses the llvm profile-runtime function
for writing the coverage file to disk.
When the webdriver shuts down we should make sure to write the
llvm_coverage file. This is only required on platforms like android or
ohos, where there is no real exiting of the process, so we need to
manually dump the profile to disk.
See also https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
Testing: Tested '/mach build -r --coverage && ./mach test-wpt -r
--coverage' and there do not seem any parsing errors anymore.
Fixes: https://github.com/servo/servo/issues/40942
---------
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
The test harness attempts to reset preferences to default values when
running a test in which previously-set preferences are no longer set.
This leads to confusing interactions with any preference customizations
that are present, such as `--pref whatever` or `--prefs-file
something.json`, which are not considered when calculating the default.
This PR changes that: whatever preference values are present when the
webdriver server starts is treated as the default value.
Testing: This is a servo-specific webdriver extension, and we're fixing
an interaction with the test harness. I don't see another way to test
this besides observing the impact on our test results.
Fixes: #42043
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Follow-up to #41823.
Now that we always execute JS with callback, we can safely remove the
obsolete sync script handler.
- Rename `ExecuteAsyncScript` to `ExecuteScriptWithCallback`
- Remove `ExecuteScript` related logic.
- Rewrite async callback wrapper to simplify things.
Testing: I expect no change in behaviour. See if WPT tests agree with
it.
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Instead of having `HeadedWindow`-specific methods here, just expose a
way to access the concrete type of a window. This is also exposed for
embedded ports and unused. They will use it in an upcoming change.
Testing: This shouldn't change behavior and is thus covered by existing
tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
With this we stop exporting ipc-channel in libservo and switch to
GenericChannel/GenericCallback.
Testing: Generic Channels are tested all over the place.
---------
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This change moves the `UserContentManager` abstraction from the
`ServoBuilder` to `WebViewBuilder` so that embedders can inject content
for each `WebView` independently. It also adds basic support for runtime
mutations to the `UserContentManager` API. Only adding new scripts is
currently supported, but future changes will add support for both other
mutations such as removal of scripts and addition & removal of
stylesheets. Future changes could also optimize the way mutations are
propagated to `ScriptThread`s by sending just the "delta" rather than
the whole `UserContents` structure for each mutation.
The `UserContentManager` now becomes just a convenient handle for the
embedders to invoke the mutation API while the actual management of the
manager's content is handled by the Constellation. The mutations are
relayed to the constellation via messages. The change also separates the
serialized version containg the user contents into a new `UserContent`
structure so that the API cannot be misused.
Testing: New unit tests have been added for the different scenarios
involving UserContentManager.
---------
Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
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>
There are two bugs listed below. Basically, we never ever set
1b0bd11e11/ports/servoshell/running_app_state.rs (L253-L255)
except by WebDriver command, so it's always been `None`.
This PR lets `WindowEvent::Focused` determine `focused_window` for
`HeadedWindow`.
For those without `winit::Window`, such as
Android/OHOS/`HeadlessWindow`, the newly created window is automatically
focused.
Fixes: #41398Fixes: #41399
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
- Use the generic channel for webdriver.
- Implement try_receive_timeout for GenericReceiver.
Testing: WPT should still work.
---------
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Route console messages through the embedding API instead of printing
directly, giving embedders control over console output handling.
Testing: Should be covered by exsisting tests
Fixes: #41145
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
This change renames the `WebView::request_open_auxiliary_webview` to
`WebView::request_create_new` and allows responding to it
asynchronously. A new `CreateNewWebViewRequest` is exposed that keeps
the response sender alive as long as it is not dropped. If dropped
without a response, the original request is denied with `None`.
This also makes the API a bit harder to misuse, because the public
`WebViewBuilder::new_auxiliary` factory is no longer exposed, in favor
of `CreateNewWebViewRequest::builder`. This makes it impossible to
create an auxiliary `WebView` without a corresponding request. This
still isn't the idea API, which would be to make creating an auxiliary
`WebView` and normal `WebView` exactly the same, but it's an
improvement.
This will allow opening auxiliary `WebView`s in new toplevel platform
windows in servoshell. That will be handled in a followup. In addition,
the `CreateNewWebViewRequest` can eventually hold the arguments passed
to `window.open`.
Testing: Corresponding changes are made in servoshell, which means that
this is tested by the WPT calling `window.open`.
Fixes: #41220.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This change makes it is that WebDriver can create whole new windows for
each new `WebView` in servoshell. The motivation for this is:
1. This is how the WebDriver specification is written. The command that
create a new WebView is actually called "New Window" [^1], so this
increases compliance with the specification and now we obey the
type hint sent with that command.
2. This change allows testing multi-window support via the WPT.
3. This will allow adding optimizations (#39923) that are otherwise
impossible because the WPT expects all open `WebView` to be live and
visible.
This does not make the change yet for windows opened via `window.open()`
(popups), as that requires #41220 to fix. In order to make this possible
a few changes to the code had to take place:
1. The new `PlatformWindow` creation function has to be passed down to
the WebDriver handler, which normally doesn't know how to make
`PlatformWindow`s.
2. This allows moving the UI command code back to the shared part of
servoshell, meaning that the embedded ports can use it as well
eventually.
3. Headless windows need a real id to differeniate them now intead of
just 0.
4. When dropping the headless `PlatformWindow` we need to make it
current. I'm not sure why surfman doesn't do this, but this is now
necessary as there are multiple contexts. This is also true when
resizing the `RenderingContext`.
Finally, errors when making the context current are upgraded to
`error!`s as they typically break the entire execution of the program.
[^1]: https://w3c.github.io/webdriver/#new-window
Testing: This is tested by the entire WPT suite.
Signed-off-by: Martin Robinson <mrobinson@igalia.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>
Remove the public API to trigger shutdown and instead trigger the
process from `Servo`'s implementation of `Drop` trait.
This makes it hard to create issues involving the order of destruction
of `Servo` and `WebView`s. It will also allow us to implement
asynchronous shutdown in the future.
Testing: Should be covered by existing unit tests.
Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This change finishes adding support for opening new windows in the
desktop version of servoshell. A new button is added to the tab bar
which opens a new window (this can be adjusted later, if necessary).
User interface commands now need to be processed in the context of the
`App` as we need access to a reference to the `ActiveEventLoop` to
create a new window.
Testing: servoshell is mainly untested, though a future change will add
new
unit tests for multi-window functionality.
Fixes: #13997.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This change makes it easier for embedders to embed the types that they
need by exporting almost everything necessary to use Servo at the root
of libservo, apart from a few exceptions. In addition, the `Servo` is
moved
to its own file so that public exports can be more easily spotted from
`components/servo/lib.rs`.
Testing: This should not change behavior and is thus covered by existing
tests.
Fixes: #18475.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This prevents crashes when exiting servoshell in different situations.
For instance, this fixes a crash when running WPT tests on some systems.
Testing: This fixes an issue when running WPT tests locally.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This is a speculative fix for a crash mentioned by @mukilan[^1]. It will
also make moving to a more consistent shutdown model (even one driven by
dropping of the `Servo` instance) possible.
[^1]: https://github.com/servo/servo/pull/40883#issuecomment-3584090609
Testing: It's difficult to test this crash because it seems to only
happen on
nixOS and we currently don't have a good way to test crashes on exit.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
For a while Servo has while had a somewhat unfinished multi-document
interface API that was meant to implement a kind of window manager
inside a single `RenderingContext`. This came with some focus handling
and a paint order implementation. This code was never really finished
and the `WebView` API is moving toward a design where compositing
different `WebView`s together is up to the embedder.
This is finally possible now that rendering to multiple
`RenderingContext`s is supported. In addition, the MDI API interferes
with focus handling when `WebView`s are distributed across windows.
Given these two points, this change starts to remove the MDI API.
- All `WebView`s can still be hidden / unhidden and start in an unhidden
state.
- All `WebView`s always have system focus. System focus never properly
interfaced with Servo's internal focus system anyway. A followup
change will add proper system focus integration.
- There are still some leftovers from the MDI interface (such as
`WebView`s having their own size). These will be cleaned up in a
followup change. Only the changes necessary to get multi-window
support working are included here.
Testing: This should not change observable behavior and tests are
updated for the
new APIs.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This change is a major re-architecture of servoshell to support multiple
windows. Unfortunately it was not possible to do this incrementally, but
@mukilan and I did this together so we feel more confident about these
changes.
The main change here is that now the `HashMap` of windows that `App`
has can be filled with more than one `ServoShellWindow`.
`ServoShellWindow` is a wrapper around a `PlatformWindow` which can
either be headed, headless, or for embedded platforms. Embedded
platforms (Android and OHOS) are only expected to have a single window,
but there is no reason that more windows cannot be added.
There is still a little bit more work to be done in order to fully
enable
mulitple windows, so this change is just the architectural preparation.
This change enables the embedded and desktop versions of servoshell to
start to be fully integrated so that the entire `RunningAppState` is
shared between them.
Testing: servoshell is the test harness so these changes are covered
by the WPT tests.
---------
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Desktop and EGL implementations were maintaining identical WebView
collection logic (HashMap, creation order tracking, focus management).
Extracted this into a shared WebViewCollection struct in
RunningAppStateBase. Both platforms now use the common implementation
through trait methods
Testing: Existing tests should cover this change.
Fixes: part of #40530
---------
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
This is a speculative attempt to make WebDriver WPT runs more stable.
Without this change, it seems likely that embedder controls could stay
open indefinitely during WebDriver test runs.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Testing: This should (hopefully) decrease the amount of tests that flake
when running WPT.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This PR eliminates duplicate code while maintaining the same
functionality across all platforms.. We move `webdriver_receiver` to
shared base where `webdriver_sender` lives
Testing: No functional changes. Existing tests should test this.
Fixes: Part of https://github.com/servo/servo/issues/40530
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
Move screenshot stability tracking to shared base. This PR eliminates
duplicate code while maintaining the same functionality across all
platforms.
Testing: No functional changes. Existing tests should test this.
Fixes: Part of #40530
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
- Reduces unnecessary type conversion between `ServoUrl`, `Url`, string
slice
- Share `WebDriverCommandMsg::LoadUrl` handler across platform
Testing: Covered by existing test. Manually tested for OHOS.
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
There are several code duplicates in servoshell. In this PR, we extract
`servo` from the desktop and EGL implementations into a shared
`RunningAppStateBase` trait. This eliminates duplicate code while
maintaining the same functionality across all platforms.
This is part of refactoring effort to consolidate shared code between
desktop and EGL implementations.
Testing: No functional changes. Existing tests should test this.
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
This reduces code duplication between egl and Desktop.
Testing: No behaviour change. Just simplification.
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Move the screenshot handler to `RunningAppStateBase` to be shared
between egl and desktop. This enables screenshot/element screenshot
capability for egl.
Testing: Existing test. For egl, tested on Ohos.
Fixes: Part of #40279
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
There are several code duplicates in servoshell. In this PR, we extract
`servoshell_preference` from the desktop and EGL implementations into a
shared RunningAppStateBase trait. This eliminates duplicate code while
maintaining the same functionality across all platforms.
This is part of refactoring effort to consolidate shared code between
desktop and EGL implementations.
Testing: No functional changes. Existing tests should test this.
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
Instead of forcing embedders to implement scrolling when wheel events
happen, have Servo take care of this. This means that scrolling happens
consistently with wheel events across all embedders.
Testing: This is tested by the WebDriver conformance suite.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: atbrakhi <atbrakhi@igalia.com>
- Support `WebDriverCommandMsg::InputEvent` for egl
- Move `pending_webdriver_events` and related handlers to
`RunningAppStateBase`
Testing: Manually tested on Ohos device. Element click now scrolls into
view + click.
Fixes: Part of #40279
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
There are several code duplicates in servoshell. In this PR, we extract
identical WebDriver support methods from the desktop and EGL
implementations into a shared `RunningAppStateBase` trait in the new
`running_app_state`.
This eliminates duplicate code while maintaining the same functionality
across all platforms.
This is the first step in a larger refactoring effort to consolidate
shared code between desktop and EGL implementations.
Testing: No functional changes. Existing tests should test this.
---------
Signed-off-by: atbrakhi <atbrakhi@igalia.com>