diff --git a/components/layout/generated_content.rs b/components/layout/generated_content.rs index 004bcf5d9de..e838bde6b95 100644 --- a/components/layout/generated_content.rs +++ b/components/layout/generated_content.rs @@ -311,9 +311,9 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> { "es.0[self.traversal.quote as usize] }; if close { - close_quote.clone() + close_quote.to_string() } else { - open_quote.clone() + open_quote.to_string() } } } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index fcf045e1de8..5b46f784d99 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -4229,8 +4229,11 @@ fn static_assert() { let ref gecko_quote_values = *self.gecko.mQuotes.mRawPtr; longhands::quotes::computed_value::T( gecko_quote_values.mQuotePairs.iter().map(|gecko_pair| { - (gecko_pair.first.to_string(), gecko_pair.second.to_string()) - }).collect() + ( + gecko_pair.first.to_string().into_boxed_str(), + gecko_pair.second.to_string().into_boxed_str(), + ) + }).collect::>().into_boxed_slice() ) } } diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index 4f3442da376..363f2a926c5 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -135,76 +135,11 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu } -<%helpers:longhand name="quotes" animation_value_type="discrete" - spec="https://drafts.csswg.org/css-content/#propdef-quotes"> - use cssparser::serialize_string; - use std::fmt; - use style_traits::ToCss; - - pub use self::computed_value::T as SpecifiedValue; - - pub mod computed_value { - #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)] - pub struct T(pub Vec<(String, String)>); - } - - impl ToCss for SpecifiedValue { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - if self.0.is_empty() { - return dest.write_str("none") - } - - let mut first = true; - for pair in &self.0 { - if !first { - dest.write_str(" ")?; - } - first = false; - serialize_string(&*pair.0, dest)?; - dest.write_str(" ")?; - serialize_string(&*pair.1, dest)?; - } - Ok(()) - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T(vec![ - ("\u{201c}".to_owned(), "\u{201d}".to_owned()), - ("\u{2018}".to_owned(), "\u{2019}".to_owned()), - ]) - } - - pub fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) - -> Result> { - if input.try(|input| input.expect_ident_matching("none")).is_ok() { - return Ok(SpecifiedValue(Vec::new())) - } - - let mut quotes = Vec::new(); - loop { - let location = input.current_source_location(); - let first = match input.next() { - Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(), - Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), - Err(_) => break, - }; - let location = input.current_source_location(); - let second = match input.next() { - Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(), - Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), - Err(e) => return Err(e.into()), - }; - quotes.push((first, second)) - } - if !quotes.is_empty() { - Ok(SpecifiedValue(quotes)) - } else { - Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } - } - +${helpers.predefined_type("quotes", + "Quotes", + "computed::Quotes::get_initial_value()", + animation_value_type="discrete", + spec="https://drafts.csswg.org/css-content/#propdef-quotes")} ${helpers.predefined_type("-moz-image-region", "ClipRectOrAuto", diff --git a/components/style/values/computed/list.rs b/components/style/values/computed/list.rs new file mode 100644 index 00000000000..49234f92ed9 --- /dev/null +++ b/components/style/values/computed/list.rs @@ -0,0 +1,26 @@ +/* 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/. */ + +//! `list` computed values. + +pub use values::specified::list::Quotes; + +impl Quotes { + /// Initial value for `quotes`. + /// + /// FIXME(emilio): This should ideally not allocate. + #[inline] + pub fn get_initial_value() -> Quotes { + Quotes(vec![ + ( + "\u{201c}".to_owned().into_boxed_str(), + "\u{201d}".to_owned().into_boxed_str(), + ), + ( + "\u{2018}".to_owned().into_boxed_str(), + "\u{2019}".to_owned().into_boxed_str(), + ), + ].into_boxed_slice()) + } +} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 3f2388698fe..dc8952cb4bc 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -54,6 +54,7 @@ pub use super::specified::{BorderStyle, TextDecorationLine}; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage}; pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength}; pub use self::length::{CSSPixelLength, NonNegativeLength, NonNegativeLengthOrPercentage}; +pub use self::list::Quotes; pub use self::outline::OutlineStyle; pub use self::percentage::Percentage; pub use self::position::{Position, GridAutoFlow, GridTemplateAreas}; @@ -80,6 +81,7 @@ pub mod image; #[cfg(feature = "gecko")] pub mod gecko; pub mod length; +pub mod list; pub mod outline; pub mod percentage; pub mod position; @@ -399,6 +401,7 @@ trivial_to_computed_value!(BorderStyle); trivial_to_computed_value!(Cursor); trivial_to_computed_value!(Namespace); trivial_to_computed_value!(String); +trivial_to_computed_value!(Box); /// A `` value. pub type Number = CSSFloat; diff --git a/components/style/values/specified/list.rs b/components/style/values/specified/list.rs new file mode 100644 index 00000000000..11a29ea14a8 --- /dev/null +++ b/components/style/values/specified/list.rs @@ -0,0 +1,71 @@ +/* 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/. */ + +//! `list` specified values. + +use cssparser::{Parser, Token}; +use parser::{Parse, ParserContext}; +use std::fmt; +use style_traits::{ParseError, StyleParseErrorKind, ToCss}; + +/// Specified and computed `quote` property. +/// +/// FIXME(emilio): It's a shame that this allocates all the time it's computed, +/// probably should just be refcounted. +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)] +pub struct Quotes(pub Box<[(Box, Box)]>); + +impl ToCss for Quotes { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + let mut iter = self.0.iter(); + + match iter.next() { + Some(&(ref l, ref r)) => { + l.to_css(dest)?; + dest.write_char(' ')?; + r.to_css(dest)?; + } + None => return dest.write_str("none"), + } + + for &(ref l, ref r) in iter { + dest.write_char(' ')?; + l.to_css(dest)?; + dest.write_char(' ')?; + r.to_css(dest)?; + } + + Ok(()) + } +} + +impl Parse for Quotes { + fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + return Ok(Quotes(Vec::new().into_boxed_slice())) + } + + let mut quotes = Vec::new(); + loop { + let location = input.current_source_location(); + let first = match input.next() { + Ok(&Token::QuotedString(ref value)) => { + value.as_ref().to_owned().into_boxed_str() + }, + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), + Err(_) => break, + }; + + let second = + input.expect_string()?.as_ref().to_owned().into_boxed_str(); + quotes.push((first, second)) + } + + if !quotes.is_empty() { + Ok(Quotes(quotes.into_boxed_slice())) + } else { + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + } + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index d9863620ae4..cb346728ad0 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -49,6 +49,7 @@ pub use self::length::{LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrNone, MaxLength, MozLength}; pub use self::length::{NoCalcLength, ViewportPercentageLength}; pub use self::length::NonNegativeLengthOrPercentage; +pub use self::list::Quotes; pub use self::outline::OutlineStyle; pub use self::rect::LengthOrNumberRect; pub use self::percentage::Percentage; @@ -79,6 +80,7 @@ pub mod gecko; pub mod grid; pub mod image; pub mod length; +pub mod list; pub mod outline; pub mod percentage; pub mod position;