Skip to content

Enable box-decoration-break for Servo - #386

Merged
Loirooriol merged 1 commit into
servo:mainfrom
Psychpsyo:main
Jul 10, 2026
Merged

Enable box-decoration-break for Servo#386
Loirooriol merged 1 commit into
servo:mainfrom
Psychpsyo:main

Conversation

@Psychpsyo

@Psychpsyo Psychpsyo commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Corresponding servo PR is at servo/servo#45492

@Loirooriol

Copy link
Copy Markdown
Collaborator

I force-pushed main for an upgrade, can you rebase your commit to the new main?

@Psychpsyo

Copy link
Copy Markdown
Contributor Author

I force-pushed main for an upgrade, can you rebase your commit to the new main?

Done.

Signed-off-by: Psychpsyo (Cameron) <60073468+Psychpsyo@users.noreply.github.com>
@Loirooriol
Loirooriol added this pull request to the merge queue Jul 10, 2026
Merged via the queue into servo:main with commit f591fc2 Jul 10, 2026
5 checks passed
fulformc pushed a commit to rhventures/servo that referenced this pull request Jul 10, 2026
This adds initial handling for the `box-decoration-break` CSS property.
The implementation thus far only does line breaks, but in the future
this will need to insert paddings/borders/margins when bidi-reordering
causes a box to be split as well.

Corresponding stylo PR is at servo/stylo#386

Testing: We now pass some css-break tests. I've also added some new
tests for related behavior.

---------

Signed-off-by: Psychpsyo (Cameron) <60073468+Psychpsyo@users.noreply.github.com>
PupilTong added a commit to PupilTong/stylo that referenced this pull request Jul 16, 2026
* Enable `scroll-behavior` and `overscroll-behavior` properties (servo#420)

A couple more keyword/bitflag properties that I'm implementing in Blitz,
and would like to enable behind the `layout.unimplemented` pref.

Signed-off-by: Nico Burns <nico@nicoburns.com>

* style: Implement iterator over all known non-custom properties (servo#406)

Servo PR: servo/servo#46118

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Enable box-decoration-break for Servo (servo#386)

Corresponding servo PR is at servo/servo#45492

Signed-off-by: Psychpsyo (Cameron) <60073468+Psychpsyo@users.noreply.github.com>

* Enable basic SVG-related CSS properties for Servo (servo#383)

Removes `engine = "gecko"` from 11 SVG-specific CSS properties to be
enabled for servo:

- **Fill (3):** `fill`, `fill-opacity`, `fill-rule`
- **Stroke (8):** `stroke`, `stroke-width`, `stroke-linecap`,
`stroke-linejoin`, `stroke-dasharray`, `stroke-dashoffset`,
`stroke-miterlimit`, `stroke-opacity`

Also updates the `ComputedValues` size test (224 → 232) for the new
fields.

Servo [PR](servo/servo#45405)

---------

Signed-off-by: Mohamed Mostafa mu-mostafa98@gmail.com
Co-authored-by: Mohamed Mostafa <mu-mostafa98@gmail.com>

* Stop requiring CI jobs to pass on Mac (servo#424)

This is a partial revert of servo#340. Waiting for an available macOS runner
frequently takes very long, which makes it annoying when trying to land
multiple patches, since they need to also be coordinated with the
companion patches in Servo.

So I think it's better to not wait for the macOS job after all. We will
still wait for the Linux and Windows ones.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>

* Share Stylo's Servo-specific derives with Gecko (servo#423)

Already landed upstream:
https://phabricator.services.mozilla.com/D311004
(71a8a43)

Importing it here early to prevent other PRs from adding new
Servo-specific derives due to copy-pasting.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>

* lynx: add the `lynx` cargo feature gating stylo to Lynx's CSS support (#2)

Introduce a `lynx` feature (implies `servo`) that turns stylo into LynxJS's
CSS engine. It does four things:

* Gates the Lynx-only additions — the rpx unit, display:linear|relative, and
  the linear-*/relative-* longhands — behind `#[cfg(feature = "lynx")]` (and
  tags their longhands.toml entries `lynx_only`), so the default `servo` build
  stays at upstream parity.

* Disables the CSS properties and keyword values Lynx does not support. The
  build script forwards the feature to the property generator (build.rs ->
  build.py -> data.PropertiesData(lynx=...)); every content property absent
  from the LYNX_SUPPORTED allowlist (derived from
  https://lynxjs.org/next/api/css/properties.md) has enabled_in_content()
  forced false, so it stops parsing from author CSS while keeping its
  LonghandId/ShorthandId (stylo still compiles). Disabled properties stay
  disabled even if their experimental servo pref is flipped on: the
  enabled_for_all_content EXPERIMENTAL set excludes lynx-disabled ids. A codegen
  assertion fails the build if a LYNX_SUPPORTED name never matched a declared
  property (typo / gecko-only guard). A curated set of value grammars is trimmed
  with `#[cfg(not(feature = "lynx"))]`: display (none|block|flex|grid plus the
  Lynx-only linear|relative), overflow{,-x,-y} (visible|hidden|scroll), and
  white-space (normal|nowrap only — the pre* keywords AND the component-longhand
  fallback are gated). Value sets verified against
  core/renderer/css/parser/enum_handler.cc.

* Enables the properties Lynx supports that stock stylo keeps behind its own
  experimental servo prefs — grid, mask, offset-path, text-overflow (gated by
  `layout.grid.enabled` / `layout.unimplemented`). Under `lynx` they are forced
  into enabled_for_all_content's ALWAYS_ENABLED set, since lynx-vello (not servo)
  supplies their layout/paint. Done via the property-id set rather than by
  clearing servo_pref, so shorthand serialization (LonghandsToSerialize
  Option-ness) is untouched. `display: grid` matches by having grid_enabled()
  return true under `lynx` rather than gate on the pref. Mask's non-exposed
  sub-longhands (mask-repeat, mask-position, ...) stay disabled — reachable only
  through the `mask` shorthand.

* Ports the Lynx-supported properties that stock stylo ships gecko-only into
  the servo build (behind `layout.unimplemented`, force-enabled under `lynx`
  like the pref-gated set above): offset-distance / offset-rotate, and the
  -webkit-text-stroke* family — the latter exposing the unprefixed text-stroke
  / text-stroke-color / text-stroke-width spellings Lynx uses as aliases (its
  hand-written shorthand parse in shorthands.rs is un-gated from gecko-only).

Add feature-gated lynx_supported_properties / lynx_disabled_properties /
lynx_value_gating test suites and a "Linux (Lynx feature)" CI job (glob target
selection `--test 'lynx_*'` so new suites are picked up automatically).

Parity note for future rebases: the gecko->servo ports are unconditional toml
edits, so even the plain `servo` build's generated property set (and
NonCustomPropertyId space) now differs from upstream — behavior parity holds
(the pref stays off by default), but it is parity-in-behavior, not
parity-in-codegen; the same edits also add the unprefixed text-stroke* aliases
to gecko builds.

Deferred (documented in tests): position:static rejection + relative default (a
W3C-vs-Lynx-default decision on a bucket-1 feature), and text-align's -webkit-*
aliases / match-parent.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* lynx: StylesheetContents::from_rules + two-word style-sharing candidate handle (#3)

* lynx: add StylesheetContents::from_rules for dynamically built rule lists

The embedder ingests Lynx's pre-parsed .web.bundle StyleInfo by
constructing stylo rule objects directly (no CSS-text round trip).
from_shared_data requires a static/shmem rules Arc (UA-sheet path);
from_rules is its ordinary-refcount counterpart for dynamically loaded
author sheets.

* lynx: size the style-sharing TLS cache for two-word element handles

Gecko's and Servo's TElement handles are one word, and FakeCandidate
hard-codes that when sizing the typeless thread-local sharing cache.
The lynx embedder's handle is an arena reference plus a generational id
(two words), which tripped the size_of assertion in
StyleSharingCache::new. Make the stand-in handle type feature-dependent.

* lynx: keep sub-longhands of supported shorthands enabled (+ outline family) (#4)

* lynx: keep sub-longhands of supported shorthands enabled

Listing a shorthand in LYNX_SUPPORTED without its servo sub-longhands made
it parse-only: shorthand parsing writes every sub-longhand unconditionally,
but ShorthandId::longhands() (CSSOM-style serialization) and gated
PropertyId::parse (per-longhand wire ingestion) both skip lynx-disabled
longhands. background-position and text-decoration serialized to empty
strings, and standalone longhand ids real .web.bundles carry (e.g.
TextDecorationColor = 148) were silently dropped at ingestion.

Enable the sub-longhands of every supported shorthand after declaration
(transitively harmless; `all` excluded — it would undo the gating
wholesale), and add the missing outline/outline-color/outline-style/
outline-width family, which lynxjs.org documents.

Found by the CSS behavior test port (lynx-vello stylo-dom test suite).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* lynx: align the disabled-properties test with shorthand sub-longhand propagation

The outline family is now deliberately supported (lynxjs.org documents
it), and background-attachment / mask-repeat are sub-longhands of the
supported background / mask shorthands, which data.py keeps enabled.
Drop them from the disabled list and add a positive companion test
pinning the propagation rule (including the wire-carried
text-decoration-color id and the background-position split longhands).
mask-position stays disabled: it is itself a shorthand not in the Lynx
list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* lynx: remove obsolete two-word element handle

* lynx: define the supported CSS grammar

* lynx: restore standard containment and sizing behavior

* lynx: preserve feature-off cascade parity

* lynx: refine color animation and property gating

---------

Signed-off-by: Nico Burns <nico@nicoburns.com>
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Signed-off-by: Psychpsyo (Cameron) <60073468+Psychpsyo@users.noreply.github.com>
Signed-off-by: Mohamed Mostafa mu-mostafa98@gmail.com
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Nico Burns <nico@nicoburns.com>
Co-authored-by: Simon Wülker <simon.wuelker@arcor.de>
Co-authored-by: Psychpsyo (Cameron) <60073468+Psychpsyo@users.noreply.github.com>
Co-authored-by: Mohamed Mostafa <mu.mostafa98@gmail.com>
Co-authored-by: Mohamed Mostafa <mu-mostafa98@gmail.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
PupilTong added a commit to PupilTong/stylo that referenced this pull request Aug 20, 2026
* Enable `scroll-behavior` and `overscroll-behavior` properties (servo#420)

A couple more keyword/bitflag properties that I'm implementing in Blitz,
and would like to enable behind the `layout.unimplemented` pref.

Signed-off-by: Nico Burns <nico@nicoburns.com>

* style: Implement iterator over all known non-custom properties (servo#406)

Servo PR: servo/servo#46118

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Enable box-decoration-break for Servo (servo#386)

Corresponding servo PR is at servo/servo#45492

Signed-off-by: Psychpsyo (Cameron) <60073468+Psychpsyo@users.noreply.github.com>

* Enable basic SVG-related CSS properties for Servo (servo#383)

Removes `engine = "gecko"` from 11 SVG-specific CSS properties to be
enabled for servo:

- **Fill (3):** `fill`, `fill-opacity`, `fill-rule`
- **Stroke (8):** `stroke`, `stroke-width`, `stroke-linecap`,
`stroke-linejoin`, `stroke-dasharray`, `stroke-dashoffset`,
`stroke-miterlimit`, `stroke-opacity`

Also updates the `ComputedValues` size test (224 → 232) for the new
fields.

Servo [PR](servo/servo#45405)

---------

Signed-off-by: Mohamed Mostafa mu-mostafa98@gmail.com
Co-authored-by: Mohamed Mostafa <mu-mostafa98@gmail.com>

* Stop requiring CI jobs to pass on Mac (servo#424)

This is a partial revert of servo#340. Waiting for an available macOS runner
frequently takes very long, which makes it annoying when trying to land
multiple patches, since they need to also be coordinated with the
companion patches in Servo.

So I think it's better to not wait for the macOS job after all. We will
still wait for the Linux and Windows ones.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>

* Share Stylo's Servo-specific derives with Gecko (servo#423)

Already landed upstream:
https://phabricator.services.mozilla.com/D311004
(71a8a43)

Importing it here early to prevent other PRs from adding new
Servo-specific derives due to copy-pasting.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>

* lynx: add the `lynx` cargo feature gating stylo to Lynx's CSS support (#2)

Introduce a `lynx` feature (implies `servo`) that turns stylo into LynxJS's
CSS engine. It does four things:

* Gates the Lynx-only additions — the rpx unit, display:linear|relative, and
  the linear-*/relative-* longhands — behind `#[cfg(feature = "lynx")]` (and
  tags their longhands.toml entries `lynx_only`), so the default `servo` build
  stays at upstream parity.

* Disables the CSS properties and keyword values Lynx does not support. The
  build script forwards the feature to the property generator (build.rs ->
  build.py -> data.PropertiesData(lynx=...)); every content property absent
  from the LYNX_SUPPORTED allowlist (derived from
  https://lynxjs.org/next/api/css/properties.md) has enabled_in_content()
  forced false, so it stops parsing from author CSS while keeping its
  LonghandId/ShorthandId (stylo still compiles). Disabled properties stay
  disabled even if their experimental servo pref is flipped on: the
  enabled_for_all_content EXPERIMENTAL set excludes lynx-disabled ids. A codegen
  assertion fails the build if a LYNX_SUPPORTED name never matched a declared
  property (typo / gecko-only guard). A curated set of value grammars is trimmed
  with `#[cfg(not(feature = "lynx"))]`: display (none|block|flex|grid plus the
  Lynx-only linear|relative), overflow{,-x,-y} (visible|hidden|scroll), and
  white-space (normal|nowrap only — the pre* keywords AND the component-longhand
  fallback are gated). Value sets verified against
  core/renderer/css/parser/enum_handler.cc.

* Enables the properties Lynx supports that stock stylo keeps behind its own
  experimental servo prefs — grid, mask, offset-path, text-overflow (gated by
  `layout.grid.enabled` / `layout.unimplemented`). Under `lynx` they are forced
  into enabled_for_all_content's ALWAYS_ENABLED set, since lynx-vello (not servo)
  supplies their layout/paint. Done via the property-id set rather than by
  clearing servo_pref, so shorthand serialization (LonghandsToSerialize
  Option-ness) is untouched. `display: grid` matches by having grid_enabled()
  return true under `lynx` rather than gate on the pref. Mask's non-exposed
  sub-longhands (mask-repeat, mask-position, ...) stay disabled — reachable only
  through the `mask` shorthand.

* Ports the Lynx-supported properties that stock stylo ships gecko-only into
  the servo build (behind `layout.unimplemented`, force-enabled under `lynx`
  like the pref-gated set above): offset-distance / offset-rotate, and the
  -webkit-text-stroke* family — the latter exposing the unprefixed text-stroke
  / text-stroke-color / text-stroke-width spellings Lynx uses as aliases (its
  hand-written shorthand parse in shorthands.rs is un-gated from gecko-only).

Add feature-gated lynx_supported_properties / lynx_disabled_properties /
lynx_value_gating test suites and a "Linux (Lynx feature)" CI job (glob target
selection `--test 'lynx_*'` so new suites are picked up automatically).

Parity note for future rebases: the gecko->servo ports are unconditional toml
edits, so even the plain `servo` build's generated property set (and
NonCustomPropertyId space) now differs from upstream — behavior parity holds
(the pref stays off by default), but it is parity-in-behavior, not
parity-in-codegen; the same edits also add the unprefixed text-stroke* aliases
to gecko builds.

Deferred (documented in tests): position:static rejection + relative default (a
W3C-vs-Lynx-default decision on a bucket-1 feature), and text-align's -webkit-*
aliases / match-parent.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* lynx: StylesheetContents::from_rules + two-word style-sharing candidate handle (#3)

* lynx: add StylesheetContents::from_rules for dynamically built rule lists

The embedder ingests Lynx's pre-parsed .web.bundle StyleInfo by
constructing stylo rule objects directly (no CSS-text round trip).
from_shared_data requires a static/shmem rules Arc (UA-sheet path);
from_rules is its ordinary-refcount counterpart for dynamically loaded
author sheets.

* lynx: size the style-sharing TLS cache for two-word element handles

Gecko's and Servo's TElement handles are one word, and FakeCandidate
hard-codes that when sizing the typeless thread-local sharing cache.
The lynx embedder's handle is an arena reference plus a generational id
(two words), which tripped the size_of assertion in
StyleSharingCache::new. Make the stand-in handle type feature-dependent.

* lynx: keep sub-longhands of supported shorthands enabled (+ outline family) (#4)

* lynx: keep sub-longhands of supported shorthands enabled

Listing a shorthand in LYNX_SUPPORTED without its servo sub-longhands made
it parse-only: shorthand parsing writes every sub-longhand unconditionally,
but ShorthandId::longhands() (CSSOM-style serialization) and gated
PropertyId::parse (per-longhand wire ingestion) both skip lynx-disabled
longhands. background-position and text-decoration serialized to empty
strings, and standalone longhand ids real .web.bundles carry (e.g.
TextDecorationColor = 148) were silently dropped at ingestion.

Enable the sub-longhands of every supported shorthand after declaration
(transitively harmless; `all` excluded — it would undo the gating
wholesale), and add the missing outline/outline-color/outline-style/
outline-width family, which lynxjs.org documents.

Found by the CSS behavior test port (lynx-vello stylo-dom test suite).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* lynx: align the disabled-properties test with shorthand sub-longhand propagation

The outline family is now deliberately supported (lynxjs.org documents
it), and background-attachment / mask-repeat are sub-longhands of the
supported background / mask shorthands, which data.py keeps enabled.
Drop them from the disabled list and add a positive companion test
pinning the propagation rule (including the wire-carried
text-decoration-color id and the background-position split longhands).
mask-position stays disabled: it is itself a shorthand not in the Lynx
list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* lynx: remove obsolete two-word element handle

* lynx: define the supported CSS grammar

* lynx: restore standard containment and sizing behavior

* lynx: preserve feature-off cascade parity

* lynx: refine color animation and property gating

---------

Signed-off-by: Nico Burns <nico@nicoburns.com>
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Signed-off-by: Psychpsyo (Cameron) <60073468+Psychpsyo@users.noreply.github.com>
Signed-off-by: Mohamed Mostafa mu-mostafa98@gmail.com
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Nico Burns <nico@nicoburns.com>
Co-authored-by: Simon Wülker <simon.wuelker@arcor.de>
Co-authored-by: Psychpsyo (Cameron) <60073468+Psychpsyo@users.noreply.github.com>
Co-authored-by: Mohamed Mostafa <mu.mostafa98@gmail.com>
Co-authored-by: Mohamed Mostafa <mu-mostafa98@gmail.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
lando-worker Bot pushed a commit to mozilla-firefox/firefox that referenced this pull request Sep 2, 2026
github-actions Bot pushed a commit to DioxusLabs/stylo that referenced this pull request Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants