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