Bug 1374233 - Part 6: Add PositiveInteger and PositiveIntegerOrAuto for column-count.
column-count should be a positive integer or auto.
MozReview-Commit-ID: 9LFvrYo8De5
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -4793,31 +4793,32 @@ clip-path
<%self:impl_trait style_struct_name="Column"
skip_longhands="column-count column-rule-width">
#[allow(unused_unsafe)]
pub fn set_column_count(&mut self, v: longhands::column_count::computed_value::T) {
use gecko_bindings::structs::{NS_STYLE_COLUMN_COUNT_AUTO, nsStyleColumn_kMaxColumnCount};
self.gecko.mColumnCount = match v {
- Either::First(number) => unsafe {
- cmp::min(number as u32, nsStyleColumn_kMaxColumnCount)
+ Either::First(integer) => unsafe {
+ cmp::min(integer.0 as u32, nsStyleColumn_kMaxColumnCount)
},
Either::Second(Auto) => NS_STYLE_COLUMN_COUNT_AUTO
};
}
${impl_simple_copy('column_count', 'mColumnCount')}
pub fn clone_column_count(&self) -> longhands::column_count::computed_value::T {
use gecko_bindings::structs::NS_STYLE_COLUMN_COUNT_AUTO;
+ use values::computed::PositiveInteger;
if self.gecko.mColumnCount != NS_STYLE_COLUMN_COUNT_AUTO {
debug_assert!((self.gecko.mColumnCount as i32) >= 0 &&
(self.gecko.mColumnCount as i32) < i32::max_value());
- Either::First(self.gecko.mColumnCount as i32)
+ Either::First(PositiveInteger(self.gecko.mColumnCount as i32))
} else {
Either::Second(Auto)
}
}
<% impl_non_negative_app_units("column_rule_width", "mColumnRuleWidth", need_clone=True,
round_to_pixels=True) %>
</%self:impl_trait>
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -41,16 +41,17 @@ use values::animated::effects::BoxShadow
use values::animated::effects::Filter as AnimatedFilter;
use values::animated::effects::FilterList as AnimatedFilterList;
use values::animated::effects::TextShadowList as AnimatedTextShadowList;
use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use values::computed::{BorderCornerRadius, ClipRect};
use values::computed::{CalcLengthOrPercentage, Color, Context, ComputedValueAsSpecified};
use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToComputedValue};
use values::computed::{GreaterThanOrEqualToOneNumber, NonNegativeAu, NonNegativeNumber};
+use values::computed::{PositiveInteger, PositiveIntegerOrAuto};
use values::computed::length::{NonNegativeLengthOrAuto, NonNegativeLengthOrNormal};
use values::computed::length::NonNegativeLengthOrNumber;
use values::generics::{SVGPaint, SVGPaintKind};
use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
use values::generics::effects::Filter;
use values::generics::position as generic_position;
/// A trait used to implement various procedures used during animation.
@@ -945,16 +946,29 @@ impl Animatable for GreaterThanOrEqualTo
}
#[inline]
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
self.0.compute_distance(&other.0)
}
}
+/// https://drafts.csswg.org/css-transitions/#animtype-integer
+impl Animatable for PositiveInteger {
+ #[inline]
+ fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
+ self.0.add_weighted(&other.0, self_portion, other_portion).map(PositiveInteger)
+ }
+
+ #[inline]
+ fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
+ self.0.compute_distance(&other.0)
+ }
+}
+
/// https://drafts.csswg.org/css-transitions/#animtype-number
impl Animatable for Angle {
#[inline]
fn add_weighted(&self, other: &Angle, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
match (*self, *other) {
% for angle_type in [ 'Degree', 'Gradian', 'Turn' ]:
(Angle::${angle_type}(val1), Angle::${angle_type}(val2)) => {
Ok(Angle::${angle_type}(
--- a/servo/components/style/properties/longhand/column.mako.rs
+++ b/servo/components/style/properties/longhand/column.mako.rs
@@ -12,22 +12,21 @@
initial_specified_value="Either::Second(Auto)",
extra_prefixes="moz",
animation_value_type="NonNegativeLengthOrAuto",
experimental=True,
spec="https://drafts.csswg.org/css-multicol/#propdef-column-width")}
${helpers.predefined_type("column-count",
- "IntegerOrAuto",
+ "PositiveIntegerOrAuto",
"Either::Second(Auto)",
- parse_method="parse_positive",
initial_specified_value="Either::Second(Auto)",
experimental="True",
- animation_value_type="ComputedValue",
+ animation_value_type="PositiveIntegerOrAuto",
extra_prefixes="moz",
spec="https://drafts.csswg.org/css-multicol/#propdef-column-count")}
${helpers.predefined_type("column-gap",
"length::NonNegativeLengthOrNormal",
"Either::Second(Normal)",
extra_prefixes="moz",
experimental=True,
--- a/servo/components/style/values/animated/mod.rs
+++ b/servo/components/style/values/animated/mod.rs
@@ -8,16 +8,17 @@
//! computed values and need yet another intermediate representation. This
//! module's raison d'ĂȘtre is to ultimately contain all these types.
use app_units::Au;
use values::computed::Angle as ComputedAngle;
use values::computed::NonNegativeAu;
use values::computed::NonNegativeNumber as ComputedNonNegativeNumber;
use values::computed::GreaterThanOrEqualToOneNumber as ComputedGreaterThanOrEqualToOneNumber;
+use values::computed::PositiveInteger as ComputedPositiveInteger;
use values::specified::url::SpecifiedUrl;
pub mod effects;
/// Conversion between computed values and intermediate values for animations.
///
/// Notably, colors are represented as four floats during animations.
pub trait ToAnimatedValue {
@@ -128,16 +129,30 @@ impl ToAnimatedValue for NonNegativeAu {
}
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
animated.max(NonNegativeAu(Au(0)))
}
}
+impl ToAnimatedValue for ComputedPositiveInteger {
+ type AnimatedValue = Self;
+
+ #[inline]
+ fn to_animated_value(self) -> Self {
+ self
+ }
+
+ #[inline]
+ fn from_animated_value(animated: Self::AnimatedValue) -> Self {
+ animated.max(ComputedPositiveInteger(1))
+ }
+}
+
/// Returns a value similar to `self` that represents zero.
pub trait ToAnimatedZero: Sized {
/// Returns a value that, when added with an underlying value, will produce the underlying
/// value. This is used for SMIL animation's "by-animation" where SMIL first interpolates from
/// the zero value to the 'by' value, and then adds the result to the underlying value.
///
/// This is not the necessarily the same as the initial value of a property. For example, the
/// initial value of 'stroke-width' is 1, but the zero value is 0, since adding 1 to the
@@ -170,12 +185,17 @@ impl ToAnimatedZero for ComputedNonNegat
fn to_animated_zero(&self) -> Result<Self, ()> { Ok(ComputedNonNegativeNumber(0.)) }
}
impl ToAnimatedZero for ComputedGreaterThanOrEqualToOneNumber {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> { Ok(ComputedGreaterThanOrEqualToOneNumber(0.)) }
}
+impl ToAnimatedZero for ComputedPositiveInteger {
+ #[inline]
+ fn to_animated_zero(&self) -> Result<Self, ()> { Ok(ComputedPositiveInteger(0)) }
+}
+
impl ToAnimatedZero for NonNegativeAu {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> { Ok(NonNegativeAu(Au(0))) }
}
--- a/servo/components/style/values/computed/mod.rs
+++ b/servo/components/style/values/computed/mod.rs
@@ -484,16 +484,31 @@ impl IntegerOrAuto {
pub fn integer_or(&self, auto_value: CSSInteger) -> CSSInteger {
match *self {
Either::First(n) => n,
Either::Second(Auto) => auto_value,
}
}
}
+/// A wrapper of Integer, but only accept a value >= 0.
+#[derive(Clone, PartialEq, PartialOrd, Copy, Debug, ToCss)]
+pub struct PositiveInteger(pub CSSInteger);
+
+impl PositiveInteger {
+ /// Returns the maximum of |self| and |other|.
+ #[inline]
+ pub fn max(self, other: Self) -> Self {
+ PositiveInteger(::std::cmp::max(self.0, other.0))
+ }
+}
+
+/// PositiveInteger | auto
+pub type PositiveIntegerOrAuto = Either<PositiveInteger, Auto>;
+
/// Computed SVG Paint value
pub type SVGPaint = ::values::generics::SVGPaint<RGBA>;
/// Computed SVG Paint Kind value
pub type SVGPaintKind = ::values::generics::SVGPaintKind<RGBA>;
impl Default for SVGPaint {
fn default() -> Self {
SVGPaint {
--- a/servo/components/style/values/specified/mod.rs
+++ b/servo/components/style/values/specified/mod.rs
@@ -734,16 +734,47 @@ impl IntegerOrAuto {
-> Result<IntegerOrAuto, ParseError<'i>> {
match IntegerOrAuto::parse(context, input) {
Ok(Either::First(integer)) if integer.value() <= 0 => Err(StyleParseError::UnspecifiedError.into()),
result => result,
}
}
}
+/// A wrapper of Integer, with value >= 1.
+#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, ToCss)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct PositiveInteger(Integer);
+
+no_viewport_percentage!(PositiveInteger);
+
+impl Parse for PositiveInteger {
+ #[inline]
+ fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
+ Integer::parse_positive(context, input).map(PositiveInteger)
+ }
+}
+
+impl ToComputedValue for PositiveInteger {
+ type ComputedValue = computed::PositiveInteger;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
+ computed::PositiveInteger(self.0.to_computed_value(context))
+ }
+
+ #[inline]
+ fn from_computed_value(computed: &Self::ComputedValue) -> Self {
+ PositiveInteger(Integer::from_computed_value(&computed.0))
+ }
+}
+
+/// PositiveInteger | auto
+pub type PositiveIntegerOrAuto = Either<PositiveInteger, Auto>;
+
#[allow(missing_docs)]
pub type UrlOrNone = Either<SpecifiedUrl, None_>;
/// The specified value of a grid `<track-breadth>`
pub type TrackBreadth = GenericTrackBreadth<LengthOrPercentage>;
/// The specified value of a grid `<track-size>`
pub type TrackSize = GenericTrackSize<LengthOrPercentage>;