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