diff options
-rw-r--r-- | components/layout_2020/flow/mod.rs | 1 | ||||
-rw-r--r-- | components/layout_2020/formatting_contexts.rs | 1 | ||||
-rw-r--r-- | components/layout_2020/sizing.rs | 30 | ||||
-rw-r--r-- | tests/wpt/meta/MANIFEST.json | 7 | ||||
-rw-r--r-- | tests/wpt/meta/css/css-sizing/keyword-sizes-on-abspos.html.ini | 9 | ||||
-rw-r--r-- | tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html | 50 |
6 files changed, 87 insertions, 11 deletions
diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index c9a1cfe55f1..01d9b1efc6d 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -431,6 +431,7 @@ fn compute_inline_content_sizes_for_block_level_boxes( containing_block, &LogicalVec2::zero(), false, /* auto_block_size_stretches_to_containing_block */ + false, /* is_replaced */ false, /* is_table */ !matches!(base.style.pseudo(), Some(PseudoElement::ServoAnonymousBox)), |_| None, /* TODO: support preferred aspect ratios on non-replaced boxes */ diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs index 21383ca40b2..d04c69f939f 100644 --- a/components/layout_2020/formatting_contexts.rs +++ b/components/layout_2020/formatting_contexts.rs @@ -215,6 +215,7 @@ impl IndependentFormattingContext { containing_block, auto_minimum, auto_block_size_stretches_to_containing_block, + self.is_replaced(), is_table, true, /* establishes_containing_block */ |padding_border_sums| self.preferred_aspect_ratio(padding_border_sums), diff --git a/components/layout_2020/sizing.rs b/components/layout_2020/sizing.rs index c745081e862..46eda7ccbde 100644 --- a/components/layout_2020/sizing.rs +++ b/components/layout_2020/sizing.rs @@ -10,6 +10,7 @@ use std::ops::{Add, AddAssign}; use app_units::Au; use serde::Serialize; use style::properties::ComputedValues; +use style::values::computed::LengthPercentage; use style::Zero; use crate::context::LayoutContext; @@ -115,6 +116,7 @@ pub(crate) fn outer_inline( containing_block: &IndefiniteContainingBlock, auto_minimum: &LogicalVec2<Au>, auto_block_size_stretches_to_containing_block: bool, + is_replaced: bool, is_table: bool, establishes_containing_block: bool, get_preferred_aspect_ratio: impl FnOnce(&LogicalVec2<Au>) -> Option<AspectRatio>, @@ -187,7 +189,7 @@ pub(crate) fn outer_inline( ), }) }; - let (preferred_min_content, preferred_max_content, preferred_depends_on_block_constraints) = + let (mut preferred_min_content, preferred_max_content, preferred_depends_on_block_constraints) = resolve_non_initial(content_box_sizes.inline.preferred) .unwrap_or_else(|| resolve_non_initial(Size::FitContent).unwrap()); let (mut min_min_content, mut min_max_content, mut min_depends_on_block_constraints) = @@ -196,7 +198,7 @@ pub(crate) fn outer_inline( auto_minimum.inline, false, )); - let (max_min_content, max_max_content, max_depends_on_block_constraints) = + let (mut max_min_content, max_max_content, max_depends_on_block_constraints) = resolve_non_initial(content_box_sizes.inline.max) .map(|(min_content, max_content, depends_on_block_constraints)| { ( @@ -207,6 +209,30 @@ pub(crate) fn outer_inline( }) .unwrap_or_default(); + // https://drafts.csswg.org/css-sizing-3/#replaced-percentage-min-contribution + // > If the box is replaced, a cyclic percentage in the value of any max size property + // > or preferred size property (width/max-width/height/max-height), is resolved against + // > zero when calculating the min-content contribution in the corresponding axis. + // + // This means that e.g. the min-content contribution of `width: calc(100% + 100px)` + // should be 100px, but it's just zero on other browsers, so we do the same. + if is_replaced { + let has_percentage = |size: Size<LengthPercentage>| { + // We need a comment here to avoid breaking `./mach test-tidy`. + matches!(size, Size::Numeric(numeric) if numeric.has_percentage()) + }; + if content_box_sizes.inline.preferred.is_initial() && + has_percentage(style.box_size(containing_block.writing_mode).inline) + { + preferred_min_content = Au::zero(); + } + if content_box_sizes.inline.max.is_initial() && + has_percentage(style.max_box_size(containing_block.writing_mode).inline) + { + max_min_content = Some(Au::zero()); + } + } + // Regardless of their sizing properties, tables are always forced to be at least // as big as their min-content size, so floor the minimums. if is_table { diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index d97e68cb65e..d248c65d75b 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -581052,6 +581052,13 @@ {} ] ], + "intrinsic-percent-replaced-028.html": [ + "f54245a1e1f0aabff40ed8823279b8c0bb48f93d", + [ + null, + {} + ] + ], "intrinsic-size-fallback-replaced.html": [ "a3325b0aea01c008ec322a20e0f279d5bd765b1c", [ diff --git a/tests/wpt/meta/css/css-sizing/keyword-sizes-on-abspos.html.ini b/tests/wpt/meta/css/css-sizing/keyword-sizes-on-abspos.html.ini deleted file mode 100644 index 508b6bddd70..00000000000 --- a/tests/wpt/meta/css/css-sizing/keyword-sizes-on-abspos.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[keyword-sizes-on-abspos.html] - [.test 17] - expected: FAIL - - [.test 22] - expected: FAIL - - [.test 27] - expected: FAIL diff --git a/tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html b/tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html new file mode 100644 index 00000000000..f54245a1e1f --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#replaced-percentage-min-contribution"> +<meta name="assert" content="A preferred or max inline size property set to a percentage is treated as zero when computing the min-content contribution."> + +<style> +.wrapper { + display: inline-block; + border: solid; + margin: 5px; +} +</style> + +<div style="width: 0px"> + <!-- Set 'width' to a percentage --> + <div class="wrapper" data-expected-client-width="0"> + <canvas style="width: 0%; max-width: 100px"></canvas> + </div> + <div class="wrapper" data-expected-client-width="0"> + <canvas style="width: 50%; max-width: 100px"></canvas> + </div> + <div class="wrapper" data-expected-client-width="0"> + <canvas style="width: 100%; max-width: 100px"></canvas> + </div> + <div class="wrapper" data-expected-client-width="0"> + <canvas style="width: 200%; max-width: 100px"></canvas> + </div> + + <!-- Set 'max-width' to a percentage --> + <div class="wrapper" data-expected-client-width="0"> + <canvas style="width: 100px; max-width: 0%"></canvas> + </div> + <div class="wrapper" data-expected-client-width="0"> + <canvas style="width: 100px; max-width: 50%"></canvas> + </div> + <div class="wrapper" data-expected-client-width="0"> + <canvas style="width: 100px; max-width: 100%"></canvas> + </div> + <div class="wrapper" data-expected-client-width="0"> + <canvas style="width: 100px; max-width: 200%"></canvas> + </div> +</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<script> +checkLayout(".wrapper"); +</script> |