diff options
Diffstat (limited to 'servo/components/style/lib.rs')
-rw-r--r-- | servo/components/style/lib.rs | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/servo/components/style/lib.rs b/servo/components/style/lib.rs new file mode 100644 index 0000000000..b2a1e20ce8 --- /dev/null +++ b/servo/components/style/lib.rs @@ -0,0 +1,332 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! Calculate [specified][specified] and [computed values][computed] from a +//! tree of DOM nodes and a set of stylesheets. +//! +//! [computed]: https://drafts.csswg.org/css-cascade/#computed +//! [specified]: https://drafts.csswg.org/css-cascade/#specified +//! +//! In particular, this crate contains the definitions of supported properties, +//! the code to parse them into specified values and calculate the computed +//! values based on the specified values, as well as the code to serialize both +//! specified and computed values. +//! +//! The main entry point is [`recalc_style_at`][recalc_style_at]. +//! +//! [recalc_style_at]: traversal/fn.recalc_style_at.html +//! +//! Major dependencies are the [cssparser][cssparser] and [selectors][selectors] +//! crates. +//! +//! [cssparser]: ../cssparser/index.html +//! [selectors]: ../selectors/index.html + +#![deny(missing_docs)] + +#[macro_use] +extern crate bitflags; +#[macro_use] +extern crate cssparser; +#[macro_use] +extern crate debug_unreachable; +#[macro_use] +extern crate derive_more; +#[macro_use] +extern crate gecko_profiler; +#[cfg(feature = "gecko")] +#[macro_use] +pub mod gecko_string_cache; +#[cfg(feature = "servo")] +#[macro_use] +extern crate html5ever; +#[macro_use] +extern crate lazy_static; +#[macro_use] +extern crate log; +#[macro_use] +extern crate malloc_size_of; +#[macro_use] +extern crate malloc_size_of_derive; +#[allow(unused_extern_crates)] +#[macro_use] +extern crate matches; +#[cfg(feature = "gecko")] +pub use nsstring; +#[cfg(feature = "gecko")] +extern crate num_cpus; +#[macro_use] +extern crate num_derive; +#[macro_use] +extern crate serde; +pub use servo_arc; +#[cfg(feature = "servo")] +#[macro_use] +extern crate servo_atoms; +#[macro_use] +extern crate static_assertions; +#[macro_use] +extern crate style_derive; +#[macro_use] +extern crate to_shmem_derive; + +#[macro_use] +mod macros; + +pub mod animation; +pub mod applicable_declarations; +#[allow(missing_docs)] // TODO. +#[cfg(feature = "servo")] +pub mod attr; +pub mod author_styles; +pub mod bezier; +pub mod bloom; +pub mod color; +#[path = "properties/computed_value_flags.rs"] +pub mod computed_value_flags; +pub mod context; +pub mod counter_style; +pub mod custom_properties; +pub mod custom_properties_map; +pub mod data; +pub mod dom; +pub mod dom_apis; +pub mod driver; +#[cfg(feature = "servo")] +mod encoding_support; +pub mod error_reporting; +pub mod font_face; +pub mod font_metrics; +#[cfg(feature = "gecko")] +#[allow(unsafe_code)] +pub mod gecko_bindings; +pub mod global_style_data; +pub mod invalidation; +#[allow(missing_docs)] // TODO. +pub mod logical_geometry; +pub mod matching; +pub mod media_queries; +pub mod parallel; +pub mod parser; +pub mod piecewise_linear; +pub mod properties_and_values; +#[macro_use] +pub mod queries; +pub mod rule_cache; +pub mod rule_collector; +pub mod rule_tree; +pub mod scoped_tls; +pub mod selector_map; +pub mod selector_parser; +pub mod shared_lock; +pub mod sharing; +pub mod str; +pub mod style_adjuster; +pub mod style_resolver; +pub mod stylesheet_set; +pub mod stylesheets; +pub mod stylist; +pub mod thread_state; +pub mod traversal; +pub mod traversal_flags; +pub mod use_counters; +#[macro_use] +#[allow(non_camel_case_types)] +pub mod values; + +#[cfg(feature = "gecko")] +pub use crate::gecko_string_cache as string_cache; +#[cfg(feature = "gecko")] +pub use crate::gecko_string_cache::Atom; +/// The namespace prefix type for Gecko, which is just an atom. +#[cfg(feature = "gecko")] +pub type Prefix = crate::values::AtomIdent; +/// The local name of an element for Gecko, which is just an atom. +#[cfg(feature = "gecko")] +pub type LocalName = crate::values::AtomIdent; +#[cfg(feature = "gecko")] +pub use crate::gecko_string_cache::Namespace; + +#[cfg(feature = "servo")] +pub use servo_atoms::Atom; + +#[cfg(feature = "servo")] +#[allow(missing_docs)] +pub type LocalName = crate::values::GenericAtomIdent<html5ever::LocalNameStaticSet>; +#[cfg(feature = "servo")] +#[allow(missing_docs)] +pub type Namespace = crate::values::GenericAtomIdent<html5ever::NamespaceStaticSet>; +#[cfg(feature = "servo")] +#[allow(missing_docs)] +pub type Prefix = crate::values::GenericAtomIdent<html5ever::PrefixStaticSet>; + +pub use style_traits::arc_slice::ArcSlice; +pub use style_traits::owned_slice::OwnedSlice; +pub use style_traits::owned_str::OwnedStr; + +use std::hash::{BuildHasher, Hash}; + +pub mod properties; + +#[cfg(feature = "gecko")] +#[allow(unsafe_code)] +pub mod gecko; + +// uses a macro from properties +#[cfg(feature = "servo")] +#[allow(unsafe_code)] +pub mod servo; + +macro_rules! reexport_computed_values { + ( $( { $name: ident } )+ ) => { + /// Types for [computed values][computed]. + /// + /// [computed]: https://drafts.csswg.org/css-cascade/#computed + pub mod computed_values { + $( + pub use crate::properties::longhands::$name::computed_value as $name; + )+ + // Don't use a side-specific name needlessly: + pub use crate::properties::longhands::border_top_style::computed_value as border_style; + } + } +} +longhand_properties_idents!(reexport_computed_values); +#[cfg(feature = "gecko")] +use crate::gecko_string_cache::WeakAtom; +#[cfg(feature = "servo")] +use servo_atoms::Atom as WeakAtom; + +/// Extension methods for selectors::attr::CaseSensitivity +pub trait CaseSensitivityExt { + /// Return whether two atoms compare equal according to this case sensitivity. + fn eq_atom(self, a: &WeakAtom, b: &WeakAtom) -> bool; +} + +impl CaseSensitivityExt for selectors::attr::CaseSensitivity { + #[inline] + fn eq_atom(self, a: &WeakAtom, b: &WeakAtom) -> bool { + match self { + selectors::attr::CaseSensitivity::CaseSensitive => a == b, + selectors::attr::CaseSensitivity::AsciiCaseInsensitive => a.eq_ignore_ascii_case(b), + } + } +} + +/// A trait pretty much similar to num_traits::Zero, but without the need of +/// implementing `Add`. +pub trait Zero { + /// Returns the zero value. + fn zero() -> Self; + + /// Returns whether this value is zero. + fn is_zero(&self) -> bool; +} + +impl<T> Zero for T +where + T: num_traits::Zero, +{ + fn zero() -> Self { + <Self as num_traits::Zero>::zero() + } + + fn is_zero(&self) -> bool { + <Self as num_traits::Zero>::is_zero(self) + } +} + +/// A trait implementing a function to tell if the number is zero without a percent +pub trait ZeroNoPercent { + /// So, `0px` should return `true`, but `0%` or `1px` should return `false` + fn is_zero_no_percent(&self) -> bool; +} + +/// A trait pretty much similar to num_traits::One, but without the need of +/// implementing `Mul`. +pub trait One { + /// Reutrns the one value. + fn one() -> Self; + + /// Returns whether this value is one. + fn is_one(&self) -> bool; +} + +impl<T> One for T +where + T: num_traits::One + PartialEq, +{ + fn one() -> Self { + <Self as num_traits::One>::one() + } + + fn is_one(&self) -> bool { + *self == One::one() + } +} + +/// An allocation error. +/// +/// TODO(emilio): Would be nice to have more information here, or for SmallVec +/// to return the standard error type (and then we can just return that). +/// +/// But given we use these mostly to bail out and ignore them, it's not a big +/// deal. +#[derive(Debug)] +pub struct AllocErr; + +impl From<smallvec::CollectionAllocErr> for AllocErr { + #[inline] + fn from(_: smallvec::CollectionAllocErr) -> Self { + Self + } +} + +impl From<std::collections::TryReserveError> for AllocErr { + #[inline] + fn from(_: std::collections::TryReserveError) -> Self { + Self + } +} + +/// Shrink the capacity of the collection if needed. +pub(crate) trait ShrinkIfNeeded { + fn shrink_if_needed(&mut self); +} + +/// We shrink the capacity of a collection if we're wasting more than a 25% of +/// its capacity, and if the collection is arbitrarily big enough +/// (>= CAPACITY_THRESHOLD entries). +#[inline] +fn should_shrink(len: usize, capacity: usize) -> bool { + const CAPACITY_THRESHOLD: usize = 64; + capacity >= CAPACITY_THRESHOLD && len + capacity / 4 < capacity +} + +impl<K, V, H> ShrinkIfNeeded for std::collections::HashMap<K, V, H> +where + K: Eq + Hash, + H: BuildHasher, +{ + fn shrink_if_needed(&mut self) { + if should_shrink(self.len(), self.capacity()) { + self.shrink_to_fit(); + } + } +} + +impl<T, H> ShrinkIfNeeded for std::collections::HashSet<T, H> +where + T: Eq + Hash, + H: BuildHasher, +{ + fn shrink_if_needed(&mut self) { + if should_shrink(self.len(), self.capacity()) { + self.shrink_to_fit(); + } + } +} + +// TODO(emilio): Measure and see if we're wasting a lot of memory on Vec / +// SmallVec, and if so consider shrinking those as well. |