├── .github └── workflows │ ├── main.yml │ ├── mirror-to-release-branch.yml │ └── sync-upstream.yml ├── .gitignore ├── Cargo.toml ├── README.md ├── SYNCING.md ├── commit-from-merge.sh ├── commit-from-squashed.sh ├── malloc_size_of ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT └── lib.rs ├── rustfmt.toml ├── selectors ├── CHANGES.md ├── Cargo.toml ├── README.md ├── attr.rs ├── bloom.rs ├── build.rs ├── builder.rs ├── context.rs ├── kleene_value.rs ├── lib.rs ├── matching.rs ├── nth_index_cache.rs ├── parser.rs ├── relative_selector │ ├── cache.rs │ ├── filter.rs │ └── mod.rs ├── sink.rs ├── tree.rs └── visitor.rs ├── servo_arc ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT └── lib.rs ├── shell.nix ├── start-rebase.sh ├── style.paths ├── style ├── Cargo.toml ├── README.md ├── animation.rs ├── applicable_declarations.rs ├── attr.rs ├── author_styles.rs ├── bezier.rs ├── bloom.rs ├── build.rs ├── build_gecko.rs ├── color │ ├── color_function.rs │ ├── component.rs │ ├── convert.rs │ ├── mix.rs │ ├── mod.rs │ ├── parsing.rs │ └── to_css.rs ├── context.rs ├── counter_style │ ├── mod.rs │ ├── predefined.rs │ └── update_predefined.py ├── custom_properties.rs ├── custom_properties_map.rs ├── data.rs ├── dom.rs ├── dom_apis.rs ├── driver.rs ├── encoding_support.rs ├── error_reporting.rs ├── font_face.rs ├── font_metrics.rs ├── gecko │ ├── arc_types.rs │ ├── conversions.rs │ ├── data.rs │ ├── media_features.rs │ ├── media_queries.rs │ ├── mod.rs │ ├── non_ts_pseudo_class_list.rs │ ├── pseudo_element.rs │ ├── pseudo_element_definition.mako.rs │ ├── regen_atoms.py │ ├── restyle_damage.rs │ ├── selector_parser.rs │ ├── snapshot.rs │ ├── snapshot_helpers.rs │ ├── traversal.rs │ ├── url.rs │ ├── values.rs │ └── wrapper.rs ├── gecko_bindings │ ├── mod.rs │ └── sugar │ │ ├── mod.rs │ │ ├── ns_com_ptr.rs │ │ ├── ns_compatibility.rs │ │ ├── ns_style_auto_array.rs │ │ ├── origin_flags.rs │ │ ├── ownership.rs │ │ └── refptr.rs ├── gecko_string_cache │ ├── mod.rs │ └── namespace.rs ├── global_style_data.rs ├── invalidation │ ├── element │ │ ├── document_state.rs │ │ ├── element_wrapper.rs │ │ ├── invalidation_map.rs │ │ ├── invalidator.rs │ │ ├── mod.rs │ │ ├── relative_selector.rs │ │ ├── restyle_hints.rs │ │ └── state_and_attributes.rs │ ├── media_queries.rs │ ├── mod.rs │ ├── stylesheets.rs │ └── viewport_units.rs ├── lib.rs ├── logical_geometry.rs ├── macros.rs ├── matching.rs ├── media_queries │ ├── media_list.rs │ ├── media_query.rs │ └── mod.rs ├── parallel.rs ├── parser.rs ├── piecewise_linear.rs ├── properties │ ├── Mako-1.1.2-py2.py3-none-any.whl │ ├── build.py │ ├── cascade.rs │ ├── computed_value_flags.rs │ ├── counted_unknown_properties.py │ ├── data.py │ ├── declaration_block.rs │ ├── gecko.mako.rs │ ├── helpers.mako.rs │ ├── helpers │ │ └── animated_properties.mako.rs │ ├── longhands │ │ ├── background.mako.rs │ │ ├── border.mako.rs │ │ ├── box.mako.rs │ │ ├── column.mako.rs │ │ ├── counters.mako.rs │ │ ├── effects.mako.rs │ │ ├── font.mako.rs │ │ ├── inherited_box.mako.rs │ │ ├── inherited_svg.mako.rs │ │ ├── inherited_table.mako.rs │ │ ├── inherited_text.mako.rs │ │ ├── inherited_ui.mako.rs │ │ ├── list.mako.rs │ │ ├── margin.mako.rs │ │ ├── outline.mako.rs │ │ ├── padding.mako.rs │ │ ├── page.mako.rs │ │ ├── position.mako.rs │ │ ├── svg.mako.rs │ │ ├── table.mako.rs │ │ ├── text.mako.rs │ │ ├── ui.mako.rs │ │ └── xul.mako.rs │ ├── mod.rs │ ├── properties.html.mako │ ├── properties.mako.rs │ └── shorthands │ │ ├── background.mako.rs │ │ ├── border.mako.rs │ │ ├── box.mako.rs │ │ ├── column.mako.rs │ │ ├── counters.mako.rs │ │ ├── effects.mako.rs │ │ ├── font.mako.rs │ │ ├── inherited_box.mako.rs │ │ ├── inherited_svg.mako.rs │ │ ├── inherited_table.mako.rs │ │ ├── inherited_text.mako.rs │ │ ├── inherited_ui.mako.rs │ │ ├── list.mako.rs │ │ ├── margin.mako.rs │ │ ├── outline.mako.rs │ │ ├── padding.mako.rs │ │ ├── page.mako.rs │ │ ├── position.mako.rs │ │ ├── svg.mako.rs │ │ ├── table.mako.rs │ │ ├── text.mako.rs │ │ ├── ui.mako.rs │ │ └── xul.mako.rs ├── properties_and_values │ ├── mod.rs │ ├── registry.rs │ ├── rule.rs │ ├── syntax │ │ ├── ascii.rs │ │ ├── data_type.rs │ │ └── mod.rs │ └── value.rs ├── queries │ ├── condition.rs │ ├── feature.rs │ ├── feature_expression.rs │ ├── mod.rs │ └── values.rs ├── rule_cache.rs ├── rule_collector.rs ├── rule_tree │ ├── core.rs │ ├── level.rs │ ├── map.rs │ ├── mod.rs │ ├── source.rs │ └── unsafe_box.rs ├── scoped_tls.rs ├── selector_map.rs ├── selector_parser.rs ├── servo │ ├── media_queries.rs │ ├── mod.rs │ ├── restyle_damage.rs │ ├── selector_parser.rs │ └── url.rs ├── shared_lock.rs ├── sharing │ ├── checks.rs │ └── mod.rs ├── simple_buckets_map.rs ├── str.rs ├── style_adjuster.rs ├── style_resolver.rs ├── stylesheet_set.rs ├── stylesheets │ ├── container_rule.rs │ ├── counter_style_rule.rs │ ├── document_rule.rs │ ├── font_face_rule.rs │ ├── font_feature_values_rule.rs │ ├── font_palette_values_rule.rs │ ├── import_rule.rs │ ├── keyframes_rule.rs │ ├── layer_rule.rs │ ├── loader.rs │ ├── margin_rule.rs │ ├── media_rule.rs │ ├── mod.rs │ ├── namespace_rule.rs │ ├── nested_declarations_rule.rs │ ├── origin.rs │ ├── page_rule.rs │ ├── position_try_rule.rs │ ├── property_rule.rs │ ├── rule_list.rs │ ├── rule_parser.rs │ ├── rules_iterator.rs │ ├── scope_rule.rs │ ├── starting_style_rule.rs │ ├── style_rule.rs │ ├── stylesheet.rs │ └── supports_rule.rs ├── stylist.rs ├── thread_state.rs ├── traversal.rs ├── traversal_flags.rs ├── use_counters │ └── mod.rs └── values │ ├── animated │ ├── color.rs │ ├── effects.rs │ ├── font.rs │ ├── grid.rs │ ├── lists.rs │ ├── mod.rs │ ├── svg.rs │ └── transform.rs │ ├── computed │ ├── align.rs │ ├── angle.rs │ ├── animation.rs │ ├── background.rs │ ├── basic_shape.rs │ ├── border.rs │ ├── box.rs │ ├── color.rs │ ├── column.rs │ ├── counters.rs │ ├── easing.rs │ ├── effects.rs │ ├── flex.rs │ ├── font.rs │ ├── image.rs │ ├── length.rs │ ├── length_percentage.rs │ ├── list.rs │ ├── mod.rs │ ├── motion.rs │ ├── outline.rs │ ├── page.rs │ ├── percentage.rs │ ├── position.rs │ ├── ratio.rs │ ├── rect.rs │ ├── resolution.rs │ ├── svg.rs │ ├── table.rs │ ├── text.rs │ ├── time.rs │ ├── transform.rs │ ├── ui.rs │ └── url.rs │ ├── distance.rs │ ├── generics │ ├── animation.rs │ ├── background.rs │ ├── basic_shape.rs │ ├── border.rs │ ├── box.rs │ ├── calc.rs │ ├── color.rs │ ├── column.rs │ ├── counters.rs │ ├── easing.rs │ ├── effects.rs │ ├── flex.rs │ ├── font.rs │ ├── grid.rs │ ├── image.rs │ ├── length.rs │ ├── mod.rs │ ├── motion.rs │ ├── page.rs │ ├── position.rs │ ├── ratio.rs │ ├── rect.rs │ ├── size.rs │ ├── svg.rs │ ├── text.rs │ ├── transform.rs │ ├── ui.rs │ └── url.rs │ ├── mod.rs │ ├── resolved │ ├── animation.rs │ ├── color.rs │ ├── counters.rs │ └── mod.rs │ └── specified │ ├── align.rs │ ├── angle.rs │ ├── animation.rs │ ├── background.rs │ ├── basic_shape.rs │ ├── border.rs │ ├── box.rs │ ├── calc.rs │ ├── color.rs │ ├── column.rs │ ├── counters.rs │ ├── easing.rs │ ├── effects.rs │ ├── flex.rs │ ├── font.rs │ ├── grid.rs │ ├── image.rs │ ├── intersection_observer.rs │ ├── length.rs │ ├── list.rs │ ├── mod.rs │ ├── motion.rs │ ├── outline.rs │ ├── page.rs │ ├── percentage.rs │ ├── position.rs │ ├── ratio.rs │ ├── rect.rs │ ├── resolution.rs │ ├── source_size_list.rs │ ├── svg.rs │ ├── svg_path.rs │ ├── table.rs │ ├── text.rs │ ├── time.rs │ ├── transform.rs │ ├── ui.rs │ └── url.rs ├── style_derive ├── Cargo.toml ├── animate.rs ├── cg.rs ├── compute_squared_distance.rs ├── lib.rs ├── parse.rs ├── specified_value_info.rs ├── to_animated_value.rs ├── to_animated_zero.rs ├── to_computed_value.rs ├── to_css.rs └── to_resolved_value.rs ├── style_traits ├── Cargo.toml ├── arc_slice.rs ├── dom.rs ├── lib.rs ├── owned_slice.rs ├── owned_str.rs ├── specified_value_info.rs └── values.rs ├── stylo_atoms ├── Cargo.toml ├── build.rs ├── lib.rs ├── predefined_counter_styles.rs └── static_atoms.txt ├── stylo_config ├── Cargo.toml └── lib.rs ├── stylo_dom ├── Cargo.toml └── lib.rs ├── stylo_static_prefs ├── Cargo.toml └── src │ └── lib.rs ├── sync.sh ├── to_shmem ├── Cargo.toml └── lib.rs └── to_shmem_derive ├── Cargo.toml ├── lib.rs ├── to_shmem.rs └── util.rs /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | workflow_dispatch: 8 | merge_group: 9 | types: [checks_requested] 10 | 11 | 12 | jobs: 13 | linux-debug: 14 | name: Linux (Debug) 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Install Rust 19 | uses: dtolnay/rust-toolchain@stable 20 | - name: Run Tests 21 | run: cargo build --features servo 22 | env: 23 | RUST_BACKTRACE: 1 24 | 25 | linux-release: 26 | name: Linux (Release) 27 | runs-on: ubuntu-latest 28 | steps: 29 | - uses: actions/checkout@v4 30 | - name: Install Rust 31 | uses: dtolnay/rust-toolchain@stable 32 | - name: Run Tests 33 | run: cargo build --release --features servo 34 | env: 35 | RUST_BACKTRACE: 1 36 | 37 | build-result: 38 | name: Result 39 | runs-on: ubuntu-latest 40 | if: ${{ always() }} 41 | needs: 42 | - linux-debug 43 | - linux-release 44 | steps: 45 | - name: Success 46 | if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} 47 | run: exit 0 48 | - name: Failure 49 | if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} 50 | run: exit 1 51 | 52 | -------------------------------------------------------------------------------- /.github/workflows/mirror-to-release-branch.yml: -------------------------------------------------------------------------------- 1 | name: 🪞 Mirror `main` 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | mirror: 9 | name: Mirror 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | fetch-depth: 0 15 | - name: Get branch name 16 | id: branch-name 17 | run: | 18 | first_commit=$(git log --pretty=\%H --grep='Servo initial downstream commit') 19 | upstream_base="$first_commit~" 20 | echo BRANCH_NAME=$(git log -n1 --pretty='%as' $upstream_base) >> $GITHUB_OUTPUT 21 | - uses: google/mirror-branch-action@v1.0 22 | name: Mirror to ${{ steps.branch-name.outputs.BRANCH_NAME }} 23 | with: 24 | github-token: ${{ secrets.GITHUB_TOKEN }} 25 | source: main 26 | dest: ${{ steps.branch-name.outputs.BRANCH_NAME }} 27 | -------------------------------------------------------------------------------- /.github/workflows/sync-upstream.yml: -------------------------------------------------------------------------------- 1 | name: Sync upstream with mozilla-central 2 | 3 | on: 4 | schedule: 5 | - cron: '0 13 * * *' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | sync: 10 | name: Sync 11 | runs-on: ubuntu-22.04 12 | steps: 13 | - uses: actions/checkout@v3 14 | with: 15 | fetch-depth: 1 16 | - uses: actions/cache@v3 17 | with: 18 | path: _cache/upstream 19 | key: upstream 20 | - run: | 21 | ./sync.sh _filtered 22 | git fetch -f --progress ./_filtered master:upstream 23 | git push -fu --progress origin upstream 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /_cache/ 2 | /_filtered/ 3 | /target/ 4 | /style/properties/__pycache__/ 5 | Cargo.lock 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "stylo_atoms", 5 | "stylo_dom", 6 | "malloc_size_of", 7 | "rustfmt.toml", 8 | "selectors", 9 | "servo_arc", 10 | "style", 11 | "style_derive", 12 | "stylo_config", 13 | "stylo_static_prefs", 14 | "style_traits", 15 | "to_shmem", 16 | "to_shmem_derive", 17 | ] 18 | default-members = ["style"] 19 | -------------------------------------------------------------------------------- /SYNCING.md: -------------------------------------------------------------------------------- 1 | # Syncing 2 | 3 | This file documents the process of syncing this repository with the upstream copy of Stylo in mozilla-central. 4 | 5 | ## Syncing `upstream` with mozilla-central 6 | 7 | Start by generating a filtered copy of mozilla-central. This will cache the raw mozilla-central in `_cache/upstream`, storing the result in `_filtered`: 8 | 9 | ```sh 10 | $ ./sync.sh _filtered 11 | ``` 12 | 13 | If `_filtered` already exists, you will need to delete it and try again: 14 | 15 | ```sh 16 | $ rm -Rf _filtered 17 | ``` 18 | 19 | Now overwrite our `upstream` with those commits and push: 20 | 21 | ```sh 22 | $ git fetch -f --progress ./_filtered master:upstream 23 | $ git push -fu --progress origin upstream 24 | ``` 25 | 26 | ## Rebasing `main` onto `upstream` 27 | 28 | Start by fetching `upstream` into your local repo: 29 | 30 | ```sh 31 | $ git fetch -f origin upstream:upstream 32 | ``` 33 | 34 | In general, the filtering process is deterministic, yielding the same commit hashes each time, so we can rebase normally: 35 | 36 | ```sh 37 | $ git rebase upstream 38 | ``` 39 | 40 | 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 `~`): 41 | 42 | ```sh 43 | $ git log --pretty=\%H --grep='Servo initial downstream commit' 44 | e62d7f0090941496e392e1dc91df103a38e3f488 45 | 46 | $ git rebase --onto upstream e62d7f0090941496e392e1dc91df103a38e3f488~ 47 | Successfully rebased and updated refs/heads/main. 48 | ``` 49 | 50 | `start-rebase.sh` takes care of this automatically, but you should still use `git rebase` for subsequent steps like `--continue` and `--abort`: 51 | 52 | ```sh 53 | $ ./start-rebase.sh upstream 54 | $ ./start-rebase.sh upstream -i # interactive 55 | $ git rebase --continue # not ./start-rebase.sh --continue 56 | $ git rebase --abort # not ./start-rebase.sh --abort 57 | ``` 58 | 59 | Or if we aren’t ready to rebase onto the tip of upstream: 60 | 61 | ```sh 62 | $ ./start-rebase.sh upstream~10 -i 63 | ``` 64 | -------------------------------------------------------------------------------- /commit-from-merge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Usage: commit-from-merge.sh [extra git-commit(1) arguments ...] 3 | # Given a merge commit made by bors, runs git-commit(1) with your local changes 4 | # while borrowing the author name/email from the right-hand parent of the merge, 5 | # and the author date from the committer date of the merge. 6 | set -eu 7 | 8 | lookup_repo=$1; shift 9 | merge_commit=$1; shift 10 | author_name_email=$(git -C "$lookup_repo" log -n1 --pretty='%aN <%aE>' "$merge_commit"\^2) 11 | committer_date=$(git -C "$lookup_repo" log -n1 --pretty='%cd' "$merge_commit") 12 | 13 | set -- git commit --author="$author_name_email" --date="$committer_date" "$@" 14 | echo "$@" 15 | "$@" 16 | -------------------------------------------------------------------------------- /commit-from-squashed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Usage: commit-from-squashed.sh [extra git-commit(1) arguments ...] 3 | # Given a squashed commit made by the GitHub merge queue, runs git-commit(1) with your local changes 4 | # while borrowing our author name/email from that commit, our author date from its committer date, 5 | # and our commit message from that commit. 6 | set -eu 7 | 8 | squashed_commit=$1; shift 9 | committer_date=$(git log -n1 --pretty='%cd' "$squashed_commit") 10 | 11 | # -c is equivalent to --author=$(...'%aN <%aE>') -m $(...'%B'), but allows editing 12 | set -- git commit -c "$squashed_commit" --date="$committer_date" "$@" 13 | echo "$@" 14 | "$@" 15 | -------------------------------------------------------------------------------- /malloc_size_of/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stylo_malloc_size_of" 3 | version = "0.3.0" 4 | authors = ["The Servo Project Developers"] 5 | license = "MIT OR Apache-2.0" 6 | repository = "https://github.com/servo/stylo" 7 | description = "An allocator-agnostic crate for measuring the heap size of a value" 8 | 9 | [lib] 10 | path = "lib.rs" 11 | 12 | [features] 13 | gecko = ["thin-vec/gecko-ffi"] 14 | servo = ["string_cache"] 15 | 16 | [dependencies] 17 | app_units = "0.7" 18 | cssparser = "0.35" 19 | euclid = "0.22" 20 | selectors = { version = "0.28", path = "../selectors" } 21 | servo_arc = { version = "0.4", path = "../servo_arc" } 22 | smallbitvec = "2.3.0" 23 | smallvec = "1.13" 24 | string_cache = { version = "0.8", optional = true } 25 | thin-vec = { version = "0.2.13" } 26 | void = "1.0.2" 27 | -------------------------------------------------------------------------------- /malloc_size_of/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | match_block_trailing_comma = true 2 | binop_separator = "Back" 3 | reorder_imports = true 4 | -------------------------------------------------------------------------------- /selectors/CHANGES.md: -------------------------------------------------------------------------------- 1 | - `parser.rs` no longer wraps values in quotes (`"..."`) but expects their `to_css` impl to already wrap it ([Gecko Bug 1854809](https://bugzilla.mozilla.org/show_bug.cgi?id=1854809)) 2 | -------------------------------------------------------------------------------- /selectors/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "selectors" 3 | version = "0.28.0" 4 | authors = ["The Servo Project Developers"] 5 | documentation = "https://docs.rs/selectors/" 6 | description = "CSS Selectors matching for Rust" 7 | repository = "https://github.com/servo/stylo" 8 | readme = "README.md" 9 | keywords = ["css", "selectors"] 10 | license = "MPL-2.0" 11 | edition = "2021" 12 | build = "build.rs" 13 | 14 | [lib] 15 | name = "selectors" 16 | path = "lib.rs" 17 | 18 | [features] 19 | bench = [] 20 | to_shmem = ["dep:to_shmem", "dep:to_shmem_derive"] 21 | 22 | [dependencies] 23 | bitflags = "2" 24 | cssparser = "0.35" 25 | derive_more = { version = "0.99", default-features = false, features = ["add", "add_assign"] } 26 | fxhash = "0.2" 27 | log = "0.4" 28 | phf = "0.11" 29 | precomputed-hash = "0.1" 30 | servo_arc = { version = "0.4", path = "../servo_arc" } 31 | smallvec = "1.0" 32 | to_shmem = { version = "0.2", path = "../to_shmem", features = ["servo_arc"], optional = true } 33 | to_shmem_derive = { version = "0.1", path = "../to_shmem_derive", optional = true } 34 | new_debug_unreachable = "1" 35 | 36 | [build-dependencies] 37 | phf_codegen = "0.11" 38 | -------------------------------------------------------------------------------- /selectors/README.md: -------------------------------------------------------------------------------- 1 | rust-selectors 2 | ============== 3 | 4 | * [![Build Status](https://travis-ci.com/servo/rust-selectors.svg?branch=master)]( 5 | https://travis-ci.com/servo/rust-selectors) 6 | * [Documentation](https://docs.rs/selectors/) 7 | * [crates.io](https://crates.io/crates/selectors) 8 | 9 | CSS Selectors library for Rust. 10 | Includes parsing and serilization of selectors, 11 | as well as matching against a generic tree of elements. 12 | Pseudo-elements and most pseudo-classes are generic as well. 13 | 14 | **Warning:** breaking changes are made to this library fairly frequently 15 | (13 times in 2016, for example). 16 | However you can use this crate without updating it that often, 17 | old versions stay available on crates.io and Cargo will only automatically update 18 | to versions that are numbered as compatible. 19 | 20 | To see how to use this library with your own tree representation, 21 | see [Kuchiki’s `src/select.rs`](https://github.com/kuchiki-rs/kuchiki/blob/master/src/select.rs). 22 | (Note however that Kuchiki is not always up to date with the latest rust-selectors version, 23 | so that code may need to be tweaked.) 24 | If you don’t already have a tree data structure, 25 | consider using [Kuchiki](https://github.com/kuchiki-rs/kuchiki) itself. 26 | -------------------------------------------------------------------------------- /selectors/build.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | extern crate phf_codegen; 6 | 7 | use std::env; 8 | use std::fs::File; 9 | use std::io::{BufWriter, Write}; 10 | use std::path::Path; 11 | 12 | fn main() { 13 | let path = Path::new(&env::var_os("OUT_DIR").unwrap()) 14 | .join("ascii_case_insensitive_html_attributes.rs"); 15 | let mut file = BufWriter::new(File::create(&path).unwrap()); 16 | 17 | let mut set = phf_codegen::Set::new(); 18 | for name in ASCII_CASE_INSENSITIVE_HTML_ATTRIBUTES.split_whitespace() { 19 | set.entry(name); 20 | } 21 | write!( 22 | &mut file, 23 | "{{ static SET: ::phf::Set<&'static str> = {}; &SET }}", 24 | set.build(), 25 | ) 26 | .unwrap(); 27 | } 28 | 29 | /// 30 | static ASCII_CASE_INSENSITIVE_HTML_ATTRIBUTES: &str = r#" 31 | accept 32 | accept-charset 33 | align 34 | alink 35 | axis 36 | bgcolor 37 | charset 38 | checked 39 | clear 40 | codetype 41 | color 42 | compact 43 | declare 44 | defer 45 | dir 46 | direction 47 | disabled 48 | enctype 49 | face 50 | frame 51 | hreflang 52 | http-equiv 53 | lang 54 | language 55 | link 56 | media 57 | method 58 | multiple 59 | nohref 60 | noresize 61 | noshade 62 | nowrap 63 | readonly 64 | rel 65 | rev 66 | rules 67 | scope 68 | scrolling 69 | selected 70 | shape 71 | target 72 | text 73 | type 74 | valign 75 | valuetype 76 | vlink 77 | "#; 78 | -------------------------------------------------------------------------------- /selectors/lib.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | // Make |cargo bench| work. 6 | #![cfg_attr(feature = "bench", feature(test))] 7 | 8 | pub mod attr; 9 | pub mod bloom; 10 | mod builder; 11 | pub mod context; 12 | pub mod kleene_value; 13 | pub mod matching; 14 | mod nth_index_cache; 15 | pub mod parser; 16 | pub mod relative_selector; 17 | pub mod sink; 18 | mod tree; 19 | pub mod visitor; 20 | 21 | pub use crate::nth_index_cache::NthIndexCache; 22 | pub use crate::parser::{Parser, SelectorImpl, SelectorList}; 23 | pub use crate::tree::{Element, OpaqueElement}; 24 | -------------------------------------------------------------------------------- /selectors/relative_selector/cache.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | use fxhash::FxHashMap; 6 | /// Relative selector cache. This is useful for following cases. 7 | /// First case is non-subject relative selector: Imagine `.anchor:has(<..>) ~ .foo`, with DOM 8 | /// `.anchor + .foo + .. + .foo`. Each match on `.foo` triggers `:has()` traversal that 9 | /// yields the same result. This is simple enough, since we just need to store 10 | /// the exact match on that anchor pass/fail. 11 | /// Second case is `querySelectorAll`: Imagine `querySelectorAll(':has(.a)')`, with DOM 12 | /// `div > .. > div > .a`. When the we perform the traversal at the top div, 13 | /// we basically end up evaluating `:has(.a)` for all anchors, which could be reused. 14 | /// Also consider the sibling version: `querySelectorAll(':has(~ .a)')` with DOM 15 | /// `div + .. + div + .a`. 16 | /// TODO(dshin): Second case is not yet handled. That is tracked in Bug 1845291. 17 | use std::hash::Hash; 18 | 19 | use crate::parser::{RelativeSelector, SelectorKey}; 20 | use crate::{tree::OpaqueElement, SelectorImpl}; 21 | 22 | /// Match data for a given element and a selector. 23 | #[derive(Clone, Copy)] 24 | pub enum RelativeSelectorCachedMatch { 25 | /// This selector matches this element. 26 | Matched, 27 | /// This selector does not match this element. 28 | NotMatched, 29 | } 30 | 31 | impl RelativeSelectorCachedMatch { 32 | /// Is the cached result a match? 33 | pub fn matched(&self) -> bool { 34 | matches!(*self, Self::Matched) 35 | } 36 | } 37 | 38 | #[derive(Clone, Copy, Hash, Eq, PartialEq)] 39 | struct Key { 40 | element: OpaqueElement, 41 | selector: SelectorKey, 42 | } 43 | 44 | impl Key { 45 | pub fn new( 46 | element: OpaqueElement, 47 | selector: &RelativeSelector, 48 | ) -> Self { 49 | Key { 50 | element, 51 | selector: SelectorKey::new(&selector.selector), 52 | } 53 | } 54 | } 55 | 56 | /// Cache to speed up matching of relative selectors. 57 | #[derive(Default)] 58 | pub struct RelativeSelectorCache { 59 | cache: FxHashMap, 60 | } 61 | 62 | impl RelativeSelectorCache { 63 | /// Add a relative selector match into the cache. 64 | pub fn add( 65 | &mut self, 66 | anchor: OpaqueElement, 67 | selector: &RelativeSelector, 68 | matched: RelativeSelectorCachedMatch, 69 | ) { 70 | self.cache.insert(Key::new(anchor, selector), matched); 71 | } 72 | 73 | /// Check if we have a cache entry for the element. 74 | pub fn lookup( 75 | &mut self, 76 | element: OpaqueElement, 77 | selector: &RelativeSelector, 78 | ) -> Option { 79 | self.cache.get(&Key::new(element, selector)).copied() 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /selectors/relative_selector/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | pub mod cache; 6 | pub mod filter; 7 | -------------------------------------------------------------------------------- /selectors/sink.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Small helpers to abstract over different containers. 6 | #![deny(missing_docs)] 7 | 8 | use smallvec::{Array, SmallVec}; 9 | 10 | /// A trait to abstract over a `push` method that may be implemented for 11 | /// different kind of types. 12 | /// 13 | /// Used to abstract over `Array`, `SmallVec` and `Vec`, and also to implement a 14 | /// type which `push` method does only tweak a byte when we only need to check 15 | /// for the presence of something. 16 | pub trait Push { 17 | /// Push a value into self. 18 | fn push(&mut self, value: T); 19 | } 20 | 21 | impl Push for Vec { 22 | fn push(&mut self, value: T) { 23 | Vec::push(self, value); 24 | } 25 | } 26 | 27 | impl Push for SmallVec { 28 | fn push(&mut self, value: A::Item) { 29 | SmallVec::push(self, value); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /servo_arc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "servo_arc" 3 | version = "0.4.1" 4 | authors = ["The Servo Project Developers"] 5 | license = "MIT OR Apache-2.0" 6 | repository = "https://github.com/servo/stylo" 7 | description = "A fork of std::sync::Arc with some extra functionality and without weak references" 8 | edition = "2021" 9 | readme = "../README.md" 10 | 11 | [lib] 12 | name = "servo_arc" 13 | path = "lib.rs" 14 | 15 | [features] 16 | default = ["track_alloc_size"] 17 | gecko_refcount_logging = [] 18 | servo = ["serde", "track_alloc_size"] 19 | track_alloc_size = [] 20 | 21 | [dependencies] 22 | serde = { version = "1.0", optional = true } 23 | stable_deref_trait = "1.0.0" 24 | -------------------------------------------------------------------------------- /servo_arc/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | with import (builtins.fetchTarball { 2 | url = "https://github.com/NixOS/nixpkgs/archive/46ae0210ce163b3cba6c7da08840c1d63de9c701.tar.gz"; 3 | }) {}; 4 | stdenv.mkDerivation rec { 5 | name = "style-sync-shell"; 6 | } 7 | -------------------------------------------------------------------------------- /start-rebase.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Usage: start-rebase.sh [extra git-rebase(1) arguments ...] 3 | # Equivalent to git rebase --onto . 4 | set -eu 5 | 6 | new_base=$1; shift 7 | first_commit=$(git log --pretty=\%H --grep='Servo initial downstream commit') 8 | old_base=$first_commit~ 9 | 10 | git rebase --onto "$new_base" "$old_base" "$@" 11 | -------------------------------------------------------------------------------- /style.paths: -------------------------------------------------------------------------------- 1 | # Filters and renames use git-filter-repo(1) --paths-from-file: 2 | # https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#_filtering_based_on_many_paths 3 | 4 | servo/components/ 5 | servo/rustfmt.toml 6 | 7 | regex:servo/components/(.+)==>\1 8 | servo/rustfmt.toml==>rustfmt.toml 9 | -------------------------------------------------------------------------------- /style/README.md: -------------------------------------------------------------------------------- 1 | servo-style 2 | =========== 3 | 4 | Style system for Servo, using [rust-cssparser](https://github.com/servo/rust-cssparser) for parsing. 5 | 6 | * [Documentation](https://book.servo.org/architecture/style.html). 7 | -------------------------------------------------------------------------------- /style/author_styles.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! A set of author stylesheets and their computed representation, such as the 6 | //! ones used for ShadowRoot. 7 | 8 | use crate::dom::TElement; 9 | use crate::invalidation::media_queries::ToMediaListKey; 10 | use crate::shared_lock::SharedRwLockReadGuard; 11 | use crate::stylesheet_set::AuthorStylesheetSet; 12 | use crate::stylesheets::StylesheetInDocument; 13 | use crate::stylist::CascadeData; 14 | use crate::stylist::Stylist; 15 | use servo_arc::Arc; 16 | 17 | /// A set of author stylesheets and their computed representation, such as the 18 | /// ones used for ShadowRoot. 19 | #[derive(MallocSizeOf)] 20 | pub struct GenericAuthorStyles 21 | where 22 | S: StylesheetInDocument + PartialEq + 'static, 23 | { 24 | /// The sheet collection, which holds the sheet pointers, the invalidations, 25 | /// and all that stuff. 26 | pub stylesheets: AuthorStylesheetSet, 27 | /// The actual cascade data computed from the stylesheets. 28 | #[ignore_malloc_size_of = "Measured as part of the stylist"] 29 | pub data: Arc, 30 | } 31 | 32 | pub use self::GenericAuthorStyles as AuthorStyles; 33 | 34 | lazy_static! { 35 | static ref EMPTY_CASCADE_DATA: Arc = Arc::new_leaked(CascadeData::new()); 36 | } 37 | 38 | impl GenericAuthorStyles 39 | where 40 | S: StylesheetInDocument + PartialEq + 'static, 41 | { 42 | /// Create an empty AuthorStyles. 43 | #[inline] 44 | pub fn new() -> Self { 45 | Self { 46 | stylesheets: AuthorStylesheetSet::new(), 47 | data: EMPTY_CASCADE_DATA.clone(), 48 | } 49 | } 50 | 51 | /// Flush the pending sheet changes, updating `data` as appropriate. 52 | /// 53 | /// TODO(emilio): Need a host element and a snapshot map to do invalidation 54 | /// properly. 55 | #[inline] 56 | pub fn flush(&mut self, stylist: &mut Stylist, guard: &SharedRwLockReadGuard) 57 | where 58 | E: TElement, 59 | S: ToMediaListKey, 60 | { 61 | let flusher = self 62 | .stylesheets 63 | .flush::(/* host = */ None, /* snapshot_map = */ None); 64 | 65 | let result = stylist.rebuild_author_data(&self.data, flusher.sheets, guard); 66 | if let Ok(Some(new_data)) = result { 67 | self.data = new_data; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /style/build.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate lazy_static; 7 | 8 | use std::env; 9 | use std::path::Path; 10 | use std::process::{exit, Command}; 11 | use walkdir::WalkDir; 12 | 13 | #[cfg(feature = "gecko")] 14 | mod build_gecko; 15 | 16 | #[cfg(not(feature = "gecko"))] 17 | mod build_gecko { 18 | pub fn generate() {} 19 | } 20 | 21 | lazy_static! { 22 | pub static ref PYTHON: String = env::var("PYTHON3").ok().unwrap_or_else(|| { 23 | let candidates = if cfg!(windows) { 24 | ["python.exe"] 25 | } else { 26 | ["python3"] 27 | }; 28 | for &name in &candidates { 29 | if Command::new(name) 30 | .arg("--version") 31 | .output() 32 | .ok() 33 | .map_or(false, |out| out.status.success()) 34 | { 35 | return name.to_owned(); 36 | } 37 | } 38 | panic!( 39 | "Can't find python (tried {})! Try fixing PATH or setting the PYTHON3 env var", 40 | candidates.join(", ") 41 | ) 42 | }); 43 | } 44 | 45 | fn generate_properties(engine: &str) { 46 | for entry in WalkDir::new("properties") { 47 | let entry = entry.unwrap(); 48 | match entry.path().extension().and_then(|e| e.to_str()) { 49 | Some("mako") | Some("rs") | Some("py") | Some("zip") => { 50 | println!("cargo:rerun-if-changed={}", entry.path().display()); 51 | }, 52 | _ => {}, 53 | } 54 | } 55 | 56 | let script = Path::new(&env::var_os("CARGO_MANIFEST_DIR").unwrap()) 57 | .join("properties") 58 | .join("build.py"); 59 | 60 | let status = Command::new(&*PYTHON) 61 | // `cargo publish` isn't happy with the `__pycache__` files that are created 62 | // when we run the property generator. 63 | // 64 | // TODO(mrobinson): Is this happening because of how we run this script? It 65 | // would be better to ensure are just placed in the output directory. 66 | .env("PYTHONDONTWRITEBYTECODE", "1") 67 | .arg(&script) 68 | .arg(engine) 69 | .arg("style-crate") 70 | .status() 71 | .unwrap(); 72 | if !status.success() { 73 | exit(1) 74 | } 75 | } 76 | 77 | fn main() { 78 | let gecko = cfg!(feature = "gecko"); 79 | let servo = cfg!(feature = "servo"); 80 | let engine = match (gecko, servo) { 81 | (true, false) => "gecko", 82 | (false, true) => "servo", 83 | _ => panic!( 84 | "\n\n\ 85 | The style crate requires enabling one of its 'servo' or 'gecko' feature flags. \ 86 | \n\n" 87 | ), 88 | }; 89 | println!("cargo:rerun-if-changed=build.rs"); 90 | println!("cargo:out_dir={}", env::var("OUT_DIR").unwrap()); 91 | generate_properties(engine); 92 | build_gecko::generate(); 93 | } 94 | -------------------------------------------------------------------------------- /style/counter_style/predefined.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | predefined! { 6 | "decimal", 7 | "decimal-leading-zero", 8 | "arabic-indic", 9 | "armenian", 10 | "upper-armenian", 11 | "lower-armenian", 12 | "bengali", 13 | "cambodian", 14 | "khmer", 15 | "cjk-decimal", 16 | "devanagari", 17 | "georgian", 18 | "gujarati", 19 | "gurmukhi", 20 | "hebrew", 21 | "kannada", 22 | "lao", 23 | "malayalam", 24 | "mongolian", 25 | "myanmar", 26 | "oriya", 27 | "persian", 28 | "lower-roman", 29 | "upper-roman", 30 | "tamil", 31 | "telugu", 32 | "thai", 33 | "tibetan", 34 | "lower-alpha", 35 | "lower-latin", 36 | "upper-alpha", 37 | "upper-latin", 38 | "cjk-earthly-branch", 39 | "cjk-heavenly-stem", 40 | "lower-greek", 41 | "hiragana", 42 | "hiragana-iroha", 43 | "katakana", 44 | "katakana-iroha", 45 | "disc", 46 | "circle", 47 | "square", 48 | "disclosure-open", 49 | "disclosure-closed", 50 | "japanese-informal", 51 | "japanese-formal", 52 | "korean-hangul-formal", 53 | "korean-hanja-informal", 54 | "korean-hanja-formal", 55 | "simp-chinese-informal", 56 | "simp-chinese-formal", 57 | "trad-chinese-informal", 58 | "trad-chinese-formal", 59 | "cjk-ideographic", 60 | "ethiopic-numeric", 61 | } 62 | -------------------------------------------------------------------------------- /style/counter_style/update_predefined.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This Source Code Form is subject to the terms of the Mozilla Public 4 | # License, v. 2.0. If a copy of the MPL was not distributed with this 5 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 6 | 7 | from os.path import join, dirname 8 | import re 9 | from urllib.request import urlopen 10 | 11 | 12 | def main(filename): 13 | names = [ 14 | re.search('>([^>]+)(|, 17 | /// The zero advance. This is usually writing mode dependent 18 | pub zero_advance_measure: Option, 19 | /// The cap-height of the font. 20 | pub cap_height: Option, 21 | /// The ideographic-width of the font. 22 | pub ic_width: Option, 23 | /// The ascent of the font (a value is always available for this). 24 | pub ascent: Length, 25 | /// Script scale down factor for math-depth 1. 26 | /// https://w3c.github.io/mathml-core/#dfn-scriptpercentscaledown 27 | pub script_percent_scale_down: Option, 28 | /// Script scale down factor for math-depth 2. 29 | /// https://w3c.github.io/mathml-core/#dfn-scriptscriptpercentscaledown 30 | pub script_script_percent_scale_down: Option, 31 | } 32 | 33 | impl Default for FontMetrics { 34 | fn default() -> Self { 35 | FontMetrics { 36 | x_height: None, 37 | zero_advance_measure: None, 38 | cap_height: None, 39 | ic_width: None, 40 | ascent: Length::new(0.0), 41 | script_percent_scale_down: None, 42 | script_script_percent_scale_down: None, 43 | } 44 | } 45 | } 46 | 47 | /// Type of font metrics to retrieve. 48 | #[derive(Clone, Debug, PartialEq)] 49 | pub enum FontMetricsOrientation { 50 | /// Get metrics for horizontal or vertical according to the Context's 51 | /// writing mode, using horizontal metrics for vertical/mixed 52 | MatchContextPreferHorizontal, 53 | /// Get metrics for horizontal or vertical according to the Context's 54 | /// writing mode, using vertical metrics for vertical/mixed 55 | MatchContextPreferVertical, 56 | /// Force getting horizontal metrics. 57 | Horizontal, 58 | } 59 | -------------------------------------------------------------------------------- /style/gecko/conversions.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! This module contains conversion helpers between Servo and Gecko types 6 | //! Ideally, it would be in geckolib itself, but coherence 7 | //! forces us to keep the traits and implementations here 8 | //! 9 | //! FIXME(emilio): This file should generally just die. 10 | 11 | #![allow(unsafe_code)] 12 | 13 | use crate::gecko_bindings::structs::{nsresult, Matrix4x4Components}; 14 | use crate::stylesheets::RulesMutateError; 15 | use crate::values::computed::transform::Matrix3D; 16 | 17 | impl From for nsresult { 18 | fn from(other: RulesMutateError) -> Self { 19 | match other { 20 | RulesMutateError::Syntax => nsresult::NS_ERROR_DOM_SYNTAX_ERR, 21 | RulesMutateError::IndexSize => nsresult::NS_ERROR_DOM_INDEX_SIZE_ERR, 22 | RulesMutateError::HierarchyRequest => nsresult::NS_ERROR_DOM_HIERARCHY_REQUEST_ERR, 23 | RulesMutateError::InvalidState => nsresult::NS_ERROR_DOM_INVALID_STATE_ERR, 24 | } 25 | } 26 | } 27 | 28 | impl<'a> From<&'a Matrix4x4Components> for Matrix3D { 29 | fn from(m: &'a Matrix4x4Components) -> Matrix3D { 30 | Matrix3D { 31 | m11: m[0], 32 | m12: m[1], 33 | m13: m[2], 34 | m14: m[3], 35 | m21: m[4], 36 | m22: m[5], 37 | m23: m[6], 38 | m24: m[7], 39 | m31: m[8], 40 | m32: m[9], 41 | m33: m[10], 42 | m34: m[11], 43 | m41: m[12], 44 | m42: m[13], 45 | m43: m[14], 46 | m44: m[15], 47 | } 48 | } 49 | } 50 | 51 | impl From for Matrix4x4Components { 52 | fn from(matrix: Matrix3D) -> Self { 53 | [ 54 | matrix.m11, matrix.m12, matrix.m13, matrix.m14, matrix.m21, matrix.m22, matrix.m23, 55 | matrix.m24, matrix.m31, matrix.m32, matrix.m33, matrix.m34, matrix.m41, matrix.m42, 56 | matrix.m43, matrix.m44, 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /style/gecko/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Gecko-specific style-system bits. 6 | 7 | #[macro_use] 8 | mod non_ts_pseudo_class_list; 9 | 10 | pub mod arc_types; 11 | pub mod conversions; 12 | pub mod data; 13 | pub mod media_features; 14 | pub mod media_queries; 15 | pub mod pseudo_element; 16 | pub mod restyle_damage; 17 | pub mod selector_parser; 18 | pub mod snapshot; 19 | pub mod snapshot_helpers; 20 | pub mod traversal; 21 | pub mod url; 22 | pub mod values; 23 | pub mod wrapper; 24 | -------------------------------------------------------------------------------- /style/gecko/traversal.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Gecko-specific bits for the styling DOM traversal. 6 | 7 | use crate::context::{SharedStyleContext, StyleContext}; 8 | use crate::dom::{TElement, TNode}; 9 | use crate::gecko::wrapper::{GeckoElement, GeckoNode}; 10 | use crate::traversal::{recalc_style_at, DomTraversal, PerLevelTraversalData}; 11 | 12 | /// This is the simple struct that Gecko uses to encapsulate a DOM traversal for 13 | /// styling. 14 | pub struct RecalcStyleOnly<'a> { 15 | shared: SharedStyleContext<'a>, 16 | } 17 | 18 | impl<'a> RecalcStyleOnly<'a> { 19 | /// Create a `RecalcStyleOnly` traversal from a `SharedStyleContext`. 20 | pub fn new(shared: SharedStyleContext<'a>) -> Self { 21 | RecalcStyleOnly { shared: shared } 22 | } 23 | } 24 | 25 | impl<'recalc, 'le> DomTraversal> for RecalcStyleOnly<'recalc> { 26 | fn process_preorder( 27 | &self, 28 | traversal_data: &PerLevelTraversalData, 29 | context: &mut StyleContext>, 30 | node: GeckoNode<'le>, 31 | note_child: F, 32 | ) where 33 | F: FnMut(GeckoNode<'le>), 34 | { 35 | if let Some(el) = node.as_element() { 36 | let mut data = unsafe { el.ensure_data() }; 37 | recalc_style_at(self, traversal_data, context, el, &mut data, note_child); 38 | } 39 | } 40 | 41 | fn process_postorder(&self, _: &mut StyleContext>, _: GeckoNode<'le>) { 42 | unreachable!(); 43 | } 44 | 45 | /// We don't use the post-order traversal for anything. 46 | fn needs_postorder_traversal() -> bool { 47 | false 48 | } 49 | 50 | fn shared_context(&self) -> &SharedStyleContext { 51 | &self.shared 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /style/gecko/values.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | #![allow(unsafe_code)] 6 | 7 | //! Different kind of helpers to interact with Gecko values. 8 | 9 | use crate::color::{AbsoluteColor, ColorSpace}; 10 | 11 | /// Convert a color value to `nscolor`. 12 | pub fn convert_absolute_color_to_nscolor(color: &AbsoluteColor) -> u32 { 13 | let srgb = color.to_color_space(ColorSpace::Srgb); 14 | u32::from_le_bytes([ 15 | (srgb.components.0 * 255.0).round() as u8, 16 | (srgb.components.1 * 255.0).round() as u8, 17 | (srgb.components.2 * 255.0).round() as u8, 18 | (srgb.alpha * 255.0).round() as u8, 19 | ]) 20 | } 21 | 22 | /// Convert a given `nscolor` to a Servo AbsoluteColor value. 23 | pub fn convert_nscolor_to_absolute_color(color: u32) -> AbsoluteColor { 24 | let [r, g, b, a] = color.to_le_bytes(); 25 | AbsoluteColor::srgb_legacy(r, g, b, a as f32 / 255.0) 26 | } 27 | 28 | #[test] 29 | fn convert_ns_color_to_absolute_color_should_be_in_legacy_syntax() { 30 | use crate::color::ColorFlags; 31 | 32 | let result = convert_nscolor_to_absolute_color(0x336699CC); 33 | assert!(result.flags.contains(ColorFlags::IS_LEGACY_SRGB)); 34 | 35 | assert!(result.is_legacy_syntax()); 36 | } 37 | -------------------------------------------------------------------------------- /style/gecko_bindings/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Gecko's C++ bindings, along with some rust helpers to ease its use. 6 | 7 | // FIXME: We allow `improper_ctypes` (for now), because the lint doesn't allow 8 | // foreign structs to have `PhantomData`. We should remove this once the lint 9 | // ignores this case. 10 | 11 | #[allow( 12 | dead_code, 13 | improper_ctypes, 14 | non_camel_case_types, 15 | non_snake_case, 16 | non_upper_case_globals, 17 | missing_docs 18 | )] 19 | // TODO: Remove this when updating bindgen, see 20 | // https://github.com/rust-lang/rust-bindgen/issues/1651 21 | #[cfg_attr(test, allow(deref_nullptr))] 22 | pub mod structs { 23 | include!(concat!(env!("OUT_DIR"), "/gecko/structs.rs")); 24 | } 25 | 26 | pub use self::structs as bindings; 27 | 28 | pub mod sugar; 29 | -------------------------------------------------------------------------------- /style/gecko_bindings/sugar/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Rust sugar and convenience methods for Gecko types. 6 | 7 | mod ns_com_ptr; 8 | mod ns_compatibility; 9 | mod ns_style_auto_array; 10 | pub mod origin_flags; 11 | pub mod ownership; 12 | pub mod refptr; 13 | -------------------------------------------------------------------------------- /style/gecko_bindings/sugar/ns_com_ptr.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Little helpers for `nsCOMPtr`. 6 | 7 | use crate::gecko_bindings::structs::nsCOMPtr; 8 | 9 | impl nsCOMPtr { 10 | /// Get this pointer as a raw pointer. 11 | #[inline] 12 | pub fn raw(&self) -> *mut T { 13 | self.mRawPtr 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /style/gecko_bindings/sugar/ns_compatibility.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Little helper for `nsCompatibility`. 6 | 7 | use crate::context::QuirksMode; 8 | use crate::gecko_bindings::structs::nsCompatibility; 9 | 10 | impl From for QuirksMode { 11 | #[inline] 12 | fn from(mode: nsCompatibility) -> QuirksMode { 13 | match mode { 14 | nsCompatibility::eCompatibility_FullStandards => QuirksMode::NoQuirks, 15 | nsCompatibility::eCompatibility_AlmostStandards => QuirksMode::LimitedQuirks, 16 | nsCompatibility::eCompatibility_NavQuirks => QuirksMode::Quirks, 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /style/gecko_bindings/sugar/origin_flags.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Helper to iterate over `OriginFlags` bits. 6 | 7 | use crate::gecko_bindings::structs::OriginFlags; 8 | use crate::stylesheets::OriginSet; 9 | 10 | /// Checks that the values for OriginFlags are the ones we expect. 11 | pub fn assert_flags_match() { 12 | use crate::stylesheets::origin::*; 13 | debug_assert_eq!( 14 | OriginFlags::UserAgent.0, 15 | OriginSet::ORIGIN_USER_AGENT.bits() 16 | ); 17 | debug_assert_eq!(OriginFlags::Author.0, OriginSet::ORIGIN_AUTHOR.bits()); 18 | debug_assert_eq!(OriginFlags::User.0, OriginSet::ORIGIN_USER.bits()); 19 | } 20 | 21 | impl From for OriginSet { 22 | fn from(flags: OriginFlags) -> Self { 23 | Self::from_bits_retain(flags.0) 24 | } 25 | } 26 | 27 | impl From for OriginFlags { 28 | fn from(set: OriginSet) -> Self { 29 | OriginFlags(set.bits()) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /style/gecko_bindings/sugar/ownership.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Helpers for different FFI pointer kinds that Gecko's FFI layer uses. 6 | 7 | use crate::gecko_bindings::structs::root::mozilla::detail::CopyablePtr; 8 | use servo_arc::Arc; 9 | use std::marker::PhantomData; 10 | use std::ops::{Deref, DerefMut}; 11 | use std::ptr; 12 | 13 | /// Gecko-FFI-safe Arc (T is an ArcInner). 14 | /// 15 | /// This can be null. 16 | /// 17 | /// Leaks on drop. Please don't drop this. 18 | #[repr(C)] 19 | pub struct Strong { 20 | ptr: *const GeckoType, 21 | _marker: PhantomData, 22 | } 23 | 24 | impl From> for Strong { 25 | fn from(arc: Arc) -> Self { 26 | Self { 27 | ptr: Arc::into_raw(arc), 28 | _marker: PhantomData, 29 | } 30 | } 31 | } 32 | 33 | impl Strong { 34 | #[inline] 35 | /// Returns whether this reference is null. 36 | pub fn is_null(&self) -> bool { 37 | self.ptr.is_null() 38 | } 39 | 40 | #[inline] 41 | /// Returns a null pointer 42 | pub fn null() -> Self { 43 | Self { 44 | ptr: ptr::null(), 45 | _marker: PhantomData, 46 | } 47 | } 48 | } 49 | 50 | impl Deref for CopyablePtr { 51 | type Target = T; 52 | fn deref(&self) -> &Self::Target { 53 | &self.mPtr 54 | } 55 | } 56 | 57 | impl DerefMut for CopyablePtr { 58 | fn deref_mut<'a>(&'a mut self) -> &'a mut T { 59 | &mut self.mPtr 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /style/gecko_string_cache/namespace.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! A type to represent a namespace. 6 | 7 | use crate::gecko_bindings::structs::nsAtom; 8 | use crate::string_cache::{Atom, WeakAtom}; 9 | use precomputed_hash::PrecomputedHash; 10 | use std::borrow::Borrow; 11 | use std::fmt; 12 | use std::ops::Deref; 13 | 14 | /// In Gecko namespaces are just regular atoms, so this is a simple macro to 15 | /// forward one macro to the other. 16 | #[macro_export] 17 | macro_rules! ns { 18 | () => { 19 | $crate::string_cache::Namespace(atom!("")) 20 | }; 21 | ($s:tt) => { 22 | $crate::string_cache::Namespace(atom!($s)) 23 | }; 24 | } 25 | 26 | /// A Gecko namespace is just a wrapped atom. 27 | #[derive( 28 | Clone, 29 | Debug, 30 | Default, 31 | Eq, 32 | Hash, 33 | MallocSizeOf, 34 | PartialEq, 35 | ToComputedValue, 36 | ToResolvedValue, 37 | ToShmem, 38 | )] 39 | #[repr(transparent)] 40 | pub struct Namespace(pub Atom); 41 | 42 | impl PrecomputedHash for Namespace { 43 | #[inline] 44 | fn precomputed_hash(&self) -> u32 { 45 | self.0.precomputed_hash() 46 | } 47 | } 48 | 49 | /// A Gecko WeakNamespace is a wrapped WeakAtom. 50 | #[derive(Deref, Hash)] 51 | pub struct WeakNamespace(WeakAtom); 52 | 53 | impl Deref for Namespace { 54 | type Target = WeakNamespace; 55 | 56 | #[inline] 57 | fn deref(&self) -> &WeakNamespace { 58 | let weak: *const WeakAtom = &*self.0; 59 | unsafe { &*(weak as *const WeakNamespace) } 60 | } 61 | } 62 | 63 | impl<'a> From<&'a str> for Namespace { 64 | fn from(s: &'a str) -> Self { 65 | Namespace(Atom::from(s)) 66 | } 67 | } 68 | 69 | impl fmt::Display for Namespace { 70 | fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { 71 | self.0.fmt(w) 72 | } 73 | } 74 | 75 | impl Borrow for Namespace { 76 | #[inline] 77 | fn borrow(&self) -> &WeakNamespace { 78 | self 79 | } 80 | } 81 | 82 | impl WeakNamespace { 83 | /// Trivially construct a WeakNamespace. 84 | #[inline] 85 | pub unsafe fn new<'a>(atom: *mut nsAtom) -> &'a Self { 86 | &*(atom as *const WeakNamespace) 87 | } 88 | 89 | /// Clone this WeakNamespace to obtain a strong reference to the same 90 | /// underlying namespace. 91 | #[inline] 92 | pub fn clone(&self) -> Namespace { 93 | Namespace(self.0.clone()) 94 | } 95 | } 96 | 97 | impl Eq for WeakNamespace {} 98 | impl PartialEq for WeakNamespace { 99 | #[inline] 100 | fn eq(&self, other: &Self) -> bool { 101 | let weak: *const WeakNamespace = self; 102 | let other: *const WeakNamespace = other; 103 | weak == other 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /style/invalidation/element/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Invalidation of element styles due to attribute or style changes. 6 | 7 | pub mod document_state; 8 | pub mod element_wrapper; 9 | pub mod invalidation_map; 10 | pub mod invalidator; 11 | pub mod relative_selector; 12 | pub mod restyle_hints; 13 | pub mod state_and_attributes; 14 | -------------------------------------------------------------------------------- /style/invalidation/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Different bits of code related to invalidating style. 6 | 7 | pub mod element; 8 | pub mod media_queries; 9 | pub mod stylesheets; 10 | pub mod viewport_units; 11 | -------------------------------------------------------------------------------- /style/invalidation/viewport_units.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Invalidates style of all elements that depend on viewport units. 6 | 7 | use crate::data::ViewportUnitUsage; 8 | use crate::dom::{TElement, TNode}; 9 | use crate::invalidation::element::restyle_hints::RestyleHint; 10 | 11 | /// Invalidates style of all elements that depend on viewport units. 12 | /// 13 | /// Returns whether any element was invalidated. 14 | pub fn invalidate(root: E) -> bool 15 | where 16 | E: TElement, 17 | { 18 | debug!("invalidation::viewport_units::invalidate({:?})", root); 19 | invalidate_recursively(root) 20 | } 21 | 22 | fn invalidate_recursively(element: E) -> bool 23 | where 24 | E: TElement, 25 | { 26 | let mut data = match element.mutate_data() { 27 | Some(data) => data, 28 | None => return false, 29 | }; 30 | 31 | if data.hint.will_recascade_subtree() { 32 | debug!("invalidate_recursively: {:?} was already invalid", element); 33 | return false; 34 | } 35 | 36 | let usage = data.styles.viewport_unit_usage(); 37 | let uses_viewport_units = usage != ViewportUnitUsage::None; 38 | if uses_viewport_units { 39 | debug!( 40 | "invalidate_recursively: {:?} uses viewport units {:?}", 41 | element, usage 42 | ); 43 | } 44 | 45 | match usage { 46 | ViewportUnitUsage::None => {}, 47 | ViewportUnitUsage::FromQuery => { 48 | data.hint.insert(RestyleHint::RESTYLE_SELF); 49 | }, 50 | ViewportUnitUsage::FromDeclaration => { 51 | data.hint.insert(RestyleHint::RECASCADE_SELF); 52 | }, 53 | } 54 | 55 | let mut any_children_invalid = false; 56 | for child in element.traversal_children() { 57 | if let Some(child) = child.as_element() { 58 | any_children_invalid |= invalidate_recursively(child); 59 | } 60 | } 61 | 62 | if any_children_invalid { 63 | debug!( 64 | "invalidate_recursively: Children of {:?} changed, setting dirty descendants", 65 | element 66 | ); 67 | unsafe { element.set_dirty_descendants() } 68 | } 69 | 70 | uses_viewport_units || any_children_invalid 71 | } 72 | -------------------------------------------------------------------------------- /style/macros.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Various macro helpers. 6 | 7 | macro_rules! trivial_to_computed_value { 8 | ($name:ty) => { 9 | impl $crate::values::computed::ToComputedValue for $name { 10 | type ComputedValue = $name; 11 | 12 | fn to_computed_value(&self, _: &$crate::values::computed::Context) -> Self { 13 | self.clone() 14 | } 15 | 16 | fn from_computed_value(other: &Self) -> Self { 17 | other.clone() 18 | } 19 | } 20 | }; 21 | } 22 | 23 | /// A macro to parse an identifier, or return an `UnexpectedIdent` error 24 | /// otherwise. 25 | /// 26 | /// FIXME(emilio): The fact that `UnexpectedIdent` is a `SelectorParseError` 27 | /// doesn't make a lot of sense to me. 28 | macro_rules! try_match_ident_ignore_ascii_case { 29 | ($input:expr, $( $match_body:tt )*) => {{ 30 | let location = $input.current_source_location(); 31 | let ident = $input.expect_ident()?; 32 | match_ignore_ascii_case! { &ident, 33 | $( $match_body )* 34 | _ => return Err(location.new_custom_error( 35 | ::selectors::parser::SelectorParseErrorKind::UnexpectedIdent(ident.clone()) 36 | )) 37 | } 38 | }} 39 | } 40 | 41 | #[cfg(feature = "servo")] 42 | macro_rules! local_name { 43 | ($s:tt) => { 44 | $crate::values::GenericAtomIdent(web_atoms::local_name!($s)) 45 | }; 46 | } 47 | 48 | #[cfg(feature = "servo")] 49 | macro_rules! ns { 50 | () => { 51 | $crate::values::GenericAtomIdent(web_atoms::ns!()) 52 | }; 53 | ($s:tt) => { 54 | $crate::values::GenericAtomIdent(web_atoms::ns!($s)) 55 | }; 56 | } 57 | 58 | #[cfg(feature = "gecko")] 59 | macro_rules! local_name { 60 | ($s:tt) => { 61 | $crate::values::AtomIdent(atom!($s)) 62 | }; 63 | } 64 | 65 | /// Asserts the size of a type at compile time. 66 | macro_rules! size_of_test { 67 | ($t: ty, $expected_size: expr) => { 68 | #[cfg(target_pointer_width = "64")] 69 | const_assert_eq!(std::mem::size_of::<$t>(), $expected_size); 70 | }; 71 | } 72 | -------------------------------------------------------------------------------- /style/media_queries/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! [Media queries][mq]. 6 | //! 7 | //! [mq]: https://drafts.csswg.org/mediaqueries/ 8 | 9 | mod media_list; 10 | mod media_query; 11 | 12 | pub use self::media_list::MediaList; 13 | pub use self::media_query::{MediaQuery, MediaQueryType, MediaType, Qualifier}; 14 | 15 | #[cfg(feature = "gecko")] 16 | pub use crate::gecko::media_queries::Device; 17 | #[cfg(feature = "servo")] 18 | pub use crate::servo::media_queries::Device; 19 | -------------------------------------------------------------------------------- /style/properties/Mako-1.1.2-py2.py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/servo/stylo/945b70e9a1984cd44ee56b7a674c302b19a4f620/style/properties/Mako-1.1.2-py2.py3-none-any.whl -------------------------------------------------------------------------------- /style/properties/longhands/column.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.predefined_type( 8 | "column-width", 9 | "length::NonNegativeLengthOrAuto", 10 | "computed::length::NonNegativeLengthOrAuto::auto()", 11 | engines="gecko servo", 12 | initial_specified_value="specified::length::NonNegativeLengthOrAuto::auto()", 13 | servo_pref="layout.columns.enabled", 14 | spec="https://drafts.csswg.org/css-multicol/#propdef-column-width", 15 | servo_restyle_damage="rebuild_box", 16 | affects="layout", 17 | )} 18 | 19 | ${helpers.predefined_type( 20 | "column-count", 21 | "ColumnCount", 22 | "computed::ColumnCount::Auto", 23 | engines="gecko servo", 24 | initial_specified_value="specified::ColumnCount::Auto", 25 | servo_pref="layout.columns.enabled", 26 | spec="https://drafts.csswg.org/css-multicol/#propdef-column-count", 27 | servo_restyle_damage="rebuild_box", 28 | affects="layout", 29 | )} 30 | 31 | ${helpers.single_keyword( 32 | "column-fill", 33 | "balance auto", 34 | engines="gecko", 35 | animation_type="discrete", 36 | gecko_enum_prefix="StyleColumnFill", 37 | spec="https://drafts.csswg.org/css-multicol/#propdef-column-fill", 38 | affects="layout", 39 | )} 40 | 41 | ${helpers.predefined_type( 42 | "column-rule-width", 43 | "BorderSideWidth", 44 | "app_units::Au::from_px(3)", 45 | engines="gecko", 46 | initial_specified_value="specified::BorderSideWidth::medium()", 47 | spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-width", 48 | affects="layout", 49 | )} 50 | 51 | // https://drafts.csswg.org/css-multicol-1/#crc 52 | ${helpers.predefined_type( 53 | "column-rule-color", 54 | "Color", 55 | "computed_value::T::currentcolor()", 56 | engines="gecko", 57 | initial_specified_value="specified::Color::currentcolor()", 58 | ignored_when_colors_disabled=True, 59 | spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-color", 60 | affects="paint", 61 | )} 62 | 63 | ${helpers.single_keyword( 64 | "column-span", 65 | "none all", 66 | engines="gecko servo", 67 | servo_pref="layout.columns.enabled", 68 | animation_type="discrete", 69 | gecko_enum_prefix="StyleColumnSpan", 70 | spec="https://drafts.csswg.org/css-multicol/#propdef-column-span", 71 | affects="layout", 72 | )} 73 | 74 | ${helpers.predefined_type( 75 | "column-rule-style", 76 | "BorderStyle", 77 | "computed::BorderStyle::None", 78 | engines="gecko", 79 | initial_specified_value="specified::BorderStyle::None", 80 | animation_type="discrete", 81 | spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-style", 82 | affects="paint", 83 | )} 84 | -------------------------------------------------------------------------------- /style/properties/longhands/counters.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.predefined_type( 8 | "content", 9 | "Content", 10 | "computed::Content::normal()", 11 | engines="gecko servo", 12 | initial_specified_value="specified::Content::normal()", 13 | animation_type="discrete", 14 | spec="https://drafts.csswg.org/css-content/#propdef-content", 15 | servo_restyle_damage="rebuild_box", 16 | affects="layout", 17 | )} 18 | 19 | ${helpers.predefined_type( 20 | "counter-increment", 21 | "CounterIncrement", 22 | engines="gecko servo", 23 | servo_pref="layout.unimplemented", 24 | initial_value="Default::default()", 25 | animation_type="discrete", 26 | spec="https://drafts.csswg.org/css-lists/#propdef-counter-increment", 27 | servo_restyle_damage="rebuild_box", 28 | affects="layout", 29 | )} 30 | 31 | ${helpers.predefined_type( 32 | "counter-reset", 33 | "CounterReset", 34 | engines="gecko servo", 35 | servo_pref="layout.unimplemented", 36 | initial_value="Default::default()", 37 | animation_type="discrete", 38 | spec="https://drafts.csswg.org/css-lists-3/#propdef-counter-reset", 39 | servo_restyle_damage="rebuild_box", 40 | affects="layout", 41 | )} 42 | 43 | ${helpers.predefined_type( 44 | "counter-set", 45 | "CounterSet", 46 | engines="gecko", 47 | initial_value="Default::default()", 48 | animation_type="discrete", 49 | spec="https://drafts.csswg.org/css-lists-3/#propdef-counter-set", 50 | servo_restyle_damage="rebuild_box", 51 | affects="layout", 52 | )} 53 | -------------------------------------------------------------------------------- /style/properties/longhands/effects.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.predefined_type( 8 | "opacity", 9 | "Opacity", 10 | "1.0", 11 | engines="gecko servo", 12 | flags="CAN_ANIMATE_ON_COMPOSITOR", 13 | spec="https://drafts.csswg.org/css-color/#transparency", 14 | servo_restyle_damage="repaint", 15 | affects="paint", 16 | )} 17 | 18 | ${helpers.predefined_type( 19 | "box-shadow", 20 | "BoxShadow", 21 | None, 22 | engines="gecko servo", 23 | vector=True, 24 | simple_vector_bindings=True, 25 | vector_animation_type="with_zero", 26 | extra_prefixes="webkit", 27 | ignored_when_colors_disabled=True, 28 | spec="https://drafts.csswg.org/css-backgrounds/#box-shadow", 29 | affects="overflow", 30 | )} 31 | 32 | ${helpers.predefined_type( 33 | "clip", 34 | "ClipRectOrAuto", 35 | "computed::ClipRectOrAuto::auto()", 36 | engines="gecko servo", 37 | boxed=True, 38 | allow_quirks="Yes", 39 | spec="https://drafts.fxtf.org/css-masking/#clip-property", 40 | affects="overflow", 41 | )} 42 | 43 | ${helpers.predefined_type( 44 | "filter", 45 | "Filter", 46 | None, 47 | engines="gecko servo", 48 | vector=True, 49 | simple_vector_bindings=True, 50 | gecko_ffi_name="mFilters", 51 | separator="Space", 52 | vector_animation_type="with_zero", 53 | extra_prefixes="webkit", 54 | spec="https://drafts.fxtf.org/filters/#propdef-filter", 55 | affects="overflow", 56 | servo_restyle_damage="repaint", 57 | )} 58 | 59 | ${helpers.predefined_type( 60 | "backdrop-filter", 61 | "Filter", 62 | None, 63 | engines="gecko servo", 64 | vector=True, 65 | simple_vector_bindings=True, 66 | gecko_ffi_name="mBackdropFilters", 67 | separator="Space", 68 | vector_animation_type="with_zero", 69 | gecko_pref="layout.css.backdrop-filter.enabled", 70 | servo_pref="layout.unimplemented", 71 | spec="https://drafts.fxtf.org/filter-effects-2/#propdef-backdrop-filter", 72 | affects="overflow", 73 | )} 74 | 75 | ${helpers.single_keyword( 76 | "mix-blend-mode", 77 | """normal multiply screen overlay darken lighten color-dodge 78 | color-burn hard-light soft-light difference exclusion hue 79 | saturation color luminosity plus-lighter""", 80 | engines="gecko servo", 81 | gecko_enum_prefix="StyleBlend", 82 | animation_type="discrete", 83 | spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode", 84 | affects="paint", 85 | servo_restyle_damage="repaint", 86 | )} 87 | -------------------------------------------------------------------------------- /style/properties/longhands/inherited_table.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.single_keyword( 8 | "border-collapse", 9 | "separate collapse", 10 | engines="gecko servo", 11 | gecko_enum_prefix="StyleBorderCollapse", 12 | animation_type="discrete", 13 | spec="https://drafts.csswg.org/css-tables/#propdef-border-collapse", 14 | servo_restyle_damage = "rebuild_box", 15 | affects="layout", 16 | )} 17 | 18 | ${helpers.single_keyword( 19 | "empty-cells", 20 | "show hide", 21 | engines="gecko servo", 22 | gecko_enum_prefix="StyleEmptyCells", 23 | animation_type="discrete", 24 | spec="https://drafts.csswg.org/css-tables/#propdef-empty-cells", 25 | servo_restyle_damage="rebuild_box", 26 | affects="paint", 27 | )} 28 | 29 | ${helpers.predefined_type( 30 | "caption-side", 31 | "table::CaptionSide", 32 | "computed::table::CaptionSide::Top", 33 | engines="gecko servo", 34 | animation_type="discrete", 35 | spec="https://drafts.csswg.org/css-tables/#propdef-caption-side", 36 | servo_restyle_damage="rebuild_box", 37 | affects="layout", 38 | )} 39 | 40 | ${helpers.predefined_type( 41 | "border-spacing", 42 | "BorderSpacing", 43 | "computed::BorderSpacing::zero()", 44 | engines="gecko servo", 45 | boxed=True, 46 | spec="https://drafts.csswg.org/css-tables/#propdef-border-spacing", 47 | servo_restyle_damage="rebuild_box", 48 | affects="layout", 49 | )} 50 | -------------------------------------------------------------------------------- /style/properties/longhands/list.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.single_keyword( 8 | "list-style-position", 9 | "outside inside", 10 | engines="gecko servo", 11 | gecko_enum_prefix="StyleListStylePosition", 12 | animation_type="discrete", 13 | spec="https://drafts.csswg.org/css-lists/#propdef-list-style-position", 14 | servo_restyle_damage="rebuild_box", 15 | affects="layout", 16 | )} 17 | 18 | // TODO(pcwalton): Implement the full set of counter styles per CSS-COUNTER-STYLES [1] 6.1: 19 | // 20 | // decimal-leading-zero, armenian, upper-armenian, lower-armenian, georgian, lower-roman, 21 | // upper-roman 22 | // 23 | // [1]: http://dev.w3.org/csswg/css-counter-styles/ 24 | % if engine == "servo": 25 | ${helpers.single_keyword( 26 | "list-style-type", 27 | """disc none circle square disclosure-open disclosure-closed 28 | decimal lower-alpha upper-alpha arabic-indic bengali cambodian cjk-decimal devanagari 29 | gujarati gurmukhi kannada khmer lao malayalam mongolian myanmar oriya persian telugu 30 | thai tibetan cjk-earthly-branch cjk-heavenly-stem lower-greek hiragana hiragana-iroha 31 | katakana katakana-iroha 32 | """, 33 | engines="servo", 34 | animation_type="discrete", 35 | spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type", 36 | servo_restyle_damage="rebuild_box", 37 | affects="layout", 38 | )} 39 | % endif 40 | % if engine == "gecko": 41 | ${helpers.predefined_type( 42 | "list-style-type", 43 | "ListStyleType", 44 | "computed::ListStyleType::disc()", 45 | engines="gecko", 46 | initial_specified_value="specified::ListStyleType::disc()", 47 | animation_type="discrete", 48 | spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type", 49 | servo_restyle_damage="rebuild_box", 50 | affects="layout", 51 | )} 52 | % endif 53 | 54 | ${helpers.predefined_type( 55 | "list-style-image", 56 | "Image", 57 | engines="gecko servo", 58 | initial_value="computed::Image::None", 59 | initial_specified_value="specified::Image::None", 60 | animation_type="discrete", 61 | spec="https://drafts.csswg.org/css-lists/#propdef-list-style-image", 62 | servo_restyle_damage="rebuild_box", 63 | affects="layout", 64 | )} 65 | 66 | ${helpers.predefined_type( 67 | "quotes", 68 | "Quotes", 69 | "computed::Quotes::get_initial_value()", 70 | engines="gecko servo", 71 | animation_type="discrete", 72 | spec="https://drafts.csswg.org/css-content/#propdef-quotes", 73 | servo_restyle_damage="rebuild_box", 74 | affects="layout", 75 | )} 76 | -------------------------------------------------------------------------------- /style/properties/longhands/margin.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | <% from data import ALL_SIDES, DEFAULT_RULES, DEFAULT_RULES_AND_PAGE, POSITION_TRY_RULE, maybe_moz_logical_alias %> 7 | 8 | % for index, side in enumerate(ALL_SIDES): 9 | <% 10 | spec = "https://drafts.csswg.org/css-box/#propdef-margin-%s" % side[0] 11 | if side[1]: 12 | spec = "https://drafts.csswg.org/css-logical-props/#propdef-margin-%s" % side[1] 13 | %> 14 | ${helpers.predefined_type( 15 | "margin-%s" % side[0], 16 | "Margin", 17 | "computed::Margin::zero()", 18 | engines="gecko servo", 19 | aliases=maybe_moz_logical_alias(engine, side, "-moz-margin-%s"), 20 | allow_quirks="No" if side[1] else "Yes", 21 | logical=side[1], 22 | logical_group="margin", 23 | gecko_ffi_name="mMargin.{}".format(index), 24 | spec=spec, 25 | rule_types_allowed=(DEFAULT_RULES if side[1] else DEFAULT_RULES_AND_PAGE) | POSITION_TRY_RULE, 26 | servo_restyle_damage="rebuild_box", 27 | affects="layout", 28 | )} 29 | % endfor 30 | 31 | ${helpers.predefined_type( 32 | "overflow-clip-margin", 33 | "Length", 34 | "computed::Length::zero()", 35 | parse_method="parse_non_negative", 36 | engines="gecko servo", 37 | spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-clip-margin", 38 | affects="overflow", 39 | )} 40 | 41 | % for index, side in enumerate(ALL_SIDES): 42 | ${helpers.predefined_type( 43 | "scroll-margin-%s" % side[0], 44 | "Length", 45 | "computed::Length::zero()", 46 | engines="gecko", 47 | logical=side[1], 48 | logical_group="scroll-margin", 49 | gecko_ffi_name="mScrollMargin.{}".format(index), 50 | spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-%s" % side[0], 51 | affects="", 52 | )} 53 | % endfor 54 | -------------------------------------------------------------------------------- /style/properties/longhands/outline.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.predefined_type( 8 | "outline-color", 9 | "Color", 10 | "computed_value::T::currentcolor()", 11 | engines="gecko servo", 12 | initial_specified_value="specified::Color::currentcolor()", 13 | ignored_when_colors_disabled=True, 14 | spec="https://drafts.csswg.org/css-ui/#propdef-outline-color", 15 | servo_restyle_damage="repaint", 16 | affects="paint", 17 | )} 18 | 19 | ${helpers.predefined_type( 20 | "outline-style", 21 | "OutlineStyle", 22 | "computed::OutlineStyle::none()", 23 | engines="gecko servo", 24 | initial_specified_value="specified::OutlineStyle::none()", 25 | animation_type="discrete", 26 | spec="https://drafts.csswg.org/css-ui/#propdef-outline-style", 27 | servo_restyle_damage="repaint", 28 | affects="overflow", 29 | )} 30 | 31 | ${helpers.predefined_type( 32 | "outline-width", 33 | "BorderSideWidth", 34 | "app_units::Au::from_px(3)", 35 | engines="gecko servo", 36 | initial_specified_value="specified::BorderSideWidth::medium()", 37 | spec="https://drafts.csswg.org/css-ui/#propdef-outline-width", 38 | servo_restyle_damage="repaint", 39 | affects="overflow", 40 | )} 41 | 42 | ${helpers.predefined_type( 43 | "outline-offset", 44 | "Length", 45 | "crate::values::computed::Length::new(0.)", 46 | engines="gecko servo", 47 | spec="https://drafts.csswg.org/css-ui/#propdef-outline-offset", 48 | servo_restyle_damage="repaint", 49 | affects="overflow", 50 | )} 51 | -------------------------------------------------------------------------------- /style/properties/longhands/padding.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | <% from data import ALL_SIDES, maybe_moz_logical_alias %> 7 | 8 | % for index, side in enumerate(ALL_SIDES): 9 | <% 10 | spec = "https://drafts.csswg.org/css-box/#propdef-padding-%s" % side[0] 11 | if side[1]: 12 | spec = "https://drafts.csswg.org/css-logical-props/#propdef-padding-%s" % side[1] 13 | %> 14 | ${helpers.predefined_type( 15 | "padding-%s" % side[0], 16 | "NonNegativeLengthPercentage", 17 | "computed::NonNegativeLengthPercentage::zero()", 18 | engines="gecko servo", 19 | aliases=maybe_moz_logical_alias(engine, side, "-moz-padding-%s"), 20 | logical=side[1], 21 | logical_group="padding", 22 | spec=spec, 23 | gecko_ffi_name="mPadding.{}".format(index), 24 | allow_quirks="No" if side[1] else "Yes", 25 | servo_restyle_damage="rebuild_box", 26 | affects="layout", 27 | )} 28 | % endfor 29 | 30 | % for index, side in enumerate(ALL_SIDES): 31 | ${helpers.predefined_type( 32 | "scroll-padding-%s" % side[0], 33 | "NonNegativeLengthPercentageOrAuto", 34 | "computed::NonNegativeLengthPercentageOrAuto::auto()", 35 | engines="gecko", 36 | logical=side[1], 37 | logical_group="scroll-padding", 38 | gecko_ffi_name="mScrollPadding.{}".format(index), 39 | spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-%s" % side[0], 40 | affects="", 41 | )} 42 | % endfor 43 | -------------------------------------------------------------------------------- /style/properties/longhands/page.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | <% from data import PAGE_RULE %> 7 | 8 | ${helpers.predefined_type( 9 | "size", 10 | "PageSize", 11 | "computed::PageSize::auto()", 12 | engines="gecko", 13 | initial_specified_value="specified::PageSize::auto()", 14 | spec="https://drafts.csswg.org/css-page-3/#page-size-prop", 15 | boxed=True, 16 | animation_type="none", 17 | rule_types_allowed=PAGE_RULE, 18 | affects="layout", 19 | )} 20 | 21 | ${helpers.predefined_type( 22 | "page", 23 | "PageName", 24 | "computed::PageName::auto()", 25 | engines="gecko", 26 | spec="https://drafts.csswg.org/css-page-3/#using-named-pages", 27 | animation_type="discrete", 28 | affects="layout", 29 | )} 30 | 31 | ${helpers.predefined_type( 32 | "page-orientation", 33 | "PageOrientation", 34 | "computed::PageOrientation::Upright", 35 | engines="gecko", 36 | initial_specified_value="specified::PageOrientation::Upright", 37 | spec="https://drafts.csswg.org/css-page-3/#page-orientation-prop", 38 | animation_type="none", 39 | rule_types_allowed=PAGE_RULE, 40 | affects="layout", 41 | )} 42 | -------------------------------------------------------------------------------- /style/properties/longhands/table.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.single_keyword( 8 | "table-layout", 9 | "auto fixed", 10 | engines="gecko servo", 11 | gecko_ffi_name="mLayoutStrategy", 12 | animation_type="discrete", 13 | gecko_enum_prefix="StyleTableLayout", 14 | spec="https://drafts.csswg.org/css-tables/#propdef-table-layout", 15 | servo_restyle_damage="rebuild_box", 16 | affects="layout", 17 | )} 18 | 19 | ${helpers.predefined_type( 20 | "-x-span", 21 | "Integer", 22 | "1", 23 | engines="gecko", 24 | spec="Internal-only (for `` pres attr)", 25 | animation_type="none", 26 | enabled_in="", 27 | affects="layout", 28 | )} 29 | -------------------------------------------------------------------------------- /style/properties/longhands/text.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.predefined_type( 8 | "text-overflow", 9 | "TextOverflow", 10 | "computed::TextOverflow::get_initial_value()", 11 | engines="gecko servo", 12 | servo_pref="layout.unimplemented", 13 | animation_type="discrete", 14 | boxed=True, 15 | spec="https://drafts.csswg.org/css-ui/#propdef-text-overflow", 16 | servo_restyle_damage="rebuild_box", 17 | affects="paint", 18 | )} 19 | 20 | ${helpers.single_keyword( 21 | "unicode-bidi", 22 | "normal embed isolate bidi-override isolate-override plaintext", 23 | engines="gecko servo", 24 | gecko_enum_prefix="StyleUnicodeBidi", 25 | animation_type="none", 26 | spec="https://drafts.csswg.org/css-writing-modes/#propdef-unicode-bidi", 27 | servo_restyle_damage="rebuild_box", 28 | affects="layout", 29 | )} 30 | 31 | ${helpers.predefined_type( 32 | "text-decoration-line", 33 | "TextDecorationLine", 34 | "specified::TextDecorationLine::none()", 35 | engines="gecko servo", 36 | initial_specified_value="specified::TextDecorationLine::none()", 37 | animation_type="discrete", 38 | spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-line", 39 | servo_restyle_damage="rebuild_box", 40 | affects="overflow", 41 | )} 42 | 43 | ${helpers.single_keyword( 44 | "text-decoration-style", 45 | "solid double dotted dashed wavy -moz-none", 46 | engines="gecko servo", 47 | gecko_enum_prefix="StyleTextDecorationStyle", 48 | animation_type="discrete", 49 | spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-style", 50 | affects="overflow", 51 | )} 52 | 53 | ${helpers.predefined_type( 54 | "text-decoration-color", 55 | "Color", 56 | "computed_value::T::currentcolor()", 57 | engines="gecko servo", 58 | initial_specified_value="specified::Color::currentcolor()", 59 | ignored_when_colors_disabled=True, 60 | spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-color", 61 | affects="paint", 62 | )} 63 | 64 | ${helpers.predefined_type( 65 | "initial-letter", 66 | "InitialLetter", 67 | "computed::InitialLetter::normal()", 68 | engines="gecko", 69 | initial_specified_value="specified::InitialLetter::normal()", 70 | animation_type="discrete", 71 | gecko_pref="layout.css.initial-letter.enabled", 72 | spec="https://drafts.csswg.org/css-inline/#sizing-drop-initials", 73 | affects="layout", 74 | )} 75 | 76 | ${helpers.predefined_type( 77 | "text-decoration-thickness", 78 | "TextDecorationLength", 79 | "generics::text::GenericTextDecorationLength::Auto", 80 | engines="gecko", 81 | initial_specified_value="generics::text::GenericTextDecorationLength::Auto", 82 | spec="https://drafts.csswg.org/css-text-decor-4/#text-decoration-width-property", 83 | affects="overflow", 84 | )} 85 | -------------------------------------------------------------------------------- /style/properties/longhands/xul.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.single_keyword( 8 | "-moz-box-align", 9 | "stretch start center baseline end", 10 | engines="gecko", 11 | gecko_ffi_name="mBoxAlign", 12 | gecko_enum_prefix="StyleBoxAlign", 13 | animation_type="discrete", 14 | aliases="-webkit-box-align", 15 | spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-align)", 16 | affects="layout", 17 | )} 18 | 19 | ${helpers.single_keyword( 20 | "-moz-box-direction", 21 | "normal reverse", 22 | engines="gecko", 23 | gecko_ffi_name="mBoxDirection", 24 | gecko_enum_prefix="StyleBoxDirection", 25 | animation_type="discrete", 26 | aliases="-webkit-box-direction", 27 | spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-direction)", 28 | affects="layout", 29 | )} 30 | 31 | ${helpers.predefined_type( 32 | "-moz-box-flex", 33 | "NonNegativeNumber", 34 | "From::from(0.)", 35 | engines="gecko", 36 | gecko_ffi_name="mBoxFlex", 37 | aliases="-webkit-box-flex", 38 | spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-flex)", 39 | affects="layout", 40 | )} 41 | 42 | ${helpers.single_keyword( 43 | "-moz-box-orient", 44 | "horizontal vertical", 45 | engines="gecko", 46 | gecko_ffi_name="mBoxOrient", 47 | gecko_aliases="inline-axis=horizontal block-axis=vertical", 48 | gecko_enum_prefix="StyleBoxOrient", 49 | animation_type="discrete", 50 | aliases="-webkit-box-orient", 51 | spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-orient)", 52 | affects="layout", 53 | )} 54 | 55 | ${helpers.single_keyword( 56 | "-moz-box-pack", 57 | "start center end justify", 58 | engines="gecko", 59 | gecko_ffi_name="mBoxPack", 60 | gecko_enum_prefix="StyleBoxPack", 61 | animation_type="discrete", 62 | aliases="-webkit-box-pack", 63 | spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-pack)", 64 | affects="layout", 65 | )} 66 | 67 | // NOTE(heycam): Odd that the initial value is 1 yet 0 is a valid value. There 68 | // are uses of `-moz-box-ordinal-group: 0` in the tree, too. 69 | ${helpers.predefined_type( 70 | "-moz-box-ordinal-group", 71 | "Integer", 72 | "1", 73 | engines="gecko", 74 | parse_method="parse_non_negative", 75 | aliases="-webkit-box-ordinal-group", 76 | gecko_ffi_name="mBoxOrdinal", 77 | animation_type="discrete", 78 | spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-box-ordinal-group)", 79 | affects="layout", 80 | )} 81 | -------------------------------------------------------------------------------- /style/properties/properties.html.mako: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Supported CSS properties in Servo 7 | 8 | 9 | 10 | 11 | 12 |
13 |

CSS properties currently supported in Servo

14 | % for kind, props in sorted(properties.items()): 15 |

${kind.capitalize()}

16 | 17 | 18 | 19 | 20 | 21 | % for name, data in sorted(props.items()): 22 | 23 | 24 | 25 | 26 | % endfor 27 |
NamePref
${name}${data['pref'] or ''}
28 | % endfor 29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /style/properties/shorthands/counters.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | -------------------------------------------------------------------------------- /style/properties/shorthands/effects.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | -------------------------------------------------------------------------------- /style/properties/shorthands/inherited_box.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | -------------------------------------------------------------------------------- /style/properties/shorthands/inherited_svg.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | <%helpers:shorthand 8 | name="marker" 9 | engines="gecko" 10 | sub_properties="marker-start marker-end marker-mid" 11 | spec="https://svgwg.org/svg2-draft/painting.html#MarkerShorthand" 12 | > 13 | use crate::values::specified::url::UrlOrNone; 14 | 15 | pub fn parse_value<'i, 't>( 16 | context: &ParserContext, 17 | input: &mut Parser<'i, 't>, 18 | ) -> Result> { 19 | use crate::parser::Parse; 20 | let url = UrlOrNone::parse(context, input)?; 21 | 22 | Ok(expanded! { 23 | marker_start: url.clone(), 24 | marker_mid: url.clone(), 25 | marker_end: url, 26 | }) 27 | } 28 | 29 | impl<'a> ToCss for LonghandsToSerialize<'a> { 30 | fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { 31 | if self.marker_start == self.marker_mid && self.marker_mid == self.marker_end { 32 | self.marker_start.to_css(dest) 33 | } else { 34 | Ok(()) 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /style/properties/shorthands/inherited_table.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | -------------------------------------------------------------------------------- /style/properties/shorthands/inherited_ui.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | -------------------------------------------------------------------------------- /style/properties/shorthands/margin.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | <% from data import DEFAULT_RULES_AND_PAGE, POSITION_TRY_RULE, DEFAULT_RULES_AND_POSITION_TRY %> 7 | 8 | ${helpers.four_sides_shorthand( 9 | "margin", 10 | "margin-%s", 11 | "specified::Margin::parse", 12 | engines="gecko servo", 13 | spec="https://drafts.csswg.org/css-box/#propdef-margin", 14 | rule_types_allowed=DEFAULT_RULES_AND_PAGE | POSITION_TRY_RULE, 15 | allow_quirks="Yes", 16 | )} 17 | 18 | ${helpers.two_properties_shorthand( 19 | "margin-block", 20 | "margin-block-start", 21 | "margin-block-end", 22 | "specified::Margin::parse", 23 | engines="gecko servo", 24 | spec="https://drafts.csswg.org/css-logical/#propdef-margin-block", 25 | rule_types_allowed=DEFAULT_RULES_AND_POSITION_TRY 26 | )} 27 | 28 | ${helpers.two_properties_shorthand( 29 | "margin-inline", 30 | "margin-inline-start", 31 | "margin-inline-end", 32 | "specified::Margin::parse", 33 | engines="gecko servo", 34 | spec="https://drafts.csswg.org/css-logical/#propdef-margin-inline", 35 | rule_types_allowed=DEFAULT_RULES_AND_POSITION_TRY 36 | )} 37 | 38 | ${helpers.four_sides_shorthand( 39 | "scroll-margin", 40 | "scroll-margin-%s", 41 | "specified::Length::parse", 42 | engines="gecko", 43 | spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin", 44 | )} 45 | 46 | ${helpers.two_properties_shorthand( 47 | "scroll-margin-block", 48 | "scroll-margin-block-start", 49 | "scroll-margin-block-end", 50 | "specified::Length::parse", 51 | engines="gecko", 52 | spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-block", 53 | )} 54 | 55 | ${helpers.two_properties_shorthand( 56 | "scroll-margin-inline", 57 | "scroll-margin-inline-start", 58 | "scroll-margin-inline-end", 59 | "specified::Length::parse", 60 | engines="gecko", 61 | spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-inline", 62 | )} 63 | -------------------------------------------------------------------------------- /style/properties/shorthands/outline.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | <%helpers:shorthand name="outline" 8 | engines="gecko servo" 9 | sub_properties="outline-color outline-style outline-width" 10 | spec="https://drafts.csswg.org/css-ui/#propdef-outline"> 11 | use crate::properties::longhands::{outline_color, outline_width, outline_style}; 12 | use crate::values::specified; 13 | use crate::parser::Parse; 14 | 15 | pub fn parse_value<'i, 't>( 16 | context: &ParserContext, 17 | input: &mut Parser<'i, 't>, 18 | ) -> Result> { 19 | let _unused = context; 20 | let mut color = None; 21 | let mut style = None; 22 | let mut width = None; 23 | let mut any = false; 24 | loop { 25 | if color.is_none() { 26 | if let Ok(value) = input.try_parse(|i| specified::Color::parse(context, i)) { 27 | color = Some(value); 28 | any = true; 29 | continue 30 | } 31 | } 32 | if style.is_none() { 33 | if let Ok(value) = input.try_parse(|input| outline_style::parse(context, input)) { 34 | style = Some(value); 35 | any = true; 36 | continue 37 | } 38 | } 39 | if width.is_none() { 40 | if let Ok(value) = input.try_parse(|input| outline_width::parse(context, input)) { 41 | width = Some(value); 42 | any = true; 43 | continue 44 | } 45 | } 46 | break 47 | } 48 | if any { 49 | Ok(expanded! { 50 | outline_color: unwrap_or_initial!(outline_color, color), 51 | outline_style: unwrap_or_initial!(outline_style, style), 52 | outline_width: unwrap_or_initial!(outline_width, width), 53 | }) 54 | } else { 55 | Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) 56 | } 57 | } 58 | 59 | impl<'a> ToCss for LonghandsToSerialize<'a> { 60 | fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { 61 | let mut wrote_value = false; 62 | 63 | % for name in "color style width".split(): 64 | if *self.outline_${name} != outline_${name}::get_initial_specified_value() { 65 | if wrote_value { 66 | dest.write_char(' ')?; 67 | } 68 | self.outline_${name}.to_css(dest)?; 69 | wrote_value = true; 70 | } 71 | % endfor 72 | 73 | if !wrote_value { 74 | self.outline_style.to_css(dest)?; 75 | } 76 | 77 | Ok(()) 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /style/properties/shorthands/padding.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | <%namespace name="helpers" file="/helpers.mako.rs" /> 6 | 7 | ${helpers.four_sides_shorthand( 8 | "padding", 9 | "padding-%s", 10 | "specified::NonNegativeLengthPercentage::parse", 11 | engines="gecko servo", 12 | spec="https://drafts.csswg.org/css-box-3/#propdef-padding", 13 | allow_quirks="Yes", 14 | )} 15 | 16 | ${helpers.two_properties_shorthand( 17 | "padding-block", 18 | "padding-block-start", 19 | "padding-block-end", 20 | "specified::NonNegativeLengthPercentage::parse", 21 | engines="gecko servo", 22 | spec="https://drafts.csswg.org/css-logical/#propdef-padding-block" 23 | )} 24 | 25 | ${helpers.two_properties_shorthand( 26 | "padding-inline", 27 | "padding-inline-start", 28 | "padding-inline-end", 29 | "specified::NonNegativeLengthPercentage::parse", 30 | engines="gecko servo", 31 | spec="https://drafts.csswg.org/css-logical/#propdef-padding-inline" 32 | )} 33 | 34 | ${helpers.four_sides_shorthand( 35 | "scroll-padding", 36 | "scroll-padding-%s", 37 | "specified::NonNegativeLengthPercentageOrAuto::parse", 38 | engines="gecko", 39 | spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding" 40 | )} 41 | 42 | ${helpers.two_properties_shorthand( 43 | "scroll-padding-block", 44 | "scroll-padding-block-start", 45 | "scroll-padding-block-end", 46 | "specified::NonNegativeLengthPercentageOrAuto::parse", 47 | engines="gecko", 48 | spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-block" 49 | )} 50 | 51 | ${helpers.two_properties_shorthand( 52 | "scroll-padding-inline", 53 | "scroll-padding-inline-start", 54 | "scroll-padding-inline-end", 55 | "specified::NonNegativeLengthPercentageOrAuto::parse", 56 | engines="gecko", 57 | spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-inline" 58 | )} 59 | -------------------------------------------------------------------------------- /style/properties/shorthands/page.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | -------------------------------------------------------------------------------- /style/properties/shorthands/table.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | -------------------------------------------------------------------------------- /style/properties/shorthands/xul.mako.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | -------------------------------------------------------------------------------- /style/properties_and_values/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Properties and Values 6 | //! 7 | //! https://drafts.css-houdini.org/css-properties-values-api-1/ 8 | 9 | pub mod registry; 10 | pub mod rule; 11 | pub mod syntax; 12 | pub mod value; 13 | -------------------------------------------------------------------------------- /style/properties_and_values/syntax/ascii.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | /// Trims ASCII whitespace characters from a slice, and returns the trimmed input. 6 | pub fn trim_ascii_whitespace(input: &str) -> &str { 7 | if input.is_empty() { 8 | return input; 9 | } 10 | 11 | let mut start = 0; 12 | { 13 | let mut iter = input.as_bytes().iter(); 14 | loop { 15 | let byte = match iter.next() { 16 | Some(b) => b, 17 | None => return "", 18 | }; 19 | 20 | if !byte.is_ascii_whitespace() { 21 | break; 22 | } 23 | start += 1; 24 | } 25 | } 26 | 27 | let mut end = input.len(); 28 | assert!(start < end); 29 | { 30 | let mut iter = input.as_bytes()[start..].iter().rev(); 31 | loop { 32 | let byte = match iter.next() { 33 | Some(b) => b, 34 | None => { 35 | debug_assert!(false, "We should have caught this in the loop above!"); 36 | return ""; 37 | }, 38 | }; 39 | 40 | if !byte.is_ascii_whitespace() { 41 | break; 42 | } 43 | end -= 1; 44 | } 45 | } 46 | 47 | &input[start..end] 48 | } 49 | 50 | #[test] 51 | fn trim_ascii_whitespace_test() { 52 | fn test(i: &str, o: &str) { 53 | assert_eq!(trim_ascii_whitespace(i), o) 54 | } 55 | 56 | test("", ""); 57 | test(" ", ""); 58 | test(" a b c ", "a b c"); 59 | test(" \t \t \ta b c \t \t \t \t", "a b c"); 60 | } 61 | -------------------------------------------------------------------------------- /style/queries/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Code shared between [media queries][mq] and [container queries][cq]. 6 | //! 7 | //! [mq]: https://drafts.csswg.org/mediaqueries/ 8 | //! [cq]: https://drafts.csswg.org/css-contain-3/#container-rule 9 | 10 | pub mod condition; 11 | 12 | #[macro_use] 13 | pub mod feature; 14 | pub mod feature_expression; 15 | pub mod values; 16 | 17 | pub use self::condition::QueryCondition; 18 | pub use self::feature::FeatureFlags; 19 | pub use self::feature_expression::{FeatureType, QueryFeatureExpression}; 20 | -------------------------------------------------------------------------------- /style/queries/values.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Common feature values between media and container features. 6 | 7 | use app_units::Au; 8 | use euclid::default::Size2D; 9 | 10 | /// The orientation media / container feature. 11 | /// https://drafts.csswg.org/mediaqueries-5/#orientation 12 | /// https://drafts.csswg.org/css-contain-3/#orientation 13 | #[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)] 14 | #[repr(u8)] 15 | #[allow(missing_docs)] 16 | pub enum Orientation { 17 | Portrait, 18 | Landscape, 19 | } 20 | 21 | impl Orientation { 22 | /// A helper to evaluate a orientation query given a generic size getter. 23 | pub fn eval(size: Size2D, value: Option) -> bool { 24 | let query_orientation = match value { 25 | Some(v) => v, 26 | None => return true, 27 | }; 28 | 29 | // Per spec, square viewports should be 'portrait' 30 | let is_landscape = size.width > size.height; 31 | match query_orientation { 32 | Self::Landscape => is_landscape, 33 | Self::Portrait => !is_landscape, 34 | } 35 | } 36 | } 37 | 38 | /// Values for the prefers-color-scheme media feature. 39 | #[derive(Clone, Copy, Debug, FromPrimitive, Parse, PartialEq, ToCss)] 40 | #[repr(u8)] 41 | #[allow(missing_docs)] 42 | pub enum PrefersColorScheme { 43 | Light, 44 | Dark, 45 | } 46 | -------------------------------------------------------------------------------- /style/rule_tree/source.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | #![forbid(unsafe_code)] 6 | 7 | use crate::properties::PropertyDeclarationBlock; 8 | use crate::shared_lock::{Locked, SharedRwLockReadGuard}; 9 | use servo_arc::Arc; 10 | use std::io::Write; 11 | use std::ptr; 12 | 13 | /// A style source for the rule node. It is a declaration block that may come from either a style 14 | /// rule or a standalone block like animations / transitions / smil / preshints / style attr... 15 | /// 16 | /// Keeping the style rule around would provide more debugability, but also causes more 17 | /// pointer-chasing in the common code-path, which is undesired. If needed, we could keep it around 18 | /// in debug builds or something along those lines. 19 | #[derive(Clone, Debug)] 20 | pub struct StyleSource(Arc>); 21 | 22 | impl PartialEq for StyleSource { 23 | fn eq(&self, other: &Self) -> bool { 24 | Arc::ptr_eq(&self.0, &other.0) 25 | } 26 | } 27 | 28 | impl StyleSource { 29 | #[inline] 30 | pub(super) fn key(&self) -> ptr::NonNull<()> { 31 | self.0.raw_ptr() 32 | } 33 | 34 | /// Creates a StyleSource from a PropertyDeclarationBlock. 35 | #[inline] 36 | pub fn from_declarations(decls: Arc>) -> Self { 37 | Self(decls) 38 | } 39 | 40 | pub(super) fn dump(&self, guard: &SharedRwLockReadGuard, writer: &mut W) { 41 | let _ = write!(writer, " -> {:?}", self.read(guard).declarations()); 42 | } 43 | 44 | /// Read the style source guard, and obtain thus read access to the 45 | /// underlying property declaration block. 46 | #[inline] 47 | pub fn read<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> &'a PropertyDeclarationBlock { 48 | self.0.read_with(guard) 49 | } 50 | 51 | /// Returns the declaration block if applicable, otherwise None. 52 | #[inline] 53 | pub fn get(&self) -> &Arc> { 54 | &self.0 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /style/rule_tree/unsafe_box.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | #![allow(unsafe_code)] 6 | 7 | use std::mem::ManuallyDrop; 8 | use std::ops::Deref; 9 | use std::ptr; 10 | 11 | /// An unsafe box, derefs to `T`. 12 | pub(super) struct UnsafeBox { 13 | inner: ManuallyDrop>, 14 | } 15 | 16 | impl UnsafeBox { 17 | /// Creates a new unsafe box. 18 | pub(super) fn from_box(value: Box) -> Self { 19 | Self { 20 | inner: ManuallyDrop::new(value), 21 | } 22 | } 23 | 24 | /// Creates a new box from a pointer. 25 | /// 26 | /// # Safety 27 | /// 28 | /// The input should point to a valid `T`. 29 | pub(super) unsafe fn from_raw(ptr: *mut T) -> Self { 30 | Self { 31 | inner: ManuallyDrop::new(Box::from_raw(ptr)), 32 | } 33 | } 34 | 35 | /// Creates a new unsafe box from an existing one. 36 | /// 37 | /// # Safety 38 | /// 39 | /// There is no refcounting or whatever else in an unsafe box, so this 40 | /// operation can lead to double frees. 41 | pub(super) unsafe fn clone(this: &Self) -> Self { 42 | Self { 43 | inner: ptr::read(&this.inner), 44 | } 45 | } 46 | 47 | /// Returns a mutable reference to the inner value of this unsafe box. 48 | /// 49 | /// # Safety 50 | /// 51 | /// Given `Self::clone`, nothing prevents anyone from creating 52 | /// multiple mutable references to the inner value, which is completely UB. 53 | pub(crate) unsafe fn deref_mut(this: &mut Self) -> &mut T { 54 | &mut this.inner 55 | } 56 | 57 | /// Drops the inner value of this unsafe box. 58 | /// 59 | /// # Safety 60 | /// 61 | /// Given this doesn't consume the unsafe box itself, this has the same 62 | /// safety caveats as `ManuallyDrop::drop`. 63 | pub(super) unsafe fn drop(this: &mut Self) { 64 | ManuallyDrop::drop(&mut this.inner) 65 | } 66 | } 67 | 68 | impl Deref for UnsafeBox { 69 | type Target = T; 70 | 71 | fn deref(&self) -> &Self::Target { 72 | &self.inner 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /style/servo/mod.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Servo-specific bits of the style system. 6 | //! 7 | //! These get compiled out on a Gecko build. 8 | 9 | pub mod media_queries; 10 | pub mod restyle_damage; 11 | pub mod selector_parser; 12 | pub mod url; 13 | -------------------------------------------------------------------------------- /style/simple_buckets_map.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | use crate::{Atom, LocalName, ShrinkIfNeeded}; 6 | use crate::selector_map::{MaybeCaseInsensitiveHashMap, PrecomputedHashMap}; 7 | 8 | /// A map for filtering by easily-discernable features in a selector. 9 | #[derive(Clone, Debug, MallocSizeOf)] 10 | pub struct SimpleBucketsMap { 11 | pub classes: MaybeCaseInsensitiveHashMap, 12 | pub ids: MaybeCaseInsensitiveHashMap, 13 | pub local_names: PrecomputedHashMap, 14 | } 15 | 16 | impl Default for SimpleBucketsMap { 17 | fn default() -> Self { 18 | // TODO(dshin): This is a bit annoying - even if these maps would be empty, 19 | // deriving this trait requires `T: Default` 20 | // This is a known issue - See https://github.com/rust-lang/rust/issues/26925. 21 | Self { 22 | classes: Default::default(), 23 | ids: Default::default(), 24 | local_names: Default::default(), 25 | } 26 | } 27 | } 28 | 29 | impl SimpleBucketsMap { 30 | /// Clears the map. 31 | #[inline(always)] 32 | pub fn clear(&mut self) { 33 | self.classes.clear(); 34 | self.ids.clear(); 35 | self.local_names.clear(); 36 | } 37 | 38 | /// Shrink the capacity of the map if needed. 39 | #[inline(always)] 40 | pub fn shrink_if_needed(&mut self) { 41 | self.classes.shrink_if_needed(); 42 | self.ids.shrink_if_needed(); 43 | self.local_names.shrink_if_needed(); 44 | } 45 | 46 | /// Returns whether there's nothing in the map. 47 | #[inline(always)] 48 | pub fn is_empty(&self) -> bool { 49 | self.classes.is_empty() && 50 | self.ids.is_empty() && 51 | self.local_names.is_empty() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /style/stylesheets/counter_style_rule.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | #![allow(missing_docs)] 6 | 7 | pub use crate::counter_style::CounterStyleRuleData as CounterStyleRule; 8 | -------------------------------------------------------------------------------- /style/stylesheets/font_face_rule.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | #![allow(missing_docs)] 6 | 7 | pub use crate::font_face::FontFaceRuleData as FontFaceRule; 8 | -------------------------------------------------------------------------------- /style/stylesheets/loader.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! The stylesheet loader is the abstraction used to trigger network requests 6 | //! for `@import` rules. 7 | 8 | use crate::media_queries::MediaList; 9 | use crate::parser::ParserContext; 10 | use crate::shared_lock::{Locked, SharedRwLock}; 11 | use crate::stylesheets::import_rule::{ImportLayer, ImportRule, ImportSupportsCondition}; 12 | use crate::values::CssUrl; 13 | use cssparser::SourceLocation; 14 | use servo_arc::Arc; 15 | 16 | /// The stylesheet loader is the abstraction used to trigger network requests 17 | /// for `@import` rules. 18 | pub trait StylesheetLoader { 19 | /// Request a stylesheet after parsing a given `@import` rule, and return 20 | /// the constructed `@import` rule. 21 | fn request_stylesheet( 22 | &self, 23 | url: CssUrl, 24 | location: SourceLocation, 25 | context: &ParserContext, 26 | lock: &SharedRwLock, 27 | media: Arc>, 28 | supports: Option, 29 | layer: ImportLayer, 30 | ) -> Arc>; 31 | } 32 | -------------------------------------------------------------------------------- /style/stylesheets/media_rule.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! An [`@media`][media] rule. 6 | //! 7 | //! [media]: https://drafts.csswg.org/css-conditional/#at-ruledef-media 8 | 9 | use crate::media_queries::MediaList; 10 | use crate::shared_lock::{DeepCloneWithLock, Locked}; 11 | use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; 12 | use crate::str::CssStringWriter; 13 | use crate::stylesheets::CssRules; 14 | use cssparser::SourceLocation; 15 | #[cfg(feature = "gecko")] 16 | use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; 17 | use servo_arc::Arc; 18 | use std::fmt::{self, Write}; 19 | use style_traits::{CssWriter, ToCss}; 20 | 21 | /// An [`@media`][media] rule. 22 | /// 23 | /// [media]: https://drafts.csswg.org/css-conditional/#at-ruledef-media 24 | #[derive(Debug, ToShmem)] 25 | pub struct MediaRule { 26 | /// The list of media queries used by this media rule. 27 | pub media_queries: Arc>, 28 | /// The nested rules to this media rule. 29 | pub rules: Arc>, 30 | /// The source position where this media rule was found. 31 | pub source_location: SourceLocation, 32 | } 33 | 34 | impl MediaRule { 35 | /// Measure heap usage. 36 | #[cfg(feature = "gecko")] 37 | pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { 38 | // Measurement of other fields may be added later. 39 | self.rules.unconditional_shallow_size_of(ops) + 40 | self.rules.read_with(guard).size_of(guard, ops) 41 | } 42 | } 43 | 44 | impl ToCssWithGuard for MediaRule { 45 | // Serialization of MediaRule is not specced. 46 | // https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSMediaRule 47 | fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { 48 | dest.write_str("@media ")?; 49 | self.media_queries 50 | .read_with(guard) 51 | .to_css(&mut CssWriter::new(dest))?; 52 | self.rules.read_with(guard).to_css_block(guard, dest) 53 | } 54 | } 55 | 56 | impl DeepCloneWithLock for MediaRule { 57 | fn deep_clone_with_lock( 58 | &self, 59 | lock: &SharedRwLock, 60 | guard: &SharedRwLockReadGuard, 61 | ) -> Self { 62 | let media_queries = self.media_queries.read_with(guard); 63 | let rules = self.rules.read_with(guard); 64 | MediaRule { 65 | media_queries: Arc::new(lock.wrap(media_queries.clone())), 66 | rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard))), 67 | source_location: self.source_location.clone(), 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /style/stylesheets/namespace_rule.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! The `@namespace` at-rule. 6 | 7 | use crate::shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; 8 | use crate::str::CssStringWriter; 9 | use crate::{Namespace, Prefix}; 10 | use cssparser::SourceLocation; 11 | use std::fmt::{self, Write}; 12 | use style_traits::{CssWriter, ToCss}; 13 | 14 | /// A `@namespace` rule. 15 | #[derive(Clone, Debug, PartialEq, ToShmem)] 16 | #[allow(missing_docs)] 17 | pub struct NamespaceRule { 18 | /// The namespace prefix, and `None` if it's the default Namespace 19 | pub prefix: Option, 20 | /// The actual namespace url. 21 | pub url: Namespace, 22 | /// The source location this rule was found at. 23 | pub source_location: SourceLocation, 24 | } 25 | 26 | impl ToCssWithGuard for NamespaceRule { 27 | // https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSNamespaceRule 28 | fn to_css( 29 | &self, 30 | _guard: &SharedRwLockReadGuard, 31 | dest_str: &mut CssStringWriter, 32 | ) -> fmt::Result { 33 | let mut dest = CssWriter::new(dest_str); 34 | dest.write_str("@namespace ")?; 35 | if let Some(ref prefix) = self.prefix { 36 | prefix.to_css(&mut dest)?; 37 | dest.write_char(' ')?; 38 | } 39 | dest.write_str("url(")?; 40 | self.url.to_string().to_css(&mut dest)?; 41 | dest.write_str(");") 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /style/stylesheets/nested_declarations_rule.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! A nested declarations rule. 6 | //! https://drafts.csswg.org/css-nesting-1/#nested-declarations-rule 7 | 8 | use crate::properties::PropertyDeclarationBlock; 9 | use crate::shared_lock::{ 10 | DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard, 11 | }; 12 | use crate::str::CssStringWriter; 13 | use cssparser::SourceLocation; 14 | use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; 15 | use servo_arc::Arc; 16 | 17 | /// A nested declarations rule. 18 | #[derive(Clone, Debug, ToShmem)] 19 | pub struct NestedDeclarationsRule { 20 | /// The declarations. 21 | pub block: Arc>, 22 | /// The source position this rule was found at. 23 | pub source_location: SourceLocation, 24 | } 25 | 26 | impl NestedDeclarationsRule { 27 | /// Measure heap usage. 28 | pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { 29 | self.block.unconditional_shallow_size_of(ops) + self.block.read_with(guard).size_of(ops) 30 | } 31 | } 32 | 33 | impl DeepCloneWithLock for NestedDeclarationsRule { 34 | fn deep_clone_with_lock(&self, lock: &SharedRwLock, guard: &SharedRwLockReadGuard) -> Self { 35 | Self { 36 | block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())), 37 | source_location: self.source_location.clone(), 38 | } 39 | } 40 | } 41 | 42 | impl ToCssWithGuard for NestedDeclarationsRule { 43 | fn to_css( 44 | &self, 45 | guard: &SharedRwLockReadGuard, 46 | dest: &mut CssStringWriter, 47 | ) -> std::fmt::Result { 48 | self.block.read_with(guard).to_css(dest) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /style/stylesheets/position_try_rule.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! A [`@position-try`][position-try] rule for Anchor Positioning. 6 | //! 7 | //! [position-try]: https://drafts.csswg.org/css-anchor-position-1/#fallback-rule 8 | 9 | use std::fmt::Write; 10 | 11 | use crate::properties::PropertyDeclarationBlock; 12 | use crate::shared_lock::{ 13 | DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard, 14 | }; 15 | use crate::str::CssStringWriter; 16 | use crate::values::DashedIdent; 17 | use cssparser::SourceLocation; 18 | #[cfg(feature = "gecko")] 19 | use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; 20 | use servo_arc::Arc; 21 | use style_traits::{CssWriter, ToCss}; 22 | 23 | /// A position-try rule. 24 | #[derive(Clone, Debug, ToShmem)] 25 | pub struct PositionTryRule { 26 | /// Name of this position-try rule. 27 | pub name: DashedIdent, 28 | /// The declaration block this position-try rule contains. 29 | pub block: Arc>, 30 | /// The source position this rule was found at. 31 | pub source_location: SourceLocation, 32 | } 33 | 34 | impl PositionTryRule { 35 | /// Measure heap usage. 36 | #[cfg(feature = "gecko")] 37 | pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { 38 | self.block.unconditional_shallow_size_of(ops) + self.block.read_with(guard).size_of(ops) 39 | } 40 | } 41 | 42 | impl DeepCloneWithLock for PositionTryRule { 43 | fn deep_clone_with_lock( 44 | &self, 45 | lock: &SharedRwLock, 46 | guard: &SharedRwLockReadGuard, 47 | ) -> Self { 48 | PositionTryRule { 49 | name: self.name.clone(), 50 | block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())), 51 | source_location: self.source_location.clone(), 52 | } 53 | } 54 | } 55 | 56 | impl ToCssWithGuard for PositionTryRule { 57 | fn to_css( 58 | &self, 59 | guard: &SharedRwLockReadGuard, 60 | dest: &mut CssStringWriter, 61 | ) -> std::fmt::Result { 62 | dest.write_str("@position-try ")?; 63 | self.name.to_css(&mut CssWriter::new(dest))?; 64 | dest.write_str(" { ")?; 65 | let declarations = self.block.read_with(guard); 66 | declarations.to_css(dest)?; 67 | if !declarations.is_empty() { 68 | dest.write_char(' ')?; 69 | } 70 | dest.write_char('}') 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /style/stylesheets/property_rule.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | pub use crate::properties_and_values::registry::PropertyRegistration as PropertyRule; 6 | -------------------------------------------------------------------------------- /style/stylesheets/starting_style_rule.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! before-change style: the `@starting-style` rules. 6 | //! https://drafts.csswg.org/css-transitions-2/#defining-before-change-style 7 | 8 | use crate::shared_lock::{DeepCloneWithLock, Locked}; 9 | use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; 10 | use crate::str::CssStringWriter; 11 | use crate::stylesheets::CssRules; 12 | use cssparser::SourceLocation; 13 | #[cfg(feature = "gecko")] 14 | use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; 15 | use servo_arc::Arc; 16 | use std::fmt::{self, Debug, Write}; 17 | 18 | /// A [`@starting-style`][starting-style] rule. 19 | /// 20 | /// [starting-style]: https://drafts.csswg.org/css-transitions-2/#at-ruledef-starting-style 21 | #[derive(Debug, ToShmem)] 22 | pub struct StartingStyleRule { 23 | /// The nested rules to this starting-style rule. 24 | pub rules: Arc>, 25 | /// The source position where this starting-style rule was found. 26 | pub source_location: SourceLocation, 27 | } 28 | 29 | impl StartingStyleRule { 30 | /// Measure heap usage. 31 | #[cfg(feature = "gecko")] 32 | pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { 33 | self.rules.unconditional_shallow_size_of(ops) + 34 | self.rules.read_with(guard).size_of(guard, ops) 35 | } 36 | } 37 | 38 | impl ToCssWithGuard for StartingStyleRule { 39 | fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { 40 | dest.write_str("@starting-style")?; 41 | self.rules.read_with(guard).to_css_block(guard, dest) 42 | } 43 | } 44 | 45 | impl DeepCloneWithLock for StartingStyleRule { 46 | fn deep_clone_with_lock( 47 | &self, 48 | lock: &SharedRwLock, 49 | guard: &SharedRwLockReadGuard, 50 | ) -> Self { 51 | let rules = self.rules.read_with(guard); 52 | StartingStyleRule { 53 | rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard))), 54 | source_location: self.source_location.clone(), 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /style/stylesheets/style_rule.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! A style rule. 6 | 7 | use crate::properties::PropertyDeclarationBlock; 8 | use crate::selector_parser::SelectorImpl; 9 | use crate::shared_lock::{ 10 | DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard, 11 | }; 12 | use crate::str::CssStringWriter; 13 | use crate::stylesheets::{CssRules, style_or_page_rule_to_css}; 14 | use cssparser::SourceLocation; 15 | #[cfg(feature = "gecko")] 16 | use malloc_size_of::{ 17 | MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf, MallocUnconditionalSizeOf, 18 | }; 19 | use selectors::SelectorList; 20 | use servo_arc::Arc; 21 | use std::fmt::{self, Write}; 22 | 23 | /// A style rule, with selectors and declarations. 24 | #[derive(Debug, ToShmem)] 25 | pub struct StyleRule { 26 | /// The list of selectors in this rule. 27 | pub selectors: SelectorList, 28 | /// The declaration block with the properties it contains. 29 | pub block: Arc>, 30 | /// The nested rules to this style rule. Only non-`None` when nesting is enabled. 31 | pub rules: Option>>, 32 | /// The location in the sheet where it was found. 33 | pub source_location: SourceLocation, 34 | } 35 | 36 | impl DeepCloneWithLock for StyleRule { 37 | /// Deep clones this StyleRule. 38 | fn deep_clone_with_lock( 39 | &self, 40 | lock: &SharedRwLock, 41 | guard: &SharedRwLockReadGuard, 42 | ) -> StyleRule { 43 | StyleRule { 44 | selectors: self.selectors.clone(), 45 | block: Arc::new(lock.wrap(self.block.read_with(guard).clone())), 46 | rules: self.rules.as_ref().map(|rules| { 47 | let rules = rules.read_with(guard); 48 | Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard))) 49 | }), 50 | source_location: self.source_location.clone(), 51 | } 52 | } 53 | } 54 | 55 | impl StyleRule { 56 | /// Measure heap usage. 57 | #[cfg(feature = "gecko")] 58 | pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { 59 | let mut n = 0; 60 | n += self.selectors.unconditional_size_of(ops); 61 | n += self.block.unconditional_shallow_size_of(ops) + 62 | self.block.read_with(guard).size_of(ops); 63 | if let Some(ref rules) = self.rules { 64 | n += rules.unconditional_shallow_size_of(ops) + 65 | rules.read_with(guard).size_of(guard, ops) 66 | } 67 | n 68 | } 69 | } 70 | 71 | impl ToCssWithGuard for StyleRule { 72 | /// https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule 73 | fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { 74 | use cssparser::ToCss; 75 | self.selectors.to_css(dest)?; 76 | dest.write_char(' ')?; 77 | style_or_page_rule_to_css(self.rules.as_ref(), &self.block, guard, dest) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /style/thread_state.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Supports dynamic assertions in about what sort of thread is running and 6 | //! what state it's in. 7 | 8 | #![deny(missing_docs)] 9 | 10 | use std::cell::RefCell; 11 | 12 | bitflags! { 13 | /// A thread state flag, used for multiple assertions. 14 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 15 | pub struct ThreadState: u32 { 16 | /// Whether we're in a script thread. 17 | const SCRIPT = 0x01; 18 | /// Whether we're in a layout thread. 19 | const LAYOUT = 0x02; 20 | 21 | /// Whether we're in a script worker thread (actual web workers), or in 22 | /// a layout worker thread. 23 | const IN_WORKER = 0x0100; 24 | 25 | /// Whether the current thread is going through a GC. 26 | const IN_GC = 0x0200; 27 | } 28 | } 29 | 30 | macro_rules! thread_types ( ( $( $fun:ident = $flag:path ; )* ) => ( 31 | impl ThreadState { 32 | /// Whether the current thread is a worker thread. 33 | pub fn is_worker(self) -> bool { 34 | self.contains(ThreadState::IN_WORKER) 35 | } 36 | 37 | $( 38 | #[allow(missing_docs)] 39 | pub fn $fun(self) -> bool { 40 | self.contains($flag) 41 | } 42 | )* 43 | } 44 | )); 45 | 46 | thread_types! { 47 | is_script = ThreadState::SCRIPT; 48 | is_layout = ThreadState::LAYOUT; 49 | } 50 | 51 | thread_local!(static STATE: RefCell> = RefCell::new(None)); 52 | 53 | /// Initializes the current thread state. 54 | pub fn initialize(x: ThreadState) { 55 | STATE.with(|ref k| { 56 | if let Some(ref s) = *k.borrow() { 57 | if x != *s { 58 | panic!("Thread state already initialized as {:?}", s); 59 | } 60 | } 61 | *k.borrow_mut() = Some(x); 62 | }); 63 | } 64 | 65 | /// Initializes the current thread as a layout worker thread. 66 | pub fn initialize_layout_worker_thread() { 67 | initialize(ThreadState::LAYOUT | ThreadState::IN_WORKER); 68 | } 69 | 70 | /// Gets the current thread state. 71 | pub fn get() -> ThreadState { 72 | let state = STATE.with(|ref k| { 73 | match *k.borrow() { 74 | None => ThreadState::empty(), // Unknown thread. 75 | Some(s) => s, 76 | } 77 | }); 78 | 79 | state 80 | } 81 | 82 | /// Enters into a given temporary state. Panics if re-entring. 83 | pub fn enter(x: ThreadState) { 84 | let state = get(); 85 | debug_assert!(!state.intersects(x)); 86 | STATE.with(|ref k| { 87 | *k.borrow_mut() = Some(state | x); 88 | }) 89 | } 90 | 91 | /// Exits a given temporary state. 92 | pub fn exit(x: ThreadState) { 93 | let state = get(); 94 | debug_assert!(state.contains(x)); 95 | STATE.with(|ref k| { 96 | *k.borrow_mut() = Some(state & !x); 97 | }) 98 | } 99 | -------------------------------------------------------------------------------- /style/traversal_flags.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Flags that control the traversal process. 6 | //! 7 | //! We CamelCase rather than UPPER_CASING so that we can grep for the same 8 | //! strings across gecko and servo. 9 | #![allow(non_upper_case_globals)] 10 | 11 | bitflags! { 12 | /// Flags that control the traversal process. 13 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 14 | pub struct TraversalFlags: u32 { 15 | /// Traverse only elements for animation restyles. 16 | const AnimationOnly = 1 << 0; 17 | /// Traverse and update all elements with CSS animations since 18 | /// @keyframes rules may have changed. Triggered by CSS rule changes. 19 | const ForCSSRuleChanges = 1 << 1; 20 | /// The final animation-only traversal, which shouldn't really care about other 21 | /// style changes anymore. 22 | const FinalAnimationTraversal = 1 << 2; 23 | /// Allows the traversal to run in parallel if there are sufficient cores on 24 | /// the machine. 25 | const ParallelTraversal = 1 << 7; 26 | /// Flush throttled animations. By default, we only update throttled animations 27 | /// when we have other non-throttled work to do. With this flag, we 28 | /// unconditionally tick and process them. 29 | const FlushThrottledAnimations = 1 << 8; 30 | 31 | } 32 | } 33 | 34 | /// Asserts that all TraversalFlags flags have a matching ServoTraversalFlags value in gecko. 35 | #[cfg(feature = "gecko")] 36 | #[inline] 37 | pub fn assert_traversal_flags_match() { 38 | use crate::gecko_bindings::structs; 39 | 40 | macro_rules! check_traversal_flags { 41 | ( $( $a:ident => $b:path ),*, ) => { 42 | if cfg!(debug_assertions) { 43 | let mut modes = TraversalFlags::all(); 44 | $( 45 | assert_eq!(structs::$a as usize, $b.bits() as usize, stringify!($b)); 46 | modes.remove($b); 47 | )* 48 | assert_eq!(modes, TraversalFlags::empty(), "all TraversalFlags bits should have an assertion"); 49 | } 50 | } 51 | } 52 | 53 | check_traversal_flags! { 54 | ServoTraversalFlags_AnimationOnly => TraversalFlags::AnimationOnly, 55 | ServoTraversalFlags_ForCSSRuleChanges => TraversalFlags::ForCSSRuleChanges, 56 | ServoTraversalFlags_FinalAnimationTraversal => TraversalFlags::FinalAnimationTraversal, 57 | ServoTraversalFlags_ParallelTraversal => TraversalFlags::ParallelTraversal, 58 | ServoTraversalFlags_FlushThrottledAnimations => TraversalFlags::FlushThrottledAnimations, 59 | } 60 | } 61 | 62 | impl TraversalFlags { 63 | /// Returns true if the traversal is for animation-only restyles. 64 | #[inline] 65 | pub fn for_animation_only(&self) -> bool { 66 | self.contains(TraversalFlags::AnimationOnly) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /style/values/animated/effects.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Animated types for CSS values related to effects. 6 | 7 | use crate::values::animated::color::Color; 8 | use crate::values::computed::length::Length; 9 | #[cfg(feature = "gecko")] 10 | use crate::values::computed::url::ComputedUrl; 11 | use crate::values::computed::{Angle, Number}; 12 | use crate::values::generics::effects::Filter as GenericFilter; 13 | use crate::values::generics::effects::SimpleShadow as GenericSimpleShadow; 14 | #[cfg(not(feature = "gecko"))] 15 | use crate::values::Impossible; 16 | 17 | /// An animated value for the `drop-shadow()` filter. 18 | pub type AnimatedSimpleShadow = GenericSimpleShadow; 19 | 20 | /// An animated value for a single `filter`. 21 | #[cfg(feature = "gecko")] 22 | pub type AnimatedFilter = 23 | GenericFilter; 24 | 25 | /// An animated value for a single `filter`. 26 | #[cfg(not(feature = "gecko"))] 27 | pub type AnimatedFilter = GenericFilter; 28 | -------------------------------------------------------------------------------- /style/values/animated/font.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Animation implementation for various font-related types. 6 | 7 | use super::{Animate, Procedure, ToAnimatedZero}; 8 | use crate::values::computed::font::FontVariationSettings; 9 | use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; 10 | 11 | /// 12 | /// 13 | /// Note that the ComputedValue implementation will already have sorted and de-dup'd 14 | /// the lists of settings, so we can just iterate over the two lists together and 15 | /// animate their individual values. 16 | impl Animate for FontVariationSettings { 17 | #[inline] 18 | fn animate(&self, other: &Self, procedure: Procedure) -> Result { 19 | let result: Box<[_]> = 20 | super::lists::by_computed_value::animate(&self.0, &other.0, procedure)?; 21 | Ok(Self(result)) 22 | } 23 | } 24 | 25 | impl ComputeSquaredDistance for FontVariationSettings { 26 | #[inline] 27 | fn compute_squared_distance(&self, other: &Self) -> Result { 28 | super::lists::by_computed_value::squared_distance(&self.0, &other.0) 29 | } 30 | } 31 | 32 | impl ToAnimatedZero for FontVariationSettings { 33 | #[inline] 34 | fn to_animated_zero(&self) -> Result { 35 | Err(()) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /style/values/animated/svg.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Animation implementations for various SVG-related types. 6 | 7 | use super::{Animate, Procedure}; 8 | use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; 9 | use crate::values::generics::svg::SVGStrokeDashArray; 10 | 11 | /// 12 | impl Animate for SVGStrokeDashArray 13 | where 14 | L: Clone + Animate, 15 | { 16 | #[inline] 17 | fn animate(&self, other: &Self, procedure: Procedure) -> Result { 18 | if matches!(procedure, Procedure::Add | Procedure::Accumulate { .. }) { 19 | // Non-additive. 20 | return Err(()); 21 | } 22 | match (self, other) { 23 | (&SVGStrokeDashArray::Values(ref this), &SVGStrokeDashArray::Values(ref other)) => { 24 | Ok(SVGStrokeDashArray::Values( 25 | super::lists::repeatable_list::animate(this, other, procedure)?, 26 | )) 27 | }, 28 | _ => Err(()), 29 | } 30 | } 31 | } 32 | 33 | impl ComputeSquaredDistance for SVGStrokeDashArray 34 | where 35 | L: ComputeSquaredDistance, 36 | { 37 | #[inline] 38 | fn compute_squared_distance(&self, other: &Self) -> Result { 39 | match (self, other) { 40 | (&SVGStrokeDashArray::Values(ref this), &SVGStrokeDashArray::Values(ref other)) => { 41 | super::lists::repeatable_list::squared_distance(this, other) 42 | }, 43 | _ => Err(()), 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /style/values/computed/angle.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed angles. 6 | 7 | use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; 8 | use crate::values::CSSFloat; 9 | use crate::Zero; 10 | use std::f64::consts::PI; 11 | use std::fmt::{self, Write}; 12 | use std::{f32, f64}; 13 | use style_traits::{CssWriter, ToCss}; 14 | 15 | /// A computed angle in degrees. 16 | #[derive( 17 | Add, 18 | Animate, 19 | Clone, 20 | Copy, 21 | Debug, 22 | Deserialize, 23 | MallocSizeOf, 24 | PartialEq, 25 | PartialOrd, 26 | Serialize, 27 | ToAnimatedZero, 28 | ToResolvedValue, 29 | )] 30 | #[repr(C)] 31 | pub struct Angle(CSSFloat); 32 | 33 | impl ToCss for Angle { 34 | fn to_css(&self, dest: &mut CssWriter) -> fmt::Result 35 | where 36 | W: Write, 37 | { 38 | self.degrees().to_css(dest)?; 39 | dest.write_str("deg") 40 | } 41 | } 42 | 43 | const RAD_PER_DEG: f64 = PI / 180.0; 44 | 45 | impl Angle { 46 | /// Creates a computed `Angle` value from a radian amount. 47 | pub fn from_radians(radians: CSSFloat) -> Self { 48 | Angle(radians / RAD_PER_DEG as f32) 49 | } 50 | 51 | /// Creates a computed `Angle` value from a degrees amount. 52 | #[inline] 53 | pub fn from_degrees(degrees: CSSFloat) -> Self { 54 | Angle(degrees) 55 | } 56 | 57 | /// Returns the amount of radians this angle represents. 58 | #[inline] 59 | pub fn radians(&self) -> CSSFloat { 60 | self.radians64().min(f32::MAX as f64).max(f32::MIN as f64) as f32 61 | } 62 | 63 | /// Returns the amount of radians this angle represents as a `f64`. 64 | /// 65 | /// Gecko stores angles as singles, but does this computation using doubles. 66 | /// 67 | /// This is significant enough to mess up rounding to the nearest 68 | /// quarter-turn for 225 degrees, for example. 69 | #[inline] 70 | pub fn radians64(&self) -> f64 { 71 | self.0 as f64 * RAD_PER_DEG 72 | } 73 | 74 | /// Return the value in degrees. 75 | #[inline] 76 | pub fn degrees(&self) -> CSSFloat { 77 | self.0 78 | } 79 | } 80 | 81 | impl Zero for Angle { 82 | #[inline] 83 | fn zero() -> Self { 84 | Angle(0.0) 85 | } 86 | 87 | #[inline] 88 | fn is_zero(&self) -> bool { 89 | self.0 == 0. 90 | } 91 | } 92 | 93 | impl ComputeSquaredDistance for Angle { 94 | #[inline] 95 | fn compute_squared_distance(&self, other: &Self) -> Result { 96 | // Use the formula for calculating the distance between angles defined in SVG: 97 | // https://www.w3.org/TR/SVG/animate.html#complexDistances 98 | self.radians64() 99 | .compute_squared_distance(&other.radians64()) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /style/values/computed/background.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed types for CSS values related to backgrounds. 6 | 7 | use crate::values::computed::length::NonNegativeLengthPercentage; 8 | use crate::values::generics::background::BackgroundSize as GenericBackgroundSize; 9 | 10 | pub use crate::values::specified::background::BackgroundRepeat; 11 | 12 | /// A computed value for the `background-size` property. 13 | pub type BackgroundSize = GenericBackgroundSize; 14 | -------------------------------------------------------------------------------- /style/values/computed/border.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed types for CSS values related to borders. 6 | 7 | use crate::values::computed::length::{NonNegativeLength, NonNegativeLengthPercentage}; 8 | use crate::values::computed::{NonNegativeNumber, NonNegativeNumberOrPercentage}; 9 | use crate::values::generics::border::{ 10 | GenericBorderCornerRadius, GenericBorderImageSideWidth, GenericBorderImageSlice, 11 | GenericBorderRadius, GenericBorderSpacing, 12 | }; 13 | use crate::values::generics::rect::Rect; 14 | use crate::values::generics::size::Size2D; 15 | use crate::values::generics::NonNegative; 16 | use crate::Zero; 17 | use app_units::Au; 18 | 19 | pub use crate::values::specified::border::BorderImageRepeat; 20 | 21 | /// A computed value for -webkit-text-stroke-width. 22 | pub type LineWidth = Au; 23 | 24 | /// A computed value for border-width (and the like). 25 | pub type BorderSideWidth = Au; 26 | 27 | /// A computed value for the `border-image-width` property. 28 | pub type BorderImageWidth = Rect; 29 | 30 | /// A computed value for a single side of a `border-image-width` property. 31 | pub type BorderImageSideWidth = 32 | GenericBorderImageSideWidth; 33 | 34 | /// A computed value for the `border-image-slice` property. 35 | pub type BorderImageSlice = GenericBorderImageSlice; 36 | 37 | /// A computed value for the `border-radius` property. 38 | pub type BorderRadius = GenericBorderRadius; 39 | 40 | /// A computed value for the `border-*-radius` longhand properties. 41 | pub type BorderCornerRadius = GenericBorderCornerRadius; 42 | 43 | /// A computed value for the `border-spacing` longhand property. 44 | pub type BorderSpacing = GenericBorderSpacing; 45 | 46 | impl BorderImageSideWidth { 47 | /// Returns `1`. 48 | #[inline] 49 | pub fn one() -> Self { 50 | GenericBorderImageSideWidth::Number(NonNegative(1.)) 51 | } 52 | } 53 | 54 | impl BorderImageSlice { 55 | /// Returns the `100%` value. 56 | #[inline] 57 | pub fn hundred_percent() -> Self { 58 | GenericBorderImageSlice { 59 | offsets: Rect::all(NonNegativeNumberOrPercentage::hundred_percent()), 60 | fill: false, 61 | } 62 | } 63 | } 64 | 65 | impl BorderSpacing { 66 | /// Returns `0 0`. 67 | pub fn zero() -> Self { 68 | GenericBorderSpacing(Size2D::new( 69 | NonNegativeLength::zero(), 70 | NonNegativeLength::zero(), 71 | )) 72 | } 73 | 74 | /// Returns the horizontal spacing. 75 | pub fn horizontal(&self) -> Au { 76 | Au::from(*self.0.width()) 77 | } 78 | 79 | /// Returns the vertical spacing. 80 | pub fn vertical(&self) -> Au { 81 | Au::from(*self.0.height()) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /style/values/computed/column.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed types for the column properties. 6 | 7 | use crate::values::computed::PositiveInteger; 8 | use crate::values::generics::column::GenericColumnCount; 9 | 10 | /// A computed type for `column-count` values. 11 | pub type ColumnCount = GenericColumnCount; 12 | -------------------------------------------------------------------------------- /style/values/computed/counters.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed values for counter properties 6 | 7 | use crate::values::computed::image::Image; 8 | use crate::values::generics::counters as generics; 9 | use crate::values::generics::counters::CounterIncrement as GenericCounterIncrement; 10 | use crate::values::generics::counters::CounterReset as GenericCounterReset; 11 | use crate::values::generics::counters::CounterSet as GenericCounterSet; 12 | 13 | /// A computed value for the `counter-increment` property. 14 | pub type CounterIncrement = GenericCounterIncrement; 15 | 16 | /// A computed value for the `counter-reset` property. 17 | pub type CounterReset = GenericCounterReset; 18 | 19 | /// A computed value for the `counter-set` property. 20 | pub type CounterSet = GenericCounterSet; 21 | 22 | /// A computed value for the `content` property. 23 | pub type Content = generics::GenericContent; 24 | 25 | /// A computed content item. 26 | pub type ContentItem = generics::GenericContentItem; 27 | -------------------------------------------------------------------------------- /style/values/computed/effects.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed types for CSS values related to effects. 6 | 7 | use crate::values::computed::color::Color; 8 | use crate::values::computed::length::{Length, NonNegativeLength}; 9 | #[cfg(feature = "gecko")] 10 | use crate::values::computed::url::ComputedUrl; 11 | use crate::values::computed::{Angle, NonNegativeNumber, ZeroToOneNumber}; 12 | use crate::values::generics::effects::BoxShadow as GenericBoxShadow; 13 | use crate::values::generics::effects::Filter as GenericFilter; 14 | use crate::values::generics::effects::SimpleShadow as GenericSimpleShadow; 15 | #[cfg(not(feature = "gecko"))] 16 | use crate::values::Impossible; 17 | 18 | /// A computed value for a single shadow of the `box-shadow` property. 19 | pub type BoxShadow = GenericBoxShadow; 20 | 21 | /// A computed value for a single `filter`. 22 | #[cfg(feature = "gecko")] 23 | pub type Filter = GenericFilter< 24 | Angle, 25 | NonNegativeNumber, 26 | ZeroToOneNumber, 27 | NonNegativeLength, 28 | SimpleShadow, 29 | ComputedUrl, 30 | >; 31 | 32 | /// A computed value for a single `filter`. 33 | #[cfg(feature = "servo")] 34 | pub type Filter = GenericFilter< 35 | Angle, 36 | NonNegativeNumber, 37 | ZeroToOneNumber, 38 | NonNegativeLength, 39 | SimpleShadow, 40 | Impossible, 41 | >; 42 | 43 | /// A computed value for the `drop-shadow()` filter. 44 | pub type SimpleShadow = GenericSimpleShadow; 45 | -------------------------------------------------------------------------------- /style/values/computed/flex.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed types for CSS values related to flexbox. 6 | 7 | use crate::values::computed::Size; 8 | use crate::values::generics::flex::FlexBasis as GenericFlexBasis; 9 | 10 | /// A computed value for the `flex-basis` property. 11 | pub type FlexBasis = GenericFlexBasis; 12 | 13 | impl FlexBasis { 14 | /// `auto` 15 | #[inline] 16 | pub fn auto() -> Self { 17 | GenericFlexBasis::Size(Size::auto()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /style/values/computed/list.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! `list` computed values. 6 | 7 | #[cfg(feature = "gecko")] 8 | pub use crate::values::specified::list::ListStyleType; 9 | pub use crate::values::specified::list::Quotes; 10 | 11 | impl Quotes { 12 | /// Initial value for `quotes`. 13 | #[inline] 14 | pub fn get_initial_value() -> Quotes { 15 | Quotes::Auto 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /style/values/computed/motion.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed types for CSS values that are related to motion path. 6 | 7 | use crate::values::computed::basic_shape::BasicShape; 8 | use crate::values::computed::url::ComputedUrl; 9 | use crate::values::computed::{Angle, LengthPercentage, Position}; 10 | use crate::values::generics::motion::{ 11 | GenericOffsetPath, GenericOffsetPathFunction, GenericOffsetPosition, GenericRayFunction, 12 | }; 13 | use crate::Zero; 14 | 15 | /// The computed value of ray() function. 16 | pub type RayFunction = GenericRayFunction; 17 | 18 | /// The computed value of . 19 | pub type OffsetPathFunction = GenericOffsetPathFunction; 20 | 21 | /// The computed value of `offset-path`. 22 | pub type OffsetPath = GenericOffsetPath; 23 | 24 | /// The computed value of `offset-position`. 25 | pub type OffsetPosition = GenericOffsetPosition; 26 | 27 | #[inline] 28 | fn is_auto_zero_angle(auto: &bool, angle: &Angle) -> bool { 29 | *auto && angle.is_zero() 30 | } 31 | 32 | /// A computed offset-rotate. 33 | #[derive( 34 | Animate, 35 | Clone, 36 | ComputeSquaredDistance, 37 | Copy, 38 | Debug, 39 | Deserialize, 40 | MallocSizeOf, 41 | PartialEq, 42 | Serialize, 43 | ToAnimatedValue, 44 | ToAnimatedZero, 45 | ToCss, 46 | ToResolvedValue, 47 | )] 48 | #[repr(C)] 49 | pub struct OffsetRotate { 50 | /// If auto is false, this is a fixed angle which indicates a 51 | /// constant clockwise rotation transformation applied to it by this 52 | /// specified rotation angle. Otherwise, the angle will be added to 53 | /// the angle of the direction in layout. 54 | #[animation(constant)] 55 | #[css(represents_keyword)] 56 | pub auto: bool, 57 | /// The angle value. 58 | #[css(contextual_skip_if = "is_auto_zero_angle")] 59 | pub angle: Angle, 60 | } 61 | 62 | impl OffsetRotate { 63 | /// Returns "auto 0deg". 64 | #[inline] 65 | pub fn auto() -> Self { 66 | OffsetRotate { 67 | auto: true, 68 | angle: Zero::zero(), 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /style/values/computed/outline.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed values for outline properties 6 | 7 | pub use crate::values::specified::OutlineStyle; 8 | -------------------------------------------------------------------------------- /style/values/computed/page.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed @page at-rule properties and named-page style properties 6 | 7 | use crate::values::computed::length::NonNegativeLength; 8 | use crate::values::computed::{Context, ToComputedValue}; 9 | use crate::values::generics; 10 | use crate::values::generics::size::Size2D; 11 | 12 | use crate::values::specified::page as specified; 13 | pub use generics::page::GenericPageSize; 14 | pub use generics::page::PageOrientation; 15 | pub use generics::page::PageSizeOrientation; 16 | pub use generics::page::PaperSize; 17 | pub use specified::PageName; 18 | 19 | /// Computed value of the @page size descriptor 20 | /// 21 | /// The spec says that the computed value should be the same as the specified 22 | /// value but with all absolute units, but it's not currently possibly observe 23 | /// the computed value of page-size. 24 | #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue, ToShmem)] 25 | #[repr(C, u8)] 26 | pub enum PageSize { 27 | /// Specified size, paper size, or paper size and orientation. 28 | Size(Size2D), 29 | /// `landscape` or `portrait` value, no specified size. 30 | Orientation(PageSizeOrientation), 31 | /// `auto` value 32 | Auto, 33 | } 34 | 35 | impl ToComputedValue for specified::PageSize { 36 | type ComputedValue = PageSize; 37 | 38 | fn to_computed_value(&self, ctx: &Context) -> Self::ComputedValue { 39 | match &*self { 40 | Self::Size(s) => PageSize::Size(s.to_computed_value(ctx)), 41 | Self::PaperSize(p, PageSizeOrientation::Landscape) => PageSize::Size(Size2D { 42 | width: p.long_edge().to_computed_value(ctx), 43 | height: p.short_edge().to_computed_value(ctx), 44 | }), 45 | Self::PaperSize(p, PageSizeOrientation::Portrait) => PageSize::Size(Size2D { 46 | width: p.short_edge().to_computed_value(ctx), 47 | height: p.long_edge().to_computed_value(ctx), 48 | }), 49 | Self::Orientation(o) => PageSize::Orientation(*o), 50 | Self::Auto => PageSize::Auto, 51 | } 52 | } 53 | 54 | fn from_computed_value(computed: &Self::ComputedValue) -> Self { 55 | match *computed { 56 | PageSize::Size(s) => Self::Size(ToComputedValue::from_computed_value(&s)), 57 | PageSize::Orientation(o) => Self::Orientation(o), 58 | PageSize::Auto => Self::Auto, 59 | } 60 | } 61 | } 62 | 63 | impl PageSize { 64 | /// `auto` value. 65 | #[inline] 66 | pub fn auto() -> Self { 67 | PageSize::Auto 68 | } 69 | 70 | /// Whether this is the `auto` value. 71 | #[inline] 72 | pub fn is_auto(&self) -> bool { 73 | matches!(*self, PageSize::Auto) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /style/values/computed/rect.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed types for CSS borders. 6 | 7 | use crate::values::computed::length::NonNegativeLengthOrNumber; 8 | use crate::values::generics::rect::Rect; 9 | 10 | /// A specified rectangle made of four `` values. 11 | pub type NonNegativeLengthOrNumberRect = Rect; 12 | -------------------------------------------------------------------------------- /style/values/computed/resolution.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Resolution values: 6 | //! 7 | //! https://drafts.csswg.org/css-values/#resolution 8 | 9 | use crate::values::computed::{Context, ToComputedValue}; 10 | use crate::values::specified; 11 | use crate::values::CSSFloat; 12 | use std::fmt::{self, Write}; 13 | use style_traits::{CssWriter, ToCss}; 14 | 15 | /// A computed ``. 16 | #[repr(C)] 17 | #[derive(Animate, Clone, Debug, MallocSizeOf, PartialEq, ToResolvedValue, ToShmem)] 18 | pub struct Resolution(CSSFloat); 19 | 20 | impl Resolution { 21 | /// Returns this resolution value as dppx. 22 | #[inline] 23 | pub fn dppx(&self) -> CSSFloat { 24 | self.0 25 | } 26 | 27 | /// Return a computed `resolution` value from a dppx float value. 28 | #[inline] 29 | pub fn from_dppx(dppx: CSSFloat) -> Self { 30 | Resolution(dppx) 31 | } 32 | } 33 | 34 | impl ToComputedValue for specified::Resolution { 35 | type ComputedValue = Resolution; 36 | 37 | #[inline] 38 | fn to_computed_value(&self, _: &Context) -> Self::ComputedValue { 39 | Resolution(crate::values::normalize(self.dppx().max(0.0))) 40 | } 41 | 42 | #[inline] 43 | fn from_computed_value(computed: &Self::ComputedValue) -> Self { 44 | specified::Resolution::from_dppx(computed.dppx()) 45 | } 46 | } 47 | 48 | impl ToCss for Resolution { 49 | fn to_css(&self, dest: &mut CssWriter) -> fmt::Result 50 | where 51 | W: fmt::Write, 52 | { 53 | self.dppx().to_css(dest)?; 54 | dest.write_str("dppx") 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /style/values/computed/svg.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed types for SVG properties. 6 | 7 | use crate::values::computed::color::Color; 8 | use crate::values::computed::url::ComputedUrl; 9 | use crate::values::computed::{LengthPercentage, NonNegativeLengthPercentage, Opacity}; 10 | use crate::values::generics::svg as generic; 11 | use crate::Zero; 12 | 13 | pub use crate::values::specified::{DProperty, MozContextProperties, SVGPaintOrder, VectorEffect}; 14 | 15 | /// Computed SVG Paint value 16 | pub type SVGPaint = generic::GenericSVGPaint; 17 | 18 | /// Computed SVG Paint Kind value 19 | pub type SVGPaintKind = generic::GenericSVGPaintKind; 20 | 21 | impl SVGPaint { 22 | /// Opaque black color 23 | pub const BLACK: Self = Self { 24 | kind: generic::SVGPaintKind::Color(Color::BLACK), 25 | fallback: generic::SVGPaintFallback::Unset, 26 | }; 27 | } 28 | 29 | /// | | | context-value 30 | pub type SVGLength = generic::GenericSVGLength; 31 | 32 | impl SVGLength { 33 | /// `0px` 34 | pub fn zero() -> Self { 35 | generic::SVGLength::LengthPercentage(LengthPercentage::zero()) 36 | } 37 | } 38 | 39 | /// An non-negative wrapper of SVGLength. 40 | pub type SVGWidth = generic::GenericSVGLength; 41 | 42 | impl SVGWidth { 43 | /// `1px`. 44 | pub fn one() -> Self { 45 | use crate::values::generics::NonNegative; 46 | generic::SVGLength::LengthPercentage(NonNegative(LengthPercentage::one())) 47 | } 48 | } 49 | 50 | /// [ | | ]# | context-value 51 | pub type SVGStrokeDashArray = generic::GenericSVGStrokeDashArray; 52 | 53 | impl Default for SVGStrokeDashArray { 54 | fn default() -> Self { 55 | generic::SVGStrokeDashArray::Values(Default::default()) 56 | } 57 | } 58 | 59 | /// | context-fill-opacity | context-stroke-opacity 60 | pub type SVGOpacity = generic::GenericSVGOpacity; 61 | 62 | impl Default for SVGOpacity { 63 | fn default() -> Self { 64 | generic::SVGOpacity::Opacity(1.) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /style/values/computed/table.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed types for CSS values related to tables. 6 | 7 | pub use super::specified::table::CaptionSide; 8 | -------------------------------------------------------------------------------- /style/values/computed/time.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Computed time values. 6 | 7 | use crate::values::CSSFloat; 8 | use crate::Zero; 9 | use std::fmt::{self, Write}; 10 | use style_traits::{CssWriter, ToCss}; 11 | 12 | /// A computed `
(input: &DeriveInput) -> A 12 | where 13 | A: FromDeriveInput, 14 | { 15 | match A::from_derive_input(input) { 16 | Ok(attrs) => attrs, 17 | Err(e) => panic!("failed to parse input attributes: {}", e), 18 | } 19 | } 20 | 21 | pub(crate) fn parse_field_attrs(field: &Field) -> A 22 | where 23 | A: FromField, 24 | { 25 | match A::from_field(field) { 26 | Ok(attrs) => attrs, 27 | Err(e) => panic!("failed to parse field attributes: {}", e), 28 | } 29 | } 30 | 31 | pub(crate) fn add_predicate(where_clause: &mut Option, pred: WherePredicate) { 32 | where_clause 33 | .get_or_insert(parse_quote!(where)) 34 | .predicates 35 | .push(pred); 36 | } 37 | 38 | pub(crate) fn fmap2_match( 39 | input: &DeriveInput, 40 | bind_style: BindStyle, 41 | mut f: F, 42 | mut g: G, 43 | ) -> TokenStream 44 | where 45 | F: FnMut(&BindingInfo) -> TokenStream, 46 | G: FnMut(&BindingInfo) -> Option, 47 | { 48 | let mut s = synstructure::Structure::new(input); 49 | s.variants_mut().iter_mut().for_each(|v| { 50 | v.bind_with(|_| bind_style); 51 | }); 52 | s.each_variant(|variant| { 53 | let (mapped, mapped_fields) = value(variant, "mapped"); 54 | let fields_pairs = variant.bindings().iter().zip(mapped_fields.iter()); 55 | let mut computations = quote!(); 56 | computations.append_all(fields_pairs.map(|(field, mapped_field)| { 57 | let expr = f(field); 58 | quote! { let #mapped_field = #expr; } 59 | })); 60 | computations.append_all( 61 | mapped_fields 62 | .iter() 63 | .map(|mapped_field| match g(mapped_field) { 64 | Some(expr) => quote! { let #mapped_field = #expr; }, 65 | None => quote!(), 66 | }), 67 | ); 68 | computations.append_all(mapped); 69 | Some(computations) 70 | }) 71 | } 72 | 73 | fn value<'a>(variant: &'a VariantInfo, prefix: &str) -> (TokenStream, Vec>) { 74 | let mut v = variant.clone(); 75 | v.bindings_mut().iter_mut().for_each(|b| { 76 | b.binding = Ident::new(&format!("{}_{}", b.binding, prefix), Span::call_site()) 77 | }); 78 | v.bind_with(|_| BindStyle::Move); 79 | (v.pat(), v.bindings().to_vec()) 80 | } 81 | --------------------------------------------------------------------------------