tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

lib.rs (11601B)


      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 shared types and messages for use by devtools/script.
      6 //! The traits are here instead of in script so that the devtools crate can be
      7 //! modified independently of the rest of Servo.
      8 
      9 #![crate_name = "style_traits"]
     10 #![crate_type = "rlib"]
     11 #![deny(unsafe_code, missing_docs)]
     12 
     13 #[macro_use]
     14 extern crate malloc_size_of_derive;
     15 #[macro_use]
     16 extern crate serde;
     17 #[macro_use]
     18 extern crate to_shmem_derive;
     19 #[cfg(feature = "servo")]
     20 extern crate url;
     21 
     22 use bitflags::bitflags;
     23 use cssparser::{CowRcStr, Token};
     24 use selectors::parser::SelectorParseErrorKind;
     25 #[cfg(feature = "servo")]
     26 use stylo_atoms::Atom;
     27 
     28 /// One hardware pixel.
     29 ///
     30 /// This unit corresponds to the smallest addressable element of the display hardware.
     31 #[derive(Clone, Copy, Debug)]
     32 pub enum DevicePixel {}
     33 
     34 /// Represents a mobile style pinch zoom factor.
     35 #[derive(Clone, Copy, Debug, PartialEq)]
     36 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize, MallocSizeOf))]
     37 pub struct PinchZoomFactor(f32);
     38 
     39 impl PinchZoomFactor {
     40    /// Construct a new pinch zoom factor.
     41    pub fn new(scale: f32) -> PinchZoomFactor {
     42        PinchZoomFactor(scale)
     43    }
     44 
     45    /// Get the pinch zoom factor as an untyped float.
     46    pub fn get(&self) -> f32 {
     47        self.0
     48    }
     49 }
     50 
     51 /// One CSS "px" in the coordinate system of the "initial viewport":
     52 /// <http://www.w3.org/TR/css-device-adapt/#initial-viewport>
     53 ///
     54 /// `CSSPixel` is equal to `DeviceIndependentPixel` times a "page zoom" factor controlled by the user.  This is
     55 /// the desktop-style "full page" zoom that enlarges content but then reflows the layout viewport
     56 /// so it still exactly fits the visible area.
     57 ///
     58 /// At the default zoom level of 100%, one `CSSPixel` is equal to one `DeviceIndependentPixel`.  However, if the
     59 /// document is zoomed in or out then this scale may be larger or smaller.
     60 #[derive(Clone, Copy, Debug)]
     61 pub enum CSSPixel {}
     62 
     63 // In summary, the hierarchy of pixel units and the factors to convert from one to the next:
     64 //
     65 // DevicePixel
     66 //   / hidpi_ratio => DeviceIndependentPixel
     67 //     / desktop_zoom => CSSPixel
     68 
     69 pub mod arc_slice;
     70 pub mod dom;
     71 pub mod specified_value_info;
     72 #[macro_use]
     73 pub mod values;
     74 pub mod owned_slice;
     75 pub mod owned_str;
     76 
     77 pub use crate::specified_value_info::{CssType, KeywordsCollectFn, SpecifiedValueInfo};
     78 pub use crate::values::{
     79    Comma, CommaWithSpace, CssString, CssStringWriter, CssWriter, NumericValue, OneOrMoreSeparated,
     80    Separator, Space, ToCss, ToTyped, TypedValue,
     81 };
     82 
     83 /// The error type for all CSS parsing routines.
     84 pub type ParseError<'i> = cssparser::ParseError<'i, StyleParseErrorKind<'i>>;
     85 
     86 /// Error in property value parsing
     87 pub type ValueParseError<'i> = cssparser::ParseError<'i, ValueParseErrorKind<'i>>;
     88 
     89 #[derive(Clone, Debug, PartialEq)]
     90 /// Errors that can be encountered while parsing CSS values.
     91 pub enum StyleParseErrorKind<'i> {
     92    /// A bad URL token in a DVB.
     93    BadUrlInDeclarationValueBlock(CowRcStr<'i>),
     94    /// A bad string token in a DVB.
     95    BadStringInDeclarationValueBlock(CowRcStr<'i>),
     96    /// Unexpected closing parenthesis in a DVB.
     97    UnbalancedCloseParenthesisInDeclarationValueBlock,
     98    /// Unexpected closing bracket in a DVB.
     99    UnbalancedCloseSquareBracketInDeclarationValueBlock,
    100    /// Unexpected closing curly bracket in a DVB.
    101    UnbalancedCloseCurlyBracketInDeclarationValueBlock,
    102    /// A property declaration value had input remaining after successfully parsing.
    103    PropertyDeclarationValueNotExhausted,
    104    /// An unexpected dimension token was encountered.
    105    UnexpectedDimension(CowRcStr<'i>),
    106    /// Missing or invalid media feature name.
    107    MediaQueryExpectedFeatureName(CowRcStr<'i>),
    108    /// Missing or invalid media feature value.
    109    MediaQueryExpectedFeatureValue,
    110    /// A media feature range operator was not expected.
    111    MediaQueryUnexpectedOperator,
    112    /// min- or max- properties must have a value.
    113    RangedExpressionWithNoValue,
    114    /// A function was encountered that was not expected.
    115    UnexpectedFunction(CowRcStr<'i>),
    116    /// Error encountered parsing a @property's `syntax` descriptor
    117    PropertySyntaxField(PropertySyntaxParseError),
    118    /// Error encountered parsing a @property's `inherits` descriptor.
    119    ///
    120    /// TODO(zrhoffman, bug 1920365): Include the custom property name in error messages.
    121    PropertyInheritsField(PropertyInheritsParseError),
    122    /// @namespace must be before any rule but @charset and @import
    123    UnexpectedNamespaceRule,
    124    /// @import must be before any rule but @charset
    125    UnexpectedImportRule,
    126    /// @import rules are disallowed in the parser.
    127    DisallowedImportRule,
    128    /// Unexpected @charset rule encountered.
    129    UnexpectedCharsetRule,
    130    /// The @property `<custom-property-name>` must start with `--`
    131    UnexpectedIdent(CowRcStr<'i>),
    132    /// A placeholder for many sources of errors that require more specific variants.
    133    UnspecifiedError,
    134    /// An unexpected token was found within a namespace rule.
    135    UnexpectedTokenWithinNamespace(Token<'i>),
    136    /// An error was encountered while parsing a property value.
    137    ValueError(ValueParseErrorKind<'i>),
    138    /// An error was encountered while parsing a selector
    139    SelectorError(SelectorParseErrorKind<'i>),
    140    /// The property declaration was for an unknown property.
    141    UnknownProperty(CowRcStr<'i>),
    142    /// The property declaration was for a disabled experimental property.
    143    ExperimentalProperty,
    144    /// The property declaration contained an invalid color value.
    145    InvalidColor(CowRcStr<'i>, Token<'i>),
    146    /// The property declaration contained an invalid filter value.
    147    InvalidFilter(CowRcStr<'i>, Token<'i>),
    148    /// The property declaration contained an invalid value.
    149    OtherInvalidValue(CowRcStr<'i>),
    150    /// `!important` declarations are disallowed in `@position-try` or keyframes.
    151    UnexpectedImportantDeclaration,
    152 }
    153 
    154 impl<'i> From<ValueParseErrorKind<'i>> for StyleParseErrorKind<'i> {
    155    fn from(this: ValueParseErrorKind<'i>) -> Self {
    156        StyleParseErrorKind::ValueError(this)
    157    }
    158 }
    159 
    160 impl<'i> From<SelectorParseErrorKind<'i>> for StyleParseErrorKind<'i> {
    161    fn from(this: SelectorParseErrorKind<'i>) -> Self {
    162        StyleParseErrorKind::SelectorError(this)
    163    }
    164 }
    165 
    166 /// Specific errors that can be encountered while parsing property values.
    167 #[derive(Clone, Debug, PartialEq)]
    168 pub enum ValueParseErrorKind<'i> {
    169    /// An invalid token was encountered while parsing a color value.
    170    InvalidColor(Token<'i>),
    171    /// An invalid filter value was encountered.
    172    InvalidFilter(Token<'i>),
    173 }
    174 
    175 impl<'i> StyleParseErrorKind<'i> {
    176    /// Create an InvalidValue parse error
    177    pub fn new_invalid<S>(name: S, value_error: ParseError<'i>) -> ParseError<'i>
    178    where
    179        S: Into<CowRcStr<'i>>,
    180    {
    181        let name = name.into();
    182        let variant = match value_error.kind {
    183            cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => match e {
    184                ValueParseErrorKind::InvalidColor(token) => {
    185                    StyleParseErrorKind::InvalidColor(name, token)
    186                },
    187                ValueParseErrorKind::InvalidFilter(token) => {
    188                    StyleParseErrorKind::InvalidFilter(name, token)
    189                },
    190            },
    191            _ => StyleParseErrorKind::OtherInvalidValue(name),
    192        };
    193        cssparser::ParseError {
    194            kind: cssparser::ParseErrorKind::Custom(variant),
    195            location: value_error.location,
    196        }
    197    }
    198 }
    199 
    200 /// Errors that can be encountered while parsing the @property rule's syntax descriptor.
    201 #[derive(Clone, Debug, PartialEq)]
    202 pub enum PropertySyntaxParseError {
    203    /// The syntax descriptor is required for the @property rule to be valid; if it’s missing, the
    204    /// @property rule is invalid.
    205    ///
    206    /// <https://drafts.css-houdini.org/css-properties-values-api-1/#ref-for-descdef-property-syntax②>
    207    NoSyntax,
    208    /// The string's length was 0.
    209    EmptyInput,
    210    /// A non-whitespace, non-pipe character was fount after parsing a component.
    211    ExpectedPipeBetweenComponents,
    212    /// The start of an identifier was expected but not found.
    213    ///
    214    /// <https://drafts.csswg.org/css-syntax-3/#name-start-code-point>
    215    InvalidNameStart,
    216    /// The name is not a valid `<ident>`.
    217    InvalidName,
    218    /// The data type name was not closed.
    219    ///
    220    /// <https://drafts.css-houdini.org/css-properties-values-api-1/#consume-data-type-name>
    221    UnclosedDataTypeName,
    222    /// The next byte was expected while parsing, but EOF was found instead.
    223    UnexpectedEOF,
    224    /// The data type is not a supported syntax component name.
    225    ///
    226    /// <https://drafts.css-houdini.org/css-properties-values-api-1/#supported-names>
    227    UnknownDataTypeName,
    228 }
    229 
    230 /// Errors that can be encountered while parsing the @property rule's inherits descriptor.
    231 #[derive(Clone, Debug, PartialEq)]
    232 pub enum PropertyInheritsParseError {
    233    /// The inherits descriptor is required for the @property rule to be valid; if it’s missing,
    234    /// the @property rule is invalid.
    235    ///
    236    /// <https://drafts.css-houdini.org/css-properties-values-api-1/#ref-for-descdef-property-inherits②>
    237    NoInherits,
    238 
    239    /// The inherits descriptor must successfully parse as `true` or `false`.
    240    InvalidInherits,
    241 }
    242 
    243 bitflags! {
    244    /// The mode to use when parsing values.
    245    #[derive(Clone, Copy, Eq, PartialEq)]
    246    #[repr(C)]
    247    pub struct ParsingMode: u8 {
    248        /// In CSS; lengths must have units, except for zero values, where the unit can be omitted.
    249        /// <https://www.w3.org/TR/css3-values/#lengths>
    250        const DEFAULT = 0;
    251        /// In SVG; a coordinate or length value without a unit identifier (e.g., "25") is assumed
    252        /// to be in user units (px).
    253        /// <https://www.w3.org/TR/SVG/coords.html#Units>
    254        const ALLOW_UNITLESS_LENGTH = 1;
    255        /// In SVG; out-of-range values are not treated as an error in parsing.
    256        /// <https://www.w3.org/TR/SVG/implnote.html#RangeClamping>
    257        const ALLOW_ALL_NUMERIC_VALUES = 1 << 1;
    258        /// In CSS Properties and Values, the initial value must be computationally
    259        /// independent.
    260        /// <https://drafts.css-houdini.org/css-properties-values-api-1/#ref-for-computationally-independent%E2%91%A0>
    261        const DISALLOW_COMPUTATIONALLY_DEPENDENT = 1 << 2;
    262    }
    263 }
    264 
    265 impl ParsingMode {
    266    /// Whether the parsing mode allows unitless lengths for non-zero values to be intpreted as px.
    267    #[inline]
    268    pub fn allows_unitless_lengths(&self) -> bool {
    269        self.intersects(ParsingMode::ALLOW_UNITLESS_LENGTH)
    270    }
    271 
    272    /// Whether the parsing mode allows all numeric values.
    273    #[inline]
    274    pub fn allows_all_numeric_values(&self) -> bool {
    275        self.intersects(ParsingMode::ALLOW_ALL_NUMERIC_VALUES)
    276    }
    277 
    278    /// Whether the parsing mode allows units or functions that are not computationally independent.
    279    #[inline]
    280    pub fn allows_computational_dependence(&self) -> bool {
    281        !self.intersects(ParsingMode::DISALLOW_COMPUTATIONALLY_DEPENDENT)
    282    }
    283 }
    284 
    285 #[cfg(feature = "servo")]
    286 /// Speculatively execute paint code in the worklet thread pool.
    287 pub trait SpeculativePainter: Send + Sync {
    288    /// <https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image>
    289    fn speculatively_draw_a_paint_image(
    290        &self,
    291        properties: Vec<(Atom, String)>,
    292        arguments: Vec<String>,
    293    );
    294 }