Commit Graph

20 Commits

Author SHA1 Message Date
elomscansio
aa7eca43b7 script: propagate VirtualMethods::unbind_from_tree with &mut JSContext (#44422)
Propagate `&mut JSContext` in `VirtualMethods::unbind_from_tree`

Testing: Successful build is enough
Fixes: #42837

---------

Signed-off-by: Emmanuel Paul Elom <elomemmanuel007@gmail.com>
2026-04-23 14:09:11 +00:00
Martin Robinson
b39d9833a4 script: Cancel animations for non-rendered nodes in script (#44299)
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>
2026-04-17 21:59:20 +00:00
Tim van der Lippe
d096560b51 script: Correctly handle modifiable elements in contenteditable (#44250)
First of all, the effective command value was wrong, since there is no
relevant CSS property for the underline command. Instead, we should
directly use the text-decoration property. This then allows us to
implement reordering of modifiable elements.

We also need to "change the element to a span", which is quite annoying
to do. Instead, it mimics what would have happened by moving children
and copying attributes.

There are some regressions, but overall this is another big step towards
the right track. The regressions look related to tricky edge cases that
I am not even sure other browsers handle.

Part of #25005

Testing: WPT

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
2026-04-16 20:50:06 +00:00
Martin Robinson
b3fdbf9821 script: Clear style data from detached subtrees when attaching a shadow DOM (#44259)
Instead of just clearing layout data, also clear style data from
descendants that are now no longer part of the flat tree when attaching
shadow DOM. This ensures that Stylo does not try to process them during
restyling. This matches what Gecko does.

Testing: This change adds a crash test and also causes a few subtests
to start passing.
Fixes: #40731.

Signed-off-by: Martin Robinson <mrobinson@fastmail.fm>
Co-authored-by: Martin Robinson <mrobinson@fastmail.fm>
2026-04-16 13:37:21 +00:00
Steven Novaryo
02ba2eaa62 script: Partially implement IntersectionObserver compute the intersection algo (#42204)
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>
2026-04-16 09:04:53 +00:00
Simon Wülker
2930beb4d1 script: Don't traverse O(the whole DOM tree) nodes when inserting elements into Vec in tree order (#44120)
Previously the code was computing a prefix sum over the number of
preceding elements in tree order to get the index that the node should
be inserted in.

That's not great if the DOM tree is big. Instead, we can compare two
nodes individually by looking at their ancestor chain and then find the
correct position with binary search.

On https://262.ecma-international.org/16.0/index.html, this reduces the
time it takes for content to appear from around 33s to 16s.

Part of https://github.com/servo/servo/issues/44113

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
2026-04-14 13:16:55 +00:00
Martin Robinson
5d28862c7b script: Expose a LayoutNode::is_root_of_user_agent_widget method (#44197)
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>
2026-04-14 10:35:00 +00:00
Martin Robinson
8eafa6e9ad script: Remove the duplicate implementation of selectors::Element (#44134)
Servo has had two implementations of `selectors::Element`, one used
during layout and one used for `Element#matches()` and
`Element#closest()`. The DOM APIs can trivially use the version that's
exposed to the layout interface, which allows removing the duplicated
implementation. This will eliminate code and prevent the two
implementations from drifting apart.

Testing: This should not change behavior in a testable way so should
be covered by existing tests.

Signed-off-by: Martin Robinson <mrobinson@fastmail.fm>
Co-authored-by: Martin Robinson <mrobinson@fastmail.fm>
2026-04-12 08:26:13 +00:00
Martin Robinson
45972e07ab script: Rewrite the layout DOM wrappers (#44114)
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>
2026-04-12 04:22:06 +00:00
Martin Robinson
12a655d42c script: Move StyleData to Element from Node (#44074)
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>
2026-04-11 07:46:28 +00:00
Simon Wülker
0fef52f10c script: Remove layout helper traits (#44092)
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>
2026-04-10 18:31:10 +00:00
Narfinger
a80744cc32 script: Move more iterators to unrooted iterators (#44018)
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>
2026-04-10 18:03:03 +00:00
Tim van der Lippe
c8029ea092 script: Rename CanGc::note() to CanGc::deprecated_note() (#44081)
Per the suggestion in

https://servo.zulipchat.com/#narrow/channel/263398-general/topic/PSA.3A.20avoid.20new.20usages.20of.20CanGc.20whenever.20possible/near/583995807
to mark this method as deprecated and make clear it shouldn't be used
anymore, as alternatives exist.

Part of #40600

Testing: It compiles

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
2026-04-10 06:07:52 +00:00
Euclid Ye
560498923e script: Skip clearing subtree layout boxes of detached element when attaching shadow to it (#44052)
There is no layout boxes to clear in this case. For the example in
#43998,
this skips the traversal many times.

Testing: Should not change visible behaviour.
[Try](https://github.com/servo/servo/actions/runs/24131782865).

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-04-10 00:12:07 +00:00
Euclid Ye
8b61ca94fc script: Make Node::clean_up_style_and_layout_data work as named (#44072)
Do not `cancel_animations_for_node` for this function.
We can then reuse it more often.

Testing: Just a refactor.

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-04-10 00:11:19 +00:00
Tim van der Lippe
cac1a7f0fc script: Add basic implementation of font-size command (#43287)
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>
2026-04-06 13:23:36 +00:00
Tim van der Lippe
a1c8896eda script: Pass &mut JSContext to reflect_node_with_proto (#43952)
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>
2026-04-05 18:07:30 +00:00
Oriol Brufau
b0582911db Upgrade Stylo to 2026-04-01 (#43878)
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>
2026-04-03 00:03:25 +00:00
Luke Warlow
087c50657f script: Refactors HTMLInputElement.rs into type specific files (#43325)
Refactors HTMLInputElement.rs to split lots of type specific input code
into their own files. These SpecificInputTypes are responsible for their
own shadow trees and also for element specific data such as
FileInputType's filelist.

Testing: Covered by WPTs
Fixes: https://github.com/servo/servo/issues/38263
Fixes: https://github.com/servo/servo/issues/43351

Signed-off-by: Luke Warlow <lwarlow@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-03-26 11:59:22 +00:00
Jayanta Pradhan
c698be8306 script: move node interfaces into node/. (#43662)
Moves node interfaces into script/dom/node/ module from script/dom/.

Testing: Just a refactor shouldn't need any testing.
Fixes: Part of #38901

Signed-off-by: Jayanta Pradhan <pradhanjayanta91@gmail.com>
2026-03-25 17:39:28 +00:00