gecko-dev/servo/components/style_traits/lib.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

256 строки
9.3 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 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)]
extern crate app_units;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate cssparser;
extern crate euclid;
servo: Merge #18938 - Replace all uses of the `heapsize` crate with `malloc_size_of` (from nnethercote:bug-1409255); r=SimonSapin Servo currently uses `heapsize`, but Stylo/Gecko use `malloc_size_of`. `malloc_size_of` is better -- it handles various cases that `heapsize` does not -- so this patch changes Servo to use `malloc_size_of`. This patch makes the following changes to the `malloc_size_of` crate. - Adds `MallocSizeOf` trait implementations for numerous types, some built-in (e.g. `VecDeque`), some external and Servo-only (e.g. `string_cache`). - Makes `enclosing_size_of_op` optional, because vanilla jemalloc doesn't support that operation. - For `HashSet`/`HashMap`, falls back to a computed estimate when `enclosing_size_of_op` isn't available. - Adds an extern "C" `malloc_size_of` function that does the actual heap measurement; this is based on the same functions from the `heapsize` crate. This patch makes the following changes elsewhere. - Converts all the uses of `heapsize` to instead use `malloc_size_of`. - Disables the "heapsize"/"heap_size" feature for the external crates that provide it. - Removes the `HeapSizeOf` implementation from `hashglobe`. - Adds `ignore` annotations to a few `Rc`/`Arc`, because `malloc_size_of` doesn't derive those types, unlike `heapsize`. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix https://bugzilla.mozilla.org/show_bug.cgi?id=1409255 <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because testing is on the Gecko side. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 4c538b642e4bdfbf42c522c5a59c258a6d14546e --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : f9a6feed1088d0b0be2b55d7f0c2ec9c594ac33b
2017-10-18 21:56:05 +03:00
extern crate malloc_size_of;
#[macro_use]
extern crate malloc_size_of_derive;
extern crate selectors;
#[cfg(feature = "servo")]
#[macro_use]
extern crate serde;
extern crate servo_arc;
#[cfg(feature = "servo")]
extern crate servo_atoms;
#[cfg(feature = "servo")]
extern crate servo_url;
extern crate to_shmem;
#[macro_use]
extern crate to_shmem_derive;
#[cfg(feature = "servo")]
extern crate webrender_api;
#[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 specified_value_info;
#[macro_use]
pub mod values;
#[macro_use]
pub mod viewport;
pub mod owned_slice;
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,
/// 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>,
);
}