Format component of style_traits

This commit is contained in:
chansuke 2018-09-06 00:32:36 +09:00
parent 81655a9a99
commit a2fc2ae517
4 changed files with 121 additions and 64 deletions

View file

@ -8,27 +8,35 @@
#![crate_name = "style_traits"] #![crate_name = "style_traits"]
#![crate_type = "rlib"] #![crate_type = "rlib"]
#![deny(unsafe_code, missing_docs)] #![deny(unsafe_code, missing_docs)]
extern crate app_units; extern crate app_units;
#[macro_use] extern crate bitflags; #[macro_use]
#[macro_use] extern crate cssparser; extern crate bitflags;
#[macro_use]
extern crate cssparser;
extern crate euclid; extern crate euclid;
extern crate malloc_size_of; extern crate malloc_size_of;
#[macro_use] extern crate malloc_size_of_derive; #[macro_use]
extern crate malloc_size_of_derive;
extern crate selectors; extern crate selectors;
#[cfg(feature = "servo")] #[macro_use] extern crate serde; #[cfg(feature = "servo")]
#[cfg(feature = "servo")] extern crate webrender_api; #[macro_use]
extern crate serde;
extern crate servo_arc; extern crate servo_arc;
#[cfg(feature = "servo")] extern crate servo_atoms; #[cfg(feature = "servo")]
#[cfg(feature = "servo")] extern crate servo_url; extern crate servo_atoms;
#[cfg(feature = "servo")]
#[cfg(feature = "servo")] pub use webrender_api::DevicePixel; extern crate servo_url;
#[cfg(feature = "servo")]
extern crate webrender_api;
#[cfg(feature = "servo")]
pub use webrender_api::DevicePixel;
use cssparser::{CowRcStr, Token}; use cssparser::{CowRcStr, Token};
use selectors::parser::SelectorParseErrorKind; use selectors::parser::SelectorParseErrorKind;
#[cfg(feature = "servo")] use servo_atoms::Atom; #[cfg(feature = "servo")]
use servo_atoms::Atom;
/// One hardware pixel. /// One hardware pixel.
/// ///
@ -40,7 +48,10 @@ pub enum DevicePixel {}
/// Represents a mobile style pinch zoom factor. /// Represents a mobile style pinch zoom factor.
/// TODO(gw): Once WR supports pinch zoom, use a type directly from webrender_api. /// TODO(gw): Once WR supports pinch zoom, use a type directly from webrender_api.
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, MallocSizeOf))] #[cfg_attr(
feature = "servo",
derive(Deserialize, Serialize, MallocSizeOf)
)]
pub struct PinchZoomFactor(f32); pub struct PinchZoomFactor(f32);
impl PinchZoomFactor { impl PinchZoomFactor {
@ -183,16 +194,14 @@ impl<'i> StyleParseErrorKind<'i> {
{ {
let name = name.into(); let name = name.into();
let variant = match value_error.kind { let variant = match value_error.kind {
cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => { cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => match e {
match e { ValueParseErrorKind::InvalidColor(token) => {
ValueParseErrorKind::InvalidColor(token) => { StyleParseErrorKind::InvalidColor(name, token)
StyleParseErrorKind::InvalidColor(name, token) },
} ValueParseErrorKind::InvalidFilter(token) => {
ValueParseErrorKind::InvalidFilter(token) => { StyleParseErrorKind::InvalidFilter(name, token)
StyleParseErrorKind::InvalidFilter(name, token) },
} },
}
}
_ => StyleParseErrorKind::OtherInvalidValue(name), _ => StyleParseErrorKind::OtherInvalidValue(name),
}; };
cssparser::ParseError { cssparser::ParseError {
@ -236,5 +245,9 @@ impl ParsingMode {
/// Speculatively execute paint code in the worklet thread pool. /// Speculatively execute paint code in the worklet thread pool.
pub trait SpeculativePainter: Send + Sync { pub trait SpeculativePainter: Send + Sync {
/// <https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image> /// <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>); fn speculatively_draw_a_paint_image(
&self,
properties: Vec<(Atom, String)>,
arguments: Vec<String>,
);
} }

View file

@ -110,7 +110,7 @@ macro_rules! impl_generic_specified_value_info {
$param::collect_completion_keywords(f); $param::collect_completion_keywords(f);
} }
} }
} };
} }
impl_generic_specified_value_info!(Option<T>); impl_generic_specified_value_info!(Option<T>);
impl_generic_specified_value_info!(Vec<T>); impl_generic_specified_value_info!(Vec<T>);

View file

@ -44,7 +44,9 @@ use std::fmt::{self, Write};
/// implement `Debug` by a single call to `ToCss::to_css`. /// implement `Debug` by a single call to `ToCss::to_css`.
pub trait ToCss { pub trait ToCss {
/// Serialize `self` in CSS syntax, writing to `dest`. /// Serialize `self` in CSS syntax, writing to `dest`.
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write; fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write;
/// Serialize `self` in CSS syntax and return a string. /// Serialize `self` in CSS syntax and return a string.
/// ///
@ -57,22 +59,34 @@ pub trait ToCss {
} }
} }
impl<'a, T> ToCss for &'a T where T: ToCss + ?Sized { impl<'a, T> ToCss for &'a T
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { where
T: ToCss + ?Sized,
{
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
(*self).to_css(dest) (*self).to_css(dest)
} }
} }
impl ToCss for str { impl ToCss for str {
#[inline] #[inline]
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
serialize_string(self, dest) serialize_string(self, dest)
} }
} }
impl ToCss for String { impl ToCss for String {
#[inline] #[inline]
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
serialize_string(self, dest) serialize_string(self, dest)
} }
} }
@ -82,7 +96,10 @@ where
T: ToCss, T: ToCss,
{ {
#[inline] #[inline]
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
self.as_ref().map_or(Ok(()), |value| value.to_css(dest)) self.as_ref().map_or(Ok(()), |value| value.to_css(dest))
} }
} }
@ -103,7 +120,10 @@ where
/// Creates a new `CssWriter`. /// Creates a new `CssWriter`.
#[inline] #[inline]
pub fn new(inner: &'w mut W) -> Self { pub fn new(inner: &'w mut W) -> Self {
Self { inner, prefix: Some("") } Self {
inner,
prefix: Some(""),
}
} }
} }
@ -179,7 +199,7 @@ where
#[inline] #[inline]
fn write_item<F>(&mut self, f: F) -> fmt::Result fn write_item<F>(&mut self, f: F) -> fmt::Result
where where
F: FnOnce(&mut CssWriter<'b, W>) -> fmt::Result F: FnOnce(&mut CssWriter<'b, W>) -> fmt::Result,
{ {
let old_prefix = self.inner.prefix; let old_prefix = self.inner.prefix;
if old_prefix.is_none() { if old_prefix.is_none() {
@ -192,7 +212,7 @@ where
match (old_prefix, self.inner.prefix) { match (old_prefix, self.inner.prefix) {
(_, None) => { (_, None) => {
// This call produced output and cleaned up after itself. // This call produced output and cleaned up after itself.
} },
(None, Some(p)) => { (None, Some(p)) => {
// Some previous call to `item` produced output, // Some previous call to `item` produced output,
// but this one did not, prefix should be the same as // but this one did not, prefix should be the same as
@ -201,12 +221,12 @@ where
// We clean up here even though it's not necessary just // We clean up here even though it's not necessary just
// to be able to do all these assertion checks. // to be able to do all these assertion checks.
self.inner.prefix = None; self.inner.prefix = None;
} },
(Some(old), Some(new)) => { (Some(old), Some(new)) => {
// No previous call to `item` produced output, and this one // No previous call to `item` produced output, and this one
// either. // either.
debug_assert_eq!(old, new); debug_assert_eq!(old, new);
} },
} }
Ok(()) Ok(())
} }
@ -282,7 +302,7 @@ impl Separator for Comma {
parse_one: F, parse_one: F,
) -> Result<Vec<T>, ParseError<'i, E>> ) -> Result<Vec<T>, ParseError<'i, E>>
where where
F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>> F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>,
{ {
input.parse_comma_separated(parse_one) input.parse_comma_separated(parse_one)
} }
@ -298,16 +318,16 @@ impl Separator for Space {
mut parse_one: F, mut parse_one: F,
) -> Result<Vec<T>, ParseError<'i, E>> ) -> Result<Vec<T>, ParseError<'i, E>>
where where
F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>> F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>,
{ {
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
let mut results = vec![parse_one(input)?]; let mut results = vec![parse_one(input)?];
loop { loop {
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
if let Ok(item) = input.try(&mut parse_one) { if let Ok(item) = input.try(&mut parse_one) {
results.push(item); results.push(item);
} else { } else {
return Ok(results) return Ok(results);
} }
} }
} }
@ -323,15 +343,15 @@ impl Separator for CommaWithSpace {
mut parse_one: F, mut parse_one: F,
) -> Result<Vec<T>, ParseError<'i, E>> ) -> Result<Vec<T>, ParseError<'i, E>>
where where
F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>> F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>,
{ {
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
let mut results = vec![parse_one(input)?]; let mut results = vec![parse_one(input)?];
loop { loop {
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
let comma_location = input.current_source_location(); let comma_location = input.current_source_location();
let comma = input.try(|i| i.expect_comma()).is_ok(); let comma = input.try(|i| i.expect_comma()).is_ok();
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
if let Ok(item) = input.try(&mut parse_one) { if let Ok(item) = input.try(&mut parse_one) {
results.push(item); results.push(item);
} else if comma { } else if comma {
@ -355,8 +375,14 @@ impl OneOrMoreSeparated for UnicodeRange {
type S = Comma; type S = Comma;
} }
impl<T> ToCss for Vec<T> where T: ToCss + OneOrMoreSeparated { impl<T> ToCss for Vec<T>
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { where
T: ToCss + OneOrMoreSeparated,
{
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
let mut iter = self.iter(); let mut iter = self.iter();
iter.next().unwrap().to_css(dest)?; iter.next().unwrap().to_css(dest)?;
for item in iter { for item in iter {
@ -367,24 +393,35 @@ impl<T> ToCss for Vec<T> where T: ToCss + OneOrMoreSeparated {
} }
} }
impl<T> ToCss for Box<T> where T: ?Sized + ToCss { impl<T> ToCss for Box<T>
where
T: ?Sized + ToCss,
{
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where W: Write, where
W: Write,
{ {
(**self).to_css(dest) (**self).to_css(dest)
} }
} }
impl<T> ToCss for Arc<T> where T: ?Sized + ToCss { impl<T> ToCss for Arc<T>
where
T: ?Sized + ToCss,
{
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where W: Write, where
W: Write,
{ {
(**self).to_css(dest) (**self).to_css(dest)
} }
} }
impl ToCss for Au { impl ToCss for Au {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
self.to_f64_px().to_css(dest)?; self.to_f64_px().to_css(dest)?;
dest.write_str("px") dest.write_str("px")
} }
@ -393,7 +430,10 @@ impl ToCss for Au {
macro_rules! impl_to_css_for_predefined_type { macro_rules! impl_to_css_for_predefined_type {
($name: ty) => { ($name: ty) => {
impl<'a> ToCss for $name { impl<'a> ToCss for $name {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
::cssparser::ToCss::to_css(self, dest) ::cssparser::ToCss::to_css(self, dest)
} }
} }

View file

@ -28,7 +28,10 @@ define_css_keyword_enum! {
/// ///
/// <https://drafts.csswg.org/css-device-adapt/#viewport-desc> /// <https://drafts.csswg.org/css-device-adapt/#viewport-desc>
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, MallocSizeOf))] #[cfg_attr(
feature = "servo",
derive(Deserialize, Serialize, MallocSizeOf)
)]
pub struct ViewportConstraints { pub struct ViewportConstraints {
/// Width and height: /// Width and height:
/// * https://drafts.csswg.org/css-device-adapt/#width-desc /// * https://drafts.csswg.org/css-device-adapt/#width-desc
@ -43,7 +46,7 @@ pub struct ViewportConstraints {
/// <https://drafts.csswg.org/css-device-adapt/#user-zoom-desc> /// <https://drafts.csswg.org/css-device-adapt/#user-zoom-desc>
pub user_zoom: UserZoom, pub user_zoom: UserZoom,
/// <https://drafts.csswg.org/css-device-adapt/#orientation-desc> /// <https://drafts.csswg.org/css-device-adapt/#orientation-desc>
pub orientation: Orientation pub orientation: Orientation,
} }
impl ToCss for ViewportConstraints { impl ToCss for ViewportConstraints {
@ -93,7 +96,8 @@ pub enum Zoom {
impl ToCss for Zoom { impl ToCss for Zoom {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where W: fmt::Write, where
W: fmt::Write,
{ {
match *self { match *self {
Zoom::Number(number) => number.to_css(dest), Zoom::Number(number) => number.to_css(dest),
@ -101,7 +105,7 @@ impl ToCss for Zoom {
Zoom::Percentage(percentage) => { Zoom::Percentage(percentage) => {
(percentage * 100.).to_css(dest)?; (percentage * 100.).to_css(dest)?;
dest.write_char('%') dest.write_char('%')
} },
} }
} }
} }
@ -121,16 +125,16 @@ impl Zoom {
// argument, and pass ParsingMode owned by the ParserContext to // argument, and pass ParsingMode owned by the ParserContext to
// is_ok() instead of using ParsingMode::DEFAULT directly. // is_ok() instead of using ParsingMode::DEFAULT directly.
// In order to do so, we might want to move these stuff into style::stylesheets::viewport_rule. // In order to do so, we might want to move these stuff into style::stylesheets::viewport_rule.
Token::Percentage { unit_value, .. } if NonNegative.is_ok(ParsingMode::DEFAULT, unit_value) => { Token::Percentage { unit_value, .. }
if NonNegative.is_ok(ParsingMode::DEFAULT, unit_value) =>
{
Ok(Zoom::Percentage(unit_value)) Ok(Zoom::Percentage(unit_value))
} },
Token::Number { value, .. } if NonNegative.is_ok(ParsingMode::DEFAULT, value) => { Token::Number { value, .. } if NonNegative.is_ok(ParsingMode::DEFAULT, value) => {
Ok(Zoom::Number(value)) Ok(Zoom::Number(value))
} },
Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => { Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => Ok(Zoom::Auto),
Ok(Zoom::Auto) ref t => Err(location.new_unexpected_token_error(t.clone())),
}
ref t => Err(location.new_unexpected_token_error(t.clone()))
} }
} }
@ -141,7 +145,7 @@ impl Zoom {
match *self { match *self {
Zoom::Number(number) => Some(number as f32), Zoom::Number(number) => Some(number as f32),
Zoom::Percentage(percentage) => Some(percentage as f32), Zoom::Percentage(percentage) => Some(percentage as f32),
Zoom::Auto => None Zoom::Auto => None,
} }
} }
} }