Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[CSS Container Queries] Use element writing mode for unit resolution
https://bugs.webkit.org/show_bug.cgi?id=258722
rdar://111565488

Reviewed by Simon Fraser.

Correct handling for vertical writing mode per w3c/csswg-drafts#6873

* LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-in-at-container-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-units-selection-expected.txt:
* Source/WebCore/css/CSSPrimitiveValue.cpp:
(WebCore::CSSPrimitiveValue::computeNonCalcLengthDouble):

Resolve logical to to physical axis based on the element writing mode.
Also explicitly fall back to small viewport units to guarantee consistency.

Canonical link: https://commits.webkit.org/265654@main
  • Loading branch information
anttijk committed Jun 30, 2023
1 parent 5373a15 commit b4d32d7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 20 deletions.
Expand Up @@ -15,8 +15,8 @@ PASS cqmin unit resolves against appropriate container (vertical writing-mode on
PASS cqmax unit resolves against appropriate container (vertical writing-mode on subject)
PASS cqw unit resolves against appropriate container (vertical writing-mode on container)
PASS cqh unit resolves against appropriate container (vertical writing-mode on container)
FAIL cqi unit resolves against appropriate container (vertical writing-mode on container) assert_equals: expected "true" but got ""
FAIL cqb unit resolves against appropriate container (vertical writing-mode on container) assert_equals: expected "true" but got ""
PASS cqi unit resolves against appropriate container (vertical writing-mode on container)
PASS cqb unit resolves against appropriate container (vertical writing-mode on container)
PASS cqmin unit resolves against appropriate container (vertical writing-mode on container)
PASS cqmax unit resolves against appropriate container (vertical writing-mode on container)

@@ -1,5 +1,5 @@
Test

PASS Container units select the proper container
FAIL Units respond to the writing-mode of the element assert_equals: expected "40px" but got "30px"
PASS Units respond to the writing-mode of the element

44 changes: 27 additions & 17 deletions Source/WebCore/css/CSSPrimitiveValue.cpp
Expand Up @@ -777,16 +777,26 @@ double CSSPrimitiveValue::computeUnzoomedNonCalcLengthDouble(CSSUnitType primiti

double CSSPrimitiveValue::computeNonCalcLengthDouble(const CSSToLengthConversionData& conversionData, CSSUnitType primitiveType, double value)
{
auto selectContainerRenderer = [&](CQ::Axis axis) -> const RenderBox* {
auto resolveContainerUnit = [&](CQ::Axis physicalAxis) -> std::optional<double> {
ASSERT(physicalAxis == CQ::Axis::Width || physicalAxis == CQ::Axis::Height);

conversionData.setUsesContainerUnits();

auto* element = conversionData.elementForContainerUnitResolution();
if (!element)
return nullptr;
return { };

// FIXME: Use cached query containers when available.
auto* container = Style::ContainerQueryEvaluator::selectContainer(axis, nullString(), *element);
auto* container = Style::ContainerQueryEvaluator::selectContainer(physicalAxis, nullString(), *element);
if (!container)
return nullptr;
return dynamicDowncast<RenderBox>(container->renderer());
return { };

auto* containerRenderer = dynamicDowncast<RenderBox>(container->renderer());
if (!containerRenderer)
return { };

auto widthOrHeight = physicalAxis == CQ::Axis::Width ? containerRenderer->contentWidth() : containerRenderer->contentHeight();
return widthOrHeight * value / 100;
};

switch (primitiveType) {
Expand Down Expand Up @@ -904,27 +914,27 @@ double CSSPrimitiveValue::computeNonCalcLengthDouble(const CSSToLengthConversion
break;

case CSSUnitType::CSS_CQW: {
if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Width))
return containerRenderer->contentWidth() * value / 100;
return value * conversionData.smallViewportFactor().width();
if (auto resolvedValue = resolveContainerUnit(CQ::Axis::Width))
return *resolvedValue;
return computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_SVW, value);
}

case CSSUnitType::CSS_CQH: {
if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Height))
return containerRenderer->contentHeight() * value / 100;
return value * conversionData.smallViewportFactor().height();
if (auto resolvedValue = resolveContainerUnit(CQ::Axis::Height))
return *resolvedValue;
return computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_SVH, value);
}

case CSSUnitType::CSS_CQI: {
if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Inline))
return containerRenderer->contentLogicalWidth() * value / 100;
return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, conversionData.smallViewportFactor(), conversionData.rootStyle());
if (auto resolvedValue = resolveContainerUnit(conversionData.style()->isHorizontalWritingMode() ? CQ::Axis::Width : CQ::Axis::Height))
return *resolvedValue;
return computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_SVI, value);
}

case CSSUnitType::CSS_CQB: {
if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Block))
return containerRenderer->contentLogicalHeight() * value / 100;
return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, conversionData.smallViewportFactor(), conversionData.rootStyle());
if (auto resolvedValue = resolveContainerUnit(conversionData.style()->isHorizontalWritingMode() ? CQ::Axis::Height : CQ::Axis::Width))
return *resolvedValue;
return computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_SVB, value);
}

case CSSUnitType::CSS_CQMAX:
Expand Down

0 comments on commit b4d32d7

Please sign in to comment.