|
1 | 1 | //! CSS percentage values. |
2 | 2 |
|
3 | | -use super::calc::Calc; |
| 3 | +use super::calc::{Calc, MathFunction}; |
4 | 4 | use super::number::CSSNumber; |
5 | 5 | use crate::error::{ParserError, PrinterError}; |
6 | 6 | use crate::printer::Printer; |
| 7 | +use crate::traits::private::AddInternal; |
7 | 8 | use crate::traits::{private::TryAdd, Parse, ToCss}; |
8 | 9 | use cssparser::*; |
9 | 10 |
|
@@ -92,6 +93,12 @@ impl std::ops::Add<Percentage> for Percentage { |
92 | 93 | } |
93 | 94 | } |
94 | 95 |
|
| 96 | +impl AddInternal for Percentage { |
| 97 | + fn add(self, other: Self) -> Self { |
| 98 | + self + other |
| 99 | + } |
| 100 | +} |
| 101 | + |
95 | 102 | impl std::cmp::PartialEq<CSSNumber> for Percentage { |
96 | 103 | fn eq(&self, other: &CSSNumber) -> bool { |
97 | 104 | self.0 == *other |
@@ -233,9 +240,44 @@ impl<D: std::ops::Mul<CSSNumber, Output = D>> std::ops::Mul<CSSNumber> for Dimen |
233 | 240 | impl<D: TryAdd<D> + Clone + std::cmp::PartialEq<CSSNumber> + std::cmp::PartialOrd<CSSNumber> + std::fmt::Debug> |
234 | 241 | std::ops::Add<DimensionPercentage<D>> for DimensionPercentage<D> |
235 | 242 | { |
236 | | - type Output = Self; |
| 243 | + type Output = DimensionPercentage<D>; |
237 | 244 |
|
238 | 245 | fn add(self, other: DimensionPercentage<D>) -> DimensionPercentage<D> { |
| 246 | + // Unwrap calc(...) functions so we can add inside. |
| 247 | + // Then wrap the result in a calc(...) again if necessary. |
| 248 | + let a = unwrap_calc(self); |
| 249 | + let b = unwrap_calc(other); |
| 250 | + let res = AddInternal::add(a, b); |
| 251 | + match res { |
| 252 | + DimensionPercentage::Calc(c) => match *c { |
| 253 | + Calc::Value(l) => *l, |
| 254 | + Calc::Function(f) if !matches!(*f, MathFunction::Calc(_)) => { |
| 255 | + DimensionPercentage::Calc(Box::new(Calc::Function(f))) |
| 256 | + } |
| 257 | + c => DimensionPercentage::Calc(Box::new(Calc::Function(Box::new(MathFunction::Calc(c))))), |
| 258 | + }, |
| 259 | + _ => res, |
| 260 | + } |
| 261 | + } |
| 262 | +} |
| 263 | + |
| 264 | +fn unwrap_calc<D>(v: DimensionPercentage<D>) -> DimensionPercentage<D> { |
| 265 | + match v { |
| 266 | + DimensionPercentage::Calc(c) => match *c { |
| 267 | + Calc::Function(f) => match *f { |
| 268 | + MathFunction::Calc(c) => DimensionPercentage::Calc(Box::new(c)), |
| 269 | + c => DimensionPercentage::Calc(Box::new(Calc::Function(Box::new(c)))), |
| 270 | + }, |
| 271 | + _ => DimensionPercentage::Calc(c), |
| 272 | + }, |
| 273 | + _ => v, |
| 274 | + } |
| 275 | +} |
| 276 | + |
| 277 | +impl<D: TryAdd<D> + Clone + std::cmp::PartialEq<CSSNumber> + std::cmp::PartialOrd<CSSNumber> + std::fmt::Debug> |
| 278 | + AddInternal for DimensionPercentage<D> |
| 279 | +{ |
| 280 | + fn add(self, other: Self) -> Self { |
239 | 281 | match self.add_recursive(&other) { |
240 | 282 | Some(r) => r, |
241 | 283 | None => self.add(other), |
@@ -309,7 +351,9 @@ impl<D: TryAdd<D> + Clone + std::cmp::PartialEq<CSSNumber> + std::cmp::PartialOr |
309 | 351 | } |
310 | 352 |
|
311 | 353 | match (a, b) { |
312 | | - (DimensionPercentage::Calc(a), DimensionPercentage::Calc(b)) => DimensionPercentage::Calc(Box::new(*a + *b)), |
| 354 | + (DimensionPercentage::Calc(a), DimensionPercentage::Calc(b)) => { |
| 355 | + DimensionPercentage::Calc(Box::new(a.add(*b))) |
| 356 | + } |
313 | 357 | (DimensionPercentage::Calc(calc), b) => { |
314 | 358 | if let Calc::Value(a) = *calc { |
315 | 359 | a.add(b) |
|
0 commit comments