servo: Merge #19529 - style: moved css longhand counter-reset out of mako (from DonatJR:counter-reset-out-of-mako); r=emilio

<!-- Please describe your changes on the following line: -->
This is a sub-PR of #19015
Code does not yet compile with `build-geckolib`.
r? emilio

---
<!-- 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
- [x] These changes fix #19387

<!-- Either: -->
- [x] These changes do not require tests

<!-- 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: 38ef515463338d1c562381fd650b80272f552dfb

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 544c775ece36dbd68987a435e2df56c462cd64dc
This commit is contained in:
Jonas Reinwald 2018-02-01 09:42:40 -06:00
parent 4197e56037
commit 65b1fa2979
11 changed files with 240 additions and 151 deletions

View File

@ -1035,8 +1035,8 @@ impl BaseFlow {
}
}
if !style.get_counters().counter_reset.0.is_empty() ||
!style.get_counters().counter_increment.0.is_empty() {
if !style.get_counters().counter_reset.get_values().is_empty() ||
!style.get_counters().counter_increment.get_values().is_empty() {
flags.insert(FlowFlags::AFFECTS_COUNTERS)
}
}

View File

@ -272,7 +272,7 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
}
self.traversal.list_item.truncate_to_level(self.level);
for &(ref counter_name, value) in &fragment.style().get_counters().counter_reset.0 {
for &(ref counter_name, value) in fragment.style().get_counters().counter_reset.get_values() {
let counter_name = &*counter_name.0;
if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) {
counter.reset(self.level, value);
@ -284,7 +284,7 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
self.traversal.counters.insert(counter_name.to_owned(), counter);
}
for &(ref counter_name, value) in &fragment.style().get_counters().counter_increment.0 {
for &(ref counter_name, value) in fragment.style().get_counters().counter_increment.get_values() {
let counter_name = &*counter_name.0;
if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) {
counter.increment(self.level, value);

View File

@ -5675,11 +5675,14 @@ clip-path
}
% for counter_property in ["Increment", "Reset"]:
pub fn set_counter_${counter_property.lower()}(&mut self, v: longhands::counter_increment::computed_value::T) {
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.0.len() as u32);
for (i, (name, value)) in v.0.into_iter().enumerate() {
v.get_values().len() as u32);
for (i, &(ref name, value)) in v.get_values().into_iter().enumerate() {
self.gecko.m${counter_property}s[i].mCounter.assign(name.0.as_slice());
self.gecko.m${counter_property}s[i].mValue = value;
}
@ -5696,11 +5699,13 @@ clip-path
self.copy_counter_${counter_property.lower()}_from(other)
}
pub fn clone_counter_${counter_property.lower()}(&self) -> longhands::counter_increment::computed_value::T {
pub fn clone_counter_${counter_property.lower()}(
&self
) -> longhands::counter_${counter_property.lower()}::computed_value::T {
use values::CustomIdent;
use gecko_string_cache::Atom;
longhands::counter_increment::computed_value::T(
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)
}).collect()

View File

@ -236,131 +236,14 @@
}
</%helpers:longhand>
<%helpers:longhand name="counter-increment" animation_value_type="discrete"
spec="https://drafts.csswg.org/css-lists/#propdef-counter-increment">
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
use values::CustomIdent;
${helpers.predefined_type("counter-increment",
"CounterIncrement",
initial_value="computed::CounterIncrement::none()",
animation_value_type="discrete",
spec="https://drafts.csswg.org/css-lists/#propdef-counter-increment")}
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[derive(Clone, Debug, PartialEq)]
pub struct SpecifiedValue(pub Vec<(CustomIdent, specified::Integer)>);
pub mod computed_value {
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
use values::CustomIdent;
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
pub struct T(pub Vec<(CustomIdent, i32)>);
impl ToCss for T {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
if self.0.is_empty() {
return dest.write_str("none")
}
let mut first = true;
for &(ref name, value) in &self.0 {
if !first {
dest.write_str(" ")?;
}
first = false;
name.to_css(dest)?;
dest.write_str(" ")?;
value.to_css(dest)?;
}
Ok(())
}
}
}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
computed_value::T(self.0.iter().map(|&(ref name, ref value)| {
(name.clone(), value.to_computed_value(context))
}).collect::<Vec<_>>())
}
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
SpecifiedValue(computed.0.iter().map(|&(ref name, ref value)| {
(name.clone(), specified::Integer::from_computed_value(&value))
}).collect::<Vec<_>>())
}
}
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T(Vec::new())
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: 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(())
}
}
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> {
parse_common(context, 1, input)
}
pub fn parse_common<'i, 't>(context: &ParserContext, default_value: i32, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> {
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
return Ok(SpecifiedValue(Vec::new()))
}
let mut counters = Vec::new();
loop {
let location = input.current_source_location();
let counter_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.try(|input| specified::Integer::parse(context, input))
.unwrap_or(specified::Integer::new(default_value));
counters.push((counter_name, counter_delta))
}
if !counters.is_empty() {
Ok(SpecifiedValue(counters))
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
}
</%helpers:longhand>
<%helpers:longhand name="counter-reset" animation_value_type="discrete"
spec="https://drafts.csswg.org/css-lists-3/#propdef-counter-reset">
pub use super::counter_increment::{SpecifiedValue, computed_value, get_initial_value};
use super::counter_increment::parse_common;
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue,ParseError<'i>> {
parse_common(context, 0, input)
}
</%helpers:longhand>
${helpers.predefined_type("counter-reset",
"CounterReset",
initial_value="computed::CounterReset::none()",
animation_value_type="discrete",
spec="https://drafts.csswg.org/css-lists-3/#propdef-counter-reset")}

View File

@ -0,0 +1,80 @@
/* 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/. */
//! Computed values for counter properties
use values::CustomIdent;
use values::computed::{Context, ToComputedValue};
use values::generics::counters::CounterIntegerList;
use values::specified::{CounterIncrement as SpecifiedCounterIncrement, CounterReset as SpecifiedCounterReset};
type ComputedIntegerList = CounterIntegerList<i32>;
/// A computed value for the `counter-increment` property.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
pub struct CounterIncrement(pub ComputedIntegerList);
impl CounterIncrement {
/// Returns the `none` value.
#[inline]
pub fn none() -> CounterIncrement {
CounterIncrement(ComputedIntegerList::new(Vec::new()))
}
/// Returns a new computed `counter-increment` object with the given values.
pub fn new(vec: Vec<(CustomIdent, i32)>) -> CounterIncrement {
CounterIncrement(ComputedIntegerList::new(vec))
}
/// Returns the values of the computed `counter-increment` object.
pub fn get_values(&self) -> &[(CustomIdent, i32)] {
self.0.get_values()
}
}
impl ToComputedValue for SpecifiedCounterIncrement {
type ComputedValue = CounterIncrement;
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
CounterIncrement(self.0.to_computed_value(context))
}
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
SpecifiedCounterIncrement(ToComputedValue::from_computed_value(&computed.0))
}
}
/// A computed value for the `counter-reset` property.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
pub struct CounterReset(pub ComputedIntegerList);
impl CounterReset {
/// Returns the `none` value.
#[inline]
pub fn none() -> CounterReset {
CounterReset(ComputedIntegerList::new(Vec::new()))
}
/// Returns a new computed `counter-reset` object with the given values.
pub fn new(vec: Vec<(CustomIdent, i32)>) -> CounterReset {
CounterReset(ComputedIntegerList::new(vec))
}
/// Returns the values of the computed `counter-reset` object.
pub fn get_values(&self) -> &[(CustomIdent, i32)] {
self.0.get_values()
}
}
impl ToComputedValue for SpecifiedCounterReset {
type ComputedValue = CounterReset;
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
CounterReset(self.0.to_computed_value(context))
}
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
SpecifiedCounterReset(ToComputedValue::from_computed_value(&computed.0))
}
}

View File

@ -46,6 +46,7 @@ pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier,
pub use self::box_::{AnimationIterationCount, AnimationName, Display, OverscrollBehavior, Contain};
pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange};
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
pub use self::counters::{CounterIncrement, CounterReset};
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
pub use self::flex::FlexBasis;
pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect};
@ -86,6 +87,7 @@ pub mod border;
#[path = "box.rs"]
pub mod box_;
pub mod color;
pub mod counters;
pub mod effects;
pub mod flex;
pub mod font;

View File

@ -5,26 +5,37 @@
//! Generic types for counters-related CSS values.
use std::fmt;
use std::fmt::Write;
use style_traits::{CssWriter, ToCss};
use values::CustomIdent;
/// A generic value for the `counter-increment` property.
/// A generic value for both the `counter-increment` and `counter-reset` property.
///
/// Keyword `none` is represented by an empty slice.
#[derive(Clone, Debug, PartialEq, ToComputedValue)]
pub struct CounterIncrement<Integer>(Box<[(CustomIdent, Integer)]);
/// Keyword `none` is represented by an empty vector.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
pub struct CounterIntegerList<I>(Box<[(CustomIdent, I)]>);
impl<I> CounterIncrement<I> {
/// Returns `none`.
impl<I> CounterIntegerList<I> {
/// Returns the `none` value.
#[inline]
pub fn none() -> Self {
CounterIncrement(vec![].into_boxed_slice())
pub fn none() -> CounterIntegerList<I> {
CounterIntegerList(vec![].into_boxed_slice())
}
/// Returns a new CounterIntegerList object.
pub fn new(vec: Vec<(CustomIdent, I)>) -> CounterIntegerList<I> {
CounterIntegerList(vec.into_boxed_slice())
}
/// Returns the values of the CounterIntegerList object.
pub fn get_values(&self) -> &[(CustomIdent, I)] {
self.0.as_ref()
}
}
impl<I> ToCss for CounterIncrement<I>
impl<I> ToCss for CounterIntegerList<I>
where
I: ToCss,
I: ToCss
{
#[inline]
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
@ -32,12 +43,15 @@ where
W: fmt::Write,
{
if self.0.is_empty() {
return dest.write_str("none");
return dest.write_str("none")
}
for (&(ref name, ref value), i) in self.0.iter().enumerate() {
if i != 0 {
let mut first = true;
for &(ref name, ref value) in self.get_values() {
if !first {
dest.write_str(" ")?;
}
first = false;
name.to_css(dest)?;
dest.write_str(" ")?;
value.to_css(dest)?;

View File

@ -16,6 +16,7 @@ pub mod basic_shape;
pub mod border;
#[path = "box.rs"]
pub mod box_;
pub mod counters;
pub mod effects;
pub mod flex;
pub mod font;

View File

@ -0,0 +1,102 @@
/* 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/. */
//! Specified types for counter properties.
use cssparser::Parser;
use parser::{Parse, ParserContext};
use style_traits::ParseError;
use values::CustomIdent;
use values::generics::counters::CounterIntegerList;
use values::specified::Integer;
/// A specified value for the `counter-increment` and `counter-reset` property.
type SpecifiedIntegerList = CounterIntegerList<Integer>;
impl SpecifiedIntegerList {
fn parse_with_default<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
default_value: i32
) -> Result<SpecifiedIntegerList, ParseError<'i>> {
use cssparser::Token;
use style_traits::StyleParseErrorKind;
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
return Ok(CounterIntegerList::new(Vec::new()))
}
let mut counters: Vec<(CustomIdent, Integer)> = Vec::new();
loop {
let location = input.current_source_location();
let counter_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.try(|input| Integer::parse(context, input))
.unwrap_or(Integer::new(default_value));
counters.push((counter_name, counter_delta))
}
if !counters.is_empty() {
Ok(CounterIntegerList::new(counters))
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
}
}
/// A specified value for the `counter-increment` property.
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[derive(Clone, Debug, PartialEq, ToCss)]
pub struct CounterIncrement(pub SpecifiedIntegerList);
impl CounterIncrement {
/// Returns a new specified `counter-increment` object with the given values.
pub fn new(vec: Vec<(CustomIdent, Integer)>) -> CounterIncrement {
CounterIncrement(SpecifiedIntegerList::new(vec))
}
/// Returns the values of the specified `counter-increment` object.
pub fn get_values(&self) -> &[(CustomIdent, Integer)] {
self.0.get_values()
}
}
impl Parse for CounterIncrement {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>
) -> Result<CounterIncrement, ParseError<'i>> {
Ok(CounterIncrement(SpecifiedIntegerList::parse_with_default(context, input, 1)?))
}
}
/// A specified value for the `counter-reset` property.
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[derive(Clone, Debug, PartialEq, ToCss)]
pub struct CounterReset(pub SpecifiedIntegerList);
impl CounterReset {
/// Returns a new specified `counter-reset` object with the given values.
pub fn new(vec: Vec<(CustomIdent, Integer)>) -> CounterReset {
CounterReset(SpecifiedIntegerList::new(vec))
}
/// Returns the values of the specified `counter-reset` object.
pub fn get_values(&self) -> &[(CustomIdent, Integer)] {
self.0.get_values()
}
}
impl Parse for CounterReset {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>
) -> Result<CounterReset, ParseError<'i>> {
Ok(CounterReset(SpecifiedIntegerList::parse_with_default(context, input, 0)?))
}
}

View File

@ -40,6 +40,7 @@ pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier,
pub use self::box_::{AnimationIterationCount, AnimationName, Display, OverscrollBehavior, Contain};
pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange};
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
pub use self::counters::{CounterIncrement, CounterReset};
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
pub use self::flex::FlexBasis;
#[cfg(feature = "gecko")]
@ -85,6 +86,7 @@ pub mod border;
pub mod box_;
pub mod calc;
pub mod color;
pub mod counters;
pub mod effects;
pub mod flex;
pub mod font;

View File

@ -1027,7 +1027,7 @@ mod shorthand_serialization {
properties.push((CustomIdent("counter1".into()), Integer::new(1)));
properties.push((CustomIdent("counter2".into()), Integer::new(-4)));
let counter_increment = CounterIncrement(properties);
let counter_increment = CounterIncrement::new(properties);
let counter_increment_css = "counter1 1 counter2 -4";
assert_eq!(counter_increment.to_css_string(), counter_increment_css);
@ -1035,7 +1035,7 @@ mod shorthand_serialization {
#[test]
fn counter_increment_without_properties_should_serialize_correctly() {
let counter_increment = CounterIncrement(Vec::new());
let counter_increment = CounterIncrement::new(Vec::new());
let counter_increment_css = "none";
assert_eq!(counter_increment.to_css_string(), counter_increment_css);