Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d324173
Servo initial downstream commit
delan Feb 7, 2024
a5eabbd
Commit our changes on top of upstream Stylo
delan Feb 15, 2024
b9eb42d
Fixup for https://phabricator.services.mozilla.com/D281332
Loirooriol Mar 5, 2026
025b43a
Fixup for https://phabricator.services.mozilla.com/D280938
Loirooriol Mar 5, 2026
cfae27b
Fixup for https://phabricator.services.mozilla.com/D280243
Loirooriol Mar 5, 2026
4724d93
Fixup for https://phabricator.services.mozilla.com/D282398
Loirooriol Mar 5, 2026
a79e275
Fixup for https://phabricator.services.mozilla.com/D284054
Loirooriol Mar 5, 2026
9202ae5
Fixup for https://phabricator.services.mozilla.com/D284378
Loirooriol Mar 5, 2026
58f6965
Fixup for https://phabricator.services.mozilla.com/D284172
Loirooriol Mar 5, 2026
4ddfe54
Fixup for https://phabricator.services.mozilla.com/D284297
Loirooriol Mar 5, 2026
ecf17b5
Bump versions
Loirooriol Mar 5, 2026
f34b80b
Add beforeinput as atom (#326)
TimvdLippe Mar 8, 2026
1d21770
Add logic for registering custom properties from script (#325)
Loirooriol Mar 8, 2026
07364a6
Make `::placeholder` public and add property restriction for `::place…
stevennovaryo Mar 8, 2026
51593b0
Remove parse condition `step_position_jump_enabled` (#323)
yezhizhen Mar 9, 2026
2373b81
Restore Servo's original form control theme colors (#327)
mrobinson Mar 10, 2026
f00c109
Share `Device` logic among Gecko and Servo (#330)
Loirooriol Mar 10, 2026
2a6d7c0
Unify `ListStyleType` among Gecko and Servo (#329)
Loirooriol Mar 11, 2026
dca3934
Enabling parsing `first-letter` pseudo element for servo (#320)
minghuaw Mar 11, 2026
d38712e
Replace Travis CI badge with GitHub workflow (#332)
atouchet Mar 16, 2026
d91c7cf
Remove the Servo non-incremental layout feature (#331)
mrobinson Mar 17, 2026
8278e5a
Bump the workspace version (#334)
jschwe Mar 18, 2026
635e1a1
Bump selectors for readme update. (#335)
jschwe Mar 18, 2026
f9d9406
Adopt "tables inherit color from body quirk" from Gecko (#333)
Loirooriol Mar 19, 2026
2052fb5
Remove declaration of gecko's `media_queries` module (#337)
simonwuelker Mar 19, 2026
a4f1d69
Don't skip animations without keyframes (#336)
simonwuelker Mar 20, 2026
4ecadfc
overhaul
yezhizhen Mar 23, 2026
ecb0a95
raw
yezhizhen Mar 23, 2026
6d1e8dd
use debug_assert
yezhizhen Mar 24, 2026
1a41cbe
Simon's comment
yezhizhen Mar 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: CI

on:
push:
branches: ["main"]
pull_request:
workflow_dispatch:
merge_group:
types: [checks_requested]


jobs:
linux-debug:
name: Linux (Debug)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Run Tests
run: cargo build --features servo
env:
RUST_BACKTRACE: 1

linux-release:
name: Linux (Release)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Run Tests
run: cargo build --release --features servo
env:
RUST_BACKTRACE: 1

macos-debug:
name: macOS (Debug)
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Run Tests
run: cargo build --features servo
env:
RUST_BACKTRACE: 1

windows-debug:
name: Windows (Debug)
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Run Tests
run: cargo build --features servo
env:
RUST_BACKTRACE: 1

build-result:
name: Result
runs-on: ubuntu-latest
if: ${{ always() }}
needs:
- linux-debug
- linux-release
steps:
- name: Success
if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}
run: exit 0
- name: Failure
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: exit 1

26 changes: 26 additions & 0 deletions .github/workflows/mirror-to-release-branch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: 🪞 Mirror `main`
on:
push:
branches:
- main

jobs:
mirror:
name: Mirror
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get branch name
id: branch-name
run: |
first_commit=$(git log --pretty=\%H --grep='Servo initial downstream commit')
upstream_base="$first_commit~"
echo BRANCH_NAME=$(git log -n1 --pretty='%as' $upstream_base) >> $GITHUB_OUTPUT
- uses: google/mirror-branch-action@v1.0
name: Mirror to ${{ steps.branch-name.outputs.BRANCH_NAME }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
source: main
dest: ${{ steps.branch-name.outputs.BRANCH_NAME }}
23 changes: 23 additions & 0 deletions .github/workflows/sync-upstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Sync upstream with mozilla-central

on:
schedule:
- cron: '0 13 * * *'
workflow_dispatch:

jobs:
sync:
name: Sync
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- uses: actions/cache@v3
with:
path: _cache/upstream
key: upstream
- run: |
./sync.sh _filtered
git fetch -f --progress ./_filtered main:upstream
git push -fu --progress origin upstream
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/_cache/
/_filtered/
/target/
/style/properties/__pycache__/
Cargo.lock
36 changes: 36 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[workspace]
resolver = "2"
members = [
"stylo_atoms",
"stylo_dom",
"malloc_size_of",
"rustfmt.toml",
"selectors",
"servo_arc",
"style",
"style_derive",
"stylo_static_prefs",
"style_traits",
"to_shmem",
"to_shmem_derive",
]
default-members = ["style"]

[workspace.package]
version = "0.14.0"

[workspace.dependencies]
# in-repo dependencies (separately versioned)
servo_arc = { version = "0.4.3", path = "./servo_arc" }
selectors = { version = "0.36.1", path = "./selectors" }
to_shmem = { version = "0.3.0", path = "./to_shmem", features = ["servo"] }
to_shmem_derive = { version = "0.1.0", path = "./to_shmem_derive" }

# in-repo dependencies (main version)
malloc_size_of = { version = "0.14.0", path = "./malloc_size_of", package = "stylo_malloc_size_of", features = ["servo"] }
static_prefs = { version = "0.14.0", path = "./stylo_static_prefs", package = "stylo_static_prefs" }
stylo_atoms = { version = "0.14.0", path = "./stylo_atoms" }
dom = { version = "0.14.0", path = "./stylo_dom", package = "stylo_dom" }
style_traits = { version = "0.14.0", path = "./style_traits", features = ["servo"], package = "stylo_traits"}
style_derive = { version = "0.14.0", path = "./style_derive", package = "stylo_derive"}
stylo = { version = "0.14.0", path = "./style" }
105 changes: 105 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
Stylo
=====

**High-Performance CSS Style Engine**

[![Build Status](https://github.com/servo/stylo/actions/workflows/main.yml/badge.svg)](https://github.com/servo/stylo/actions)
[![Crates.io](https://img.shields.io/crates/v/stylo.svg)](https://crates.io/crates/stylo)
[![Docs](https://docs.rs/stylo/badge.svg)](https://docs.rs/stylo)
![Crates.io License](https://img.shields.io/crates/l/stylo)

Stylo is a high-performance, browser-grade CSS style engine written in Rust that powers [Servo](https://servo.org) and [Firefox](https://firefox.com). This repo contains Servo’s downstream version of Stylo. The upstream version lives in mozilla-central with the rest of the Gecko/Firefox codebase.

Coordination of Stylo development happens:

- Here in Github Issues
- In the [#stylo](https://servo.zulipchat.com/#narrow/channel/417109-stylo) channel of the [Servo Zulip](https://servo.zulipchat.com/)
- In the [#layout](https://chat.mozilla.org/#/room/#layout:mozilla.org) room of the Mozilla Matrix instance (matrix.mozilla.org)

## High-Level Documentation

- This [Mozilla Hacks article](https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-engine-quantum-css-aka-stylo) contains a high-level overview of the Stylo architecture.
- There is a [chapter](https://book.servo.org/architecture/style.html) in the Servo Book (although it is a little out of date).

## Branches

The branches are as follows:

- [**upstream**](https://github.com/servo/style/tree/upstream) has upstream [mozilla-central](https://searchfox.org/mozilla-central/source/servo) filtered to the paths we care about ([style.paths](style.paths)), but is otherwise unmodified.
- [**main**](https://github.com/servo/style/tree/ci) adds our downstream patches, plus the scripts and workflows for syncing with mozilla-central on top of **upstream**.

> [!WARNING]
> This repo syncs from upstream by creating a new branch and then rebasing our changes on top of it. This means that `git pull` will not work across syncs (you will need to use `git fetch`, `git reset` and `git rebase`).

More information on the syncing process is available in [SYNCING.md](SYNCING.md)

## Crates

A guide to the crates contained within this repo

### Stylo Crates

These crates are largely implementation details of Stylo, although you may need to use some of them directly if you use Stylo.

| Directory | Crate | Notes |
| --- | --- | --- |
| style | [![Crates.io](https://img.shields.io/crates/v/stylo.svg)](https://crates.io/crates/stylo) | The main Stylo crate containing the entire CSS engine |
| style_traits | [![Crates.io](https://img.shields.io/crates/v/stylo_traits.svg)](https://crates.io/crates/stylo_traits) | Types and traits which allow other code to interoperate with Stylo without depending on the main crate directly. |
| stylo_dom | [![Crates.io](https://img.shields.io/crates/v/stylo_dom.svg)](https://crates.io/crates/stylo_dom) | Similar to stylo_traits (but much smaller) |
| stylo_atoms | [![Crates.io](https://img.shields.io/crates/v/stylo_atoms.svg)](https://crates.io/crates/stylo_atoms) | [Atoms](https://docs.rs/string_cache/latest/string_cache/struct.Atom.html) for CSS and HTML event related strings |
| stylo_static_prefs | [![Crates.io](https://img.shields.io/crates/v/stylo_static_prefs.svg)](https://crates.io/crates/stylo_static_prefs) | Configuration for Stylo. Can be used to set runtime preferences (enabling/disabling properties, etc) |
| style_derive | [![Crates.io](https://img.shields.io/crates/v/stylo_derive.svg)](https://crates.io/crates/stylo_derive) | Internal derive macro for stylo crate |

### Standalone Crates

These crates form part of Stylo but are also be useful standalone.

| Directory | Crate | Notes |
| --- | --- | --- |
| selectors | [![Crates.io](https://img.shields.io/crates/v/selectors.svg)](https://crates.io/crates/selectors) | CSS Selector matching |
| servo_arc | [![Crates.io](https://img.shields.io/crates/v/servo_arc.svg)](https://crates.io/crates/servo_arc) | A variant on `std::Arc` |

You may also be interested in the `cssparser` crate which lives in the [servo/rust-cssparser](https://github.com/servo/rust-cssparser) repo.

### Support Crates

Low-level crates which could technically be used standalone but are unlikely to be generally useful in practice.

| Directory | Crate | Notes |
| --- | --- | --- |
| malloc_size_of | [![Crates.io](https://img.shields.io/crates/v/stylo_malloc_size_of.svg)](https://crates.io/crates/stylo_malloc_size_of) | Heap size measurement for Stylo values |
| to_shmem | [![Crates.io](https://img.shields.io/crates/v/to_shmem.svg)](https://crates.io/crates/to_shmem) | Internal utility crate for sharing memory across processes. |
| to_shmem_derive | [![Crates.io](https://img.shields.io/crates/v/to_shmem_derive.svg)](https://crates.io/crates/to_shmem_derive) | Internal derive macro for to_shmem crate |

## Building Servo Against a Local Copy of Stylo

Assuming your local `servo` and `stylo` directories are siblings, you can build `servo` against `stylo` by adding the following to `servo/Cargo.toml`:

```toml
[patch."https://github.com/servo/stylo"]
selectors = { path = "../stylo/selectors" }
servo_arc = { path = "../stylo/servo_arc" }
stylo = { path = "../stylo/style" }
stylo_atoms = { path = "../stylo/stylo_atoms" }
stylo_dom = { path = "../stylo/stylo_dom" }
stylo_malloc_size_of = { path = "../stylo/malloc_size_of" }
stylo_static_prefs = { path = "../stylo/stylo_static_prefs" }
stylo_traits = { path = "../stylo/style_traits" }
```

## Releases

Releases are made every time this repository rebases its changes on top of the latest version of upstream Stylo. There are a lot of crates here. In order to publish them, they must be done in order. One order that works is:

- selectors
- stylo_static_prefs
- stylo_atoms
- stylo_malloc_size_of
- stylo_dom
- stylo_derive
- stylo_traits
- stylo

## License

Stylo is licensed under MPL 2.0
63 changes: 63 additions & 0 deletions SYNCING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Syncing

This file documents the process of syncing this repository with the upstream copy of Stylo in mozilla-central.

## Syncing `upstream` with mozilla-central

Start by generating a filtered copy of mozilla-central. This will cache the raw mozilla-central in `_cache/upstream`, storing the result in `_filtered`:

```sh
$ ./sync.sh _filtered
```

If `_filtered` already exists, you will need to delete it and try again:

```sh
$ rm -Rf _filtered
```

Now overwrite our `upstream` with those commits and push:

```sh
$ git fetch -f --progress ./_filtered main:upstream
$ git push -fu --progress origin upstream
```

## Rebasing `main` onto `upstream`

Start by fetching `upstream` into your local repo:

```sh
$ git fetch -f origin upstream:upstream
```

In general, the filtering process is deterministic, yielding the same commit hashes each time, so we can rebase normally:

```sh
$ git rebase upstream
```

But if the filtering config changes or Mozilla moves to GitHub, the commit hashes on `upstream` may change. In this case, we need to tell git where the old upstream ends and our own commits start (notice the `~`):

```sh
$ git log --pretty=\%H --grep='Servo initial downstream commit'
e62d7f0090941496e392e1dc91df103a38e3f488

$ git rebase --onto upstream e62d7f0090941496e392e1dc91df103a38e3f488~
Successfully rebased and updated refs/heads/main.
```

`start-rebase.sh` takes care of this automatically, but you should still use `git rebase` for subsequent steps like `--continue` and `--abort`:

```sh
$ ./start-rebase.sh upstream
$ ./start-rebase.sh upstream -i # interactive
$ git rebase --continue # not ./start-rebase.sh --continue
$ git rebase --abort # not ./start-rebase.sh --abort
```

Or if we aren’t ready to rebase onto the tip of upstream:

```sh
$ ./start-rebase.sh upstream~10 -i
```
15 changes: 15 additions & 0 deletions commit-from-merge.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh
# Usage: commit-from-merge.sh <path/to/servo/servo> <merge commit> [extra git-commit(1) arguments ...]
# Given a merge commit made by bors, runs git-commit(1) with your local changes
# while borrowing the author name/email from the right-hand parent of the merge,
# and the author date from the committer date of the merge.
set -eu

lookup_repo=$1; shift
merge_commit=$1; shift
author_name_email=$(git -C "$lookup_repo" log -n1 --pretty='%aN <%aE>' "$merge_commit"\^2)
committer_date=$(git -C "$lookup_repo" log -n1 --pretty='%cd' "$merge_commit")

set -- git commit --author="$author_name_email" --date="$committer_date" "$@"
echo "$@"
"$@"
14 changes: 14 additions & 0 deletions commit-from-squashed.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh
# Usage: commit-from-squashed.sh <squashed commit> [extra git-commit(1) arguments ...]
# Given a squashed commit made by the GitHub merge queue, runs git-commit(1) with your local changes
# while borrowing our author name/email from that commit, our author date from its committer date,
# and our commit message from that commit.
set -eu

squashed_commit=$1; shift
committer_date=$(git log -n1 --pretty='%cd' "$squashed_commit")

# -c is equivalent to --author=$(...'%aN <%aE>') -m $(...'%B'), but allows editing
set -- git commit -c "$squashed_commit" --date="$committer_date" "$@"
echo "$@"
"$@"
14 changes: 7 additions & 7 deletions malloc_size_of/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "malloc_size_of"
version = "0.0.1"
name = "stylo_malloc_size_of"
version.workspace = true
authors = ["The Servo Project Developers"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/servo/stylo"
Expand All @@ -18,10 +18,10 @@ servo = ["string_cache"]
app_units = "0.7"
cssparser = "0.36"
euclid = "0.22"
selectors = { path = "../selectors" }
servo_arc = { path = "../servo_arc" }
selectors = { workspace = true }
servo_arc = { workspace = true }
smallbitvec = "2.3.0"
smallvec = "1.0"
string_cache = { version = "0.8", optional = true }
thin-vec = { version = "0.2.1" }
smallvec = "1.13"
string_cache = { version = "0.9", optional = true }
thin-vec = { version = "0.2.13" }
void = "1.0.2"
Loading
Loading