mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
style: Implement ToCss for CalcNode.
We'll use `CalcNode` as the specified value representation for <length> and <length-percentage> values, so they'll have to implement ToCss. There's one minor issue (two calls to to_css() instead of to_css_impl() which are addressed later in the series). Differential Revision: https://phabricator.services.mozilla.com/D63395
This commit is contained in:
parent
c52bae1923
commit
869553357d
3 changed files with 144 additions and 5 deletions
|
@ -287,6 +287,19 @@ impl PartialOrd for CalcNode {
|
|||
}
|
||||
|
||||
impl CalcNode {
|
||||
fn is_simple_negative(&self) -> bool {
|
||||
match *self {
|
||||
Self::Length(ref l) => l.is_negative(),
|
||||
Self::Percentage(n) |
|
||||
Self::Number(n) => n < 0.,
|
||||
Self::Angle(ref a) => a.degrees() < 0.,
|
||||
Self::Time(ref t) => t.seconds() < 0.,
|
||||
Self::MinMax(..) |
|
||||
Self::Sum(..) |
|
||||
Self::Clamp { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn negate(&mut self) {
|
||||
self.mul_by(-1.);
|
||||
}
|
||||
|
@ -1022,4 +1035,93 @@ impl CalcNode {
|
|||
Err(()) => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_css_impl<W>(&self, dest: &mut CssWriter<W>, is_outermost: bool) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
let write_closing_paren = match *self {
|
||||
Self::MinMax(_, op) => {
|
||||
dest.write_str(match op {
|
||||
MinMaxOp::Max => "max(",
|
||||
MinMaxOp::Min => "min(",
|
||||
})?;
|
||||
true
|
||||
},
|
||||
Self::Clamp { .. } => {
|
||||
dest.write_str("clamp(")?;
|
||||
true
|
||||
},
|
||||
_ => {
|
||||
if is_outermost {
|
||||
dest.write_str("calc(")?;
|
||||
}
|
||||
is_outermost
|
||||
},
|
||||
};
|
||||
|
||||
match *self {
|
||||
Self::MinMax(ref children, _) => {
|
||||
let mut first = true;
|
||||
for child in &**children {
|
||||
if !first {
|
||||
dest.write_str(", ")?;
|
||||
}
|
||||
first = false;
|
||||
child.to_css_impl(dest, false)?;
|
||||
}
|
||||
},
|
||||
Self::Sum(ref children) => {
|
||||
let mut first = true;
|
||||
for child in &**children {
|
||||
if !first {
|
||||
if child.is_simple_negative() {
|
||||
dest.write_str(" - ")?;
|
||||
let mut c = child.clone();
|
||||
c.negate();
|
||||
c.to_css(dest)?;
|
||||
} else {
|
||||
dest.write_str(" + ")?;
|
||||
child.to_css(dest)?;
|
||||
}
|
||||
} else {
|
||||
first = false;
|
||||
child.to_css_impl(dest, false)?;
|
||||
}
|
||||
}
|
||||
},
|
||||
Self::Clamp {
|
||||
ref min,
|
||||
ref center,
|
||||
ref max,
|
||||
} => {
|
||||
min.to_css_impl(dest, false)?;
|
||||
dest.write_str(", ")?;
|
||||
center.to_css_impl(dest, false)?;
|
||||
dest.write_str(", ")?;
|
||||
max.to_css_impl(dest, false)?;
|
||||
},
|
||||
Self::Length(ref l) => l.to_css(dest)?,
|
||||
Self::Number(ref n) => n.to_css(dest)?,
|
||||
Self::Percentage(p) => crate::values::serialize_percentage(p, dest)?,
|
||||
Self::Angle(ref a) => a.to_css(dest)?,
|
||||
Self::Time(ref t) => t.to_css(dest)?,
|
||||
|
||||
}
|
||||
|
||||
if write_closing_paren {
|
||||
dest.write_str(")")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for CalcNode {
|
||||
/// <https://drafts.csswg.org/css-values/#calc-serialize>
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
self.to_css_impl(dest, /* is_outermost = */ true)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,16 @@ impl FontRelativeLength {
|
|||
FontRelativeLength::Em(v) |
|
||||
FontRelativeLength::Ex(v) |
|
||||
FontRelativeLength::Ch(v) |
|
||||
FontRelativeLength::Rem(v) => v == 0.0,
|
||||
FontRelativeLength::Rem(v) => v == 0.,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_negative(&self) -> bool {
|
||||
match *self {
|
||||
FontRelativeLength::Em(v) |
|
||||
FontRelativeLength::Ex(v) |
|
||||
FontRelativeLength::Ch(v) |
|
||||
FontRelativeLength::Rem(v) => v < 0.,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +275,16 @@ impl ViewportPercentageLength {
|
|||
ViewportPercentageLength::Vw(v) |
|
||||
ViewportPercentageLength::Vh(v) |
|
||||
ViewportPercentageLength::Vmin(v) |
|
||||
ViewportPercentageLength::Vmax(v) => v == 0.0,
|
||||
ViewportPercentageLength::Vmax(v) => v == 0.,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_negative(&self) -> bool {
|
||||
match *self {
|
||||
ViewportPercentageLength::Vw(v) |
|
||||
ViewportPercentageLength::Vh(v) |
|
||||
ViewportPercentageLength::Vmin(v) |
|
||||
ViewportPercentageLength::Vmax(v) => v < 0.,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,6 +388,18 @@ impl AbsoluteLength {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_negative(&self) -> bool {
|
||||
match *self {
|
||||
AbsoluteLength::Px(v) |
|
||||
AbsoluteLength::In(v) |
|
||||
AbsoluteLength::Cm(v) |
|
||||
AbsoluteLength::Mm(v) |
|
||||
AbsoluteLength::Q(v) |
|
||||
AbsoluteLength::Pt(v) |
|
||||
AbsoluteLength::Pc(v) => v < 0.,
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this into a pixel value.
|
||||
#[inline]
|
||||
pub fn to_px(&self) -> CSSFloat {
|
||||
|
@ -484,6 +514,16 @@ impl Mul<CSSFloat> for NoCalcLength {
|
|||
}
|
||||
|
||||
impl NoCalcLength {
|
||||
/// Returns whether the value of this length without unit is less than zero.
|
||||
pub fn is_negative(&self) -> bool {
|
||||
match *self {
|
||||
NoCalcLength::Absolute(v) => v.is_negative(),
|
||||
NoCalcLength::FontRelative(v) => v.is_negative(),
|
||||
NoCalcLength::ViewportPercentage(v) => v.is_negative(),
|
||||
NoCalcLength::ServoCharacterWidth(c) => c.0 < 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a given absolute or relative dimension.
|
||||
pub fn parse_dimension(
|
||||
context: &ParserContext,
|
||||
|
|
|
@ -120,9 +120,6 @@ impl Percentage {
|
|||
Token::Function(ref name) => {
|
||||
let function = CalcNode::math_function(name, location)?;
|
||||
let value = CalcNode::parse_percentage(context, input, function)?;
|
||||
|
||||
// TODO(emilio): -moz-image-rect is the only thing that uses
|
||||
// the clamping mode... I guess we could disallow it...
|
||||
Ok(Percentage {
|
||||
value,
|
||||
calc_clamping_mode: Some(num_context),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue