Move specified and computed percentages to submodules

This commit is contained in:
Anthony Ramine 2017-08-14 02:37:32 +02:00
parent fb8400d745
commit 796a2b9632
7 changed files with 212 additions and 174 deletions

View file

@ -888,21 +888,6 @@ impl Animatable for Angle {
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-percentage
impl Animatable for Percentage {
#[inline]
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
Ok(Percentage((self.0 as f64 * self_portion + other.0 as f64 * other_portion) as f32))
}
}
impl ToAnimatedZero for Percentage {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
Ok(Percentage(0.))
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-visibility
impl Animatable for Visibility {
#[inline]

View file

@ -49,6 +49,7 @@ pub use super::generics::grid::GridLine;
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage};
pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength};
pub use self::length::NonNegativeLengthOrPercentage;
pub use self::percentage::Percentage;
pub use self::position::Position;
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth};
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
@ -66,6 +67,7 @@ pub mod image;
#[cfg(feature = "gecko")]
pub mod gecko;
pub mod length;
pub mod percentage;
pub mod position;
pub mod rect;
pub mod svg;
@ -658,45 +660,6 @@ impl From<Au> for NonNegativeAu {
}
}
/// A computed `<percentage>` value.
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Default, HasViewportPercentage, PartialEq)]
#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))]
pub struct Percentage(pub CSSFloat);
impl Percentage {
/// 0%
#[inline]
pub fn zero() -> Self {
Percentage(0.)
}
/// 100%
#[inline]
pub fn hundred() -> Self {
Percentage(1.)
}
}
impl ToCss for Percentage {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
write!(dest, "{}%", self.0 * 100.)
}
}
impl ToComputedValue for specified::Percentage {
type ComputedValue = Percentage;
#[inline]
fn to_computed_value(&self, _: &Context) -> Percentage {
Percentage(self.get())
}
#[inline]
fn from_computed_value(computed: &Percentage) -> Self {
specified::Percentage::new(computed.0)
}
}
/// The computed value of a CSS `url()`, resolved relative to the stylesheet URL.
#[cfg(feature = "servo")]
#[derive(Clone, Debug, HeapSizeOf, Serialize, Deserialize, PartialEq)]

View file

@ -0,0 +1,54 @@
/* 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 percentages.
use properties::animated_properties::Animatable;
use std::fmt;
use style_traits::ToCss;
use values::CSSFloat;
use values::animated::ToAnimatedZero;
/// A computed percentage.
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Default, HasViewportPercentage, PartialEq)]
#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))]
pub struct Percentage(pub CSSFloat);
impl Percentage {
/// 0%
#[inline]
pub fn zero() -> Self {
Percentage(0.)
}
/// 100%
#[inline]
pub fn hundred() -> Self {
Percentage(1.)
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-percentage
impl Animatable for Percentage {
#[inline]
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
Ok(Percentage((self.0 as f64 * self_portion + other.0 as f64 * other_portion) as f32))
}
}
impl ToAnimatedZero for Percentage {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
Ok(Percentage(0.))
}
}
impl ToCss for Percentage {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where
W: fmt::Write,
{
write!(dest, "{}%", self.0 * 100.)
}
}

View file

@ -785,7 +785,7 @@ impl From<NoCalcLength> for LengthOrPercentage {
impl From<Percentage> for LengthOrPercentage {
#[inline]
fn from(pc: Percentage) -> Self {
if pc.calc_clamping_mode.is_some() {
if pc.is_calc() {
LengthOrPercentage::Calc(Box::new(CalcLengthOrPercentage {
percentage: Some(computed::Percentage(pc.get())),
.. Default::default()

View file

@ -44,6 +44,7 @@ pub use self::length::{LengthOrPercentageOrNone, MaxLength, MozLength};
pub use self::length::{NoCalcLength, ViewportPercentageLength};
pub use self::length::NonNegativeLengthOrPercentage;
pub use self::rect::LengthOrNumberRect;
pub use self::percentage::Percentage;
pub use self::position::{Position, PositionComponent};
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth};
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
@ -65,6 +66,7 @@ pub mod gecko;
pub mod grid;
pub mod image;
pub mod length;
pub mod percentage;
pub mod position;
pub mod rect;
pub mod svg;
@ -1047,121 +1049,3 @@ impl ToCss for Attr {
}
impl ComputedValueAsSpecified for Attr {}
/// A percentage value.
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Percentage {
/// The percentage value as a float.
///
/// [0 .. 100%] maps to [0.0 .. 1.0]
value: CSSFloat,
/// If this percentage came from a calc() expression, this tells how
/// clamping should be done on the value.
calc_clamping_mode: Option<AllowedNumericType>,
}
no_viewport_percentage!(Percentage);
impl ToCss for Percentage {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::Write,
{
if self.calc_clamping_mode.is_some() {
dest.write_str("calc(")?;
}
write!(dest, "{}%", self.value * 100.)?;
if self.calc_clamping_mode.is_some() {
dest.write_str(")")?;
}
Ok(())
}
}
impl Percentage {
/// Create a percentage from a numeric value.
pub fn new(value: CSSFloat) -> Self {
Self {
value,
calc_clamping_mode: None,
}
}
/// Get the underlying value for this float.
pub fn get(&self) -> CSSFloat {
self.calc_clamping_mode.map_or(self.value, |mode| mode.clamp(self.value))
}
/// Reverse this percentage, preserving calc-ness.
///
/// For example: If it was 20%, convert it into 80%.
pub fn reverse(&mut self) {
let new_value = 1. - self.value;
self.value = new_value;
}
/// Parse a specific kind of percentage.
pub fn parse_with_clamping_mode<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
num_context: AllowedNumericType,
) -> Result<Self, ParseError<'i>> {
// FIXME: remove early returns when lifetimes are non-lexical
match *input.next()? {
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
return Ok(Percentage::new(unit_value))
}
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into())
}
let result = input.parse_nested_block(|i| {
CalcNode::parse_percentage(context, i)
})?;
// TODO(emilio): -moz-image-rect is the only thing that uses
// the clamping mode... I guess we could disallow it...
Ok(Percentage {
value: result,
calc_clamping_mode: Some(num_context),
})
}
/// Parses a percentage token, but rejects it if it's negative.
pub fn parse_non_negative<'i, 't>(context: &ParserContext,
input: &mut Parser<'i, 't>)
-> Result<Self, ParseError<'i>> {
Self::parse_with_clamping_mode(context, input, AllowedNumericType::NonNegative)
}
/// 0%
#[inline]
pub fn zero() -> Self {
Percentage {
value: 0.,
calc_clamping_mode: None,
}
}
/// 100%
#[inline]
pub fn hundred() -> Self {
Percentage {
value: 1.,
calc_clamping_mode: None,
}
}
}
impl Parse for Percentage {
#[inline]
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>
) -> Result<Self, ParseError<'i>> {
Self::parse_with_clamping_mode(context, input, AllowedNumericType::All)
}
}

View file

@ -0,0 +1,152 @@
/* 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 percentages.
use cssparser::{BasicParseError, Parser, Token};
use parser::{Parse, ParserContext};
use std::ascii::AsciiExt;
use std::fmt;
use style_traits::{ParseError, ToCss};
use style_traits::values::specified::AllowedNumericType;
use values::CSSFloat;
use values::computed::{Context, ToComputedValue};
use values::computed::percentage::Percentage as ComputedPercentage;
use values::specified::calc::CalcNode;
/// A percentage value.
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Percentage {
/// The percentage value as a float.
///
/// [0 .. 100%] maps to [0.0 .. 1.0]
value: CSSFloat,
/// If this percentage came from a calc() expression, this tells how
/// clamping should be done on the value.
calc_clamping_mode: Option<AllowedNumericType>,
}
no_viewport_percentage!(Percentage);
impl ToCss for Percentage {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::Write,
{
if self.calc_clamping_mode.is_some() {
dest.write_str("calc(")?;
}
write!(dest, "{}%", self.value * 100.)?;
if self.calc_clamping_mode.is_some() {
dest.write_str(")")?;
}
Ok(())
}
}
impl Percentage {
/// Creates a percentage from a numeric value.
pub fn new(value: CSSFloat) -> Self {
Self {
value,
calc_clamping_mode: None,
}
}
/// `0%`
#[inline]
pub fn zero() -> Self {
Percentage {
value: 0.,
calc_clamping_mode: None,
}
}
/// `100%`
#[inline]
pub fn hundred() -> Self {
Percentage {
value: 1.,
calc_clamping_mode: None,
}
}
/// Gets the underlying value for this float.
pub fn get(&self) -> CSSFloat {
self.calc_clamping_mode.map_or(self.value, |mode| mode.clamp(self.value))
}
/// Returns whether this percentage is a `calc()` value.
pub fn is_calc(&self) -> bool {
self.calc_clamping_mode.is_some()
}
/// Reverses this percentage, preserving calc-ness.
///
/// For example: If it was 20%, convert it into 80%.
pub fn reverse(&mut self) {
let new_value = 1. - self.value;
self.value = new_value;
}
/// Parses a specific kind of percentage.
pub fn parse_with_clamping_mode<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
num_context: AllowedNumericType,
) -> Result<Self, ParseError<'i>> {
// FIXME: remove early returns when lifetimes are non-lexical
match *input.next()? {
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
return Ok(Percentage::new(unit_value));
}
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
}
let result = input.parse_nested_block(|i| {
CalcNode::parse_percentage(context, i)
})?;
// TODO(emilio): -moz-image-rect is the only thing that uses
// the clamping mode... I guess we could disallow it...
Ok(Percentage {
value: result,
calc_clamping_mode: Some(num_context),
})
}
/// Parses a percentage token, but rejects it if it's negative.
pub fn parse_non_negative<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_with_clamping_mode(context, input, AllowedNumericType::NonNegative)
}
}
impl Parse for Percentage {
#[inline]
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>
) -> Result<Self, ParseError<'i>> {
Self::parse_with_clamping_mode(context, input, AllowedNumericType::All)
}
}
impl ToComputedValue for Percentage {
type ComputedValue = ComputedPercentage;
#[inline]
fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
ComputedPercentage(self.get())
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
Percentage::new(computed.0)
}
}

View file

@ -2,7 +2,7 @@
* 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 types for CSS borders.
//! Specified types for CSS borders.
use cssparser::Parser;
use parser::ParserContext;