Adding an optional message to be attached to a NotFoundError.
Testing: Just a refactor
Part of #39053
---------
Signed-off-by: Rodion Borovyk <rodion.borovyk@gmail.com>
Instead of having every single embedder implement keyboard scrolling,
handle it in script in the default key event handler. This allows
properly targeting the scroll events to their scroll containers as well
as appropriately sizing "page up" and "page down" scroll deltas.
This change means that when you use the keyboard to scroll, the focused
or most recently clicked `<iframe>` or overflow scroll container is
scrolled, rather than the main frame.
In addition, when a particular scroll frame is larger than its content
in the axis of the scroll, the scrolling operation is chained to
the parent (as in other browsers). One exception is for `<iframe>`s,
which will be implemented in a followup change.
Testing: automated tests runnable locally with `mach test-wpt --product
servodriver`
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Follow the HTML specification and take into account that the HTML
`<image>/<source>` element inserting/removal steps should only be
counted as relevant mutations for `<image>` element if the parent of the
inclusive ancestor that was inserted/removed is the parent `<picture>`
element.
See <https://html.spec.whatwg.org/multipage/#relevant-mutations>.
Testing: Improvements in the following tests
-
html/semantics/embedded-content/the-img-element/relevant-mutations.html
Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
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>
The xpath resolver is a function provided by the user to resolve
namespace prefixes. Previously, we were ignoring the argument.
Testing: New web platform tests start to pass
Part of https://github.com/servo/servo/issues/34527
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This uses the ScriptThread::custom_element_reaction_stack to call the
enqueue_callback_reaction on the Rc instead of in the loop.
Potentially saving access to thread_local variables.
Testing: Should not change functionality and should be covered by wpt
tests.
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Rework the flow of code in `Element:scroll_into_view_with_options` to
more closely follow the specification. This also simplifies the code a
bit and adds some TODOs about future improvements.
Testing: This should not change behavior and is thus covered by existing
tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Adding an optional message to be attached to a SyntaxError. Unblocks
#39050.
The enum definition of Syntax is now `Syntax(Option<String>)`. Future
PRs should probably add more appropriate messages to some of the
`Syntax(None)`s.
Testing: Just a refactor
Fixes: Partially #39053
Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
We store a pointer to the ScriptThread singleton for a thread in
thread-local storage. While we don't have yet have profiles pointing to
this TLS access as a hot spot, we can remove a potential performance
footgun without a lot of effort by passing around small pieces of data
that we otherwise need to fetch from the ScriptThread.
Testing: Existing WPT is sufficient
Fixes: part of #37969
---------
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
- Add `ShadowRoot` to `JSValue` to avoid
`WebDriverJSError::UnknownType`, and
`JavaScriptEvaluationError::SerializationError` when execute JS from
embedder.
- Add unit test.
- Move [is_detached](https://w3c.github.io/webdriver/#dfn-is-detached)
to `fn is_detached` to be reused.
- Other random simplification.
Testing: WebDriver conformance tests.
---------
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
Parameterize and rename both `Layout::content_box_query` and
`Layout::content_boxes_query` to support the query of rendered padding
area and content area that accounts for transform and scroll. Both of
these query have been misleading for a time since they are using border
box, instead of content box of a Node.
This PR adds a new type `layout_api::BoxAreaType` to be passed from
`ScriptThread` to `LayoutThread` to query the respective area. It is
then used for the query within `IntersectionObserver` to pass several
WPTs.
Testing: Existing WPT Coverage.
---------
Signed-off-by: Jo Steven Novaryo <jo.steven.novaryo@huawei.com>
Additionally, several methods were updated with
spec comments. That's because the "adopt the document
from the element document" step was missing.
By adding these spec comments, I also restructured
some code to avoid duplication of mutation records
and custom element reaction queueing.
Node.textContent doesn't propagate the error yet,
as that method has a lot of separate callers of
elements that wouldn't fail. I will refactor those
in a follow-up PR to keep things manageable.
This implements part of the DOM integration from
https://github.com/whatwg/dom/pull/1268
Part of #36258
---------
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
Signed-off-by: Tim van der Lippe <TimvdLippe@users.noreply.github.com>
This patch adds support for rendering static inline SVG documents in the
DOM tree by serializing the SVGElement's subtree and leveraging the
existing resvg based SVG stack for rendering. Serialiing the subtree is
necessary as resvg's tree representation (roxmltree) is immutable, so we
can't construct the tree incrementally.
Few other design choices here:
1. The `SVGSVGElement` is now treated as a replaced element and the
layout code is responsible for plumbing the serialized SVG source
(encoded as a base64 data: url) into the image cache, much like how
background images are handled.
2. The serialization is done on the script thread after an initial
layout pass. This is necessary because the serialization code asserts
that it is invoked from script thread i.e we can't call it from layout
workers.
3. The serialized SVG data: url is cached to avoid recomputing it on
subsequent layouts. The cache is invalidated when the SVGSVGElement's
subtree is mutated.
The original SVGSVGElement code was behind the `dom_svg_enabled` pref.
This patch also removes the preference and make SVG support using resvg
available unconditionally.
Below is the analysis of the new test failures:
These tests use inline SVG but used to pass by accident.
They now fail because they contain SVG with no intrinsic
sizing which is not handled by resvg in a way that would
allows us to distinguish it from the sized case. The same
limitation applies to non-inline SVG.
- /css/CSS2/positioning/absolute-replaced-width-003a.xht
- /css/CSS2/positioning/absolute-replaced-width-003b.xht
- /css/CSS2/positioning/absolute-replaced-width-003c.xht
These tests employ CSS styles in the HTML that
target the elements in inline SVG, which is not currently
supported.
-
/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg-basic.html
- /css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg.html
This is a tentative test that uses the unsupported 'border-shape' CSS
property. The ref uses SVG, so it used to pass accidentally. The ref
still doesn't render correctly since it also relies on styling SVG
elements using CSS classes in the HTML (instead of inline in SVG).
- /css/css-borders/tentative/border-shape/border-shape-stroke.html
These tests use the attribute 'clip-path=circle(...)' in the
test, but this doesn't seem to work in resvg.
- /css/css-masking/clip-path/clip-path-borderBox-1b.html
- /css/css-masking/clip-path/clip-path-contentBox-1b.html
- /css/css-masking/clip-path/clip-path-contentBox-1c.html
- /css/css-masking/clip-path/clip-path-fillBox-1b.html
- /css/css-masking/clip-path/clip-path-marginBox-1a.html
- /css/css-masking/clip-path/clip-path-paddingBox-1b.html
- /css/css-masking/clip-path/clip-path-strokeBox-1b.html
- /css/css-masking/clip-path/clip-path-strokeBox-1c.html
- /css/css-masking/clip-path/clip-path-viewBox-1a.html
- /css/css-masking/clip-path/clip-path-viewBox-1b.html
- /css/css-masking/clip-path/clip-path-viewBox-1d.html
- /css/css-masking/clip-path/svg-clip-path-circle-offset.html
- /css/css-masking/clip-path/svg-clip-path-ellipse-offset.html
Additionally, the below two tests use a `foreignObject` SVG element
which
embeds a html div fragment. This is also not supported by resvg.
- /css/css-masking/clip-path/clip-path-viewBox-1d.html
- /css/css-masking/clip-path/clip-path-fillBox-1b.html
The following test fails because of apparent pixel differences
between a circle rendered purely using CSS clip-path vs a circle
rendered in SVG using resvg.
- /css/css-masking/clip-path/clip-path-contentBox-1c.html
These tests style the inline SVG elements using CSS in the HTML or
separate stylesheet. This is not supported by this implementation.
- /css-transforms/document-styles/svg-document-styles-{001..004}.html
- /css-transforms/document-styles/svg-document-styles-012.html
- /css-transforms/external-styles/svg-external-styles-{001..004}.html
- /css-transforms/external-styles/svg-external-styles-014.html
These tests seem like they should pass, but they fail because of what
seems like an anti-aliasing issue in the rendering engine. The
transformed element has a thin outline which is causing pixel difference
with the ref:
- /css/css-transforms/group/svg-transform-group-008.html
- /css/css-transforms/group/svg-transform-group-009.html
- /css/css-transforms/group/svg-transform-nested-009.html
- /css/css-transforms/group/svg-transform-nested-013.html
- /css/css-transforms/group/svg-transform-nested-014.html
- /css/css-transforms/group/svg-transform-nested-018.html
- /css/css-transforms/group/svg-transform-nested-019.html
- /css/css-transforms/group/svg-transform-nested-008.html
The below tests fail because resvg is calculating the wrong size for the
'rect' inside the SVG. The dimensions of the SVG are established via the
CSS in the HTML, so it seems resvg is using incorrect coordinates for
the children of the svg when explict width/height are not specified in
the root svg element.
- /css/css-transforms/group/svg-transform-group-011.html
- /css/css-transforms/group/svg-transform-nested-021.html
- /css/css-transforms/group/svg-transform-nested-029.html
All these tests use an SVG that doesn't have width nor height attributes
and this causes resvg to use incorrect coordinates for the SVG's
children. In addition, the following tests use the CSS syntax for
transforms inside the SVG (using style attribute) which is not supported
by resvg (it only supports the SVG 1.1 transform syntax).
- /css/css-transforms/inline-styles/svg-inline-styles-{001..004}.html
- /css/css-transforms/inline-styles/svg-inline-styles-012.html
In the case of these four tests, the `style` attribute specifies an
invalid transform, but resvg doesn't fallback to the transform specified
via the `transform` attribute on the same element.
- /css/css-transforms/inline-styles/svg-inline-styles-005.html
- /css/css-transforms/inline-styles/svg-inline-styles-006.html
- /css/css-transforms/inline-styles/svg-inline-styles-010.html
- /css/css-transforms/inline-styles/svg-inline-styles-013.html
The following test fails because of the lack of width/height in SVG as
described above but it also exposes gaps in our CSS tranform
implementation.
- /css/css-transforms/preserve3d-and-filter-with-perspective.html
These tests failure because resvg doesn't handle the SVG without
explicit width and height, but specified via CSS in the HTML. In
addition, there are pixel differences between the ref due to
antialiasing issues.
- /css/css-transforms/matrix/svg-matrix-{005...008}.html
- /css/css-transforms/matrix/svg-matrix-010.html
- /css/css-transforms/matrix/svg-matrix-012.html
- /css/css-transforms/matrix/svg-matrix-{015..069}.html
- /css/css-transforms/rotate/svg-rotate-angle-45-001.html
- /css/css-transforms/rotate/svg-rotate-angle-45-011.html
- /css/css-transforms/rotate/svg-rotate-angle-45-022.html
- /css/css-transforms/scale/svg-scale-006.html
- /css/css-transforms/scale/svg-scale-007.html
These tests seem to be failing due to some sort of antialiasing issue,
where a transformed SVG element has a thin border that causes pixel
differences compared to the solid colored reference.
- /css/css-transforms/skewX/svg-skewx-001.html
- /css/css-transforms/skewX/svg-skewx-006.html
- /css/css-transforms/skewX/svg-skewx-011.html
- /css/css-transforms/skewX/svg-skewx-016.html
- /css/css-transforms/skewX/svg-skewx-021.html
- /css/css-transforms/skewX/svg-skewxy-001.html
- /css/css-transforms/skewY/svg-skewy-001.html
- /css/css-transforms/skewY/svg-skewy-006.html
- /css/css-transforms/skewY/svg-skewy-011.html
- /css/css-transforms/skewY/svg-skewy-016.html
- /css/css-transforms/skewY/svg-skewy-021.html
These tests specify several SVG attributes such as transform,
vector-effect etc via CSS in the HTML (rather than inline in SVG). The
current implementation doesn't support this.
- /css/css-transforms/transform-box/stroke-box-mutation-001.html
- /css/css-transforms/transform-box/stroke-box-mutation-002.html
- /css/css-transforms/transform-box/stroke-box-mutation-003.html
- /css/css-transforms/transform-box/stroke-box-mutation-004.html
- /css/css-transforms/transform-box/svgbox-stroke-box-002.html
- /css/css-transforms/transform-box/svgbox-stroke-box-003.html
- /css/css-transforms/transform-box/svgbox-stroke-box-004.html
- /css/css-transforms/transform-box/svgbox-stroke-box-005.html
These tests depend on 'transform-origin' specified on an element inside
an SVG, but this transform is influenced by the 'tranform-box' set via
CSS in the HTML itself (not the SVG). The current implementation doesn't
support styling the SVG using document styles, so these tests just fail.
- /css/css-transforms/transform-origin/svg-origin-relative-length-*.html
These tests check the fallback behaviour when invalid syntax is
encountered in the 'transform-origin' value. resvg doesn't correctly
fallback to 0,0 causing the tests to fail.
-
/css/css-transforms/transform-origin/svg-origin-relative-length-invalid-001.html
-
/css/css-transforms/transform-origin/svg-origin-relative-length-invalid-002.html
-
/css/css-transforms/transform-origin/svg-origin-relative-length-invalid-003.html
-
/css/css-transforms/transform-origin/svg-origin-relative-length-invalid-004.html
These tests use unimplemented Canvas APIs like 'beginLayer' and
the 'CanvasFilter' constructor and hence fail at runtime.
-
/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.html
-
/html/canvas/element/filters/2d.filter.layers.gaussianBlur.tentative.html
-
/html/canvas/element/layers/2d.layer.anisotropic-blur.isotropic.tentative.html
-
/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-x.tentative.html
-
/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-y.tentative.html
-
/html/canvas/element/layers/2d.layer.anisotropic-blur.x-only.tentative.html
-
/html/canvas/element/layers/2d.layer.anisotropic-blur.y-only.tentative.html
-
/html/canvas/element/layers/2d.layer.css-filters.blur-and-shadow.tentative.html
- /html/canvas/element/layers/2d.layer.css-filters.blur.tentative.html
- /html/canvas/element/layers/2d.layer.css-filters.shadow.tentative.html
- /html/canvas/element/layers/2d.layer.ctm.layer-filter.tentative.html
-
/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html
-
/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.html
-
/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.tentative.html
-
/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.tentative.html
-
/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic.tentative.html
-
/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x.tentative.html
-
/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y.tentative.html
-
/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only.tentative.html
-
/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only.tentative.html
-
/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow.tentative.html
- /html/canvas/offscreen/layers/2d.layer.css-filters.blur.tentative.html
-
/html/canvas/offscreen/layers/2d.layer.css-filters.shadow.tentative.html
- /html/canvas/offscreen/layers/2d.layer.ctm.layer-filter.tentative.html
These tests fail because resvg doesn't seem to honour the 'translate'
CSS property specified on an SVG element using an inline 'style'
attribute.
- /css/css-transforms/translate/svg-translate-with-units.html
-
/css/css-transforms/translate/translate-and-transform-attribute-in-svg.html
-
/css/css-transforms/translate/translate-and-transform-css-property-in-svg.html
- /css/css-transforms/translate/translate-in-svg.html
These tests seem to fail due to the filter effect implementation in
resvg either not being complete or spec compliant.
- /css/filter-effects/feconvolve-divisor.html
- /css/filter-effects/feconvolve-region-001.html
- /css/filter-effects/feconvolve-region-002.html
- /css/filter-effects/filter-subregion-01.html
- /css/filter-effects/svg-feimage-002.html
- /css/filter-effects/svg-feimage-003.html
- /css/filter-effects/svg-feimage-004.html
- /css/filter-effects/svg-feoffset-001.html
The test /css/filter-effects/svg-feimage-004.html should ideally PASS
but currently fails because we don't propagate height/width set using
CSS in HTML element to the root SVG, so resvg uses the wrong dimensions
when rendering the children of the SVG.
These failures are due to deficienies in our current implementation
i.e we don't support styling SVG elements using CSS in HTML.
-
/css/css-transforms/gradientTransform/svg-gradientTransform-combination-001.html
- /css/selectors/sharing-in-svg-use.html
The below test fails as our current implementation relies on resvg to
tell us the intrinsic ratio of the SVG, but this doesn't always work
correctly.
- /css/css-sizing/svg-intrinsic-size-005.html
This failure is due to lack of proper fallback to no-op transform in
resvg when the `rotate()` syntax is specified with an invalid list e.g
`rotate(90,)`.
- /css/css-transforms/rotate/svg-rotate-3args-invalid-002.html
This test only passes in CI and based on the raw log output, it seems
that no text inside the SVG is rendered in the CI. This could be an font
stack related issue.
- /css/css-display/display-contents-svg-elements.html
This test asserts that the CSP blocks loads triggered using `use`
elements in SVG. It used to TIMEOUT as without inline SVG support, no
CSP violation event was triggered. It fails now since the event is now
triggered for the load of the SVG itself (our current implementation
loads inline SVGs as serialized base64 data: urls). This doesn't match
the blocked URL in the use element though.
- /content-security-policy/img-src/svg-use-blocked.tentative.html
Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Testing: [Try run][1] did not reveal any test failures. There doesn't
seem to be any straightforward failure scenarios that can be triggered
in `xml5ever` that are not IO errors and the xml_serialize method simply
serializes to a String buffer.
[1]:
https://github.com/servo/servo/actions/runs/16824267959/job/47657275606l
Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
IntersectionObserver needs to be able to query node geometry without
forcing a layout. A previous layout could have run without needing a
`StackingContextTree`. In that case the layout-less query should finish
building the `StackingContextTree` before doing the query. Add a new
type of layout API which requests that layout finishes building the
StackingContextTree.
This change also slightly simplifies and corrects the naming of
`Element` APIs around client box queries.
Testing: This should fix intermittent failures in WPT tests.
Fixes: #38380.
Fixes: #38390.
Closes: #38400.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Instead of running "update the rendering" at every IPC message, only run
it when a timeout has occured in script. In addition, avoid updating the
rendering if a rendering update isn't necessary. This should greatly
reduce the amount of processing that has to happen in script.
Because we are running many fewer calls to "update the rendering" it is
reasonable now to ensure that these always work the same way. In
particular, we always run rAF and update the animation timeline when
updating the ernder
In addition, pull the following things out of reflow:
- Code dealing with informing the Constellation that a Pipeline has
become Idle when waiting for a screenshot.
- Detecting when it is time to fulfill the `document.fonts.ready`
promise.
The latter means that reflow can never cause a garbage collection,
making timing of reflows more consistent and simplifying many callsites
that need to do script queries.
Followup changes will seek to simplify the way that ScriptThread-driven
animation timeouts happen even simpler.
Testing: In general, this should not change testable behavior so much,
though it
does seem to fix one test. The main improvement here should be that
the ScriptThread does less work.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Depends on #37427.
In addition to the changes introduced by
https://github.com/servo/servo/pull/37065, there are several performance
improvements and nits as follows:
- Use the internal pseudo element for style matching, this will reduce
the performance regression by ~66%.
- Manual construction of the `Text` node inside a text container. This
is followed by the modification of the inner `Text` node instead of
using `SetTextContent` which is more expensive.
- Use `implemented_pseudo_element` instead of
`text_control_inner_editor` `NodeFlag` to handle the special cases that
these elements should follow, specifically the:
- focus delegation workaround;
- selections; and
- line height resolving.
- More documentation.
Servo's side of: https://github.com/servo/stylo/pull/217
Testing: No new unexpected WPT failure, except for the one introduced by
https://github.com/servo/servo/pull/37065/.
Fixes: #36307#37205
---------
Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
These changes introduce a new kind of task that uses a variation of the
`task!` syntax. Existing `task!` usages create task structs that have a
`Send` bound, which requires the use of `Trusted<T>` to reference a DOM
object T inside of the task closure. The new syntax replaces the `Send`
bound with a `JSTraceable` bound, which requires explicit capture
clauses with types. This looks like:
```rust
task!(ScriptPrepare: {script: DomRoot<HTMLScriptElement>} |script| {
script.prepare(CanGc::note());
}),
```
The capture clauses must list every value that will be referenced from
the closure's environment—these values are moved into fields in the
generated task structure, which allows them to be traced by the GC as
part of a generated JSTraceable implementation. Since the closure itself
is not a `move` closure, any attempts to reference values not explicitly
captured will generate a borrow checker error since the closure requires
the `'static` lifetime.
Testing: Existing WPT tests exercise these code paths. I also attempted
to write incorrect tasks that capture references or use values not
explicitly captured, and the compiler correctly errors out.
Fixes: part of #35517
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This change aims to reduce the scope of incremental box tree
construction. Previously, when text content changed, the parent node
would always be marked as requiring box tree reconstruction; now, it is
adjusted to only mark the parent node as needing to recollect its box
tree children.
Testing: This should not change observable behavior and is thus covered
by existing WPT tests.
Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
There is a new default cargo clippy lint, `unsafe_op_in_unsafe_fn`,
which requires unsafe code to be wrapped in unsafe blocks, even inside
functions marked as unsafe. The lint is disabled as much of our code
doesn't fulfill this contract. The thing itself is pretty useful in
order to gradually remove unsafety, so this change starts adding
`unsafe` blocks so we can eventually enable this lint.
Testing: This doesn't change behavior so existings tests should suffice.
Fixes: This is part of #35955.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
The iterator produced by Node::inclusive_ancestors roots the items but
rev_version just drop and unroot them right away. This patch makes it
possible to work on the Node references instead to avoid rooting.
*Describe the changes that this pull request makes here. This will be
the commit message.*
Testing: *Describe how this pull request is tested or why it doesn't
require tests*
Fixes: *Link to an issue this pull requests fixes or remove this line if
there is no issue*
Signed-off-by: webbeef <me@webbeef.org>
A recent update in the spec (https://github.com/whatwg/dom/pull/1079)
introduced new rules for name validation of attribute, element, and
doctype. This PR implements the new name validation rules in
`components/script/dom/bindings/domname.rs`. The old XML name validation
rules are not fully removed because there remains a few usage of it in
`ProcessingInstructions` and `xpath`.
Testing: Covered by WPT tests
Fixes: #37746
---------
Signed-off-by: minghuaw <michael.wu1107@gmail.com>
Signed-off-by: Minghua Wu <michael.wu1107@gmail.com>
Co-authored-by: Xiaocheng Hu <xiaochengh.work@gmail.com>
Implement internal pseudo element, which would be resolved as a
"Implemented Pseudo Element" within style computation. This is an
concrete element that would has a primary style after the style
computation, but could match and style resolved like an pseudo element.
Therefore, it would have a different behavior compared to how does
`pseudo`s that `ServoLayoutNode` had. Where they would not have a
concrete element behind it. Note that, due to the nature of these pseudo
elements residing inside a UA widget, these pseudo elements would
therefore not be accessible in JavaScript by default.
This kind of element is required in order to implement the [form control
pseudo element](https://drafts.csswg.org/css-forms-1/#pseudo-elements)
like `::placeholder`, `::color-swatch`, `::field-text`, etc.
See [this docs](https://hackmd.io/@ChaKweTiau/BJ3zRdLQlg) for more
details of the implementation.
Then, the implemented pseudo element is utilized to implement style
matching for input `type=text`.
Servo's side of: https://github.com/servo/stylo/pull/212
Testing: No WPT regression.
---------
Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
This change:
- Adds a new type of LayoutDamage that signifies that a box needs its
children recollected, because one or more of them need to be rebuilt.
- During restyle damage propagation, propagate this new damage upward in
the tree. Then box tree construction should be able to preserve any
still-valid box tree nodes from box slots.
- During BlockLevelBox job finalization, if a box slot is valid and
there is not LayoutDamage to the element, use the old box slot,
ensuring that its fragment cache is invalidated.
Testing: This should not change observable behavior and thus is covered
by existing WPT tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: coding-joedow <ibluegalaxy_taoj@163.com>
Cloned nodes were re-parsing already-parsed style attributes. As such,
they were also checking CSP, which shouldn't happen as the original node
already was checked for it.
Testing: The existing WPT test now mostly passes. It had two cases which
were passing in no browsers.
Fixes: Part of #4577
Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
- Instead of eagerly computing `pageX` and `pageY`, collect the offset
from the content's initial containing block in the compositor and pass
that information through to `MouseEvent`. This prevents a layout flush
that was happening when eagerly trying to fetch `Document` scroll
offsets.
- Pass keyboard modifiers properly to `MouseEvent`.
- Now all this information is stored and passed as `Point2D` (typed) and
`Modifiers` which greatly reduces the amount of arguments that need to
be passed around.
Testing: It is difficult to test input events as they require WebDriver
which
isn't completely working yet. I have manually run Speedometer 2.1 and I
have
verified that this fixes the regression from #37601.
Fixes: #37601.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Now that we are standardizing on the `_traits` crates becoming `_api`
and exposing the API of the crate that they get their name from [^1],
`script_layout_interface` becomes `layout_api` as it exposes the API for
`layout` that is used by `script` This brings the crate in line with the
naming of the other ones in `shared`.
[^1]:
https://servo.zulipchat.com/#narrow/channel/263398-general/topic/Organizing.20*_traits.20crates/with/396893711
Testing: This should not change any behavior and thus is covered by
existing tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
No longer store scroll offsets for elements in the DOM. Instead
consistently get and set these in layout's `ScrollTree`. This more
consistently requires layout to run when querying scroll offsets, which
ensures that they are up-to-date and properly bounded by scrollable
overflow area.
Testing: This causes several WPT tests to start passing, and one to
start
failing. In the case of
`/shadow-dom/scroll-to-the-fragment-in-shadow-tree.html`, I believe the
issue
is that we don't properly handle scrolling and shadow DOM elements.
Before, the
faulty scrolling was hiding this issue.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Exclude CDATASection nodes from Node::normalize. I made it under the
assumption that CDATAs can't have children so we don't need to go into
the `else node.Normalize()` branch on line 3485 with them, hope this is
correct.
Testing: covered by `dom/nodes/Node-normalize.html`
Fixes: https://github.com/servo/servo/issues/37006
---------
Signed-off-by: Rodion Borovyk <rodion.borovyk@gmail.com>
Created a new method `HTMLElement::is_body_element` that replaces
`HTMLBodyElement::is_the_html_body_element`.
Testing: Existing WPT tests should pass.
Fixes: https://github.com/servo/servo/issues/37429
---------
Signed-off-by: iamlockon <xdddxyyyxzzz123@gmail.com>
This change has two parts which depend on each other:
1. An early exit in the layout process, which allows for skipping
display list construction entirely when nothing would change.
2. A simplification and unification of the way that "fake" animation
frames are triggered. Now this happens on an entire ScriptThread at
once and is based on whether or not any Pipeline triggered a display
list update.
Animations are never canceled in the compositor when the Pipeline
isn't updating, instead the fake animation frame is triggered far
enough in the future that an unexpected compositor tick will cancel
it. This could happen, for instance, if some other Pipeline in some
other ScriptThread produced a new display list for a tick. This makes
everything simpler about these ticks.
The goal is that in a future change the ScriptThread-based animation
ticks will be made more generic so that they can throttle the number of
"update the rendering" calls triggered by script.
This should make Servo do a lot less work when moving the cursor over a
page. Before it would constantly produce new display lists.
Fixes: #17029.
Testing: This should not cause any web observable changes. The fact that
all WPT tests keep passing is the test for this change.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
The default of `enum-variant-name-threshold` is 3, so adding any new
variants will lead to the lint being triggered, reference:
[enum_variant_names](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names).
This PR fix this potential clippy lint warning for facilitate the
addition of new variant in following PR about incremental box tree
update.
Testing: No logic changed, just covered by existing WPT tests
Fixes: None
Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
This is pretty much just wiring up the necessary stylo methods. Note
that the `exportparts` attribute is not yet supported, I'll do that in a
followup change
Testing: Covered by existing web platform tests.
This is the first half of https://github.com/servo/servo/issues/35349
Fixes https://github.com/servo/servo/issues/37325
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This reverts commit 5580704438.
Let's re-land that fix when a working solution is found. Keeping that
regression makes it hard to evaluate other potential improvements.
Signed-off-by: webbeef <me@webbeef.org>
XPath's `lang()` and `id()` functions were still unimplemented.
Also:
* Add WPT tests for `id()`.
* Fix uniqueness check in `NodesetHelpers::document_order_unique`.
* Tweak the AST a bit to make it clearer to express "no predicates".
* Fix a parsing bug where "/" was attempted before "//", leaving the
"//" branch as always unused.
---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix#34593
- [x] There are tests for these changes
---------
Signed-off-by: Ville Lindholm <ville@lindholm.dev>
Upgrade `ScriptThread::node_ids` to `pipeline_to_node_ids` to track the
owner pipeline of the node
This will enable webdriver to know if it is requesting element from
other origins and properly distinguish "stale element reference" from
"no such element".
Testing: [Action
run](https://github.com/yezhizhen/servo/actions/runs/15385994907), no
regression. We can now pass WebDriver "cross origin" tests.
Fixes: #35749
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Implement Shadow Tree construction for input `type=text`, adding a text
control inner editor container and placeholder container. Subsequently,
due to the changes of the DOM tree structure, the changes will add a new
NodeFlag `IS_TEXT_CONTROL_INNER_EDITOR` to handle the following cases.
- If a mouse click button event hits a text control inner editor, it
will redirect the focus target to its shadow host.
- In text run's construction, the text control inner editor container
queries the selection from its shadow host. This is later used to
resolve caret and selection painting in the display list.
This will be the first step of fixing input `type=text` and other
single-line text input element widgets. Such as, implementing
`::placeholder` selector.
Testing: Existing WPT test and new Servo specific appearance WPT.
Fixes: #36307
---------
Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
The original implementation of `HTMLOptionElement::Text` is recursive,
and the program may run out of stack space for a sufficiently large
number of iterations. The patch switches to an iterative implementation,
with `TreeIterator`.
Note that, instead of the usual `while let Some(node) = iterator.next()`
approach, we use `while let Some(node) = iterator.peek()` with the newly
added `TreeIterator::peek` function. This is because the choice of the
next node depends on some checks performed inside the `while` block,
whereas the `next` function determines the next node before entering the
block.
Moreover, the `TreeIterator::peek` function is added, instead of
wrapping the iterator into `Peekable`. This is because we will lose
access to the `TreeIterator::next_skipping_children` function if we wrap
it into `Peekable`.
Testing: This refactoring has to pass the existing tests.
Fixes: #36959
Signed-off-by: Kingsley Yung <kingsley@kkoyung.dev>
This change adds support for rendering static SVG images using the
`resvg` crate, allowing svg sources in the `img` tag and in CSS
`background` and `content` properties. There are some limitations in
using resvg:
1. There is no support for animations or interactivity as these would
require implementing the full DOM layer of SVG specification.
2. Only system fonts can be used for text rendering. There is some
mechanism to provide a custom font resolver to usvg, but that is not
explored in this change.
3. resvg's handling of certain edge cases involving lack of explicit
`width` and `height` on the root svg element deviates from what the
specification expects from browsers. For example, resvg uses the values
in `viewBox` to derive the missing width or height dimension, but
without scaling that dimension to preserve the aspect ratio. It also
doesn't allow overriding this behavior.
Demo screenshot:

<details>
<summary>Source</summary>
```
<style>
#svg1 {
border: 1px solid red;
}
#svg2 {
border: 1px solid red;
width: 300px;
}
#svg3 {
border: 1px solid red;
width: 300px;
height: 200px;
object-fit: contain;
}
#svg4 {
border: 1px solid red;
width: 300px;
height: 200px;
object-fit: cover;
}
#svg5 {
border: 1px solid red;
width: 300px;
height: 200px;
object-fit: fill;
}
#svg6 {
border: 1px solid red;
width: 300px;
height: 200px;
object-fit: none;
}
</style>
</head>
<body>
<div>
<img id="svg1" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
</div>
<div>
<img id="svg2" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
<img id="svg3" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
<img id="svg4" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
</div>
<div>
<img id="svg5" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
<img id="svg6" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
</div>
</body>
```
</details>
---------
Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This change adds a shadow-tree widget for `<input type=color>` elements.
It also involves some changes to the way layout interacts with the DOM,
because currently all `input` and `textarea` elements are rendered as
plain text and their descendants are ignored. This obviously doesn't
work for `<input type={color, date, range, etc}>`.

<details><summary>HTML used for the screenshot above</summary>
```html
<input type=color>
```
</details>
Testing: I doubt that this affects WPT tests, because the appearance and
behaviour of the widget is almost entirely unspecified.
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Add mock SVGImageElement interface to fix TIMEOUT WPT tests
which are related to ImageBitmap (html/canvas/*).
https://svgwg.org/svg2-draft/embedded.html#InterfaceSVGImageElement
Rationality of this change to fire event "error" on any attempt to fetch
image resource on href attribute change to not block WPT tests
execution.
Some WPT tests use the legacy namespace attribute "xlink:href", so
support for it was added to source code.
https://svgwg.org/svg2-draft/linking.html#XLinkHrefAttribute
- setAttributeNS("http://www.w3.org/1999/xlink", 'xlink:href', src);
Testing: Covered by existed WPT tests
- fetch/metadata/generated/svg-image*
- html/canvas/element/manual/*
- html/dom/idlharness.https.html
- html/semantics/embedded-content/the-canvas-element/*
- html/webappapis/scripting/events/event-handler-all-global-events.html
- mozilla/interfaces.https.html
Fixes: https://github.com/servo/servo/issues/35881
Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
`ensure_rare_data` returns a RefMut that extends the borrow of
Node.rare_data. This can lead to a panic in any method that triggers a
GC while this borrow is outstanding, such as Node.childNodes.
Testing: Manual testing on the testcase from the issue. It is impossible
to create a deterministic WPT crash test that is fast enough and can be
counted upon to continue working in the future.
Fixes: #36868
Signed-off-by: Josh Matthews <josh@joshmatthews.net>