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>
This change is a minor cleanup of the way that layout flushes the
stylesheets of shadow roots. This avoids exposing so many public methods
in our and gradually to stop using Stylo's `TShadowRoot` in layout
entirely.
Testing: This should not change behavior, so should be covered by
existing tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This file was getting way too big and too cluttered. Instead, split it
up into multiple files in a dedicated folder.
Part of #25005
Part of #43709
Testing: It compiles
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
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>
`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>
Adjust event targeting for keyboard events when a shadow host is
involved. This is needed to not interfere with keyboard default action
like tabindex focusing.
Testing: Updated WPT tests expectations
Fixes: #43809
---------
Signed-off-by: webbeef <me@webbeef.org>
Make Servo match the focus bits of the HTML specification a bit more by
storing a `FocusableArea` as the currently focused thing in a
`Document` instead of an optional `Element`. There is always a focused
area of a `Document`, defaulting to the viewport. This is important to
support the case of focused navigables and image maps parts in the
future.
Some focus chain debugging code has been removed as the focus chain
concept needs to be reworked to match the specification more closely.
Testing: This should not change behavior so existing tests should
suffice.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Servo has lots of `LayoutXYZHelper` traits that are used to define
additional methods on `LayoutDom<XYZ>`. We can replace them with `impl
LayoutDom<XYZ>` blocks, reducing the number of LoC and making it easier
to add or modify methods.
Testing: These should be covered by existing tests
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This is another part of moving more operations safely to unrooted
iterators.
- Some uses of inclusively_*_siblings
- Some uses of children()
- Some uses of child_elements()
Testing: Compilation is the test as we only use previously made iterator
functions.
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Several more TODO's are now implemented:
1. We correctly restore values for fontsize now
2. We implement relevant logic in wrap_node_list
3. We implement simple modifiable
4. We clear overrides whenever the selection changes
(which is triggered for both the selection itself and
any containing ranges).
Part of #25005
Testing: WPT
Signed-off-by: Tim van der Lippe <tvanderlippe@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>
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>
This makes the most basic tests pass for the font-size command. Future
PR's will continue the work,
but since this is already large enough, this is a good save point.
Part of #25005
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
A lot (and I mean, really a lot) depends on these constructors.
Therefore, this is the one spaghetti ball that I could extract and
convert all `can_gc` to `cx`. There are some new introductions of
`temp_cx` in the callbacks of the servo parser, but we already had some
in other callbacks.
Part of #40600
Testing: It compiles
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This is an initial implementation for `relatedTarget` of `focus` and
`blur` events. As the code doesn't yet follow the specification this is
a bit tricky to associate with specification text, but this should be
correct. A later change will adapt the code to the "focusing steps" part
of the specification.
In addition, a duplicated call to `Element::set_focus_state` is removed.
Testing: This gets one more WPT test passing.
Signed-off-by: Martin Robinson <mrobinson@fastmail.fm>
Co-authored-by: Martin Robinson <mrobinson@fastmail.fm>
The specification says that `:focus` should be active on all shadow
hosts of ancestors of focused areas. This change does that by exposing a
new `DocumentFocusHandler::set_focused_element` method and also using it
during the "removing steps." This is important because unlike the
"focusing steps" `set_focused_element` does not cause focus and blur
events.
Testing: This leads to a progression in results on 8 WPT tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This continues the work to split up the large DOM structs. In this case
we create a helper struct to store focus-related state much like
`DocumentEventHandler`.
Testing: This is mostly code motion, so should be covered by existing
tests.
Fixes: #43720
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
`DocumentOrShadowRoot#activeElement` should return retargeted results.
What that means is that if the DOM anchor of the `Document`'s focused
focusable area is within a shadow root, `Document#activeElement` should
return the shadow host. This change implements that behavior, properly
returning the `activeElement` from both `Document` and `ShadowRoot`.
Testing: This causes a decent number of WPT tests and subtests to start
passing. One subtest starts to fail, because it uses the `autofocus`
attribute
which we do not yet support.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
When navigating to a fragment the specification says to run the focusing
steps. This is possible now that the focusing steps are properly
exposed. This change also adds support for the fallback option, which is
used when the focus target is not associated with a focuable area. In
this case the fallback is to focus the viewport.
Testing: This change adds a new WPT for this behavior, which was
seemingly not tested before.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
`HTMLOrSVGElement#focus` specifies the "scroll into view" steps should
be run after focusing. This was happening implicitly as part of the
`Document`'s implementation of the "focusing steps." That behavior is
not in the specification, so this change moves the scrolling call to
where it is specified. Along with making the code match the
specification, this change simplifies it as well.
Testing: This should not modify behavior, so existing tests should
suffice.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
For years Servo has had the concept of a focus transaction which was
used only to allow falling back to focusing the viewport when focusing a
clicked element failed. As this concept isn't part of the specification,
this change removes it.
Instead, a `FocusableArea` (a specification concept) is passed to
the `Document` focusing code. A `FocusableArea` might also be the
`Document`'s viewport.
As part of this change, some focus-related methods are moved to `Node`
from `Element` as the `Document` is not an `Element`. This brings the
code closer to implementing the "focusing steps" from the specification.
Testing: This should not change behavior and is thus covered by existing
tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.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>
This change has two main interdependent parts:
1. It starts to align Servo's focus code with what is written in the
HTML specification. This is going to be a gradual change, so there
are still many parts that do not match the specification yet. Still,
this adds the major pieces.
2. It adds initial support for the `ShadowRoot.delegatesFocus` property
which controls how focusing a shadow DOM root can delegate focus to
one of its children.
Testing: This causes a few WPT tests to start passing.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
# Checklist
Relevant methods in Document are:
- [x] enter_fullscreen
- [x] exit_fullscreen
- [x] get_allow_fullscreen
Relevant method in DocumentOrShadowRoot is:
- [x] get_fullscreen_element
Relevant methods in Element are:
- [x] fullscreen_element_ready_check
Relevant structs in element.rs are:
- [x] ElementPerformFullscreenExit
- [x] ElementPerformFullscreenEnter
Testing: The PR moves functions around and we don't need to modify any
tests
Fixes: #43719
---------
Signed-off-by: Niya Gupta <niyabits@disroot.org>
Co-authored-by: Niya Gupta <niyabits@disroot.org>
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>
Expose set_cookie_for_url, get_cookie_for_url, allow applications to
get/set cookies.
Testing: Unit test for `SiteDataManager` and manual test with
ServoShell.
---------
Signed-off-by: batu_hoang <longvatrong111@gmail.com>
UA widgets (such as textual `<input>`) create a shadow DOM to contain
their various parts. When clicking on these parts (such as the text node
of the widget contents), we should use the root node of the widget as
the activable node. This means that wehen you click on the inside of an
`<input>` element, the input matches the `:active` pseudo-selector.
Testing: This improves WPT tests.
Fixes: #41102
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Also move the related `navigate_to_fragment` method next to it.
Part of #40600
Testing: It compiles
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This is the first step toward implementing the Web Animations
specification. It adds support for the `AnimationTimeline` and
`DocumentTimeline` specification concepts. Note that there was already
an `AnimationTimeline`, but it did not implement the specification.
Testing: Various WPT start to pass or no longer error / timeout.
Signed-off-by: Martin Robinson <mrobinson@abandonedwig.info>
Co-authored-by: Martin Robinson <mrobinson@abandonedwig.info>
Both `Window::load_url` and `ScriptThread::navigate` implement parts of
the same navigate algorithm from the HTML spec
(https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate).
`ScriptThread::navigate` had only one caller: `Window::load_url`.
This merges both methods into a single `navigate` function in
`navigation.rs`, which is the appropriate home for navigation logic. All
previous callers of `Window::load_url` now call `navigation::navigate`
directly.
Testing: This is a pure refactor with no behaviour changes, so no new
tests are needed. Existing tests cover the navigation paths affected.
Fixes: #43494
---------
Signed-off-by: thebabalola <t.babalolajoseph@gmail.com>
- canvas
- constellation_traits
- canvas_traits
- constellation
Testing: This should not change any behaviour.
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Moves interfaces defined by the document spec to the
script/dom/document/ module from script/dom/.
Testing: Just a refactor shouldn't need any testing
Fixes: Partially #38901
---------
Signed-off-by: Emmanuel Paul Elom <elomemmanuel007@gmail.com>