Skip to main content

style/
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//! Calculate [specified][specified] and [computed values][computed] from a
6//! tree of DOM nodes and a set of stylesheets.
7//!
8//! [computed]: https://drafts.csswg.org/css-cascade/#computed
9//! [specified]: https://drafts.csswg.org/css-cascade/#specified
10//!
11//! In particular, this crate contains the definitions of supported properties,
12//! the code to parse them into specified values and calculate the computed
13//! values based on the specified values, as well as the code to serialize both
14//! specified and computed values.
15//!
16//! The main entry point is [`recalc_style_at`][recalc_style_at].
17//!
18//! [recalc_style_at]: traversal/fn.recalc_style_at.html
19//!
20//! A list of supported style properties can be found as [docs::supported_properties]
21//!
22//! Major dependencies are the [cssparser][cssparser] and [selectors][selectors]
23//! crates.
24//!
25//! [cssparser]: ../cssparser/index.html
26//! [selectors]: ../selectors/index.html
27
28#![deny(missing_docs)]
29
30// Needed by macros that refer to `$crate::cssparser`.
31#[allow(clippy::single_component_path_imports)]
32pub(crate) use cssparser;
33
34#[macro_use]
35extern crate bitflags;
36#[macro_use]
37#[cfg(feature = "gecko")]
38extern crate gecko_profiler;
39#[cfg(feature = "gecko")]
40#[macro_use]
41pub mod gecko_string_cache;
42#[macro_use]
43extern crate log;
44#[macro_use]
45extern crate serde;
46pub use servo_arc;
47#[cfg(feature = "servo")]
48#[macro_use]
49extern crate stylo_atoms;
50#[macro_use]
51extern crate static_assertions;
52
53#[macro_use]
54mod macros;
55
56mod derives {
57    pub(crate) use derive_more::{Add, AddAssign, Deref, DerefMut, From};
58    pub(crate) use malloc_size_of_derive::MallocSizeOf;
59    pub(crate) use num_derive::FromPrimitive;
60    pub(crate) use style_derive::{
61        Animate, ComputeSquaredDistance, Parse, SpecifiedValueInfo, ToAnimatedValue,
62        ToAnimatedZero, ToComputedValue, ToCss, ToResolvedValue, ToTyped,
63    };
64    pub(crate) use to_shmem_derive::ToShmem;
65}
66
67pub mod applicable_declarations;
68pub mod author_styles;
69pub mod bezier;
70pub mod bloom;
71pub mod color;
72#[path = "properties/computed_value_flags.rs"]
73pub mod computed_value_flags;
74pub mod context;
75pub mod counter_style;
76pub mod custom_properties;
77pub mod custom_properties_map;
78pub mod data;
79pub mod device;
80pub mod dom;
81pub mod dom_apis;
82pub mod driver;
83pub mod error_reporting;
84pub mod font_face;
85pub mod font_metrics;
86#[cfg(feature = "gecko")]
87#[allow(unsafe_code)]
88pub mod gecko_bindings;
89pub mod global_style_data;
90pub mod invalidation;
91#[allow(missing_docs)] // TODO.
92pub mod logical_geometry;
93pub mod matching;
94pub mod media_queries;
95pub mod parallel;
96pub mod parser;
97pub mod piecewise_linear;
98pub mod prefs;
99pub mod properties_and_values;
100#[macro_use]
101pub mod queries;
102pub mod rule_cache;
103pub mod rule_collector;
104pub mod rule_tree;
105pub mod scoped_tls;
106pub mod selector_map;
107pub mod selector_parser;
108pub mod shared_lock;
109pub mod sharing;
110mod simple_buckets_map;
111pub mod str;
112pub mod style_adjuster;
113pub mod style_resolver;
114pub mod stylesheet_set;
115pub mod stylesheets;
116pub mod stylist;
117pub mod thread_state;
118pub mod traversal;
119pub mod traversal_flags;
120pub mod typed_om;
121pub mod url;
122pub mod use_counters;
123
124#[macro_use]
125#[allow(non_camel_case_types)]
126pub mod values;
127
128#[cfg(all(doc, feature = "servo"))]
129/// Documentation
130pub mod docs {
131    /// The CSS properties supported by the style system.
132    /// Generated from the `properties.mako.rs` template by `build.rs`
133    pub mod supported_properties {
134        #![doc = include_str!(concat!(env!("OUT_DIR"), "/css-properties.html"))]
135    }
136}
137
138#[cfg(feature = "gecko")]
139pub use crate::gecko_string_cache as string_cache;
140#[cfg(feature = "gecko")]
141pub use crate::gecko_string_cache::Atom;
142/// The namespace prefix type for Gecko, which is just an atom.
143#[cfg(feature = "gecko")]
144pub type Prefix = crate::values::AtomIdent;
145/// The local name of an element for Gecko, which is just an atom.
146#[cfg(feature = "gecko")]
147pub type LocalName = crate::values::AtomIdent;
148#[cfg(feature = "gecko")]
149pub use crate::gecko_string_cache::Namespace;
150
151#[cfg(feature = "servo")]
152pub use stylo_atoms::Atom;
153
154#[cfg(feature = "servo")]
155#[allow(missing_docs)]
156pub type LocalName = crate::values::GenericAtomIdent<web_atoms::LocalNameStaticSet>;
157#[cfg(feature = "servo")]
158#[allow(missing_docs)]
159pub type Namespace = crate::values::GenericAtomIdent<web_atoms::NamespaceStaticSet>;
160#[cfg(feature = "servo")]
161#[allow(missing_docs)]
162pub type Prefix = crate::values::GenericAtomIdent<web_atoms::PrefixStaticSet>;
163
164pub use style_traits::arc_slice::ArcSlice;
165pub use style_traits::owned_array::OwnedArray;
166pub use style_traits::owned_slice::OwnedSlice;
167pub use style_traits::owned_str::OwnedStr;
168
169use std::hash::{BuildHasher, Hash};
170
171#[cfg_attr(feature = "servo", macro_use)]
172pub mod properties;
173
174#[cfg(feature = "gecko")]
175#[allow(unsafe_code)]
176pub mod gecko;
177
178// uses a macro from properties
179#[cfg(feature = "servo")]
180#[allow(unsafe_code)]
181pub mod servo;
182#[cfg(feature = "servo")]
183pub use servo::{animation, attr};
184
185macro_rules! reexport_computed_values {
186    ( $( { $name: ident } )+ ) => {
187        /// Types for [computed values][computed].
188        ///
189        /// [computed]: https://drafts.csswg.org/css-cascade/#computed
190        pub mod computed_values {
191            $(
192                pub use crate::properties::longhands::$name::computed_value as $name;
193            )+
194            // Don't use a side-specific name needlessly:
195            pub use crate::properties::longhands::border_top_style::computed_value as border_style;
196        }
197    }
198}
199longhand_properties_idents!(reexport_computed_values);
200#[cfg(feature = "gecko")]
201use crate::gecko_string_cache::WeakAtom;
202#[cfg(feature = "servo")]
203use stylo_atoms::Atom as WeakAtom;
204
205/// Extension methods for selectors::attr::CaseSensitivity
206pub trait CaseSensitivityExt {
207    /// Return whether two atoms compare equal according to this case sensitivity.
208    fn eq_atom(self, a: &WeakAtom, b: &WeakAtom) -> bool;
209}
210
211impl CaseSensitivityExt for selectors::attr::CaseSensitivity {
212    #[inline]
213    fn eq_atom(self, a: &WeakAtom, b: &WeakAtom) -> bool {
214        match self {
215            selectors::attr::CaseSensitivity::CaseSensitive => a == b,
216            selectors::attr::CaseSensitivity::AsciiCaseInsensitive => a.eq_ignore_ascii_case(b),
217        }
218    }
219}
220
221/// A trait pretty much similar to num_traits::Zero, but without the need of
222/// implementing `Add`.
223pub trait Zero {
224    /// Returns the zero value.
225    fn zero() -> Self;
226
227    /// Returns whether this value is zero.
228    fn is_zero(&self) -> bool;
229}
230
231impl<T> Zero for T
232where
233    T: num_traits::Zero,
234{
235    fn zero() -> Self {
236        <Self as num_traits::Zero>::zero()
237    }
238
239    fn is_zero(&self) -> bool {
240        <Self as num_traits::Zero>::is_zero(self)
241    }
242}
243
244/// A trait implementing a function to tell if the number is zero without a percent
245pub trait ZeroNoPercent {
246    /// So, `0px` should return `true`, but `0%` or `1px` should return `false`
247    fn is_zero_no_percent(&self) -> bool;
248}
249
250/// A trait pretty much similar to num_traits::One, but without the need of
251/// implementing `Mul`.
252pub trait One {
253    /// Reutrns the one value.
254    fn one() -> Self;
255
256    /// Returns whether this value is one.
257    fn is_one(&self) -> bool;
258}
259
260impl<T> One for T
261where
262    T: num_traits::One + PartialEq,
263{
264    fn one() -> Self {
265        <Self as num_traits::One>::one()
266    }
267
268    fn is_one(&self) -> bool {
269        *self == One::one()
270    }
271}
272
273/// An allocation error.
274///
275/// TODO(emilio): Would be nice to have more information here, or for SmallVec
276/// to return the standard error type (and then we can just return that).
277///
278/// But given we use these mostly to bail out and ignore them, it's not a big
279/// deal.
280#[derive(Debug)]
281pub struct AllocErr;
282
283impl From<smallvec::CollectionAllocErr> for AllocErr {
284    #[inline]
285    fn from(_: smallvec::CollectionAllocErr) -> Self {
286        Self
287    }
288}
289
290impl From<std::collections::TryReserveError> for AllocErr {
291    #[inline]
292    fn from(_: std::collections::TryReserveError) -> Self {
293        Self
294    }
295}
296
297/// Shrink the capacity of the collection if needed.
298pub(crate) trait ShrinkIfNeeded {
299    fn shrink_if_needed(&mut self);
300}
301
302/// We shrink the capacity of a collection if we're wasting more than a 25% of
303/// its capacity, and if the collection is arbitrarily big enough
304/// (>= CAPACITY_THRESHOLD entries).
305#[inline]
306fn should_shrink(len: usize, capacity: usize) -> bool {
307    const CAPACITY_THRESHOLD: usize = 64;
308    capacity >= CAPACITY_THRESHOLD && len + capacity / 4 < capacity
309}
310
311impl<K, V, H> ShrinkIfNeeded for std::collections::HashMap<K, V, H>
312where
313    K: Eq + Hash,
314    H: BuildHasher,
315{
316    fn shrink_if_needed(&mut self) {
317        if should_shrink(self.len(), self.capacity()) {
318            self.shrink_to_fit();
319        }
320    }
321}
322
323impl<T, H> ShrinkIfNeeded for std::collections::HashSet<T, H>
324where
325    T: Eq + Hash,
326    H: BuildHasher,
327{
328    fn shrink_if_needed(&mut self) {
329        if should_shrink(self.len(), self.capacity()) {
330            self.shrink_to_fit();
331        }
332    }
333}
334
335// TODO(emilio): Measure and see if we're wasting a lot of memory on Vec /
336// SmallVec, and if so consider shrinking those as well.