Browse Source

LibWeb: Actually check if percentage used flex basis is definite

Previously, we considered all LengthPercentage values for used flex
basis to be definite. This is not accurate, as percentages should only
be considered definite if the reference value they resolve against is
a definite size.

Fix this by checking the flex container's main definite size flag.
Andreas Kling 3 years ago
parent
commit
4cbec00c44

+ 0 - 2
Userland/Libraries/LibWeb/CSS/ComputedValues.h

@@ -98,8 +98,6 @@ struct TransformOrigin {
 struct FlexBasisData {
     CSS::FlexBasis type { CSS::FlexBasis::Auto };
     Optional<CSS::LengthPercentage> length_percentage;
-
-    bool is_definite() const { return type == CSS::FlexBasis::LengthPercentage; }
 };
 
 struct ShadowData {

+ 14 - 2
Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp

@@ -599,8 +599,20 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(
     flex_item.flex_base_size = [&] {
         flex_item.used_flex_basis = used_flex_basis_for_item(flex_item);
 
+        flex_item.used_flex_basis_is_definite = [&](CSS::FlexBasisData const& flex_basis) -> bool {
+            if (flex_basis.type != CSS::FlexBasis::LengthPercentage)
+                return false;
+            if (flex_basis.length_percentage->is_auto())
+                return false;
+            if (flex_basis.length_percentage->is_length())
+                return true;
+            if (is_row_layout())
+                return m_flex_container_state.has_definite_width();
+            return m_flex_container_state.has_definite_height();
+        }(flex_item.used_flex_basis);
+
         // A. If the item has a definite used flex basis, that’s the flex base size.
-        if (flex_item.used_flex_basis.is_definite()) {
+        if (flex_item.used_flex_basis_is_definite) {
             return get_pixel_size(m_state, child_box, flex_item.used_flex_basis.length_percentage.value());
         }
 
@@ -987,7 +999,7 @@ void FlexFormattingContext::resolve_flexible_lengths()
             // https://drafts.csswg.org/css-flexbox-1/#definite-sizes
             // 1. If the flex container has a definite main size, then the post-flexing main sizes of its flex items are treated as definite.
             // 2. If a flex-item’s flex basis is definite, then its post-flexing main size is also definite.
-            if (has_definite_main_size(flex_container()) || flex_item->used_flex_basis.is_definite()) {
+            if (has_definite_main_size(flex_container()) || flex_item->used_flex_basis_is_definite) {
                 set_has_definite_main_size(flex_item->box, true);
             }
         }

+ 1 - 0
Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h

@@ -43,6 +43,7 @@ private:
     struct FlexItem {
         Box& box;
         CSS::FlexBasisData used_flex_basis {};
+        bool used_flex_basis_is_definite { false };
         float flex_base_size { 0 };
         float hypothetical_main_size { 0 };
         float hypothetical_cross_size { 0 };