This undoes #35882 according to the last CSSWG resolution, since this is
required by web compat.
Testing: Modifying the relevant test
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Also includes a fix to not throw a type error in
`XPathResult.invalidIteratorState`.
Testing: Includes a new web platform test
Part of https://github.com/servo/servo/issues/34527
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
The existing `assert!(node.is_connected())` is wrong. What it *wants* to
assert is that the style element has an owner, which is either a
Document or a ShadowRoot that the element is a descendant of. However,
if the element is descendant of a ShadowRoot which is itself not
connected to a document then the assertion would fail.
Instead, we use `node.is_in_a_document_tree() ||
node.is_in_a_shadow_tree()`, which more accurately reflects the intent.
Testing: This change adds the test case from
https://github.com/servo/servo/issues/37781 as a crashtest
Fixes https://github.com/servo/servo/issues/39457
Fixes https://github.com/servo/servo/issues/37781
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This isn't needed as the border box query already takes into account the
containing block chain. Instead, consistently calculate the new
scroll position for a scroller relative to its current scroll offset.
In addition, fix a small bug where the border of a scroll container was
considered part of scrollport.
Testing: A new WPT test is added.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Sticky positioning tries to keep an element visible within the nearest
scrollport. However, the element can't be offset to go beyond its
containing block. We implement this as offset bounds.
The problem was that, if the element would already be overflowing its
containing block before applying the sticky positioning, then we were
forcing it to move inside the containing block. That was wrong, and is
solved by flooring or ceiling the offset bounds by zero.
Testing: Adding new tests
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Automated downstream sync of changes from upstream as of 21-09-2025
[no-wpt-sync]
---------
Signed-off-by: WPT Sync Bot <ghbot+wpt-sync@servo.org>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Co-authored-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Variables in xpath via the javascript bindings are a bit mysterious, as
there is no way that a variable can be specified. We currently panic
when encountering a variable, which is not good. Instead we now throw an
error.
We keep parsing the variables because the code is already there and it
seems realistic that their behaviour will be specified in the future.
I'm fine with removing them too if that is preferred.
Testing: This behaviour is unspecified and different browser produce
different results. There is no "correct" way to do this, but we should
not crash
Part of: https://github.com/servo/servo/issues/34527
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Taffy treats static and sticky positionings as relative. So the inset
properties shifted the element in the relpos way, which was no good.
It's better to just treat them as `auto` instead.
Testing: 3 existing tests pass, and adding a new one.
Fixes: #39399
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
We were returning null for all `<html>` elements, but now we will check
for the root element instead.
We were also returning null for "the body element", now we will return
null for all `<body>` elements even if they aren't "the body element".
This part diverges from the spec, but matches what all browsers do.
https://github.com/w3c/csswg-drafts/issues/12834
Testing: Adding new test
Fixes: #10521
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
#33426 only added support for relative positioning on captions with
`caption-side: top`, but forgot about `caption-side: bottom`. This
unifies the logic for both kinds of captions to avoid divergences.
Testing: Modifying an existing test to also cover this case.
Fixes: #39386
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
According to https://drafts.csswg.org/css-inline/#invisible-line-boxes,
if a line box contains non-zero inline-axis margins, padding or borders,
then it can't be phantom.
Therefore, this patch makes adds a `has_inline_pbm` flag to the line.
Note that we can't use the `has_content` flag, because that would add a
soft wrap opportunity between the padding/border/margin and the first
content of the line.
The patch also renames `InlineFormattingContext::had_inflow_content` to
`has_line_boxes`, which is what we care about for collapsing margins
through.
Testing: Adding new tests
Fixes: #39057
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This patch refactors the logic for propagating overflow to the viewport,
fixing various issues:
- Now we won't propagate from the root element if it has no box. Note
the fix isn't observable in Servo because we lack scrollbars.
- If the first `<body>` element has no box, we won't keep searching for
other `<body>` elements. This deviates from the spec, but aligns us with
other browsers.
- We won't propagate from the `<body>` if it has no box. We were already
handling `display: none` but not `display: contents`. This deviates from
the spec, but aligns us with other browsers.
Also, when we flag the root or `<body>` as having propagated `overflow`
to the viewport, we retrieve the `LayoutBoxBase`. Therefore, now we get
the computed style from the `LayoutBoxBase` in a single operation,
instead of first retrieving the style from the DOM element and then
getting the `LayoutBoxBase` from the box.
Testing: Adding more tests. We were only failing one of them, but it's
hard to test the fixes given that we don't show scrollbars. The tests
that were already passing are useful too, e.g. Firefox fails one of
them.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
`InlineFormattingContextLayout::finish_current_line_and_reset()` has an
early return in case the line has no fragment. However, if the line only
has a forced line break, then we still need to set the baseline.
Testing: Adding new test.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This test crashes in Servo, and passes on Gecko, Blink and Webkit.
The crash should be addressed by #39204.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
To find scrolling ancestors, we need to walk up the flat tree and only
consider the elements that are in the chain of containing block
ancestors of an element. `scrollParent` now does this so we can use it
to properly implement `scrollIntoView`.
Testing: There are WPT tests for this change.
---------
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
While I adding spec comments to the CSP crate, I discovered two issues:
1. We should only use the last sandbox value (WPT test added)
2. We weren't checking for the scripting sandbox flag in document
Also, the autoplay test should have allowed scripts to run, otherwise
the test doesn't run. Since we weren't checking the flag before, the
test ran fine for Servo. However, it wouldn't run for other browsers.
Also realized that an existing test was pointing to a non-existent file
(since it doesn't have `.sub`). Updated that and confirmed that in other
browsers it now properly works (it no longer shows a 404). However,
Servo now fails that test as we don't fire an load event.
Part of #913
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
When encountering such an ancestor, we were returning null instead of
skipping it.
Testing: Adding new subtest for this. And while I'm at it, another one
for the root element, unrelated to this fix.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Removes a test related to autoplay and sandboxing which will always
fail.
In https://github.com/servo/servo/pull/39079 I introduced a wpt to test
autoplay functionality, but the test was flawed in its approach -
shortly after merge, myself and @TimvdLippe found that this test would
simulataneously require scripts to be enabled, as well as disabled for
the test to pass.
This slipped past me becuase we hadn't correctly implemented whether
scripting was enabled yet in Servo.
Testing: Removes a single WPT - this test has not been merged upstream.
Signed-off-by: Shane Handley <shanehandley@fastmail.com>
Implements document's active sandboxing flags. These are currently
populated only from CSP-derived sandboxing flags for a new document,
when defined in the CSP.
Testing: 1 new pass, and some new wpt's are added to test points in the
spec where these flags influence behaviour.
Signed-off-by: Shane Handley <shanehandley@fastmail.com>
This new API allows getting the element which establishes an element's
scroll container. This will be used to properly implement
`scrollIntoView`. There is still work to do for this API and
`offsetParent` to properly handle ancestors which are
closed-shadow-hidden from the original query element.
In addition, fix an issue where inline boxes were establishing scrolling
containers (they shouldn't do that).
Testing: There are tests for this change.
Fixes: #39096.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Instead of panicking when doing a geometry script query on a node with
an uninvertible transform, return a zero-sized rectangle at the
untransformed position. This is similar to what Gecko and Blink do
(though it seems there are some differences in positioning this
zero-sized rectangle). Mostly importantly, do not panic.
Testing: This change adds a new WPT crash test.
Fixes: #38848.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
It's expected that script queries be able to interact with collapsed
table rows and columns, so this change starts laying them out. They
still do not affect table dimensions, nor are they painted.
This does not fix all interaction with collapsed rows and columns. For
instance, setting scroll offsets of contained scrolling nodes does not
work properly. It does fix the panic though, which is the most important
thing.
Testing: this change includes a new WPT crash test.
Fixes: #37421.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Phantom line boxes should be treated as non-existing for most purposes,
so don't let them affect the baseline of their block container.
Testing: An existing test passes, and also adding a new one which
doesn't rely on `<button>`
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Replaced usage of `typed_insert` since it ended converting `UTF-8` to
lowercase.
Removed one of the test cases since it wasn't following spec since
[xhr/205](https://github.com/whatwg/xhr/pull/205).
Testing: Changes covered by wpt
Fixes: #20436
---------
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
This adds the remaining window as well as specific svg and animation
listeners. The test suite was erroring before, as we don't implement
`SVGAnimationElement` yet. Now, the test gracefully checks if the
interface exists before doing a lookup.
Part of #36258
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
While building the stacking context tree we were assuming that `<body>`
would have propagated its `overflow` value to the viewport, and thus its
used `overflow` would be `visible`.
However, the element that propagates `overflow` can be the root element
instead. Since #38598 we are correctly taking this into account in
`effective_overflow()`, so we no longer need to do anything special in
the stacking context logic.
Testing: `css/css-overflow/overflow-body-propagation-012.html`
Fixes: #38799
Signed-off-by: Shubham Gupta <shubham13297@gmail.com>
Servo shows a behavior unlike FF and Safari(I don't have Chrome), where
stopping a window does not cancel planned form navigation, resulting in
an infinite navigation loop. The current behavior of Servo does seem to
follow the wording of the spec, so I will open a [companion issue at the
spec](https://github.com/whatwg/html/issues/11562), and I have also
written a WPT tests for the non-standard but widely followed behavior.
This PR also adds a beginning of an implementation of the "ongoing
navigation" concept, which is used by the spec to cancel navigations,
and which is used in this PR only to cancel planned form navigations.
The generation id concept, which corresponds to the planned navigation
concept in the spec, is turned into a simple struct private cell, and is
documented per the spec.
Testing: A new WPT test is added
Fixes: Only one part of https://github.com/servo/servo/issues/36747
---------
Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
Signed-off-by: Gregory Terzian <2792687+gterzian@users.noreply.github.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
The `overflow-*` values of either the root element or the `<body>` get
propagated to the viewport. However, we were missing this part:
> The element from which the value is propagated must then have a used
`overflow` value of `visible`.
See https://drafts.csswg.org/css-overflow/#overflow-propagation
Testing:
- `css/cssom-view/scrolling-quirks-vs-nonquirks.html`
- `css/css-overflow/overflow-body-propagation-007.html`
- `css/css-overflow/overflow-body-propagation-008.html`
- `css/css-overflow/overflow-body-propagation-009.html`
- `css/css-overflow/scrollable-overflow-with-nested-elements-001.html`
- `css/css-overflow/scrollable-overflow-with-nested-elements-002.html`
- `css/css-overflow/scrollable-overflow-with-nested-elements-003.html`
- `css/css-overflow/scrollable-overflow-with-nested-elements-004.html`
- `css/css-overflow/scrollbar-gutter-scroll-into-view.html`
Failures:
- `css/css-overflow/overflow-body-propagation-010.html`
Failing because of missing support for `contain: paint`.
- `css/css-overflow/scrollable-overflow-with-nested-elements-005.html`
Failing because of wrong `data-expected-height`, but correct
`data-expected-scroll-height` which is core of this PR.
`data-expected-height` can be dealt separately.
Fixes: #38248
---------
Signed-off-by: Shubham Gupta <shubham13297@gmail.com>
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
On `ServoWdSpecBrowser`, we set the window size to `800x600` and open
`about:blank`. This will unify the behavior of servo and servodriver.
604b6ea26d/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py (L101-L102)
Testing: Unify the behavior of servo and servodriver for wdspec
Signed-off-by: PotatoCP <Kenzie.Raditya.Tirtarahardja@huawei.com>
Reimplementation of: #35931
For a `FragmentTree` we define a scrollable overflow calculation that
includes the overflow all of it's children `Fragments`. In practice we
are using this calculation for scrolling area of the viewport and
defining the root scroll frames. However, since uncontained fixed
positioned element is located outside of the document and should not be
scrolled, and therefore it would make no sense to include them in the
calculation of its scrollable overflow as well.
Testing: New and existing WPT tests
Fixes: #38617Fixes: #38182
---------
Signed-off-by: Jo Steven Novaryo <jo.steven.novaryo@huawei.com>
Implements (de)serialization behavior for QuotaExceededError and enables
the annotation on the WebIDL spec.
Testing: Adds its own WPT tests
Fixes: https://github.com/servo/servo/issues/38685
---------
Signed-off-by: Rahul Menon <menonrahul02@gmail.com>
The `Canvas2dMsg::MeasureText` is dropped inside `send_canvas_2d_msg` if
the canvas is not paintable,
leading to a panic on the receiving end. Checking the paint-ability
before sending the message prevents this panic, and if the canvas is not
pain-table, a default text metrics is used.
Testing: Manual testing of the minimal test case in the associated
issue, and crash test added.
Fixes: https://github.com/servo/servo/issues/36845
---------
Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
Applies the change from https://github.com/servo/servo/pull/36335 to the
non-default servodriver WPT executor as well.
Testing: Tested manually with `--product=servodriver` on the webxr
directory.
Part of #34683
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
We were instead stretching to the containing block, which implied that
the behaviors of a `stretch` size and `stretch` alignment weren't
consistent.
As resolved by the CSSWG, the behavior will now be:
- If the cross size of the line is known, stretch to the line.
- Otherwise, stretch to the containing block.
See https://github.com/w3c/csswg-drafts/issues/11784
This aligns us with Blink, which has already shipped this new behavior.
Testing: Improves existing WPT and adds a new test.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
When stretching the cross size of a flex item to its flex line, we were
computing the stretch size by subtracting padding, border and margin
from the line size. However, this could result in a negative amount for
the content-box cross size. Therefore, this floors it by zero.
Testing: Adding new tests
Fixes: #38517
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
When restoring context/state we need to pop all clips from current
state, before we just poped one (even if there was none).
Testing: Added new WPT tests
---------
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
Block-level boxes that establish an independent formatting context need
to avoid overlapping floats. If their inline size stretches, then we may
need to lay out multiple times.
The problem was that when trying with a different inline size, the
intrinsic block size can change, but we were using the cached final
block size from the previous attempt.
Testing: Adding new test
Fixes: #38365
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
- According to
[spec](https://w3c.github.io/webdriver/#ref-for-dfn-in-view-3), we
should use container instead of element itself to determine "in-view".
- Updated `test_element_intercepted_no_pointer_events` in
`element_click/interactability.py` to expect "element not interactable".
This was outdated with spec as original test was written 7 years ago
https://github.com/web-platform-tests/wpt/pull/11453.
Testing: new passing cases for `<option>`, `<select>`.
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
When a testharness test also prints debugging output, sometimes the
output can be mixed with the JSON output printed via an alert. This
causes a JSON decoding error in the output. Instead of crashing the
harness and printing many lines of Python stack trace output, print a
nice error. This makes the test output easier to read.
Testing: This is a change to the test harness itself, so no tests
necessary.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>