Переглянути джерело

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 роки тому
батько
коміт
4cbec00c44

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

@@ -98,8 +98,6 @@ struct TransformOrigin {
 struct FlexBasisData {
 struct FlexBasisData {
     CSS::FlexBasis type { CSS::FlexBasis::Auto };
     CSS::FlexBasis type { CSS::FlexBasis::Auto };
     Optional<CSS::LengthPercentage> length_percentage;
     Optional<CSS::LengthPercentage> length_percentage;
-
-    bool is_definite() const { return type == CSS::FlexBasis::LengthPercentage; }
 };
 };
 
 
 struct ShadowData {
 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.flex_base_size = [&] {
         flex_item.used_flex_basis = used_flex_basis_for_item(flex_item);
         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.
         // 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());
             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
             // 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.
             // 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.
             // 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);
                 set_has_definite_main_size(flex_item->box, true);
             }
             }
         }
         }

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

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