Title: [291474] trunk
Revision
291474
Author
[email protected]
Date
2022-03-18 02:01:12 -0700 (Fri, 18 Mar 2022)

Log Message

[CSS Container Queries] Basic support for container units
https://bugs.webkit.org/show_bug.cgi?id=238021

Reviewed by Antoine Quint.

LayoutTests/imported/w3c:

* web-platform-tests/css/css-contain/container-queries/container-units-animation-expected.txt:
* web-platform-tests/css/css-contain/container-queries/container-units-basic-expected.txt:
* web-platform-tests/css/css-contain/container-queries/container-units-computational-independence-expected.txt:
* web-platform-tests/css/css-contain/container-queries/container-units-invalidation-expected.txt:
* web-platform-tests/css/css-contain/container-queries/container-units-selection-expected.txt:
* web-platform-tests/css/css-contain/container-queries/container-units-small-viewport-fallback-expected.txt:
* web-platform-tests/css/css-contain/container-queries/container-units-typed-om-expected.txt:

Source/WebCore:

Container Relative Lengths: the cqw, cqh, cqi, cqb, cqmin, cqmax units
https://drafts.csswg.org/css-contain-3/#container-lengths

* css/CSSPrimitiveValue.cpp:
(WebCore::isValidCSSUnitTypeForDoubleConversion):
(WebCore::isStringType):
(WebCore::CSSPrimitiveValue::cleanup):
(WebCore::CSSPrimitiveValue::computeNonCalcLengthDouble):

Resolve container units by resolving the query container and computing the value against it.

(WebCore::CSSPrimitiveValue::unitTypeString):
(WebCore::CSSPrimitiveValue::formatNumberForCustomCSSText const):
(WebCore::CSSPrimitiveValue::equals const):
* css/CSSPrimitiveValue.h:
(WebCore::CSSPrimitiveValue::isLength):
* css/CSSToLengthConversionData.cpp:
(WebCore::CSSToLengthConversionData::CSSToLengthConversionData):
* css/CSSToLengthConversionData.h:
(WebCore::CSSToLengthConversionData::element const):
* css/CSSUnits.cpp:
(WebCore::unitCategory):
(WebCore::operator<<):
* css/CSSUnits.h:
* css/ContainerQuery.h:
* css/calc/CSSCalcCategoryMapping.cpp:
(WebCore::calcUnitCategory):
(WebCore::calculationCategoryForCombination):
(WebCore::hasDoubleValue):
* css/parser/CSSParserToken.cpp:
(WebCore::cssPrimitiveValueUnitFromTrie):

Parsing support.

* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::LengthRawKnownTokenTypeDimensionConsumer::consume):
* style/ContainerQueryEvaluator.cpp:
(WebCore::Style::ContainerQueryEvaluator::selectContainer const):
(WebCore::Style::ContainerQueryEvaluator::selectContainer):

Factor container selection into static function that can be used from the unit resolution code.

* style/ContainerQueryEvaluator.h:
* style/SelectorMatchingState.h:

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (291473 => 291474)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2022-03-18 09:01:12 UTC (rev 291474)
@@ -1,3 +1,18 @@
+2022-03-18  Antti Koivisto  <[email protected]>
+
+        [CSS Container Queries] Basic support for container units
+        https://bugs.webkit.org/show_bug.cgi?id=238021
+
+        Reviewed by Antoine Quint.
+
+        * web-platform-tests/css/css-contain/container-queries/container-units-animation-expected.txt:
+        * web-platform-tests/css/css-contain/container-queries/container-units-basic-expected.txt:
+        * web-platform-tests/css/css-contain/container-queries/container-units-computational-independence-expected.txt:
+        * web-platform-tests/css/css-contain/container-queries/container-units-invalidation-expected.txt:
+        * web-platform-tests/css/css-contain/container-queries/container-units-selection-expected.txt:
+        * web-platform-tests/css/css-contain/container-queries/container-units-small-viewport-fallback-expected.txt:
+        * web-platform-tests/css/css-contain/container-queries/container-units-typed-om-expected.txt:
+
 2022-03-17  Matt Woodrow  <[email protected]>
 
         Subgrid items should always be stretched.

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-animation-expected.txt (291473 => 291474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-animation-expected.txt	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-animation-expected.txt	2022-03-18 09:01:12 UTC (rev 291474)
@@ -1,14 +1,14 @@
 
-FAIL Animation using cqw unit assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqw unit responds to changing container size assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqh unit assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqh unit responds to changing container size assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqi unit assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqi unit responds to changing container size assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqb unit assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqb unit responds to changing container size assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqmin unit assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqmin unit responds to changing container size assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqmax unit assert_equals: expected "60px" but got "auto"
-FAIL Animation using cqmax unit responds to changing container size assert_equals: expected "60px" but got "auto"
+PASS Animation using cqw unit
+FAIL Animation using cqw unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqh unit
+FAIL Animation using cqh unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqi unit
+FAIL Animation using cqi unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqb unit
+FAIL Animation using cqb unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqmin unit
+FAIL Animation using cqmin unit responds to changing container size assert_equals: expected "90px" but got "60px"
+PASS Animation using cqmax unit
+FAIL Animation using cqmax unit responds to changing container size assert_equals: expected "90px" but got "60px"
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-basic-expected.txt (291473 => 291474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-basic-expected.txt	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-basic-expected.txt	2022-03-18 09:01:12 UTC (rev 291474)
@@ -1,5 +1,5 @@
 Test
 
-FAIL Container relative units assert_equals: expected "3px" but got "0px"
-FAIL Container relative units in math functions assert_equals: expected "30px" but got "0px"
+PASS Container relative units
+PASS Container relative units in math functions
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-computational-independence-expected.txt (291473 => 291474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-computational-independence-expected.txt	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-computational-independence-expected.txt	2022-03-18 09:01:12 UTC (rev 291474)
@@ -1,8 +1,20 @@
 
-PASS Container relative unit cqw is not computationally independent
-PASS Container relative unit cqh is not computationally independent
-PASS Container relative unit cqi is not computationally independent
-PASS Container relative unit cqb is not computationally independent
-PASS Container relative unit cqmin is not computationally independent
-PASS Container relative unit cqmax is not computationally independent
+FAIL Container relative unit cqw is not computationally independent assert_throws_dom: function "() => {
+        CSS.registerProperty({ name: '--x', inherits: false, syntax: '<length>', initialValue: `1${unit}` });
+      }" did not throw
+FAIL Container relative unit cqh is not computationally independent assert_throws_dom: function "() => {
+        CSS.registerProperty({ name: '--x', inherits: false, syntax: '<length>', initialValue: `1${unit}` });
+      }" threw object "InvalidModificationError: This property has already been registered." that is not a DOMException SyntaxError: property "code" is equal to 13, expected 12
+FAIL Container relative unit cqi is not computationally independent assert_throws_dom: function "() => {
+        CSS.registerProperty({ name: '--x', inherits: false, syntax: '<length>', initialValue: `1${unit}` });
+      }" threw object "InvalidModificationError: This property has already been registered." that is not a DOMException SyntaxError: property "code" is equal to 13, expected 12
+FAIL Container relative unit cqb is not computationally independent assert_throws_dom: function "() => {
+        CSS.registerProperty({ name: '--x', inherits: false, syntax: '<length>', initialValue: `1${unit}` });
+      }" threw object "InvalidModificationError: This property has already been registered." that is not a DOMException SyntaxError: property "code" is equal to 13, expected 12
+FAIL Container relative unit cqmin is not computationally independent assert_throws_dom: function "() => {
+        CSS.registerProperty({ name: '--x', inherits: false, syntax: '<length>', initialValue: `1${unit}` });
+      }" threw object "InvalidModificationError: This property has already been registered." that is not a DOMException SyntaxError: property "code" is equal to 13, expected 12
+FAIL Container relative unit cqmax is not computationally independent assert_throws_dom: function "() => {
+        CSS.registerProperty({ name: '--x', inherits: false, syntax: '<length>', initialValue: `1${unit}` });
+      }" threw object "InvalidModificationError: This property has already been registered." that is not a DOMException SyntaxError: property "code" is equal to 13, expected 12
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-invalidation-expected.txt (291473 => 291474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-invalidation-expected.txt	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-invalidation-expected.txt	2022-03-18 09:01:12 UTC (rev 291474)
@@ -1,8 +1,8 @@
 Test
 
-FAIL cqi respond when selected container changes type (inline-size -> none) assert_equals: expected "30px" but got "0px"
-FAIL cqb respond when selected container changes type (size -> none) assert_equals: expected "40px" but got "0px"
-FAIL cqb respond when intermediate container changes type (inline-size -> size) assert_equals: expected "40px" but got "0px"
-FAIL cqi respond when selected container changes inline-size assert_equals: expected "30px" but got "0px"
-FAIL cqb respond when selected container changes block-size assert_equals: expected "40px" but got "0px"
+FAIL cqi respond when selected container changes type (inline-size -> none) assert_equals: expected "50px" but got "30px"
+FAIL cqb respond when selected container changes type (size -> none) assert_equals: expected "60px" but got "40px"
+FAIL cqb respond when intermediate container changes type (inline-size -> size) assert_equals: expected "20px" but got "40px"
+FAIL cqi respond when selected container changes inline-size assert_equals: expected "5px" but got "30px"
+FAIL cqb respond when selected container changes block-size assert_equals: expected "5px" but got "40px"
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-selection-expected.txt (291473 => 291474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-selection-expected.txt	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-selection-expected.txt	2022-03-18 09:01:12 UTC (rev 291474)
@@ -1,5 +1,5 @@
 Test
 
-FAIL Container units select the proper container assert_equals: expected "10px" but got "0px"
-FAIL Units respond to the writing-mode of the element assert_equals: expected "30px" but got "0px"
+FAIL Container units select the proper container assert_equals: expected "30px" but got "10px"
+FAIL Units respond to the writing-mode of the element assert_equals: expected "40px" but got "30px"
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-small-viewport-fallback-expected.txt (291473 => 291474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-small-viewport-fallback-expected.txt	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-small-viewport-fallback-expected.txt	2022-03-18 09:01:12 UTC (rev 291474)
@@ -1,4 +1,4 @@
 
 
-FAIL Use small viewport size as fallback assert_equals: expected "7px" but got "auto"
+PASS Use small viewport size as fallback
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-typed-om-expected.txt (291473 => 291474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-typed-om-expected.txt	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-typed-om-expected.txt	2022-03-18 09:01:12 UTC (rev 291474)
@@ -1,26 +1,26 @@
 
 FAIL CSS.cqw function func is not a function. (In 'func(10)', 'func' is undefined)
-FAIL Reify value with cqw unit null is not an object (evaluating 'value.value')
+FAIL Reify value with cqw unit assert_equals: expected (number) 10 but got (undefined) undefined
 FAIL Set value with cqw unit (string) element.attributeStyleMap.set is not a function. (In 'element.attributeStyleMap.set('top', `10${unit}`)', 'element.attributeStyleMap.set' is undefined)
 FAIL Set value with cqw unit (CSS.cqw) func is not a function. (In 'func(10)', 'func' is undefined)
 FAIL CSS.cqh function func is not a function. (In 'func(10)', 'func' is undefined)
-FAIL Reify value with cqh unit null is not an object (evaluating 'value.value')
+FAIL Reify value with cqh unit assert_equals: expected (number) 10 but got (undefined) undefined
 FAIL Set value with cqh unit (string) element.attributeStyleMap.set is not a function. (In 'element.attributeStyleMap.set('top', `10${unit}`)', 'element.attributeStyleMap.set' is undefined)
 FAIL Set value with cqh unit (CSS.cqh) func is not a function. (In 'func(10)', 'func' is undefined)
 FAIL CSS.cqi function func is not a function. (In 'func(10)', 'func' is undefined)
-FAIL Reify value with cqi unit null is not an object (evaluating 'value.value')
+FAIL Reify value with cqi unit assert_equals: expected (number) 10 but got (undefined) undefined
 FAIL Set value with cqi unit (string) element.attributeStyleMap.set is not a function. (In 'element.attributeStyleMap.set('top', `10${unit}`)', 'element.attributeStyleMap.set' is undefined)
 FAIL Set value with cqi unit (CSS.cqi) func is not a function. (In 'func(10)', 'func' is undefined)
 FAIL CSS.cqb function func is not a function. (In 'func(10)', 'func' is undefined)
-FAIL Reify value with cqb unit null is not an object (evaluating 'value.value')
+FAIL Reify value with cqb unit assert_equals: expected (number) 10 but got (undefined) undefined
 FAIL Set value with cqb unit (string) element.attributeStyleMap.set is not a function. (In 'element.attributeStyleMap.set('top', `10${unit}`)', 'element.attributeStyleMap.set' is undefined)
 FAIL Set value with cqb unit (CSS.cqb) func is not a function. (In 'func(10)', 'func' is undefined)
 FAIL CSS.cqmin function func is not a function. (In 'func(10)', 'func' is undefined)
-FAIL Reify value with cqmin unit null is not an object (evaluating 'value.value')
+FAIL Reify value with cqmin unit assert_equals: expected (number) 10 but got (undefined) undefined
 FAIL Set value with cqmin unit (string) element.attributeStyleMap.set is not a function. (In 'element.attributeStyleMap.set('top', `10${unit}`)', 'element.attributeStyleMap.set' is undefined)
 FAIL Set value with cqmin unit (CSS.cqmin) func is not a function. (In 'func(10)', 'func' is undefined)
 FAIL CSS.cqmax function func is not a function. (In 'func(10)', 'func' is undefined)
-FAIL Reify value with cqmax unit null is not an object (evaluating 'value.value')
+FAIL Reify value with cqmax unit assert_equals: expected (number) 10 but got (undefined) undefined
 FAIL Set value with cqmax unit (string) element.attributeStyleMap.set is not a function. (In 'element.attributeStyleMap.set('top', `10${unit}`)', 'element.attributeStyleMap.set' is undefined)
 FAIL Set value with cqmax unit (CSS.cqmax) func is not a function. (In 'func(10)', 'func' is undefined)
 

Modified: trunk/Source/WebCore/ChangeLog (291473 => 291474)


--- trunk/Source/WebCore/ChangeLog	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/ChangeLog	2022-03-18 09:01:12 UTC (rev 291474)
@@ -1,3 +1,55 @@
+2022-03-18  Antti Koivisto  <[email protected]>
+
+        [CSS Container Queries] Basic support for container units
+        https://bugs.webkit.org/show_bug.cgi?id=238021
+
+        Reviewed by Antoine Quint.
+
+        Container Relative Lengths: the cqw, cqh, cqi, cqb, cqmin, cqmax units
+        https://drafts.csswg.org/css-contain-3/#container-lengths
+
+        * css/CSSPrimitiveValue.cpp:
+        (WebCore::isValidCSSUnitTypeForDoubleConversion):
+        (WebCore::isStringType):
+        (WebCore::CSSPrimitiveValue::cleanup):
+        (WebCore::CSSPrimitiveValue::computeNonCalcLengthDouble):
+
+        Resolve container units by resolving the query container and computing the value against it.
+
+        (WebCore::CSSPrimitiveValue::unitTypeString):
+        (WebCore::CSSPrimitiveValue::formatNumberForCustomCSSText const):
+        (WebCore::CSSPrimitiveValue::equals const):
+        * css/CSSPrimitiveValue.h:
+        (WebCore::CSSPrimitiveValue::isLength):
+        * css/CSSToLengthConversionData.cpp:
+        (WebCore::CSSToLengthConversionData::CSSToLengthConversionData):
+        * css/CSSToLengthConversionData.h:
+        (WebCore::CSSToLengthConversionData::element const):
+        * css/CSSUnits.cpp:
+        (WebCore::unitCategory):
+        (WebCore::operator<<):
+        * css/CSSUnits.h:
+        * css/ContainerQuery.h:
+        * css/calc/CSSCalcCategoryMapping.cpp:
+        (WebCore::calcUnitCategory):
+        (WebCore::calculationCategoryForCombination):
+        (WebCore::hasDoubleValue):
+        * css/parser/CSSParserToken.cpp:
+        (WebCore::cssPrimitiveValueUnitFromTrie):
+
+        Parsing support.
+
+        * css/parser/CSSPropertyParserHelpers.cpp:
+        (WebCore::CSSPropertyParserHelpers::LengthRawKnownTokenTypeDimensionConsumer::consume):
+        * style/ContainerQueryEvaluator.cpp:
+        (WebCore::Style::ContainerQueryEvaluator::selectContainer const):
+        (WebCore::Style::ContainerQueryEvaluator::selectContainer):
+
+        Factor container selection into static function that can be used from the unit resolution code.
+
+        * style/ContainerQueryEvaluator.h:
+        * style/SelectorMatchingState.h:
+
 2022-03-18  Carlos Garcia Campos  <[email protected]>
 
         Add a public build option for PDF.js

Modified: trunk/Source/WebCore/css/CSSPrimitiveValue.cpp (291473 => 291474)


--- trunk/Source/WebCore/css/CSSPrimitiveValue.cpp	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/CSSPrimitiveValue.cpp	2022-03-18 09:01:12 UTC (rev 291474)
@@ -35,6 +35,7 @@
 #include "CalculationValue.h"
 #include "Color.h"
 #include "ColorSerialization.h"
+#include "ContainerQueryEvaluator.h"
 #include "Counter.h"
 #include "DeprecatedCSSOMPrimitiveValue.h"
 #include "FontCascade.h"
@@ -113,6 +114,12 @@
     case CSSUnitType::CSS_DPI:
     case CSSUnitType::CSS_DPPX:
     case CSSUnitType::CSS_X:
+    case CSSUnitType::CSS_CQW:
+    case CSSUnitType::CSS_CQH:
+    case CSSUnitType::CSS_CQI:
+    case CSSUnitType::CSS_CQB:
+    case CSSUnitType::CSS_CQMIN:
+    case CSSUnitType::CSS_CQMAX:
         return true;
     case CSSUnitType::CSS_ATTR:
     case CSSUnitType::CSS_COUNTER:
@@ -221,6 +228,12 @@
     case CSSUnitType::CSS_VMAX:
     case CSSUnitType::CSS_VMIN:
     case CSSUnitType::CSS_VW:
+    case CSSUnitType::CSS_CQW:
+    case CSSUnitType::CSS_CQH:
+    case CSSUnitType::CSS_CQI:
+    case CSSUnitType::CSS_CQB:
+    case CSSUnitType::CSS_CQMIN:
+    case CSSUnitType::CSS_CQMAX:
         return false;
     }
 
@@ -606,6 +619,12 @@
     case CSSUnitType::CSS_UNICODE_RANGE:
     case CSSUnitType::CSS_PROPERTY_ID:
     case CSSUnitType::CSS_VALUE_ID:
+    case CSSUnitType::CSS_CQW:
+    case CSSUnitType::CSS_CQH:
+    case CSSUnitType::CSS_CQI:
+    case CSSUnitType::CSS_CQB:
+    case CSSUnitType::CSS_CQMIN:
+    case CSSUnitType::CSS_CQMAX:
         ASSERT(!isStringType(type));
         break;
     }
@@ -803,6 +822,16 @@
 
 double CSSPrimitiveValue::computeNonCalcLengthDouble(const CSSToLengthConversionData& conversionData, CSSUnitType primitiveType, double value)
 {
+    auto selectContainerRenderer = [&](CQ::Axis axis) -> const RenderBox* {
+        if (!conversionData.element())
+            return nullptr;
+        // FIXME: Use cached query containers when available.
+        auto* container = Style::ContainerQueryEvaluator::selectContainer(axis, nullString(), *conversionData.element(), nullptr);
+        if (!container)
+            return nullptr;
+        return dynamicDowncast<RenderBox>(container->renderer());
+    };
+
     switch (primitiveType) {
     case CSSUnitType::CSS_EMS:
     case CSSUnitType::CSS_QUIRKY_EMS:
@@ -921,6 +950,36 @@
             value *= conversionData.style()->computedLineHeight();
         break;
 
+    case CSSUnitType::CSS_CQW: {
+        if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Width))
+            return containerRenderer->width() * value / 100;
+        return value * conversionData.smallViewportFactor().width();
+    }
+
+    case CSSUnitType::CSS_CQH: {
+        if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Height))
+            return containerRenderer->height() * value / 100;
+        return value * conversionData.smallViewportFactor().height();
+    }
+
+    case CSSUnitType::CSS_CQI: {
+        if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Inline))
+            return containerRenderer->logicalWidth() * value / 100;
+        return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, conversionData.smallViewportFactor(), conversionData.rootStyle());
+    }
+
+    case CSSUnitType::CSS_CQB: {
+        if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Block))
+            return containerRenderer->logicalHeight() * value / 100;
+        return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, conversionData.smallViewportFactor(), conversionData.rootStyle());
+    }
+
+    case CSSUnitType::CSS_CQMAX:
+        return std::max(computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_CQB, value), computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_CQI, value));
+
+    case CSSUnitType::CSS_CQMIN:
+        return std::min(computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_CQB, value), computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_CQI, value));
+
     case CSSUnitType::CSS_RLHS:
         if (conversionData.rootStyle()) {
             if (conversionData.computingLineHeight() || conversionData.computingFontSize())
@@ -1224,6 +1283,12 @@
         case CSSUnitType::CSS_REMS: return "rem";
         case CSSUnitType::CSS_CHS: return "ch";
         case CSSUnitType::CSS_IC: return "ic";
+        case CSSUnitType::CSS_CQW: return "cqw";
+        case CSSUnitType::CSS_CQH: return "cqh";
+        case CSSUnitType::CSS_CQI: return "cqi";
+        case CSSUnitType::CSS_CQB: return "cqb";
+        case CSSUnitType::CSS_CQMAX: return "cqmax";
+        case CSSUnitType::CSS_CQMIN: return "cqmin";
 
         case CSSUnitType::CSS_UNKNOWN:
         case CSSUnitType::CSS_NUMBER:
@@ -1321,6 +1386,18 @@
         return formatNumberValue("lh");
     case CSSUnitType::CSS_RLHS:
         return formatNumberValue("rlh");
+    case CSSUnitType::CSS_CQW:
+        return formatNumberValue("cqw");
+    case CSSUnitType::CSS_CQH:
+        return formatNumberValue("cqh");
+    case CSSUnitType::CSS_CQI:
+        return formatNumberValue("cqi");
+    case CSSUnitType::CSS_CQB:
+        return formatNumberValue("cqb");
+    case CSSUnitType::CSS_CQMAX:
+        return formatNumberValue("cqmax");
+    case CSSUnitType::CSS_CQMIN:
+        return formatNumberValue("cqmin");
     case CSSUnitType::CSS_DIMENSION:
         // FIXME: This isn't correct.
         return formatNumberValue("");
@@ -1510,6 +1587,12 @@
     case CSSUnitType::CSS_LHS:
     case CSSUnitType::CSS_RLHS:
     case CSSUnitType::CSS_DIMENSION:
+    case CSSUnitType::CSS_CQW:
+    case CSSUnitType::CSS_CQH:
+    case CSSUnitType::CSS_CQI:
+    case CSSUnitType::CSS_CQB:
+    case CSSUnitType::CSS_CQMIN:
+    case CSSUnitType::CSS_CQMAX:
         return m_value.num == other.m_value.num;
     case CSSUnitType::CSS_PROPERTY_ID:
         return propertyName(m_value.propertyID) == propertyName(other.m_value.propertyID);

Modified: trunk/Source/WebCore/css/CSSPrimitiveValue.h (291473 => 291474)


--- trunk/Source/WebCore/css/CSSPrimitiveValue.h	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/CSSPrimitiveValue.h	2022-03-18 09:01:12 UTC (rev 291474)
@@ -314,6 +314,12 @@
         || type == CSSUnitType::CSS_Q
         || type == CSSUnitType::CSS_LHS
         || type == CSSUnitType::CSS_RLHS
+        || type == CSSUnitType::CSS_CQW
+        || type == CSSUnitType::CSS_CQH
+        || type == CSSUnitType::CSS_CQI
+        || type == CSSUnitType::CSS_CQB
+        || type == CSSUnitType::CSS_CQMIN
+        || type == CSSUnitType::CSS_CQMAX
         || isViewportPercentageLength(type)
         || type == CSSUnitType::CSS_QUIRKY_EMS;
 }

Modified: trunk/Source/WebCore/css/CSSToLengthConversionData.cpp (291473 => 291474)


--- trunk/Source/WebCore/css/CSSToLengthConversionData.cpp	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/CSSToLengthConversionData.cpp	2022-03-18 09:01:12 UTC (rev 291474)
@@ -43,6 +43,7 @@
     , m_rootStyle(builderContext.rootElementStyle)
     , m_parentStyle(&builderContext.parentStyle)
     , m_renderView(builderContext.document->renderView())
+    , m_element(builderContext.element)
     , m_viewportDependencyDetectionStyle(const_cast<RenderStyle*>(m_style))
 {
 }

Modified: trunk/Source/WebCore/css/CSSToLengthConversionData.h (291473 => 291474)


--- trunk/Source/WebCore/css/CSSToLengthConversionData.h	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/CSSToLengthConversionData.h	2022-03-18 09:01:12 UTC (rev 291474)
@@ -36,6 +36,7 @@
 
 namespace WebCore {
 
+class Element;
 class FloatSize;
 class RenderStyle;
 class RenderView;
@@ -61,6 +62,7 @@
     bool computingLineHeight() const { return m_propertyToCompute == CSSPropertyLineHeight; }
     CSSPropertyID propertyToCompute() const { return m_propertyToCompute.value_or(CSSPropertyInvalid); }
     const RenderView* renderView() const { return m_renderView; }
+    const Element* element() const { return m_element.get(); }
 
     FloatSize defaultViewportFactor() const;
     FloatSize smallViewportFactor() const;
@@ -96,6 +98,7 @@
     const RenderStyle* m_rootStyle { nullptr };
     const RenderStyle* m_parentStyle { nullptr };
     const RenderView* m_renderView { nullptr };
+    RefPtr<const Element> m_element;
     std::optional<float> m_zoom;
     std::optional<CSSPropertyID> m_propertyToCompute;
     // FIXME: Remove this hack.

Modified: trunk/Source/WebCore/css/CSSUnits.cpp (291473 => 291474)


--- trunk/Source/WebCore/css/CSSUnits.cpp	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/CSSUnits.cpp	2022-03-18 09:01:12 UTC (rev 291474)
@@ -71,6 +71,12 @@
     case CSSUnitType::CSS_DVMAX:
     case CSSUnitType::CSS_DVB:
     case CSSUnitType::CSS_DVI:
+    case CSSUnitType::CSS_CQW:
+    case CSSUnitType::CSS_CQH:
+    case CSSUnitType::CSS_CQI:
+    case CSSUnitType::CSS_CQB:
+    case CSSUnitType::CSS_CQMIN:
+    case CSSUnitType::CSS_CQMAX:
         return CSSUnitCategory::Length;
     case CSSUnitType::CSS_MS:
     case CSSUnitType::CSS_S:
@@ -224,6 +230,12 @@
     case CSSUnitType::CSS_Q: ts << "q"; break;
     case CSSUnitType::CSS_LHS: ts << "lh"; break;
     case CSSUnitType::CSS_RLHS: ts << "rlh"; break;
+    case CSSUnitType::CSS_CQW: ts << "cqw"; break;
+    case CSSUnitType::CSS_CQH: ts << "cqh"; break;
+    case CSSUnitType::CSS_CQI: ts << "cqi"; break;
+    case CSSUnitType::CSS_CQB: ts << "cqb"; break;
+    case CSSUnitType::CSS_CQMAX: ts << "cqmax"; break;
+    case CSSUnitType::CSS_CQMIN: ts << "cqmin"; break;
     case CSSUnitType::CSS_PAIR: ts << "pair"; break;
     case CSSUnitType::CSS_UNICODE_RANGE: ts << "unicode_range"; break;
     case CSSUnitType::CSS_TURN: ts << "turn"; break;

Modified: trunk/Source/WebCore/css/CSSUnits.h (291473 => 291474)


--- trunk/Source/WebCore/css/CSSUnits.h	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/CSSUnits.h	2022-03-18 09:01:12 UTC (rev 291474)
@@ -84,6 +84,13 @@
     FirstViewportCSSUnitType = CSS_VW,
     LastViewporCSSUnitType = CSS_DVI,
 
+    CSS_CQW,
+    CSS_CQH,
+    CSS_CQI,
+    CSS_CQB,
+    CSS_CQMIN,
+    CSS_CQMAX,
+
     CSS_DPPX,
     CSS_X,
     CSS_DPI,

Modified: trunk/Source/WebCore/css/ContainerQuery.h (291473 => 291474)


--- trunk/Source/WebCore/css/ContainerQuery.h	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/ContainerQuery.h	2022-03-18 09:01:12 UTC (rev 291474)
@@ -24,6 +24,7 @@
 
 #pragma once
 
+#include <wtf/Forward.h>
 #include <wtf/OptionSet.h>
 #include <wtf/text/AtomString.h>
 
@@ -30,6 +31,7 @@
 namespace WebCore {
 
 class CSSValue;
+class Element;
 
 namespace CQ {
 
@@ -93,4 +95,6 @@
     ContainerQuery query;
 };
 
+using CachedQueryContainers = Vector<Ref<const Element>>;
+
 }

Modified: trunk/Source/WebCore/css/calc/CSSCalcCategoryMapping.cpp (291473 => 291474)


--- trunk/Source/WebCore/css/calc/CSSCalcCategoryMapping.cpp	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/calc/CSSCalcCategoryMapping.cpp	2022-03-18 09:01:12 UTC (rev 291474)
@@ -75,6 +75,12 @@
     case CSSUnitType::CSS_DVMAX:
     case CSSUnitType::CSS_DVB:
     case CSSUnitType::CSS_DVI:
+    case CSSUnitType::CSS_CQW:
+    case CSSUnitType::CSS_CQH:
+    case CSSUnitType::CSS_CQI:
+    case CSSUnitType::CSS_CQB:
+    case CSSUnitType::CSS_CQMIN:
+    case CSSUnitType::CSS_CQMAX:
         return CalculationCategory::Length;
     case CSSUnitType::CSS_PERCENTAGE:
         return CalculationCategory::Percent;
@@ -152,6 +158,12 @@
     case CSSUnitType::CSS_DVMAX:
     case CSSUnitType::CSS_DVB:
     case CSSUnitType::CSS_DVI:
+    case CSSUnitType::CSS_CQW:
+    case CSSUnitType::CSS_CQH:
+    case CSSUnitType::CSS_CQI:
+    case CSSUnitType::CSS_CQB:
+    case CSSUnitType::CSS_CQMIN:
+    case CSSUnitType::CSS_CQMAX:
     default:
         return CalculationCategory::Other;
     }
@@ -233,6 +245,12 @@
     case CSSUnitType::CSS_Q:
     case CSSUnitType::CSS_LHS:
     case CSSUnitType::CSS_RLHS:
+    case CSSUnitType::CSS_CQW:
+    case CSSUnitType::CSS_CQH:
+    case CSSUnitType::CSS_CQI:
+    case CSSUnitType::CSS_CQB:
+    case CSSUnitType::CSS_CQMIN:
+    case CSSUnitType::CSS_CQMAX:
         return true;
     case CSSUnitType::CSS_UNKNOWN:
     case CSSUnitType::CSS_STRING:

Modified: trunk/Source/WebCore/css/parser/CSSParserToken.cpp (291473 => 291474)


--- trunk/Source/WebCore/css/parser/CSSParserToken.cpp	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/parser/CSSParserToken.cpp	2022-03-18 09:01:12 UTC (rev 291474)
@@ -128,6 +128,20 @@
         break;
     case 3:
         switch (toASCIILower(data[0])) {
+        case 'c':
+            if (toASCIILower(data[1]) == 'q') {
+                switch (toASCIILower(data[2])) {
+                case 'b':
+                    return CSSUnitType::CSS_CQB;
+                case 'h':
+                    return CSSUnitType::CSS_CQH;
+                case 'i':
+                    return CSSUnitType::CSS_CQI;
+                case 'w':
+                    return CSSUnitType::CSS_CQW;
+                }
+            }
+            break;
         case 'd':
             switch (toASCIILower(data[1])) {
             case 'e':
@@ -252,6 +266,20 @@
             if (toASCIILower(data[1]) == '_' && toASCIILower(data[2]) == 'q' && toASCIILower(data[3]) == 'e' && toASCIILower(data[4]) == 'm')
                 return CSSUnitType::CSS_QUIRKY_EMS;
             break;
+        case 'c':
+            if (toASCIILower(data[1]) == 'q' && toASCIILower(data[2]) == 'm') {
+                switch (toASCIILower(data[3])) {
+                case 'a':
+                    if (toASCIILower(data[4]) == 'x')
+                        return CSSUnitType::CSS_CQMAX;
+                    break;
+                case 'i':
+                    if (toASCIILower(data[4]) == 'n')
+                        return CSSUnitType::CSS_CQMIN;
+                    break;
+                }
+            }
+            break;
         case 'd':
             if (toASCIILower(data[1]) == 'v' && toASCIILower(data[2]) == 'm') {
                 switch (toASCIILower(data[3])) {

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (291473 => 291474)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2022-03-18 09:01:12 UTC (rev 291474)
@@ -519,6 +519,12 @@
         case CSSUnitType::CSS_DVB:
         case CSSUnitType::CSS_DVI:
         case CSSUnitType::CSS_Q:
+        case CSSUnitType::CSS_CQW:
+        case CSSUnitType::CSS_CQH:
+        case CSSUnitType::CSS_CQI:
+        case CSSUnitType::CSS_CQB:
+        case CSSUnitType::CSS_CQMIN:
+        case CSSUnitType::CSS_CQMAX:
             break;
         default:
             return std::nullopt;

Modified: trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp (291473 => 291474)


--- trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp	2022-03-18 09:01:12 UTC (rev 291474)
@@ -78,6 +78,23 @@
         };
     };
 
+    auto* cachedQueryContainers = m_selectorMatchingState ? &m_selectorMatchingState->queryContainers : nullptr;
+
+    auto* container = selectContainer(filteredContainerQuery.axisFilter, filteredContainerQuery.nameFilter, m_element.get(), cachedQueryContainers, m_pseudoId);
+    if (!container)
+        return { };
+
+    return makeSelectedContainer(*container);
+}
+
+const Element* ContainerQueryEvaluator::selectContainer(OptionSet<CQ::Axis> axes, const String& name, const Element& element, const CachedQueryContainers* cachedQueryContainers, PseudoId pseudoId)
+{
+    // "For each element, the query container to be queried is selected from among the element’s
+    // ancestor query containers that have a valid container-type for all the container features
+    // in the <container-condition>. The optional <container-name> filters the set of query containers
+    // considered to just those with a matching query container name."
+    // https://drafts.csswg.org/css-contain-3/#container-rule
+
     auto isValidContainerForRequiredAxes = [&](ContainerType containerType, const RenderElement* principalBox) {
         switch (containerType) {
         case ContainerType::Size:
@@ -86,9 +103,9 @@
             // Without a principal box the container matches but the query against it will evaluate to Unknown.
             if (!principalBox)
                 return true;
-            if (filteredContainerQuery.axisFilter.contains(CQ::Axis::Block))
+            if (axes.contains(CQ::Axis::Block))
                 return false;
-            return !filteredContainerQuery.axisFilter.contains(principalBox->isHorizontalWritingMode() ? CQ::Axis::Height : CQ::Axis::Width);
+            return !axes.contains(principalBox->isHorizontalWritingMode() ? CQ::Axis::Height : CQ::Axis::Width);
         case ContainerType::None:
             return false;
         }
@@ -101,27 +118,27 @@
             return false;
         if (!isValidContainerForRequiredAxes(style->containerType(), element.renderer()))
             return false;
-        if (filteredContainerQuery.nameFilter.isEmpty())
+        if (name.isEmpty())
             return true;
-        return style->containerNames().contains(filteredContainerQuery.nameFilter);
+        return style->containerNames().contains(name);
     };
 
-    if (m_selectorMatchingState) {
-        for (auto& container : makeReversedRange(m_selectorMatchingState->queryContainers)) {
+    if (cachedQueryContainers) {
+        for (auto& container : makeReversedRange(*cachedQueryContainers)) {
             if (isContainerForQuery(container))
-                return makeSelectedContainer(container);
+                return container.ptr();
         }
         return { };
     }
 
-    if (m_pseudoId != PseudoId::None) {
-        if (isContainerForQuery(m_element))
-            return makeSelectedContainer(m_element);
+    if (pseudoId != PseudoId::None) {
+        if (isContainerForQuery(element))
+            return &element;
     }
 
-    for (auto& ancestor : composedTreeAncestors(const_cast<Element&>(m_element.get()))) {
+    for (auto& ancestor : composedTreeAncestors(const_cast<Element&>(element))) {
         if (isContainerForQuery(ancestor))
-            return makeSelectedContainer(ancestor);
+            return &ancestor;
     }
     return { };
 }

Modified: trunk/Source/WebCore/style/ContainerQueryEvaluator.h (291473 => 291474)


--- trunk/Source/WebCore/style/ContainerQueryEvaluator.h	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/style/ContainerQueryEvaluator.h	2022-03-18 09:01:12 UTC (rev 291474)
@@ -42,6 +42,8 @@
 
     bool evaluate(const FilteredContainerQuery&) const;
 
+    static const Element* selectContainer(OptionSet<CQ::Axis>, const String& name, const Element&, const CachedQueryContainers*, PseudoId = PseudoId::None);
+
 private:
     struct SelectedContainer;
     std::optional<SelectedContainer> selectContainer(const FilteredContainerQuery&) const;

Modified: trunk/Source/WebCore/style/SelectorMatchingState.h (291473 => 291474)


--- trunk/Source/WebCore/style/SelectorMatchingState.h	2022-03-18 08:35:25 UTC (rev 291473)
+++ trunk/Source/WebCore/style/SelectorMatchingState.h	2022-03-18 09:01:12 UTC (rev 291474)
@@ -24,6 +24,7 @@
 
 #pragma once
 
+#include "ContainerQuery.h"
 #include "HasSelectorFilter.h"
 #include "SelectorFilter.h"
 #include <wtf/HashMap.h>
@@ -38,7 +39,7 @@
 struct SelectorMatchingState {
     SelectorFilter selectorFilter;
 
-    Vector<Ref<const Element>> queryContainers;
+    CachedQueryContainers queryContainers;
 
     HashMap<HasPseudoClassCacheKey, HasPseudoClassMatch> hasPseudoClassMatchCache;
     HashMap<HasPseudoClassFilterKey, std::unique_ptr<HasSelectorFilter>> hasPseudoClassSelectorFilters;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to