forked from mirrors/gecko-dev
		
	 4bdd7b8cc4
			
		
	
	
		4bdd7b8cc4
		
	
	
	
	
		
			
			Do it so that we always try to evaluate the media expression and the modern syntax last, so that the most specific error message comes up. MozReview-Commit-ID: 2tqdAsWh6Kh
		
			
				
	
	
		
			240 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| /* 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 http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| //! This module contains shared types and messages for use by devtools/script.
 | |
| //! The traits are here instead of in script so that the devtools crate can be
 | |
| //! modified independently of the rest of Servo.
 | |
| 
 | |
| #![crate_name = "style_traits"]
 | |
| #![crate_type = "rlib"]
 | |
| 
 | |
| #![deny(unsafe_code, missing_docs)]
 | |
| 
 | |
| extern crate app_units;
 | |
| #[macro_use] extern crate bitflags;
 | |
| #[macro_use] extern crate cssparser;
 | |
| extern crate euclid;
 | |
| extern crate malloc_size_of;
 | |
| #[macro_use] extern crate malloc_size_of_derive;
 | |
| extern crate selectors;
 | |
| #[cfg(feature = "servo")] #[macro_use] extern crate serde;
 | |
| #[cfg(feature = "servo")] extern crate webrender_api;
 | |
| extern crate servo_arc;
 | |
| #[cfg(feature = "servo")] extern crate servo_atoms;
 | |
| #[cfg(feature = "servo")] extern crate servo_url;
 | |
| 
 | |
| #[cfg(feature = "servo")] pub use webrender_api::DevicePixel;
 | |
| 
 | |
| use cssparser::{CowRcStr, Token};
 | |
| use selectors::parser::SelectorParseErrorKind;
 | |
| #[cfg(feature = "servo")] use servo_atoms::Atom;
 | |
| 
 | |
| /// One hardware pixel.
 | |
| ///
 | |
| /// This unit corresponds to the smallest addressable element of the display hardware.
 | |
| #[cfg(not(feature = "servo"))]
 | |
| #[derive(Clone, Copy, Debug)]
 | |
| pub enum DevicePixel {}
 | |
| 
 | |
| /// Represents a mobile style pinch zoom factor.
 | |
| /// TODO(gw): Once WR supports pinch zoom, use a type directly from webrender_api.
 | |
| #[derive(Clone, Copy, Debug, PartialEq)]
 | |
| #[cfg_attr(feature = "servo", derive(Deserialize, Serialize, MallocSizeOf))]
 | |
| pub struct PinchZoomFactor(f32);
 | |
| 
 | |
| impl PinchZoomFactor {
 | |
|     /// Construct a new pinch zoom factor.
 | |
|     pub fn new(scale: f32) -> PinchZoomFactor {
 | |
|         PinchZoomFactor(scale)
 | |
|     }
 | |
| 
 | |
|     /// Get the pinch zoom factor as an untyped float.
 | |
|     pub fn get(&self) -> f32 {
 | |
|         self.0
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// One CSS "px" in the coordinate system of the "initial viewport":
 | |
| /// <http://www.w3.org/TR/css-device-adapt/#initial-viewport>
 | |
| ///
 | |
| /// `CSSPixel` is equal to `DeviceIndependentPixel` times a "page zoom" factor controlled by the user.  This is
 | |
| /// the desktop-style "full page" zoom that enlarges content but then reflows the layout viewport
 | |
| /// so it still exactly fits the visible area.
 | |
| ///
 | |
| /// At the default zoom level of 100%, one `CSSPixel` is equal to one `DeviceIndependentPixel`.  However, if the
 | |
| /// document is zoomed in or out then this scale may be larger or smaller.
 | |
| #[derive(Clone, Copy, Debug)]
 | |
| pub enum CSSPixel {}
 | |
| 
 | |
| // In summary, the hierarchy of pixel units and the factors to convert from one to the next:
 | |
| //
 | |
| // DevicePixel
 | |
| //   / hidpi_ratio => DeviceIndependentPixel
 | |
| //     / desktop_zoom => CSSPixel
 | |
| 
 | |
| pub mod cursor;
 | |
| pub mod specified_value_info;
 | |
| #[macro_use]
 | |
| pub mod values;
 | |
| #[macro_use]
 | |
| pub mod viewport;
 | |
| 
 | |
| pub use specified_value_info::{CssType, KeywordsCollectFn, SpecifiedValueInfo};
 | |
| pub use values::{Comma, CommaWithSpace, CssWriter, OneOrMoreSeparated, Separator, Space, ToCss};
 | |
| 
 | |
| /// The error type for all CSS parsing routines.
 | |
| pub type ParseError<'i> = cssparser::ParseError<'i, StyleParseErrorKind<'i>>;
 | |
| 
 | |
| /// Error in property value parsing
 | |
| pub type ValueParseError<'i> = cssparser::ParseError<'i, ValueParseErrorKind<'i>>;
 | |
| 
 | |
| #[derive(Clone, Debug, PartialEq)]
 | |
| /// Errors that can be encountered while parsing CSS values.
 | |
| pub enum StyleParseErrorKind<'i> {
 | |
|     /// A bad URL token in a DVB.
 | |
|     BadUrlInDeclarationValueBlock(CowRcStr<'i>),
 | |
|     /// A bad string token in a DVB.
 | |
|     BadStringInDeclarationValueBlock(CowRcStr<'i>),
 | |
|     /// Unexpected closing parenthesis in a DVB.
 | |
|     UnbalancedCloseParenthesisInDeclarationValueBlock,
 | |
|     /// Unexpected closing bracket in a DVB.
 | |
|     UnbalancedCloseSquareBracketInDeclarationValueBlock,
 | |
|     /// Unexpected closing curly bracket in a DVB.
 | |
|     UnbalancedCloseCurlyBracketInDeclarationValueBlock,
 | |
|     /// A property declaration value had input remaining after successfully parsing.
 | |
|     PropertyDeclarationValueNotExhausted,
 | |
|     /// An unexpected dimension token was encountered.
 | |
|     UnexpectedDimension(CowRcStr<'i>),
 | |
|     /// Missing or invalid media feature name.
 | |
|     MediaQueryExpectedFeatureName(CowRcStr<'i>),
 | |
|     /// Missing or invalid media feature value.
 | |
|     MediaQueryExpectedFeatureValue,
 | |
|     /// A media feature range operator was not expected.
 | |
|     MediaQueryUnexpectedOperator,
 | |
|     /// min- or max- properties must have a value.
 | |
|     RangedExpressionWithNoValue,
 | |
|     /// A function was encountered that was not expected.
 | |
|     UnexpectedFunction(CowRcStr<'i>),
 | |
|     /// @namespace must be before any rule but @charset and @import
 | |
|     UnexpectedNamespaceRule,
 | |
|     /// @import must be before any rule but @charset
 | |
|     UnexpectedImportRule,
 | |
|     /// Unexpected @charset rule encountered.
 | |
|     UnexpectedCharsetRule,
 | |
|     /// Unsupported @ rule
 | |
|     UnsupportedAtRule(CowRcStr<'i>),
 | |
|     /// A placeholder for many sources of errors that require more specific variants.
 | |
|     UnspecifiedError,
 | |
|     /// An unexpected token was found within a namespace rule.
 | |
|     UnexpectedTokenWithinNamespace(Token<'i>),
 | |
|     /// An error was encountered while parsing a property value.
 | |
|     ValueError(ValueParseErrorKind<'i>),
 | |
|     /// An error was encountered while parsing a selector
 | |
|     SelectorError(SelectorParseErrorKind<'i>),
 | |
| 
 | |
|     /// The property declaration was for an unknown property.
 | |
|     UnknownProperty(CowRcStr<'i>),
 | |
|     /// An unknown vendor-specific identifier was encountered.
 | |
|     UnknownVendorProperty,
 | |
|     /// The property declaration was for a disabled experimental property.
 | |
|     ExperimentalProperty,
 | |
|     /// The property declaration contained an invalid color value.
 | |
|     InvalidColor(CowRcStr<'i>, Token<'i>),
 | |
|     /// The property declaration contained an invalid filter value.
 | |
|     InvalidFilter(CowRcStr<'i>, Token<'i>),
 | |
|     /// The property declaration contained an invalid value.
 | |
|     OtherInvalidValue(CowRcStr<'i>),
 | |
|     /// The declaration contained an animation property, and we were parsing
 | |
|     /// this as a keyframe block (so that property should be ignored).
 | |
|     ///
 | |
|     /// See: https://drafts.csswg.org/css-animations/#keyframes
 | |
|     AnimationPropertyInKeyframeBlock,
 | |
|     /// The property is not allowed within a page rule.
 | |
|     NotAllowedInPageRule,
 | |
| }
 | |
| 
 | |
| impl<'i> From<ValueParseErrorKind<'i>> for StyleParseErrorKind<'i> {
 | |
|     fn from(this: ValueParseErrorKind<'i>) -> Self {
 | |
|         StyleParseErrorKind::ValueError(this)
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<'i> From<SelectorParseErrorKind<'i>> for StyleParseErrorKind<'i> {
 | |
|     fn from(this: SelectorParseErrorKind<'i>) -> Self {
 | |
|         StyleParseErrorKind::SelectorError(this)
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// Specific errors that can be encountered while parsing property values.
 | |
| #[derive(Clone, Debug, PartialEq)]
 | |
| pub enum ValueParseErrorKind<'i> {
 | |
|     /// An invalid token was encountered while parsing a color value.
 | |
|     InvalidColor(Token<'i>),
 | |
|     /// An invalid filter value was encountered.
 | |
|     InvalidFilter(Token<'i>),
 | |
| }
 | |
| 
 | |
| impl<'i> StyleParseErrorKind<'i> {
 | |
|     /// Create an InvalidValue parse error
 | |
|     pub fn new_invalid<S>(name: S, value_error: ParseError<'i>) -> ParseError<'i>
 | |
|     where
 | |
|         S: Into<CowRcStr<'i>>,
 | |
|     {
 | |
|         let name = name.into();
 | |
|         let variant = match value_error.kind {
 | |
|             cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => {
 | |
|                 match e {
 | |
|                     ValueParseErrorKind::InvalidColor(token) => {
 | |
|                         StyleParseErrorKind::InvalidColor(name, token)
 | |
|                     }
 | |
|                     ValueParseErrorKind::InvalidFilter(token) => {
 | |
|                         StyleParseErrorKind::InvalidFilter(name, token)
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             _ => StyleParseErrorKind::OtherInvalidValue(name),
 | |
|         };
 | |
|         cssparser::ParseError {
 | |
|             kind: cssparser::ParseErrorKind::Custom(variant),
 | |
|             location: value_error.location,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| bitflags! {
 | |
|     /// The mode to use when parsing values.
 | |
|     pub struct ParsingMode: u8 {
 | |
|         /// In CSS; lengths must have units, except for zero values, where the unit can be omitted.
 | |
|         /// <https://www.w3.org/TR/css3-values/#lengths>
 | |
|         const DEFAULT = 0x00;
 | |
|         /// In SVG; a coordinate or length value without a unit identifier (e.g., "25") is assumed
 | |
|         /// to be in user units (px).
 | |
|         /// <https://www.w3.org/TR/SVG/coords.html#Units>
 | |
|         const ALLOW_UNITLESS_LENGTH = 0x01;
 | |
|         /// In SVG; out-of-range values are not treated as an error in parsing.
 | |
|         /// <https://www.w3.org/TR/SVG/implnote.html#RangeClamping>
 | |
|         const ALLOW_ALL_NUMERIC_VALUES = 0x02;
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl ParsingMode {
 | |
|     /// Whether the parsing mode allows unitless lengths for non-zero values to be intpreted as px.
 | |
|     #[inline]
 | |
|     pub fn allows_unitless_lengths(&self) -> bool {
 | |
|         self.intersects(ParsingMode::ALLOW_UNITLESS_LENGTH)
 | |
|     }
 | |
| 
 | |
|     /// Whether the parsing mode allows all numeric values.
 | |
|     #[inline]
 | |
|     pub fn allows_all_numeric_values(&self) -> bool {
 | |
|         self.intersects(ParsingMode::ALLOW_ALL_NUMERIC_VALUES)
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[cfg(feature = "servo")]
 | |
| /// Speculatively execute paint code in the worklet thread pool.
 | |
| pub trait SpeculativePainter: Send + Sync {
 | |
|     /// <https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image>
 | |
|     fn speculatively_draw_a_paint_image(&self, properties: Vec<(Atom, String)>, arguments: Vec<String>);
 | |
| }
 |