Special-case "compressible replaced elements" in grid sizing algorithm (#807)
Signed-off-by: Nico Burns <nico@nicoburns.com>
a4b481f99f435f2b304ef63d272bbd49136d4f14 · by Nico Burns · (1 year ago) · parent 8437796cc · browse the tree at this commit
Semantic delta · 10
src/compute/grid/types/grid_item.rs
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index a84c77429..5746303c4 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -28,6 +28,9 @@ pub(in super::super) struct GridItem {
/// (in origin-zero coordinates)
pub column: Line<OriginZeroLine>,
+ /// Is it a compressible replaced element?
+ /// https://drafts.csswg.org/css-sizing-3/#min-content-zero
+ pub is_compressible_replaced: bool,
/// The item's overflow style
pub overflow: Point<Overflow>,
/// The item's box_sizing style
@@ -104,6 +107,7 @@ impl GridItem {
source_order,
row: row_span,
column: col_span,
+ is_compressible_replaced: style.is_compressible_replaced(),
overflow: style.overflow(),
box_sizing: style.box_sizing(),
size: style.size(),
@@ -504,7 +508,20 @@ impl GridItem {
// Otherwise, the automatic minimum size is zero, as usual.
if use_content_based_minimum {
- self.min_content_contribution_cached(axis, tree, known_dimensions, inner_node_size)
+ let mut minimum_contribution =
+ self.min_content_contribution_cached(axis, tree, known_dimensions, inner_node_size);
+
+ // If the item is a compressible replaced element, and has a definite preferred size or maximum size in the
+ // relevant axis, the size suggestion is capped by those sizes; for this purpose, any indefinite percentages
+ // in these sizes are resolved against zero (and considered definite).
+ if self.is_compressible_replaced {
+ let size = self.size.get(axis).maybe_resolve(Some(0.0), |val, basis| tree.calc(val, basis));
+ let max_size =
+ self.max_size.get(axis).maybe_resolve(Some(0.0), |val, basis| tree.calc(val, basis));
+ minimum_contribution = minimum_contribution.maybe_min(size).maybe_min(max_size);
+ }
+
+ minimum_contribution
} else {
0.0
}
diff --git a/src/style/mod.rs b/src/style/mod.rs
index e1709ef2a..41cef747a 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -54,6 +54,12 @@ pub trait CoreStyle {
fn is_block(&self) -> bool {
false
}
+ /// Is it a compressible replaced element?
+ /// https://drafts.csswg.org/css-sizing-3/#min-content-zero
+ #[inline(always)]
+ fn is_compressible_replaced(&self) -> bool {
+ false
+ }
/// Which box do size styles apply to
#[inline(always)]
fn box_sizing(&self) -> BoxSizing {
@@ -338,6 +344,9 @@ pub struct Style {
/// Whether a child is display:table or not. This affects children of block layouts.
/// This should really be part of `Display`, but it is currently seperate because table layout isn't implemented
pub item_is_table: bool,
+ /// Is it a replaced element like an image or form field?
+ /// https://drafts.csswg.org/css-sizing-3/#min-content-zero
+ pub item_is_replaced: bool,
/// Should size styles apply to the content box or the border box of the node
pub box_sizing: BoxSizing,
@@ -465,6 +474,7 @@ impl Style {
pub const DEFAULT: Style = Style {
display: Display::DEFAULT,
item_is_table: false,
+ item_is_replaced: false,
box_sizing: BoxSizing::BorderBox,
overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
scrollbar_width: 0.0,
@@ -544,6 +554,10 @@ impl CoreStyle for Style {
matches!(self.display, Display::Block)
}
#[inline(always)]
+ fn is_compressible_replaced(&self) -> bool {
+ self.item_is_replaced
+ }
+ #[inline(always)]
fn box_sizing(&self) -> BoxSizing {
self.box_sizing
}
@@ -603,6 +617,10 @@ impl<T: CoreStyle> CoreStyle for &'_ T {
(*self).is_block()
}
#[inline(always)]
+ fn is_compressible_replaced(&self) -> bool {
+ (*self).is_compressible_replaced()
+ }
+ #[inline(always)]
fn box_sizing(&self) -> BoxSizing {
(*self).box_sizing()
}
@@ -939,6 +957,7 @@ mod tests {
let old_defaults = Style {
display: Default::default(),
item_is_table: false,
+ item_is_replaced: false,
box_sizing: Default::default(),
overflow: Default::default(),
scrollbar_width: 0.0,