From f817f28f6f7489ae2d077ef8ab27db4720bb86be Mon Sep 17 00:00:00 2001
From: Sam Atkins <sam@ladybird.org>
Date: Thu, 12 Dec 2024 17:23:57 +0000
Subject: [PATCH] WIP: Bring percentage handling up to date with spec -
 INCOMPLETE!!!

See https://github.com/w3c/css-houdini-drafts/commit/3d51716987994673b9f24fbe5fa3bf94e0447781
---
 Libraries/LibWeb/CSS/CSSNumericType.cpp             | 13 ++++++++-----
 .../LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp |  8 +++++---
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/Libraries/LibWeb/CSS/CSSNumericType.cpp b/Libraries/LibWeb/CSS/CSSNumericType.cpp
index 2bc74fe409604..c11182c993685 100644
--- a/Libraries/LibWeb/CSS/CSSNumericType.cpp
+++ b/Libraries/LibWeb/CSS/CSSNumericType.cpp
@@ -280,19 +280,22 @@ Optional<CSSNumericType> CSSNumericType::consistent_type(CSSNumericType const& o
 // https://drafts.css-houdini.org/css-typed-om-1/#apply-the-percent-hint
 void CSSNumericType::apply_percent_hint(BaseType hint)
 {
-    // To apply the percent hint hint to a type, perform the following steps:
+    // To apply the percent hint hint to a type without a percent hint, perform the following steps:
 
-    // 1. If type doesn’t contain hint, set type[hint] to 0.
+    // 1. Set type’s percent hint to hint,
+    set_percent_hint(hint);
+
+    // 2. If type doesn’t contain hint, set type[hint] to 0.
     if (!exponent(hint).has_value())
         set_exponent(hint, 0);
 
-    // 2. If type contains "percent", add type["percent"] to type[hint], then set type["percent"] to 0.
-    if (exponent(BaseType::Percent).has_value()) {
+    // 3. If hint is anything other than "percent", and type contains "percent", add type["percent"] to type[hint], then set type["percent"] to 0.
+    if (hint != BaseType::Percent && exponent(BaseType::Percent).has_value()) {
         set_exponent(hint, exponent(BaseType::Percent).value() + exponent(hint).value());
         set_exponent(BaseType::Percent, 0);
     }
 
-    // 3. Set type’s percent hint to hint.
+    // 4. Set type’s percent hint to hint.
     set_percent_hint(hint);
 }
 
diff --git a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp
index 51096ee74526b..5e2386f5349d7 100644
--- a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp
+++ b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp
@@ -156,14 +156,16 @@ NonnullOwnPtr<NumericCalculationNode> NumericCalculationNode::create(NumericValu
             //    If, in the context in which the math function containing this calculation is placed,
             //    <percentage>s are resolved relative to another type of value (such as in width,
             //    where <percentage> is resolved against a <length>), and that other type is not <number>,
-            //    the type is determined as the other type.
+            //    the type is determined as the other type, but with a percent hint set to that other type.
             if (percentage_resolved_type.has_value() && percentage_resolved_type != ValueType::Number && percentage_resolved_type != ValueType::Percentage) {
                 auto base_type = CSSNumericType::base_type_from_value_type(*percentage_resolved_type);
                 VERIFY(base_type.has_value());
-                return CSSNumericType { base_type.value(), 1 };
+                auto result = CSSNumericType { base_type.value(), 1 };
+                result.set_percent_hint(base_type);
+                return result;
             }
 
-            //    Otherwise, the type is «[ "percent" → 1 ]».
+            //    Otherwise, the type is «[ "percent" → 1 ]», with a percent hint of "percent".
             return CSSNumericType { CSSNumericType::BaseType::Percent, 1 };
         });
     // In all cases, the associated percent hint is null.