1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
/* 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/. */
//! 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)]
use bitflags::bitflags;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize};
#[cfg(feature = "servo")]
pub use webrender_api::units::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 arc_slice;
pub mod dom;
pub mod specified_value_info;
#[macro_use]
pub mod values;
#[macro_use]
pub mod viewport;
pub mod owned_slice;
pub mod owned_str;
pub use crate::specified_value_info::{CssType, KeywordsCollectFn, SpecifiedValueInfo};
pub use crate::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,
/// @import rules are disallowed in the parser.
DisallowedImportRule,
/// 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>),
/// 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>,
);
}