Commit Graph

49 Commits

Author SHA1 Message Date
Tim van der Lippe
6d70fcda1b script: Fire selectionchange events for textcontrol elements (#44461)
Part of #7492

Testing: WPT

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
2026-04-25 13:04:22 +00:00
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
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
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
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
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
Martin Robinson
9cb65e242e script: Use TextInputWidget to implement <textarea> shadow DOM (#43770)
In addition to making it so that textual `<input>` and `<textarea>`
share a common shadow DOM structure, this allows styling the
`<textarea>` placeholder. It is now properly shown in grey.

Testing: This fixes a few WPT tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-04-01 11:41:28 +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
Euclid Ye
cae0752676 cargo: Rename workspace-local library starting with b to servo_* (#43552)
Follow up of #43526. This addresses Nico's comment:
https://github.com/servo/servo/pull/43526#issuecomment-4104953308

- `bluetooth_traits` -> `servo_bluetooth_traits`
- `base` -> `servo_base`
- `bluetooth` -> `servo_bluetooth`
- `background_hang_monitor` -> `servo_background_hang_monitor`

Testing: This should not change any behaviour.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2026-03-23 08:26:49 +00:00
Martin Robinson
56e79459f2 script: Modify and copy the contents of <textarea> placeholder less (#43452)
Instead of always doing the newline fixup on the `<textarea>`
placeholder, only do it when the placeholder attribute itself changes.
This avoids doing string replacements when they are not necessary (such
as when a `<textarea>` switches from having text to only having the
placeholder and viceversa).

In addition make it so that `DOMString::clear` preserves the string
allocation when called.

Testing: This is just a small optimization so testing should not be
necessary. Existing behavior is verified via WPT tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-03-19 15:57:28 +00:00
Tim van der Lippe
479a9b6be3 script: Pass &mut JSContext to attribute_mutated (#43383)
It pushes the `temp_cx` 1 level up to `element.rs` where the calling
chain begins. Other than that this was purely a mechanical change where
I used regexes to replace all patterns with the new ones.

Part of #42812

Testing: It compiles

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
2026-03-18 11:03:54 +00:00
Gae24
e8b581aaf0 script: Pass &mut JSContext in more places (#43252)
Continuation of #43220, removes many `temp_cx` calls introduced by that.

Testing: No behaviour change, a successful build is enough.
Fixes: #43241 #43240

---------

Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
2026-03-14 10:03:48 +00:00
Gae24
ef97d7e199 script: Pass &mut JSContext to VirtualMethods::bind_to_tree (#43220)
Testing: No behaviour change, a successful build is enough.
Fixes: #42838 #43239

Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
2026-03-14 07:37:47 +00:00
Martin Robinson
4c6dbd59cb script: Only trigger one default event handler for form controls (#43247)
There is a `handle_event` virtual method on `Node` that triggers the
default event handler. Typically the "superclass" virtual method is
called and then the specific type runs its default event handler. This
isn't good for form controls, because typically the event handler should
prevent further event handlers from running. This badness can be
observed by pressing down in a text input, which will both move the
cursor as well as scroll the page. 🙃

This change makes it so that the default form control event handler
consistently calls the `Event::mark_as_handled` method and triggers the
"superclass" event handler *after* running its own. In addition, the
scrolling default event handler on `Node` now doesn't run if the `Event`
was already handled.

Finally, a little bit of dead event handling code is removed.

Testing: This change adds a Servo-specific test for this behavior.
Fixes: #40785

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-03-13 16:27:22 +00:00
Gae24
048612fe84 script: Pass &mut JSContext to children_changed and adopting_steps (#43219)
Switch `VirtualMethods::children_changed` and
`VirtualMethods::adopting_steps` to `&mut JSContext`.

Testing: No behaviour change, a successful build is enough.
Part of #40600

---------

Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
2026-03-13 13:40:40 +00:00
Gae24
4ef22ed227 script: Pass &mut JSContext to VirtualMethods::cloning_steps and Node::clone (#43130)
Continuation of #43108, two new `temp_cx()` calls were required:
- inside `maybe_clone_an_option_into_selectedcontent` since it's part of
a markup5ever trait
- inside `serialize_and_cache_subtree` replacing a `CanGc::note()` call,
propagating it inside reflow code will require even more effort.

Testing: No behaviour change, a successful build is enough.
Part of #40600

---------

Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
2026-03-10 17:05:34 +00:00
Martin Robinson
b47b39f974 script: Distinguish between sequential (keyboard) and click focusability (#43019)
This changes makes it so that keyboard and click focusability are two
separate concepts in `script`. Some elements may be focusable only by
the keyboard and some only by the click events.

In addition, the `SEQUENTIALLY_FOCUSABLE` `Node` flag is removed in
favor of a
more specification-aligned approach of checking lazily if an element is
a focusable area. This allows moving the focus fixup steps to their
correct place, asynchronously during "update the rendering" and
synchronously during `unbind_from_tree`.

Testing: This causes some WPT tests to start passing and some to start
failing:
- Two subtests tests in
`tests/wpt/meta/css/css-conditional/container-queries/` because
we do not implement support for container queries. These are legitimate
failures
   and they are compensated by a good subtest pass in the same file.
- A few subtests in `/html/interaction/focus/tabindex-focus-flag.html`
because now
we do not allow focusing non-rendering elements. The failures are HTML
elements with
`<svg>` which we do not rendering and `<summary>` elements of
`<details>` which
   need special handling we do not implement yet.
- `html/semantics/forms/the-fieldset-element/disabled-003.html`: Some of
these tests
start to fail, but they are not spec compliant and browser properly
implementing
   the asynchronous focus fixup rule also fail them. 

Fixes: #31870.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-03-05 08:58:59 +00:00
Martin Robinson
aac17cd4a8 Revert "script: Fire select events for user input selections (#42806)" (#42876)
This reverts commit 1f42551042.

This change led to a decrease in Speedometer performance and needs to be
reworked to avoid that.

Testing: This is just a revert.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-02-26 11:52:36 +00:00
Narfinger
a122bde4b1 Script: Use &mut JSContext in CheckValidity and ReportValidity Methods (#42820)
This is part of replacing can_gc with the new &JSContext/&mut JSContext
method.
We modify CheckValidity and ReportValidity in various HTML Elements to
use the context instead of CanGc.

Testing: Compilation is the test as this is mostly mechanical.

---------

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
2026-02-25 10:34:21 +00:00
Martin Robinson
1f42551042 script: Fire select events for user input selections (#42806)
This change makes it so that selection changes driven by user input
events also fire the `select` event and not just selection changes from
script. In addition the change eliminate the `SelectionState` data
structure instead opting to store the `SelectionDirection` in the
`SharedSelection`. That way there is a centralized place that selection
changes are handled.

Testing: This change adds a Servo-specific WPT test. This is
Servo-specific as
it relies on engine-specific text selection behavior.
Fixes: #41308.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-02-24 19:34:18 +00:00
Steven Novaryo
ad358de589 libservo: Add allow_virtual_keyboard flag for InputMethodControl (#42467)
Following the convention of other major UAs of gating the virtual
keyboard by certain user activation, adding a flags to let the embedder
knows about the user activation. This would be used to determine whether
the virtual keyboard needs to be shown or not in android and ohos.

Testing: Manual testing.

---------

Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2026-02-24 07:30:49 +00:00
Steven Novaryo
c90d7d0a64 script: Ensure UA shadow DOM is initialized on <textarea> bind to tree (#42233)
Ensure that the UA shadow DOM for `<textarea>` is initialized when we
are binding to a tree.

Testing: New WPT.
Fixes: #42231

---------

Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
2026-01-29 08:37:53 +00:00
Martin Robinson
2a7d2780b3 fonts: Store shaping output per-character rather than per-code point (#42105)
This change is a reworking of the shaping code and simplification of the
`GlyphRun` data structure.

The shaper was written between 2012 and 2014 against an early version of
Rust. It was originally written to have a single glyph entry per UTF-8
code point. This is useful when you always need to iterate through
glyphs based on UTF-8 code points. Unfortunately, this required a
tri-level data structure to hold detailed glyphs and meant that CJK
characters took over 3x the memory usage of ASCII characters. In
addition, iterating through glyphs (the most common and basic operation
on shaped text) required doing a lookup involving a binary search for
detailed glyphs (ones that had large advances or mapped to more or less
than a single UTF-8 code point).

The new design of the `GlyphStore` is instead based on `chars` in the
input string. These are tracked during layout so that the resulting
glyph output can be interpreted relatively to its original character
offset in the containing IFC. We are already dealing with IFC text on a
per-character basis for a variety of reasons (such as text
transformation and whitespace collapse). In addition, we will now able
to
implement mapping between the character offsets before and after layout
transformations of the original DOM string.

Now the penalty of more complex glyph iteration is only paid when
transforming glyph offsets to character offsets. Currently this is only
done for selections and clicking in text boxes, both of which are much
less common than layout.

This change does not properly handle selections in RTL text, though
rendering and basic selection and visual movement works (though buggy).

It does not seem like this affects the performance of shaping based on
measurement using the text shaping performance counters. This likely
means that the performance of shaping is dominated on our machines by
HarfBuzz. We noticed no performance degradation in Speedometer when run
on a M3 Mac.

Followup work:
 - Properly handle selection in RTL text.
 - Support mapping from original DOM character offsets to offsets in
   layout after text transformation and whitespace collapse. This is now
   possible.

Testing: This causes some tests to pass and a few to fail. This is
likely
due to the fact that we are handling glyphs more consistently while
shaping. Of the new failures:
- `letter-spacing-bengali-yaphala-001.html`,
`letter-spacing-cursive-001.html`, `font-feature-settings-tibetan.html`
where passing before probably because we were not applying letter
spacing to detailed glyphs. These scripts should not have letter spacing
applied to them, because they are cursive -- which we never implemented
properly. It will be handled in a a followup.
- `shaping-arabic-diacritics-001.html`: This was a false pass. The tests
verifies that Arabic diacritics are applied to NBSP. This wasn't
happening before nor after this change, but the results matched anyway.
Now they don't, but before and after are equally broken.
 - 
Fixes: #216
Part of #35540.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-01-26 12:38:04 +00:00
Martin Robinson
ceedfec729 script: Allow selecting text in input fields with the mouse (#42049)
This change adds basic support for selecting text via dragging the mouse
in text inputs. This is currently handled entirely inside of text
inputs, but will be integrated into a more global drag handler when that
is implemented in the `DocumentEventHandler`. This means that events
that happen outside of the text input currently don't update the
selection.

Testing: This adds Servo-specific WPT-style tests. There are WPT tests
that test this sort of behavior, but I believe they rely on selection
events, which we have no implemented yet (we will soon).

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-01-22 07:51:51 +00:00
Martin Robinson
4a9c95ac8e layout: Handle selection during display list construction (#41963)
Instead of handling selection in text input during box tree / fragment
tree construction, fully handle it during display list construction.
This means that when the selection changes in script, it updates
automatically in the `FragmentTree` and only a new display list is
necessary. This avoids a layout while changing the selection in text
fields.

Testing: This fixes a few rendering issues, but these are very hard
to isolate and test for. It causes one test to start failing, but this
is
because a cursor that wasn't rendered properly now starts showing
up.
Fixes: #41920.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-01-21 08:04:15 +00:00
Martin Robinson
e8f88468d0 script: Consider a selection collapsed when the edit point equals the selection origin (#41978)
In text inputs, the edit point can be equal to a non-`None` selection
origin for a variety of reasons such as when the selection is set by a
DOM API or when a composition event inserts a zero length string. In
both of these cases, we should treat the selection as collapsed. It is
important to do this because for the purposes of arrow key movement and
context menu entries, we should think of the text input as not having a
selection at all.

Testing: This change adds a Servo-specific WPT test, as key press
behavior is
platform specific.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-01-19 15:08:40 +00:00
Martin Robinson
1a92d62a97 script: Simplify TextInput::new (#41975)
This constructors takes more arguments than it needs to. The three
arguments removed are almost always the default values. The exception is
in the unit tests. In this change those calls are modified to use
`set_max_length` like is done in the actual script code.

Testing: This is just a simplification of the code, so should be covered
by existing tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-01-17 14:04:28 +00:00
Martin Robinson
ee8c727944 script: Add selection behavior for double and triple click in text fields (#41926)
This change adds support for updating the selection when double and
triple clicking in text fields. Double clicking selects the most
relevant word while triple clicking selects the entire line.

Testing: This change adds unit tests for `Rope` as well as a
Servo-specific WPT style test. These behaviors are platform
dependent.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-01-16 23:03:05 +00:00
Martin Robinson
075ecd6107 script: Do not allow pasting newlines in single line text boxes (#41934)
This change moves all single versus multiline input handling to script.
It didn't really belong in `Rope`. In addition, it ensures that all
insertions into single line text boxes are sanitized by replacing
linebreaks with spaces.

Testing: As pasting is hard to test with a WPT-style test, this changes
includes new unit tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-01-16 15:32:09 +00:00
Martin Robinson
d5dcdd6e06 script: Add support for setting the edit point with the mouse in <input> and <textarea> (#41906)
This change updates and implements the old `query_text_index` layout
query to properly look for the glyph index of a point within a node's
`Fragment`s. This should work properly with the shadow DOM of both
`<input>` and `<textarea>` elements. In particular, multiple lines are
supported.

Caveats:
 - `<input>` and `<textarea>` that are transformed are currently not
   supported. This will happen in a followup.
 - For multi-line inputs, we should be finding the text offset of the
   nearest line that is within the block range of the click. This will
   happen in a followup.

Testing: This change adds two Servo-specific WPT-style tests. These are
Servo-specific because the behavior of clicking in text fields isn't
fully specified.

Fixes: #35432
Fixes: #10083

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-01-14 13:23:43 +00:00
WaterWhisperer
2a759ed6de Replace allow(crown::unrooted_must_root) with expect(crown::unrooted_must_root) (#41815)
Testing: `./mach build -d --use-crown` with no warnings
Fixes: #41761

Signed-off-by: WaterWhisperer <waterwhisperer24@qq.com>
2026-01-10 08:05:49 +00:00
Martin Robinson
cbb23c72af script: Implement all user agent widgets for form controls with shadow DOM (#41760)
This change makes it so that all form controls are implemented with
shadow DOM, completely removing the legacy text content and selection
code paths for form controls. The motivation for this change is:

- to allow properly hit testing against the text nodes of `<textarea>`
  and other widgets. This is important for implementing mouse-based
  selection on the page.
- to simplify the way that form controls are implemented in general and
  to prepare the way for proper implementations of the user interface of
  other controls.

Testing: This should not change observable behavior at the moment,so
should be covered by existing WPT tests.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-01-09 01:11:20 +00:00
Martin Robinson
2efa7d5d96 script: Add a Rope type and use it for TextInput (#41650)
`TextInput` internally stores a rope of text content, one segment for
each line. This change separates out the rope into a separate `Rope`
data structure that can be shared with other parts of Servo.

`TextInput` needs to move through text content in a variety of ways,
depending on the keys pressed when interacting with a text area. This
change provides a unified movement API in both `Rope` and in
`TextInput` ensuring that selection is handled consistently (apart from
a few minor quirks [^1]). This simplifies the code an improves
interactive behavior.

[^1]: One of these quirks is that the edit point will move to
directional end of the motion when collapsing a selection, but only when
moving by grapheme or word (and not by line). These quirks existed in an
undocumented way previously and they are preserved with code comments.

Testing: This is covered by existing unit tests (updated for the new
API) and
the WPT suite.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-01-06 14:52:08 +00:00
Martin Robinson
e4822c9c5d script: More thoroughly convert between UTF-16 and UTF-8 offsets in text inputs (#41588)
DOM APIs for interacting with selection and text in text inputs
`<input type=text>` and `<textarea>` all accept offsets and lengths in
UTF-16 code units. Servo was not converting all of these offsets into
UTF-8 code units. This change makes it so that this conversion is done
more thoroughly and makes it clear when the code is dealing with UTF-8
offsets and UTF-16 offsets.

Helper functions are added for doing this conversion in both directions
as it is necessary. In addition, a `char` iterator is added for
`TextInput` as it is useful for doing this conversion. It will be used
more completely in the future when a `Rope` data structure is extracted
from `TextInput`.

Finally, specification text is added to all of the DOM implementation
touched here.

Testing: This change includes a new WPT crash test as well as a series
of unit
tests to verify conversion between UTF-8 and UTF-16 offsets.
Fixes #36719.
Fixes #20028.
Fixes #39184.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-12-31 09:29:25 +00:00
Martin Robinson
f418c1272f base: Move Unicode offset types to base (#41521)
This moves the Unicode offset types to the `base` crate and makes them
generally more usable throughout the Servo codebase. In addition, they
are renamed to use Rust naming and to be a bit more consistent:

 - `UTF8Bytes` -> `Utf8CodeUnitLength`
 - `UTF16CodeUnits` -> `Utf16CodeUnitLength`

There is also a bit more documentation explaining their use.

This is preparation for fixing issues with UTF-16 offsets in editable
text fields.

Testing: This does not change behavior so existing WPT tests should
suffice.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-12-25 14:48:40 +00:00
Oriol Brufau
02ed2af193 script: Don't dirty with ContentOrHeritage damage when changing state (#40902)
When for example changing the hover state of an element, we were
dirtying it with ContentOrHeritage damage, which forced it to be laid
out again.

This was added in #39102 in order to fix #38989, but for the most part
it's no longer needed.

However, we will now dirty when a `<textarea>` or `<input>` which can be
selected gets or loses focus. This is to ensure that the caret or
selections get correctly updated.

Testing: Manually tested that #38989 is not regressing

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-12-02 10:19:50 +00:00
Martin Robinson
1e4feeaa0d script: Add context-based context menu options (#40501)
Add context menu options for images, links, and editable text areas. In
addition add the ability to show menu options that are disabled. This
also improves the visual style of the context menu in egui as part of
supporting disabled options.

Testing: This has been manually tested, but we could we should be able
to
easily add unit tests when enriching the API with information about the
active element under context menus.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
2025-11-11 11:03:41 +00:00
Andrei Volykhin
9efe79065e dom: Add the attribute mutation reason (#40527)
For some specific cases (one of them see below) where are requirement to
identify the reason of the attribute mutation (by whom/why it was
changed - by cloning, parser or directly), so the following `reason`
parameter was added to `AttributeMutation::Set` option.

Note that for the HTMLMediaElement the internal `muted` state should be
set to true when the element is created and the element has a `muted`
content attribute specified (should be done once on the first attribute
mutation caused by parser or cloning).

See https://html.spec.whatwg.org/multipage/#dom-media-muted

Testing: Improvements in the following tests
-
html/semantics/embedded-content/media-elements/user-interface/muted.html

Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
2025-11-10 10:09:03 +00:00
Excitable Snowball
a5c3cc3b4e script: Use InputEvent for input events (#39989)
Use `InputEvent` for text input and set appropriate values for the
`composed`, `data`, `isComposing`, and `inputType` attributes. Use a
placeholder for `dataTransfer` attribute and `getTargetRanges` function,
as they are only applicable to contenteditable, which isn't implemented.

Testing: I added two tests under `tests/wpt/mozilla/tests/input-events`
based on the similarly named ones for contenteditable under
`tests/wpt/tests/input-events`.
Fixes: https://github.com/servo/servo/issues/36398

---------

Signed-off-by: Excitable Snowball <excitablesnowball@gmail.com>
2025-11-08 23:04:03 +00:00
atbrakhi
ad8c81d634 servoshell: Implement context menu in servoshell (#40434)
This PR adds context menu support with clickable menu items in the
Minibrowser. The menu appears on right click and supports basic
navigation actions (Back, Forward, Reload).


Testing: We already have tests for ContextMenu in WebView API test.

Signed-off-by: atbrakhi <atbrakhi@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-11-08 11:11:09 +00:00
WaterWhisperer
158bf97e30 script/dom/: Change some #[allow]s to #[expect]s (#40454)
Removes some unneeded lints, especially `#[allow(unsafe_code)]`.

Testing: Refactor
Part of: #40383

Signed-off-by: WaterWhisperer <waterwhisperer24@qq.com>
2025-11-06 11:06:03 +00:00
Simon Wülker
c4ae451612 Turn all commented links before functions into doccomments (#40331)
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>
2025-11-01 05:32:45 +00:00
Yerkebulan Tulibergenov
5cc786a98e script: add CanGc as argument to VirtualMethods::children_changed (#40325)
script: add CanGc as argument to VirtualMethods::children_changed

Testing: These changes do not require tests because they are a refactor.
Addresses part of https://github.com/servo/servo/issues/34573

Signed-off-by: Yerkebulan Tulibergenov <yerkebulan@gmail.com>
2025-11-01 00:20:25 +00:00
Yerkebulan Tulibergenov
132bd24c6d add CanGc as argument to Validatable.validity_state (#40155)
add CanGc as argument to Validatable.validity_state

Testing: These changes do not require tests because they are a refactor.
Addresses part of https://github.com/servo/servo/issues/34573.

Signed-off-by: Yerkebulan Tulibergenov <yerkebulan@gmail.com>
2025-10-25 06:06:32 +00:00
Martin Robinson
868793e175 libservo: Merge input method activation into the EmbedderControl API (#40014)
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>
2025-10-24 12:09:31 +00:00
Narfinger
423800eec4 Script: Lazily transform the DOMString into Rust String instead of immediately. (#39509)
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>
2025-10-09 18:18:03 +00:00
Narfinger
a4c8ffe753 Script: Change script/dom/{bluetooth,canvas,html} to not rely on Deref<str> for DOMString (#39480)
This is part of the future work of implementing LazyDOMString as
outlined in https://github.com/servo/servo/issues/39479.

We use str() method or direct implementations on DOMString for these
methods. We also change some types.

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>


Testing: This is essentially just renaming a method and a type and
should not change functionality.

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
2025-09-25 15:53:21 +00:00
Jonathan Schwender
f4dd2960b8 Add direct script to embedder channel (#39039)
This PR **removes** `ScriptToConstellationMessage::ForwardToEmbedder`,
and replaces it with an explicit `ScriptToEmbedderChannel`. This new
channel is based on `GenericCallback` and in single-process mode will
directly send the message the to the embedder and wake it. In
multi-process mode, the message is routed via the ROUTER, since waking
is only possible from the same process currently. This means in
multi-process mode there are likely no direct perf benefits, since we
still need to hop the message over the ROUTER (instead of over the
constellation).
In single-process mode we can directly send the message to the embedder,
which should provide a noticable latency improvement in all cases where
script is blocked waiting on the embedder to reply.

This does not change the way the embedder receives messages - the
receiving end is unchanged.

## How was sending messages to the embedder working before?

1. Script wraps it's message to the embedder in
`ScriptToConstellationMessage::ForwardToEmbedder` and sends it to
constellation.
2. The [constellation event loop] receives the message in
[handle_request]
3. If deserialization fails, [an error is logged and the message is
ignored]
4. Since our message came from script, it is handle in
[handle_request_from_script]
5. The message is logged with trace log level
6. If the pipeline is closed, [a warning is logged and the message
ignored]
7. The wrapped `EmbedderMsg` [is forwarded to the embedder]. Sending the
message also invokes `wake()` on the embedder eventloop waker.

[constellation event loop]:
2e1b2e7260/components/constellation/constellation.rs (L755)

[handle request]:
2e1b2e7260/components/constellation/constellation.rs (L1182)

[an error is logged and the message is ignored]:
2e1b2e7260/components/constellation/constellation.rs (L1252)

[handle_request_from_script]:
https://github.com/servo/servo/blob/main/components/constellation/constellation.rs#L1590
 
[a warning is logged and the message ignored]:
2e1b2e7260/components/constellation/constellation.rs (L1599)

[is forwarded to the embedder]:
2e1b2e7260/components/constellation/constellation.rs (L1701)

Testing: Communication between Script and Embedder is extensive, so this
should be covered by existing tests.

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
2025-09-02 06:33:44 +00:00
Ashwin Naren
c92cd9e624 script: Move HTML DOM interfaces to script/dom/html/ (#39046)
See #38901.

Testing: Refactor
Fixes: Partially #38901

Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
2025-08-31 01:00:09 +00:00