From 22f99c71b935d64a7734df783f3d1ec1c327b1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E5=8D=9A=E6=96=87?= Date: Thu, 20 Apr 2017 11:27:19 +0800 Subject: [PATCH] Add to_computed method for CalcLengthOrPercentage * Add to_computed method to calculate `calc()` value with parent size, if parent container size is `None`, the result will be `None`. * Add from_option method for `MaybeAuto`, to construct from `Option`. * Update some test case. --- components/layout/block.rs | 22 ++++++++----------- components/layout/flex.rs | 12 +++++----- components/layout/model.rs | 13 ++++++++--- components/style/values/computed/length.rs | 10 +++++++++ tests/unit/style/attr.rs | 13 +++++++++++ .../html/calc-height-block-1.htm.ini | 3 --- .../html/calc-max-height-block-1.htm.ini | 3 --- .../html/calc-min-height-block-1.htm.ini | 3 --- 8 files changed, 47 insertions(+), 32 deletions(-) delete mode 100644 tests/wpt/metadata-css/css-values-3_dev/html/calc-height-block-1.htm.ini delete mode 100644 tests/wpt/metadata-css/css-values-3_dev/html/calc-max-height-block-1.htm.ini delete mode 100644 tests/wpt/metadata-css/css-values-3_dev/html/calc-min-height-block-1.htm.ini diff --git a/components/layout/block.rs b/components/layout/block.rs index 9e28cf2095d..32cbe6e23e8 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -324,22 +324,20 @@ impl CandidateBSizeIterator { (LengthOrPercentageOrAuto::Percentage(percent), Some(block_container_block_size)) => { MaybeAuto::Specified(block_container_block_size.scale_by(percent)) } - (LengthOrPercentageOrAuto::Calc(calc), Some(block_container_block_size)) => { - MaybeAuto::Specified(calc.length() + block_container_block_size.scale_by(calc.percentage())) + (LengthOrPercentageOrAuto::Calc(calc), _) => { + MaybeAuto::from_option(calc.to_computed(block_container_block_size)) } (LengthOrPercentageOrAuto::Percentage(_), None) | - (LengthOrPercentageOrAuto::Auto, _) | - (LengthOrPercentageOrAuto::Calc(_), _) => MaybeAuto::Auto, + (LengthOrPercentageOrAuto::Auto, _) => MaybeAuto::Auto, (LengthOrPercentageOrAuto::Length(length), _) => MaybeAuto::Specified(length), }; let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) { (LengthOrPercentageOrNone::Percentage(percent), Some(block_container_block_size)) => { Some(block_container_block_size.scale_by(percent)) } - (LengthOrPercentageOrNone::Calc(calc), Some(block_container_block_size)) => { - Some(block_container_block_size.scale_by(calc.percentage()) + calc.length()) + (LengthOrPercentageOrNone::Calc(calc), _) => { + calc.to_computed(block_container_block_size) } - (LengthOrPercentageOrNone::Calc(_), _) | (LengthOrPercentageOrNone::Percentage(_), None) | (LengthOrPercentageOrNone::None, _) => None, (LengthOrPercentageOrNone::Length(length), _) => Some(length), @@ -348,10 +346,9 @@ impl CandidateBSizeIterator { (LengthOrPercentage::Percentage(percent), Some(block_container_block_size)) => { block_container_block_size.scale_by(percent) } - (LengthOrPercentage::Calc(calc), Some(block_container_block_size)) => { - calc.length() + block_container_block_size.scale_by(calc.percentage()) + (LengthOrPercentage::Calc(calc), _) => { + calc.to_computed(block_container_block_size).unwrap_or(Au(0)) } - (LengthOrPercentage::Calc(calc), None) => calc.length(), (LengthOrPercentage::Percentage(_), None) => Au(0), (LengthOrPercentage::Length(length), _) => length, }; @@ -1168,15 +1165,14 @@ impl BlockFlow { let content_block_size = self.fragment.style().content_block_size(); match (content_block_size, containing_block_size) { - (LengthOrPercentageOrAuto::Calc(calc), Some(container_size)) => { - Some(container_size.scale_by(calc.percentage()) + calc.length()) + (LengthOrPercentageOrAuto::Calc(calc), _) => { + calc.to_computed(containing_block_size) } (LengthOrPercentageOrAuto::Length(length), _) => Some(length), (LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => { Some(container_size.scale_by(percent)) } (LengthOrPercentageOrAuto::Percentage(_), None) | - (LengthOrPercentageOrAuto::Calc(_), None) | (LengthOrPercentageOrAuto::Auto, None) => { None } diff --git a/components/layout/flex.rs b/components/layout/flex.rs index 5fd9459ab02..cf77455afa8 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -53,9 +53,9 @@ impl AxisSize { } } LengthOrPercentageOrAuto::Calc(calc) => { - match content_size { - Some(size) => AxisSize::Definite(size.scale_by(calc.percentage())), - None => AxisSize::Infinite + match calc.to_computed(content_size) { + Some(length) => AxisSize::Definite(length), + None => AxisSize::Infinite, } } LengthOrPercentageOrAuto::Auto => { @@ -79,10 +79,8 @@ fn from_flex_basis(flex_basis: LengthOrPercentageOrAutoOrContent, MaybeAuto::Specified(size.scale_by(percent)), (LengthOrPercentageOrAutoOrContent::Percentage(_), None) => MaybeAuto::Auto, - (LengthOrPercentageOrAutoOrContent::Calc(calc), Some(size)) => - MaybeAuto::Specified(calc.length() + size.scale_by(calc.percentage())), - (LengthOrPercentageOrAutoOrContent::Calc(_), None) => - MaybeAuto::Auto, + (LengthOrPercentageOrAutoOrContent::Calc(calc), _) => + MaybeAuto::from_option(calc.to_computed(containing_length)), (LengthOrPercentageOrAutoOrContent::Content, _) => MaybeAuto::Auto, (LengthOrPercentageOrAutoOrContent::Auto, Some(size)) => diff --git a/components/layout/model.rs b/components/layout/model.rs index 8382c9af7d0..a6d64e557ac 100644 --- a/components/layout/model.rs +++ b/components/layout/model.rs @@ -408,12 +408,20 @@ impl MaybeAuto { MaybeAuto::Specified(containing_length.scale_by(percent)) } LengthOrPercentageOrAuto::Calc(calc) => { - MaybeAuto::Specified(calc.length() + containing_length.scale_by(calc.percentage())) + MaybeAuto::from_option(calc.to_computed(Some(containing_length))) } LengthOrPercentageOrAuto::Length(length) => MaybeAuto::Specified(length) } } + #[inline] + pub fn from_option(au: Option) -> MaybeAuto { + match au { + Some(l) => MaybeAuto::Specified(l), + _ => MaybeAuto::Auto, + } + } + #[inline] pub fn specified_or_default(&self, default: Au) -> Au { match *self { @@ -455,8 +463,7 @@ pub fn specified_or_none(length: LengthOrPercentageOrNone, containing_length: Au match length { LengthOrPercentageOrNone::None => None, LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent)), - LengthOrPercentageOrNone::Calc(calc) => - Some(containing_length.scale_by(calc.percentage()) + calc.length()), + LengthOrPercentageOrNone::Calc(calc) => calc.to_computed(Some(containing_length)), LengthOrPercentageOrNone::Length(length) => Some(length), } } diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index c21a03c1ca6..298a2b8e706 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -76,6 +76,16 @@ impl CalcLengthOrPercentage { pub fn percentage(&self) -> CSSFloat { self.percentage.unwrap_or(0.) } + + /// If there are special rules for computing percentages in a value (e.g. the height property), + /// they apply whenever a calc() expression contains percentages. + pub fn to_computed(&self, container_len: Option) -> Option { + match (container_len, self.percentage) { + (Some(len), Some(percent)) => Some(self.length + len.scale_by(percent)), + (_, None) => Some(self.length), + _ => None, + } + } } impl From for CalcLengthOrPercentage { diff --git a/tests/unit/style/attr.rs b/tests/unit/style/attr.rs index 0521df3a690..10f1bd5e585 100644 --- a/tests/unit/style/attr.rs +++ b/tests/unit/style/attr.rs @@ -4,6 +4,19 @@ use app_units::Au; use style::attr::{AttrValue, LengthOrPercentageOrAuto, parse_length}; +use style::values::computed::CalcLengthOrPercentage; + +#[test] +fn test_length_calc() { + let calc = CalcLengthOrPercentage { length: Au(10), percentage: Some(0.2) }; + assert_eq!(calc.to_computed(Some(Au(10))), Some(Au(12))); + assert_eq!(calc.to_computed(Some(Au(0))), Some(Au(10))); + assert_eq!(calc.to_computed(None), None); + + let calc = CalcLengthOrPercentage { length: Au(10), percentage: None }; + assert_eq!(calc.to_computed(Some(Au(0))), Some(Au(10))); + assert_eq!(calc.to_computed(None), Some(Au(10))); +} #[test] fn test_parse_double() { diff --git a/tests/wpt/metadata-css/css-values-3_dev/html/calc-height-block-1.htm.ini b/tests/wpt/metadata-css/css-values-3_dev/html/calc-height-block-1.htm.ini deleted file mode 100644 index e79c4829fb0..00000000000 --- a/tests/wpt/metadata-css/css-values-3_dev/html/calc-height-block-1.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[calc-height-block-1.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css-values-3_dev/html/calc-max-height-block-1.htm.ini b/tests/wpt/metadata-css/css-values-3_dev/html/calc-max-height-block-1.htm.ini deleted file mode 100644 index ea2466a53a3..00000000000 --- a/tests/wpt/metadata-css/css-values-3_dev/html/calc-max-height-block-1.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[calc-max-height-block-1.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css-values-3_dev/html/calc-min-height-block-1.htm.ini b/tests/wpt/metadata-css/css-values-3_dev/html/calc-min-height-block-1.htm.ini deleted file mode 100644 index 5d79c139f72..00000000000 --- a/tests/wpt/metadata-css/css-values-3_dev/html/calc-min-height-block-1.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[calc-min-height-block-1.htm] - type: reftest - expected: FAIL