Bug 1457332: Derive ToCss for Counters. r?xidorn
MozReview-Commit-ID: 1jOglcqt1Dd
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -5692,19 +5692,19 @@ clip-path
% for counter_property in ["Increment", "Reset"]:
pub fn set_counter_${counter_property.lower()}(
&mut self,
v: longhands::counter_${counter_property.lower()}::computed_value::T
) {
unsafe {
bindings::Gecko_ClearAndResizeCounter${counter_property}s(&mut self.gecko, v.len() as u32);
- for (i, &(ref name, value)) in v.iter().enumerate() {
- self.gecko.m${counter_property}s[i].mCounter.assign(name.0.as_slice());
- self.gecko.m${counter_property}s[i].mValue = value;
+ for (i, ref pair) in v.iter().enumerate() {
+ self.gecko.m${counter_property}s[i].mCounter.assign(pair.name.0.as_slice());
+ self.gecko.m${counter_property}s[i].mValue = pair.delta;
}
}
}
pub fn copy_counter_${counter_property.lower()}_from(&mut self, other: &Self) {
unsafe {
bindings::Gecko_CopyCounter${counter_property}sFrom(&mut self.gecko, &other.gecko)
}
@@ -5712,22 +5712,26 @@ clip-path
pub fn reset_counter_${counter_property.lower()}(&mut self, other: &Self) {
self.copy_counter_${counter_property.lower()}_from(other)
}
pub fn clone_counter_${counter_property.lower()}(
&self
) -> longhands::counter_${counter_property.lower()}::computed_value::T {
+ use values::generics::counters::CounterPair;
use values::CustomIdent;
use gecko_string_cache::Atom;
longhands::counter_${counter_property.lower()}::computed_value::T::new(
self.gecko.m${counter_property}s.iter().map(|ref gecko_counter| {
- (CustomIdent(Atom::from(gecko_counter.mCounter.to_string())), gecko_counter.mValue)
+ CounterPair {
+ name: CustomIdent(Atom::from(gecko_counter.mCounter.to_string())),
+ delta: gecko_counter.mValue,
+ }
}).collect()
)
}
% endfor
</%self:impl_trait>
<%self:impl_trait style_struct_name="UI" skip_longhands="-moz-force-broken-image-icon">
${impl_simple_type_with_conversion("_moz_force_broken_image_icon", "mForceBrokenImageIcon")}
--- a/servo/components/style/values/generics/counters.rs
+++ b/servo/components/style/values/generics/counters.rs
@@ -1,96 +1,76 @@
/* 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/. */
//! Generic types for counters-related CSS values.
-use std::fmt;
-use std::fmt::Write;
use std::ops::Deref;
-use style_traits::{CssWriter, ToCss};
use values::CustomIdent;
+/// A name / value pair for counters.
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
+ ToComputedValue, ToCss)]
+pub struct CounterPair<Integer> {
+ /// The name of the counter.
+ pub name: CustomIdent,
+ /// The value of the counter / increment / etc.
+ pub delta: Integer,
+}
+
/// A generic value for the `counter-increment` property.
#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
pub struct CounterIncrement<I>(Counters<I>);
impl<I> CounterIncrement<I> {
/// Returns a new value for `counter-increment`.
#[inline]
- pub fn new(counters: Vec<(CustomIdent, I)>) -> Self {
+ pub fn new(counters: Vec<CounterPair<I>>) -> Self {
CounterIncrement(Counters(counters.into_boxed_slice()))
}
}
impl<I> Deref for CounterIncrement<I> {
- type Target = [(CustomIdent, I)];
+ type Target = [CounterPair<I>];
#[inline]
fn deref(&self) -> &Self::Target {
&(self.0).0
}
}
/// A generic value for the `counter-reset` property.
#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
pub struct CounterReset<I>(Counters<I>);
impl<I> CounterReset<I> {
/// Returns a new value for `counter-reset`.
#[inline]
- pub fn new(counters: Vec<(CustomIdent, I)>) -> Self {
+ pub fn new(counters: Vec<CounterPair<I>>) -> Self {
CounterReset(Counters(counters.into_boxed_slice()))
}
}
impl<I> Deref for CounterReset<I> {
- type Target = [(CustomIdent, I)];
+ type Target = [CounterPair<I>];
#[inline]
fn deref(&self) -> &Self::Target {
&(self.0).0
}
}
/// A generic value for lists of counters.
///
/// Keyword `none` is represented by an empty vector.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
- ToComputedValue)]
-pub struct Counters<I>(#[css(if_empty = "none")] Box<[(CustomIdent, I)]>);
+ ToComputedValue, ToCss)]
+pub struct Counters<I>(#[css(iterable, if_empty = "none")] Box<[CounterPair<I>]>);
impl<I> Default for Counters<I> {
#[inline]
fn default() -> Self {
Counters(vec![].into_boxed_slice())
}
}
-
-impl<I> ToCss for Counters<I>
-where
- I: ToCss,
-{
- #[inline]
- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
- where
- W: fmt::Write,
- {
- if self.0.is_empty() {
- return dest.write_str("none");
- }
-
- let mut first = true;
- for &(ref name, ref value) in &*self.0 {
- if !first {
- dest.write_str(" ")?;
- }
- first = false;
- name.to_css(dest)?;
- dest.write_str(" ")?;
- value.to_css(dest)?;
- }
- Ok(())
- }
-}
--- a/servo/components/style/values/specified/counters.rs
+++ b/servo/components/style/values/specified/counters.rs
@@ -7,16 +7,17 @@
#[cfg(feature = "servo")]
use computed_values::list_style_type::T as ListStyleType;
use cssparser::{Parser, Token};
use parser::{Parse, ParserContext};
use style_traits::{ParseError, StyleParseErrorKind};
use values::CustomIdent;
#[cfg(feature = "gecko")]
use values::generics::CounterStyleOrNone;
+use values::generics::counters::CounterPair;
use values::generics::counters::CounterIncrement as GenericCounterIncrement;
use values::generics::counters::CounterReset as GenericCounterReset;
#[cfg(feature = "gecko")]
use values::specified::Attr;
use values::specified::Integer;
#[cfg(feature = "gecko")]
use values::specified::url::SpecifiedImageUrl;
@@ -43,37 +44,37 @@ impl Parse for CounterReset {
Ok(Self::new(parse_counters(context, input, 0)?))
}
}
fn parse_counters<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
default_value: i32,
-) -> Result<Vec<(CustomIdent, Integer)>, ParseError<'i>> {
+) -> Result<Vec<CounterPair<Integer>>, ParseError<'i>> {
if input
.try(|input| input.expect_ident_matching("none"))
.is_ok()
{
return Ok(vec![]);
}
let mut counters = Vec::new();
loop {
let location = input.current_source_location();
- let counter_name = match input.next() {
+ let name = match input.next() {
Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(location, ident, &["none"])?,
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
Err(_) => break,
};
- let counter_delta = input
+ let delta = input
.try(|input| Integer::parse(context, input))
.unwrap_or(Integer::new(default_value));
- counters.push((counter_name, counter_delta))
+ counters.push(CounterPair { name, delta });
}
if !counters.is_empty() {
Ok(counters)
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
}