Changeset 289838 in webkit


Ignore:
Timestamp:
Feb 15, 2022 11:14:03 AM (5 months ago)
Author:
Antti Koivisto
Message:

[CSS Container Queries] Support all size features
https://bugs.webkit.org/show_bug.cgi?id=236640

Reviewed by Tim Nguyen and Sam Weinig.

LayoutTests/imported/w3c:

  • web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt:
  • web-platform-tests/css/css-contain/container-queries/query-content-box-expected.txt:
  • web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt:
  • web-platform-tests/css/css-contain/container-queries/unsupported-axis-expected.txt:

Source/WebCore:

Support inline-size, block-size, aspect-ratio and orientation in addition to the currently
supported width and height.

  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • css/ContainerQuery.cpp: Copied from Source/WebCore/css/ContainerQuery.h.

(WebCore::CQ::FeatureNames::width):
(WebCore::CQ::FeatureNames::height):
(WebCore::CQ::FeatureNames::inlineSize):
(WebCore::CQ::FeatureNames::blockSize):
(WebCore::CQ::FeatureNames::aspectRatio):
(WebCore::CQ::FeatureNames::orientation):

  • css/ContainerQuery.h:
  • css/ContainerQueryParser.cpp:

(WebCore::ContainerQueryParser::consumeSizeFeature):

Parse the new features.

  • css/parser/CSSPropertyParser.cpp:

(WebCore::consumeAspectRatio):

Use the new consumeAspectRatioValue helper.

  • css/parser/CSSPropertyParserHelpers.cpp:

(WebCore::CSSPropertyParserHelpers::consumeAspectRatioValue):

  • css/parser/CSSPropertyParserHelpers.h:
  • style/ContainerQueryEvaluator.cpp:

(WebCore::Style::computeSize):
(WebCore::Style::ContainerQueryEvaluator::evaluateSizeFeature const):

LayoutTests:

Location:
trunk
Files:
17 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r289834 r289838  
     12022-02-15  Antti Koivisto  <antti@apple.com>
     2
     3        [CSS Container Queries] Support all size features
     4        https://bugs.webkit.org/show_bug.cgi?id=236640
     5
     6        Reviewed by Tim Nguyen and Sam Weinig.
     7
     8        * TestExpectations:
     9
    1102022-02-15  Matteo Flores  <matteo_flores@apple.com>
    211
  • trunk/LayoutTests/TestExpectations

    r289810 r289838  
    47534753
    47544754# Container queries
    4755 webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/display-in-container.html [ ImageOnlyFailure ]
    47564755webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/pseudo-elements-002.tentative.html [ ImageOnlyFailure ]
    47574756
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r289813 r289838  
     12022-02-15  Antti Koivisto  <antti@apple.com>
     2
     3        [CSS Container Queries] Support all size features
     4        https://bugs.webkit.org/show_bug.cgi?id=236640
     5
     6        Reviewed by Tim Nguyen and Sam Weinig.
     7
     8        * web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt:
     9        * web-platform-tests/css/css-contain/container-queries/query-content-box-expected.txt:
     10        * web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt:
     11        * web-platform-tests/css/css-contain/container-queries/unsupported-axis-expected.txt:
     12
    1132022-02-15  Ziran Sun  <zsun@igalia.com>
    214
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/aspect-ratio-feature-evaluation-expected.txt

    r289222 r289838  
    11
    2 FAIL @container queries with aspect-ratio and size containment assert_equals: Should match for block-size containment expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
     2FAIL @container queries with aspect-ratio and size containment assert_equals: Should not match for inline-size containment expected "rgb(255, 0, 0)" but got "rgb(0, 128, 0)"
    33FAIL @container query with aspect-ratio change after resize assert_equals: Should match 2/1 min-ratio expected "rgb(0, 255, 0)" but got "rgba(0, 0, 0, 0)"
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt

    r289742 r289838  
    66PASS size(min-height: 0px)
    77PASS size(max-height: 0px)
    8 FAIL size(aspect-ratio) assert_equals: expected "true" but got ""
    9 FAIL size(min-aspect-ratio: 1/2) assert_equals: expected 2 but got 0
    10 FAIL size(max-aspect-ratio: 1/2) assert_equals: expected 2 but got 0
    11 FAIL size(orientation: portrait) assert_equals: expected 2 but got 0
    12 FAIL size(inline-size) assert_equals: expected "true" but got ""
    13 FAIL size(min-inline-size: 0px) assert_equals: expected "true" but got ""
    14 FAIL size(max-inline-size: 0px) assert_equals: expected "true" but got ""
    15 FAIL size(block-size) assert_equals: expected "true" but got ""
    16 FAIL size(min-block-size: 0px) assert_equals: expected "true" but got ""
    17 FAIL size(max-block-size: 0px) assert_equals: expected "true" but got ""
     8PASS size(aspect-ratio)
     9PASS size(min-aspect-ratio: 1/2)
     10PASS size(max-aspect-ratio: 1/2)
     11PASS size(orientation: portrait)
     12PASS size(inline-size)
     13PASS size(min-inline-size: 0px)
     14PASS size(max-inline-size: 0px)
     15PASS size(block-size)
     16PASS size(min-block-size: 0px)
     17PASS size(max-block-size: 0px)
    1818PASS size(width: 100px)
    1919PASS size((width: 100px))
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/query-content-box-expected.txt

    r289222 r289838  
    11
    2 FAIL Size queries with content-box sizing assert_equals: expected "rgb(0, 128, 0)" but got "rgba(0, 0, 0, 0)"
    3 FAIL Size queries with border-box sizing assert_equals: expected "rgb(0, 128, 0)" but got "rgba(0, 0, 0, 0)"
     2PASS Size queries with content-box sizing
     3PASS Size queries with border-box sizing
    44FAIL Size queries with content-box sizing and overflow:scroll assert_equals: expected "rgb(0, 128, 0)" but got "rgba(0, 0, 0, 0)"
    55FAIL Size queries with border-box sizing and overflow:scroll assert_equals: expected "rgb(0, 128, 0)" but got "rgba(0, 0, 0, 0)"
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt

    r289789 r289838  
    1414PASS size(max-height: 199px) (.horizontal)
    1515PASS size(inline-size < 100px) (.horizontal)
    16 FAIL size(inline-size >= 100px) (.horizontal) assert_equals: expected "true" but got ""
    17 FAIL size(min-inline-size: 100px) (.horizontal) assert_equals: expected "true" but got ""
     16PASS size(inline-size >= 100px) (.horizontal)
     17PASS size(min-inline-size: 100px) (.horizontal)
    1818PASS size(min-inline-size: 101px) (.horizontal)
    19 FAIL size(max-inline-size: 100px) (.horizontal) assert_equals: expected "true" but got ""
     19PASS size(max-inline-size: 100px) (.horizontal)
    2020PASS size(max-inline-size: 99px) (.horizontal)
    2121PASS size(block-size < 200px) (.horizontal)
    22 FAIL size(block-size >= 200px) (.horizontal) assert_equals: expected "true" but got ""
    23 FAIL size(min-block-size: 200px) (.horizontal) assert_equals: expected "true" but got ""
     22PASS size(block-size >= 200px) (.horizontal)
     23PASS size(min-block-size: 200px) (.horizontal)
    2424PASS size(min-block-size: 201px) (.horizontal)
    25 FAIL size(max-block-size: 200px) (.horizontal) assert_equals: expected "true" but got ""
     25PASS size(max-block-size: 200px) (.horizontal)
    2626PASS size(max-block-size: 199px) (.horizontal)
    2727PASS size(orientation: landscape) (.horizontal)
    28 FAIL size(orientation: portrait) (.horizontal) assert_equals: expected "true" but got ""
    29 FAIL size(aspect-ratio: 1/2) (.horizontal) assert_equals: expected "true" but got ""
     28PASS size(orientation: portrait) (.horizontal)
     29PASS size(aspect-ratio: 1/2) (.horizontal)
    3030PASS size(aspect-ratio: 2/1) (.horizontal)
    3131PASS size(width < 100px) (.vertical)
     
    4242PASS size(max-height: 199px) (.vertical)
    4343PASS size(block-size < 100px) (.vertical)
    44 FAIL size(block-size >= 100px) (.vertical) assert_equals: expected "true" but got ""
    45 FAIL size(min-block-size: 100px) (.vertical) assert_equals: expected "true" but got ""
     44PASS size(block-size >= 100px) (.vertical)
     45PASS size(min-block-size: 100px) (.vertical)
    4646PASS size(min-block-size: 101px) (.vertical)
    47 FAIL size(max-block-size: 100px) (.vertical) assert_equals: expected "true" but got ""
     47PASS size(max-block-size: 100px) (.vertical)
    4848PASS size(max-block-size: 99px) (.vertical)
    4949PASS size(inline-size < 200px) (.vertical)
    50 FAIL size(inline-size >= 200px) (.vertical) assert_equals: expected "true" but got ""
    51 FAIL size(min-inline-size: 200px) (.vertical) assert_equals: expected "true" but got ""
     50PASS size(inline-size >= 200px) (.vertical)
     51PASS size(min-inline-size: 200px) (.vertical)
    5252PASS size(min-inline-size: 201px) (.vertical)
    53 FAIL size(max-inline-size: 200px) (.vertical) assert_equals: expected "true" but got ""
     53PASS size(max-inline-size: 200px) (.vertical)
    5454PASS size(max-inline-size: 199px) (.vertical)
    5555PASS size(orientation: landscape) (.vertical)
    56 FAIL size(orientation: portrait) (.vertical) assert_equals: expected "true" but got ""
    57 FAIL size(aspect-ratio: 1/2) (.vertical) assert_equals: expected "true" but got ""
     56PASS size(orientation: portrait) (.vertical)
     57PASS size(aspect-ratio: 1/2) (.vertical)
    5858PASS size(aspect-ratio: 2/1) (.vertical)
    5959
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/unsupported-axis-expected.txt

    r289789 r289838  
    55PASS size((height > 0px) or (width > 0px))
    66PASS size((width > 0px) or (height > 0px))
    7 FAIL size((orientation: landscape) or (width > 0px)) assert_equals: expected "true" but got ""
    8 FAIL size((width > 0px) or (orientation: landscape)) assert_equals: expected "true" but got ""
    9 PASS size((height > 0px) or (orientation: landscape))
    10 PASS size((height > 0px) or (orientation: landscape)), with contain:size
    11 FAIL size(inline-size > 0px) assert_equals: expected "true" but got ""
    12 PASS size(block-size > 0px)
    13 PASS size(block-size > 0px), with writing-mode:vertical-rl
     7PASS size((orientation: landscape) or (width > 0px))
     8PASS size((width > 0px) or (orientation: landscape))
     9FAIL size((height > 0px) or (orientation: landscape)) assert_equals: expected "" but got "true"
     10FAIL size((height > 0px) or (orientation: landscape)), with contain:size assert_equals: expected "" but got "true"
     11PASS size(inline-size > 0px)
     12FAIL size(block-size > 0px) assert_equals: expected "" but got "true"
     13FAIL size(block-size > 0px), with writing-mode:vertical-rl assert_equals: expected "" but got "true"
    1414
  • trunk/Source/WebCore/ChangeLog

    r289818 r289838  
     12022-02-15  Antti Koivisto  <antti@apple.com>
     2
     3        [CSS Container Queries] Support all size features
     4        https://bugs.webkit.org/show_bug.cgi?id=236640
     5
     6        Reviewed by Tim Nguyen and Sam Weinig.
     7
     8        Support inline-size, block-size, aspect-ratio and orientation in addition to the currently
     9        supported width and height.
     10
     11        * Sources.txt:
     12        * WebCore.xcodeproj/project.pbxproj:
     13        * css/ContainerQuery.cpp: Copied from Source/WebCore/css/ContainerQuery.h.
     14        (WebCore::CQ::FeatureNames::width):
     15        (WebCore::CQ::FeatureNames::height):
     16        (WebCore::CQ::FeatureNames::inlineSize):
     17        (WebCore::CQ::FeatureNames::blockSize):
     18        (WebCore::CQ::FeatureNames::aspectRatio):
     19        (WebCore::CQ::FeatureNames::orientation):
     20        * css/ContainerQuery.h:
     21        * css/ContainerQueryParser.cpp:
     22        (WebCore::ContainerQueryParser::consumeSizeFeature):
     23
     24        Parse the new features.
     25
     26        * css/parser/CSSPropertyParser.cpp:
     27        (WebCore::consumeAspectRatio):
     28
     29        Use the new consumeAspectRatioValue helper.
     30
     31        * css/parser/CSSPropertyParserHelpers.cpp:
     32        (WebCore::CSSPropertyParserHelpers::consumeAspectRatioValue):
     33        * css/parser/CSSPropertyParserHelpers.h:
     34        * style/ContainerQueryEvaluator.cpp:
     35        (WebCore::Style::computeSize):
     36        (WebCore::Style::ContainerQueryEvaluator::evaluateSizeFeature const):
     37
    1382022-02-15  Megan Gardner  <megan_gardner@apple.com>
    239
  • trunk/Source/WebCore/Sources.txt

    r289790 r289838  
    705705crypto/keys/CryptoKeyRaw.cpp
    706706css/BasicShapeFunctions.cpp
     707css/ContainerQuery.cpp
    707708css/ContainerQueryParser.cpp
    708709css/CSSAspectRatioValue.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r289818 r289838  
    1761317613                E4F1573D27B93B4C00B330D8 /* ContainerQueryParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContainerQueryParser.h; sourceTree = "<group>"; };
    1761417614                E4F1573F27B93B5800B330D8 /* ContainerQueryParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ContainerQueryParser.cpp; sourceTree = "<group>"; };
     17615                E4F1574927BB93BE00B330D8 /* ContainerQuery.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ContainerQuery.cpp; sourceTree = "<group>"; };
    1761517616                E4F38D192626F13B007B1064 /* DefaultResourceLoadPriority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DefaultResourceLoadPriority.h; sourceTree = "<group>"; };
    1761617617                E4F38D1C2626F144007B1064 /* DefaultResourceLoadPriority.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DefaultResourceLoadPriority.cpp; sourceTree = "<group>"; };
     
    3159731598                                FBD6AF8415EF21D4008B7110 /* BasicShapeFunctions.cpp */,
    3159831599                                FBD6AF8515EF21D4008B7110 /* BasicShapeFunctions.h */,
     31600                                E4F1574927BB93BE00B330D8 /* ContainerQuery.cpp */,
    3159931601                                E4F1573227B6991F00B330D8 /* ContainerQuery.h */,
    3160031602                                E4F1573F27B93B5800B330D8 /* ContainerQueryParser.cpp */,
  • trunk/Source/WebCore/css/ContainerQuery.cpp

    r289837 r289838  
    2323 */
    2424
    25 #pragma once
     25#include "config.h"
     26#include "ContainerQuery.h"
    2627
    27 #include <wtf/text/AtomString.h>
     28#include <wtf/NeverDestroyed.h>
    2829
    29 namespace WebCore {
     30namespace WebCore::CQ::FeatureNames {
    3031
    31 class CSSPrimitiveValue;
     32const AtomString& width()
     33{
     34    static MainThreadNeverDestroyed<AtomString> name { "width"_s };
     35    return name;
     36}
    3237
    33 namespace CQ {
     38const AtomString& height()
     39{
     40    static MainThreadNeverDestroyed<AtomString> name { "height"_s };
     41    return name;
     42}
    3443
    35 struct ContainerCondition;
    36 struct SizeCondition;
    37 struct SizeFeature;
     44const AtomString& inlineSize()
     45{
     46    static MainThreadNeverDestroyed<AtomString> name { "inline-size"_s };
     47    return name;
     48}
    3849
    39 struct UnknownQuery { };
     50const AtomString& blockSize()
     51{
     52    static MainThreadNeverDestroyed<AtomString> name { "block-size"_s };
     53    return name;
     54}
    4055
    41 using SizeQuery = std::variant<SizeCondition, SizeFeature>;
    42 using ContainerQuery = std::variant<ContainerCondition, SizeQuery, UnknownQuery>;
     56const AtomString& aspectRatio()
     57{
     58    static MainThreadNeverDestroyed<AtomString> name { "aspect-ratio"_s };
     59    return name;
     60}
    4361
    44 enum class LogicalOperator : uint8_t { And, Or, Not };
    45 enum class ComparisonOperator : uint8_t { LessThan, LessThanOrEqual, Equal, GreaterThan, GreaterThanOrEqual, True };
    46 
    47 struct ContainerCondition {
    48     LogicalOperator logicalOperator { LogicalOperator::And };
    49     Vector<ContainerQuery> queries;
    50 };
    51 
    52 struct SizeCondition {
    53     LogicalOperator logicalOperator { LogicalOperator::And };
    54     Vector<SizeQuery> queries;
    55 };
    56 
    57 struct SizeFeature {
    58     ComparisonOperator comparisonOperator { ComparisonOperator::Equal };
    59     AtomString name;
    60     RefPtr<CSSPrimitiveValue> value;
    61 };
     62const AtomString& orientation()
     63{
     64    static MainThreadNeverDestroyed<AtomString> name { "orientation"_s };
     65    return name;
     66}
    6267
    6368}
    6469
    65 using ContainerQuery = CQ::ContainerQuery;
    66 
    67 struct FilteredContainerQuery {
    68     AtomString nameFilter;
    69     ContainerQuery query;
    70 };
    71 
    72 }
  • trunk/Source/WebCore/css/ContainerQuery.h

    r289742 r289838  
    2929namespace WebCore {
    3030
    31 class CSSPrimitiveValue;
     31class CSSValue;
    3232
    3333namespace CQ {
     
    5858    ComparisonOperator comparisonOperator { ComparisonOperator::Equal };
    5959    AtomString name;
    60     RefPtr<CSSPrimitiveValue> value;
     60    RefPtr<CSSValue> value;
     61};
     62
     63namespace FeatureNames {
     64const AtomString& width();
     65const AtomString& height();
     66const AtomString& inlineSize();
     67const AtomString& blockSize();
     68const AtomString& aspectRatio();
     69const AtomString& orientation();
    6170};
    6271
  • trunk/Source/WebCore/css/ContainerQueryParser.cpp

    r289789 r289838  
    211211    range.consumeWhitespace();
    212212
    213     auto length = CSSPropertyParserHelpers::consumeLength(range, m_context.mode, ValueRange::All);
    214     if (!length)
    215         return { };
    216 
    217     return CQ::SizeFeature { *op, name.toAtomString(), length };
    218 }
    219 
    220 }
     213    auto featureName = name.toAtomString();
     214
     215    auto consumeValue = [&]() -> RefPtr<CSSValue> {
     216        if (featureName == CQ::FeatureNames::orientation())
     217            return CSSPropertyParserHelpers::consumeIdent(range);
     218        if (featureName == CQ::FeatureNames::aspectRatio())
     219            return CSSPropertyParserHelpers::consumeAspectRatioValue(range);
     220        return CSSPropertyParserHelpers::consumeLength(range, m_context.mode, ValueRange::All);
     221    };
     222
     223    auto value = consumeValue();
     224
     225    return CQ::SizeFeature { *op, WTFMove(featureName), WTFMove(value) };
     226}
     227
     228}
  • trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp

    r289722 r289838  
    40094009
    40104010    if (range.atEnd())
    4011         return RefPtr<CSSValue>(WTFMove(autoValue));
    4012 
    4013     auto leftValue = consumeNumber(range, ValueRange::NonNegative);
    4014     if (!leftValue)
    4015         return nullptr;
    4016 
    4017     bool slashSeen = consumeSlashIncludingWhitespace(range);
    4018 
    4019     auto rightValue = consumeNumber(range, ValueRange::NonNegative);
    4020     if ((rightValue && !slashSeen) || (!rightValue && slashSeen))
    4021         return nullptr;
    4022     if (!slashSeen && !rightValue) // A missing right-hand is treated as 1.
    4023         rightValue = CSSValuePool::singleton().createValue(1, CSSUnitType::CSS_NUMBER);
     4011        return autoValue;
     4012
     4013    auto ratioList = consumeAspectRatioValue(range);
     4014    if (!ratioList)
     4015        return nullptr;
     4016
    40244017    if (!autoValue)
    40254018        autoValue = consumeIdent<CSSValueAuto>(range);
    40264019
    4027     auto ratioList = CSSValueList::createSlashSeparated();
    4028     ratioList->append(leftValue.releaseNonNull());
    4029     if (rightValue)
    4030         ratioList->append(rightValue.releaseNonNull());
    40314020    if (!autoValue)
    4032         return RefPtr<CSSValue>(WTFMove(ratioList));
     4021        return ratioList;
     4022
    40334023    auto list = CSSValueList::createSpaceSeparated();
    40344024    list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAuto));
    4035     list->append(ratioList);
    4036     return RefPtr<CSSValue>(WTFMove(list));
     4025    list->append(ratioList.releaseNonNull());
     4026
     4027    return list;
    40374028}
    40384029
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp

    r288675 r289838  
    45324532}
    45334533
     4534RefPtr<CSSValueList> consumeAspectRatioValue(CSSParserTokenRange& range)
     4535{
     4536    auto leftValue = consumeNumber(range, ValueRange::NonNegative);
     4537    if (!leftValue)
     4538        return nullptr;
     4539
     4540    bool slashSeen = consumeSlashIncludingWhitespace(range);
     4541    auto rightValue = slashSeen
     4542        ? consumeNumber(range, ValueRange::NonNegative)
     4543        : CSSValuePool::singleton().createValue(1, CSSUnitType::CSS_NUMBER);
     4544
     4545    if (!rightValue)
     4546        return nullptr;
     4547
     4548    auto ratioList = CSSValueList::createSlashSeparated();
     4549    ratioList->append(leftValue.releaseNonNull());
     4550    ratioList->append(rightValue.releaseNonNull());
     4551
     4552    return ratioList;
     4553}
     4554
    45344555} // namespace CSSPropertyParserHelpers
    45354556
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h

    r288675 r289838  
    214214bool isFontStyleAngleInRange(double angleInDegrees);
    215215
     216RefPtr<CSSValueList> consumeAspectRatioValue(CSSParserTokenRange&);
     217
    216218// Template and inline implementations are at the bottom of the file for readability.
    217219
     
    246248}
    247249
     250
    248251} // namespace CSSPropertyParserHelpers
    249252
  • trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp

    r289742 r289838  
    2626#include "ContainerQueryEvaluator.h"
    2727
     28#include "CSSPrimitiveValue.h"
    2829#include "CSSToLengthConversionData.h"
     30#include "CSSValueList.h"
    2931#include "Document.h"
    3032#include "MediaFeatureNames.h"
     
    4446    : m_containers(containers)
    4547{
    46 }
    47 
    48 static std::optional<LayoutUnit> computeSize(const CSSPrimitiveValue& value, const CSSToLengthConversionData& conversionData)
    49 {
    50     if (value.isNumberOrInteger()) {
    51         if (value.doubleValue())
    52             return { };
    53         return 0_lu;
    54     }
    55 
    56     if (!value.isLength())
    57         return { };
    58     return value.computeLength<LayoutUnit>(conversionData);
    5948}
    6049
     
    155144}
    156145
     146static std::optional<LayoutUnit> computeSize(const CSSValue* value, const CSSToLengthConversionData& conversionData)
     147{
     148    if (!is<CSSPrimitiveValue>(value))
     149        return { };
     150    auto& primitiveValue = downcast<CSSPrimitiveValue>(*value);
     151
     152    if (primitiveValue.isNumberOrInteger()) {
     153        if (primitiveValue.doubleValue())
     154            return { };
     155        return 0_lu;
     156    }
     157
     158    if (!primitiveValue.isLength())
     159        return { };
     160    return primitiveValue.computeLength<LayoutUnit>(conversionData);
     161}
     162
    157163auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFeature, const EvaluationContext& context) const -> EvaluationResult
    158164{
    159     auto evaluateSize = [&](LayoutUnit size) {
    160         std::optional<LayoutUnit> expressionSize;
    161 
    162         if (sizeFeature.comparisonOperator != CQ::ComparisonOperator::True) {
    163             if (!sizeFeature.value)
    164                 return false;
    165             expressionSize = computeSize(*sizeFeature.value, context.conversionData);
    166             if (!expressionSize)
    167                 return false;
    168         }
    169 
     165    auto toEvaluationResult = [](bool boolean) {
     166        return boolean ? EvaluationResult::True : EvaluationResult::False;
     167    };
     168
     169    auto compare = [&](auto left, auto right) {
    170170        switch (sizeFeature.comparisonOperator) {
    171171        case CQ::ComparisonOperator::LessThan:
    172             return size < *expressionSize;
     172            return left < right;
    173173        case CQ::ComparisonOperator::GreaterThan:
    174             return size > *expressionSize;
     174            return left > right;
    175175        case CQ::ComparisonOperator::LessThanOrEqual:
    176             return size <= *expressionSize;
     176            return left <= right;
    177177        case CQ::ComparisonOperator::GreaterThanOrEqual:
    178             return size >= *expressionSize;
     178            return left >= right;
    179179        case CQ::ComparisonOperator::Equal:
    180             return size == *expressionSize;
     180            return left == right;
    181181        case CQ::ComparisonOperator::True:
    182             return !!size;
    183         }
    184     };
    185 
    186     // FIXME: Support all features.
    187     if (sizeFeature.name == MediaFeatureNames::width)
    188         return evaluateSize(context.renderer.width()) ? EvaluationResult::True : EvaluationResult::False;
    189     if (sizeFeature.name == MediaFeatureNames::height)
    190         return evaluateSize(context.renderer.height()) ? EvaluationResult::True : EvaluationResult::False;
     182            ASSERT_NOT_REACHED();
     183            return false;
     184        }
     185    };
     186
     187    auto evaluateSize = [&](LayoutUnit size) {
     188        if (sizeFeature.comparisonOperator == CQ::ComparisonOperator::True)
     189            return toEvaluationResult(!!size);
     190
     191        auto expressionSize = computeSize(sizeFeature.value.get(), context.conversionData);
     192        if (!expressionSize)
     193            return EvaluationResult::Unknown;
     194
     195        return toEvaluationResult(compare(size, *expressionSize));
     196    };
     197
     198    if (sizeFeature.name == CQ::FeatureNames::width())
     199        return evaluateSize(context.renderer.contentWidth());
     200
     201    if (sizeFeature.name == CQ::FeatureNames::height())
     202        return evaluateSize(context.renderer.contentHeight());
     203
     204    if (sizeFeature.name == CQ::FeatureNames::inlineSize())
     205        return evaluateSize(context.renderer.contentLogicalWidth());
     206
     207    if (sizeFeature.name == CQ::FeatureNames::blockSize())
     208        return evaluateSize(context.renderer.contentLogicalHeight());
     209
     210    if (sizeFeature.name == CQ::FeatureNames::aspectRatio()) {
     211        auto boxRatio = context.renderer.contentWidth().toDouble() / context.renderer.contentHeight().toDouble();
     212        if (sizeFeature.comparisonOperator == CQ::ComparisonOperator::True)
     213            return toEvaluationResult(!!boxRatio);
     214
     215        if (!is<CSSValueList>(sizeFeature.value))
     216            return EvaluationResult::Unknown;
     217
     218        auto& ratioList = downcast<CSSValueList>(*sizeFeature.value);
     219        if (ratioList.length() != 2)
     220            return EvaluationResult::Unknown;
     221
     222        auto first = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(0));
     223        auto second = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(1));
     224
     225        if (!first || !second || !first->isNumberOrInteger() || !second->isNumberOrInteger())
     226            return EvaluationResult::Unknown;
     227
     228        auto expressionRatio = first->doubleValue() / second->doubleValue();
     229
     230        return toEvaluationResult(compare(boxRatio, expressionRatio));
     231    }
     232
     233    if (sizeFeature.name == CQ::FeatureNames::orientation()) {
     234        if (!is<CSSPrimitiveValue>(sizeFeature.value) || sizeFeature.comparisonOperator != CQ::ComparisonOperator::Equal)
     235            return EvaluationResult::Unknown;
     236
     237        auto& value = downcast<CSSPrimitiveValue>(*sizeFeature.value);
     238
     239        bool isPortrait = context.renderer.contentHeight() >= context.renderer.contentWidth();
     240        if (value.valueID() == CSSValuePortrait)
     241            return toEvaluationResult(isPortrait);
     242        if (value.valueID() == CSSValueLandscape)
     243            return toEvaluationResult(!isPortrait);
     244
     245        return EvaluationResult::Unknown;
     246    }
    191247
    192248    return EvaluationResult::Unknown;
Note: See TracChangeset for help on using the changeset viewer.