| Differences between
and this patch
- a/Source/WebCore/ChangeLog +43 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2022-02-14  Antti Koivisto  <antti@apple.com>
2
3
        [CSS Container Queries] Implement full query parser and evaluator
4
        https://bugs.webkit.org/show_bug.cgi?id=236580
5
6
        Reviewed by Sam Weinig.
7
8
        So far we have been using the media query parser to parse container queries.
9
        It does not support nesting and other necessary features. Also the produced data
10
        structures are awkward to evaluate.
11
12
        https://drafts.csswg.org/css-contain-3/#container-rule
13
14
        This patch supports size queries but not style queries. It supports both the current spec
15
        size query syntax "size(foo)" (used in WPTs), and the non-function POR syntax from
16
        https://github.com/w3c/csswg-drafts/issues/6870#issuecomment-1022430911.
17
18
        * Sources.txt:
19
        * WebCore.xcodeproj/project.pbxproj:
20
        * css/ContainerQuery.h:
21
        * css/ContainerQueryParser.cpp: Added.
22
        (WebCore::ContainerQueryParser::parse):
23
        (WebCore::ContainerQueryParser::consumeContainerQuery):
24
        (WebCore::ContainerQueryParser::consumeCondition):
25
        (WebCore::ContainerQueryParser::consumeSizeQuery):
26
27
        No support for range operators ('<' etc) yet.
28
29
        * css/ContainerQueryParser.h: Copied from Source/WebCore/css/ContainerQuery.h.
30
        (WebCore::ContainerQueryParser::ContainerQueryParser):
31
        * css/parser/CSSParserImpl.cpp:
32
        (WebCore::CSSParserImpl::consumeContainerRule):
33
        * style/ContainerQueryEvaluator.cpp:
34
        (WebCore::Style::computeSize):
35
        (WebCore::Style::ContainerQueryEvaluator::evaluate const):
36
        (WebCore::Style::ContainerQueryEvaluator::evaluateQuery const):
37
        (WebCore::Style::ContainerQueryEvaluator::evaluateCondition const):
38
        (WebCore::Style::ContainerQueryEvaluator::evaluateSizeFeature const):
39
40
        Just 'width' and 'height' for now, no new size features yet.
41
42
        * style/ContainerQueryEvaluator.h:
43
1
2022-02-13  Antti Koivisto  <antti@apple.com>
44
2022-02-13  Antti Koivisto  <antti@apple.com>
2
45
3
        [CSS Container Queries] Add separate ContainerQuery and FilteredContainerQuery types
46
        [CSS Container Queries] Add separate ContainerQuery and FilteredContainerQuery types
- a/Source/WebCore/Sources.txt +1 lines
Lines 704-709 crypto/keys/CryptoKeyRSA.cpp a/Source/WebCore/Sources.txt_sec1
704
crypto/keys/CryptoKeyRSAComponents.cpp
704
crypto/keys/CryptoKeyRSAComponents.cpp
705
crypto/keys/CryptoKeyRaw.cpp
705
crypto/keys/CryptoKeyRaw.cpp
706
css/BasicShapeFunctions.cpp
706
css/BasicShapeFunctions.cpp
707
css/ContainerQueryParser.cpp
707
css/CSSAspectRatioValue.cpp
708
css/CSSAspectRatioValue.cpp
708
css/CSSBasicShapes.cpp
709
css/CSSBasicShapes.cpp
709
css/CSSBorderImage.cpp
710
css/CSSBorderImage.cpp
- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj -1 / +7 lines
Lines 5429-5434 a/Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec1
5429
		E4ED3ECC2768A51D00F17AC8 /* HasSelectorFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = E4ED3ECA2768A51C00F17AC8 /* HasSelectorFilter.h */; };
5429
		E4ED3ECC2768A51D00F17AC8 /* HasSelectorFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = E4ED3ECA2768A51C00F17AC8 /* HasSelectorFilter.h */; };
5430
		E4F0BE3125712F6E009E7431 /* CaretRectComputation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */; };
5430
		E4F0BE3125712F6E009E7431 /* CaretRectComputation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */; };
5431
		E4F1573927B9261500B330D8 /* ContainerQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F1573227B6991F00B330D8 /* ContainerQuery.h */; settings = {ATTRIBUTES = (Private, ); }; };
5431
		E4F1573927B9261500B330D8 /* ContainerQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F1573227B6991F00B330D8 /* ContainerQuery.h */; settings = {ATTRIBUTES = (Private, ); }; };
5432
		E4F1574127B93B7700B330D8 /* ContainerQueryParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F1573D27B93B4C00B330D8 /* ContainerQueryParser.h */; };
5432
		E4F38D1B2626F13B007B1064 /* DefaultResourceLoadPriority.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F38D192626F13B007B1064 /* DefaultResourceLoadPriority.h */; };
5433
		E4F38D1B2626F13B007B1064 /* DefaultResourceLoadPriority.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F38D192626F13B007B1064 /* DefaultResourceLoadPriority.h */; };
5433
		E4F819C626FB4EBF0094E162 /* InlineBoxPainter.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F819C526FB4EBF0094E162 /* InlineBoxPainter.h */; };
5434
		E4F819C626FB4EBF0094E162 /* InlineBoxPainter.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F819C526FB4EBF0094E162 /* InlineBoxPainter.h */; };
5434
		E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
5435
		E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
Lines 17611-17616 a/Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec2
17611
		E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CaretRectComputation.h; sourceTree = "<group>"; };
17612
		E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CaretRectComputation.h; sourceTree = "<group>"; };
17612
		E4F0BE3025710A76009E7431 /* CaretRectComputation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CaretRectComputation.cpp; sourceTree = "<group>"; };
17613
		E4F0BE3025710A76009E7431 /* CaretRectComputation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CaretRectComputation.cpp; sourceTree = "<group>"; };
17613
		E4F1573227B6991F00B330D8 /* ContainerQuery.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContainerQuery.h; sourceTree = "<group>"; };
17614
		E4F1573227B6991F00B330D8 /* ContainerQuery.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContainerQuery.h; sourceTree = "<group>"; };
17615
		E4F1573D27B93B4C00B330D8 /* ContainerQueryParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContainerQueryParser.h; sourceTree = "<group>"; };
17616
		E4F1573F27B93B5800B330D8 /* ContainerQueryParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ContainerQueryParser.cpp; sourceTree = "<group>"; };
17614
		E4F38D192626F13B007B1064 /* DefaultResourceLoadPriority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DefaultResourceLoadPriority.h; sourceTree = "<group>"; };
17617
		E4F38D192626F13B007B1064 /* DefaultResourceLoadPriority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DefaultResourceLoadPriority.h; sourceTree = "<group>"; };
17615
		E4F38D1C2626F144007B1064 /* DefaultResourceLoadPriority.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DefaultResourceLoadPriority.cpp; sourceTree = "<group>"; };
17618
		E4F38D1C2626F144007B1064 /* DefaultResourceLoadPriority.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DefaultResourceLoadPriority.cpp; sourceTree = "<group>"; };
17616
		E4F819C226FB4EAF0094E162 /* InlineBoxPainter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineBoxPainter.cpp; sourceTree = "<group>"; };
17619
		E4F819C226FB4EAF0094E162 /* InlineBoxPainter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineBoxPainter.cpp; sourceTree = "<group>"; };
Lines 31596-31601 a/Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec3
31596
				FBD6AF8415EF21D4008B7110 /* BasicShapeFunctions.cpp */,
31599
				FBD6AF8415EF21D4008B7110 /* BasicShapeFunctions.cpp */,
31597
				FBD6AF8515EF21D4008B7110 /* BasicShapeFunctions.h */,
31600
				FBD6AF8515EF21D4008B7110 /* BasicShapeFunctions.h */,
31598
				E4F1573227B6991F00B330D8 /* ContainerQuery.h */,
31601
				E4F1573227B6991F00B330D8 /* ContainerQuery.h */,
31602
				E4F1573F27B93B5800B330D8 /* ContainerQueryParser.cpp */,
31603
				E4F1573D27B93B4C00B330D8 /* ContainerQueryParser.h */,
31599
				A80E6CDA0A1989CA007FB8C5 /* Counter.h */,
31604
				A80E6CDA0A1989CA007FB8C5 /* Counter.h */,
31600
				CAE9F90D146441F000C245B0 /* CSSAspectRatioValue.cpp */,
31605
				CAE9F90D146441F000C245B0 /* CSSAspectRatioValue.cpp */,
31601
				CAE9F90E146441F000C245B0 /* CSSAspectRatioValue.h */,
31606
				CAE9F90E146441F000C245B0 /* CSSAspectRatioValue.h */,
Lines 33871-33877 a/Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec4
33871
				E596DD352519041400C275A7 /* ContactsSelectOptions.h in Headers */,
33876
				E596DD352519041400C275A7 /* ContactsSelectOptions.h in Headers */,
33872
				A818721C0977D3C0005826D9 /* ContainerNode.h in Headers */,
33877
				A818721C0977D3C0005826D9 /* ContainerNode.h in Headers */,
33873
				E1A1470811102B1500EEC0F3 /* ContainerNodeAlgorithms.h in Headers */,
33878
				E1A1470811102B1500EEC0F3 /* ContainerNodeAlgorithms.h in Headers */,
33879
				E4F1573927B9261500B330D8 /* ContainerQuery.h in Headers */,
33874
				E4AAB38727AA95D7009F5899 /* ContainerQueryEvaluator.h in Headers */,
33880
				E4AAB38727AA95D7009F5899 /* ContainerQueryEvaluator.h in Headers */,
33881
				E4F1574127B93B7700B330D8 /* ContainerQueryParser.h in Headers */,
33875
				6FB5E214221F2453003989CF /* ContentChangeObserver.h in Headers */,
33882
				6FB5E214221F2453003989CF /* ContentChangeObserver.h in Headers */,
33876
				BC5EB9810E82072500B25965 /* ContentData.h in Headers */,
33883
				BC5EB9810E82072500B25965 /* ContentData.h in Headers */,
33877
				51B45D211AB8D1E200117CD2 /* ContentExtension.h in Headers */,
33884
				51B45D211AB8D1E200117CD2 /* ContentExtension.h in Headers */,
Lines 37188-37194 a/Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec5
37188
				E45322AC140CE267005A0F92 /* SelectorQuery.h in Headers */,
37195
				E45322AC140CE267005A0F92 /* SelectorQuery.h in Headers */,
37189
				F4D43D662188038B00ECECAC /* SerializedAttachmentData.h in Headers */,
37196
				F4D43D662188038B00ECECAC /* SerializedAttachmentData.h in Headers */,
37190
				E18DF33518AAF12C00773E59 /* SerializedCryptoKeyWrap.h in Headers */,
37197
				E18DF33518AAF12C00773E59 /* SerializedCryptoKeyWrap.h in Headers */,
37191
				E4F1573927B9261500B330D8 /* ContainerQuery.h in Headers */,
37192
				077AF14018F4AE400001ED61 /* SerializedPlatformDataCue.h in Headers */,
37198
				077AF14018F4AE400001ED61 /* SerializedPlatformDataCue.h in Headers */,
37193
				077AF14318F4B1BB0001ED61 /* SerializedPlatformDataCueMac.h in Headers */,
37199
				077AF14318F4B1BB0001ED61 /* SerializedPlatformDataCueMac.h in Headers */,
37194
				076D1C1F23F6EB5B00D95B06 /* SerializedPlatformDataCueValue.h in Headers */,
37200
				076D1C1F23F6EB5B00D95B06 /* SerializedPlatformDataCueValue.h in Headers */,
- a/Source/WebCore/css/CSSValueKeywords.in +5 lines
Lines 1641-1643 ray a/Source/WebCore/css/CSSValueKeywords.in_sec1
1641
// farthest-corner
1641
// farthest-corner
1642
sides
1642
sides
1643
// contain
1643
// contain
1644
1645
// for @media/@supports/@container
1646
and
1647
or
1648
not
- a/Source/WebCore/css/ContainerQuery.h -3 / +35 lines
Lines 28-40 a/Source/WebCore/css/ContainerQuery.h_sec1
28
28
29
namespace WebCore {
29
namespace WebCore {
30
30
31
class MediaQuerySet;
31
class CSSPrimitiveValue;
32
32
33
using ContainerQuery = MediaQuerySet;
33
namespace CQ {
34
35
struct ContainerCondition;
36
struct SizeCondition;
37
struct SizeFeature;
38
39
struct UnknownQuery { };
40
41
using SizeQuery = std::variant<SizeCondition, SizeFeature>;
42
using ContainerQuery = std::variant<ContainerCondition, SizeQuery, UnknownQuery>;
43
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
};
62
63
}
64
65
using ContainerQuery = CQ::ContainerQuery;
34
66
35
struct FilteredContainerQuery {
67
struct FilteredContainerQuery {
36
    AtomString nameFilter;
68
    AtomString nameFilter;
37
    Ref<ContainerQuery> query;
69
    ContainerQuery query;
38
};
70
};
39
71
40
}
72
}
- a/Source/WebCore/css/ContainerQueryParser.cpp +177 lines
Line 0 a/Source/WebCore/css/ContainerQueryParser.cpp_sec1
1
/*
2
 * Copyright (C) 2022 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
25
#include "config.h"
26
#include "ContainerQueryParser.h"
27
28
#include "CSSPrimitiveValue.h"
29
#include "CSSPropertyParserHelpers.h"
30
31
namespace WebCore {
32
33
std::optional<ContainerQuery> ContainerQueryParser::consumeContainerQuery(CSSParserTokenRange& range, const CSSParserContext& context)
34
{
35
    ContainerQueryParser parser(context);
36
    return parser.consumeContainerQuery(range);
37
}
38
39
std::optional<CQ::ContainerQuery> ContainerQueryParser::consumeContainerQuery(CSSParserTokenRange& range)
40
{
41
    if (range.peek().type() == FunctionToken) {
42
        bool isSizeQuery = range.peek().functionId() == CSSValueSize;
43
44
        auto blockRange = range.consumeBlock();
45
        blockRange.consumeWhitespace();
46
47
        if (!isSizeQuery)
48
            return CQ::UnknownQuery { };
49
50
        auto sizeQuery = consumeSizeQuery(blockRange);
51
        if (!sizeQuery)
52
            return { };
53
        return { *sizeQuery };
54
    }
55
56
    if (range.peek().type() == LeftParenthesisToken) {
57
        auto blockRange = range.consumeBlock();
58
        range.consumeWhitespace();
59
60
        blockRange.consumeWhitespace();
61
62
        // Try to parse as a size query first.
63
        auto blockForSizeQuery = blockRange;
64
        if (auto sizeQuery = consumeSizeQuery(blockForSizeQuery))
65
            return { *sizeQuery };
66
67
        if (auto condition = consumeCondition<CQ::ContainerCondition>(blockRange))
68
            return { condition };
69
    }
70
71
    return { };
72
}
73
74
template<typename ConditionType>
75
std::optional<ConditionType> ContainerQueryParser::consumeCondition(CSSParserTokenRange& range)
76
{
77
    auto consumeQuery = [&](CSSParserTokenRange& range) {
78
        if constexpr (std::is_same_v<CQ::ContainerCondition, ConditionType>)
79
            return consumeContainerQuery(range);
80
        if constexpr (std::is_same_v<CQ::SizeCondition, ConditionType>) {
81
            if (range.peek().type() != LeftParenthesisToken)
82
                return std::optional<CQ::SizeQuery>();
83
            auto blockRange = range.consumeBlock();
84
            return consumeSizeQuery(blockRange);
85
        }
86
    };
87
88
    if (range.peek().type() == IdentToken) {
89
        if (range.peek().id() == CSSValueNot) {
90
            range.consumeIncludingWhitespace();
91
            if (auto query = consumeQuery(range))
92
                return ConditionType { CQ::LogicalOperator::Not, { *query } };
93
            return { };
94
        }
95
    }
96
97
    ConditionType condition;
98
99
    auto query = consumeQuery(range);
100
    if (!query)
101
        return { };
102
103
    condition.queries.append(*query);
104
    range.consumeWhitespace();
105
106
    auto consumeOperator = [&]() -> std::optional<CQ::LogicalOperator> {
107
        auto operatorToken = range.consumeIncludingWhitespace();
108
        if (operatorToken.type() != IdentToken)
109
            return { };
110
        if (operatorToken.id() == CSSValueAnd)
111
            return CQ::LogicalOperator::And;
112
        if (operatorToken.id() == CSSValueOr)
113
            return CQ::LogicalOperator::Or;
114
        return { };
115
    };
116
117
    while (!range.atEnd()) {
118
        auto op = consumeOperator();
119
        if (!op)
120
            return { };
121
        if (condition.queries.size() > 1 && condition.logicalOperator != *op)
122
            return { };
123
124
        condition.logicalOperator = *op;
125
126
        auto query = consumeQuery(range);
127
        if (!query)
128
            return { };
129
130
        condition.queries.append(*query);
131
        range.consumeWhitespace();
132
    }
133
134
    return condition;
135
}
136
137
std::optional<CQ::SizeQuery> ContainerQueryParser::consumeSizeQuery(CSSParserTokenRange& range)
138
{
139
    if (range.peek().type() != IdentToken || range.peek().id() == CSSValueNot) {
140
        auto sizeCondition = consumeCondition<CQ::SizeCondition>(range);
141
        if (!sizeCondition)
142
            return { };
143
        return { *sizeCondition };
144
    }
145
146
    auto nameToken = range.consumeIncludingWhitespace();
147
    auto name = nameToken.value();
148
149
    if (range.atEnd())
150
        return CQ::SizeFeature { CQ::ComparisonOperator::True, name.toAtomString(), { } };
151
152
    auto opToken = range.consumeIncludingWhitespace();
153
    if (range.atEnd())
154
        return { };
155
156
    // FIXME: Support '<' style operators and ranges.
157
    auto op = CQ::ComparisonOperator::Equal;
158
    if (opToken.type() == ColonToken) {
159
        if (name.startsWith("min-"))
160
            op = CQ::ComparisonOperator::GreaterThanOrEqual;
161
        else if (name.startsWith("max-"))
162
            op = CQ::ComparisonOperator::LessThanOrEqual;
163
164
        if (op != CQ::ComparisonOperator::Equal)
165
            name = name.substring(4);
166
        if (name.isEmpty())
167
            return { };
168
    }
169
170
    auto length = CSSPropertyParserHelpers::consumeLength(range, m_context.mode, ValueRange::All);
171
    if (!length)
172
        return { };
173
174
    return CQ::SizeFeature { op, name.toAtomString(), length };
175
}
176
177
}
- a/Source/WebCore/css/ContainerQueryParser.h +47 lines
Line 0 a/Source/WebCore/css/ContainerQueryParser.h_sec1
1
/*
2
 * Copyright (C) 2022 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
25
#pragma once
26
27
#include "CSSParserToken.h"
28
#include "ContainerQuery.h"
29
30
namespace WebCore {
31
32
class ContainerQueryParser {
33
public:
34
    static std::optional<ContainerQuery> consumeContainerQuery(CSSParserTokenRange&, const CSSParserContext&);
35
36
private:
37
    std::optional<CQ::ContainerQuery> consumeContainerQuery(CSSParserTokenRange&);
38
    std::optional<CQ::SizeQuery> consumeSizeQuery(CSSParserTokenRange&);
39
    template<typename ConditionType> std::optional<ConditionType> consumeCondition(CSSParserTokenRange&);
40
41
    ContainerQueryParser(const CSSParserContext& context)
42
        : m_context(context) { }
43
44
    const CSSParserContext m_context;
45
};
46
47
}
- a/Source/WebCore/css/parser/CSSParserImpl.cpp -3 / +8 lines
Lines 47-52 a/Source/WebCore/css/parser/CSSParserImpl.cpp_sec1
47
#include "CSSSupportsParser.h"
47
#include "CSSSupportsParser.h"
48
#include "CSSTokenizer.h"
48
#include "CSSTokenizer.h"
49
#include "CSSVariableParser.h"
49
#include "CSSVariableParser.h"
50
#include "ContainerQueryParser.h"
50
#include "Document.h"
51
#include "Document.h"
51
#include "Element.h"
52
#include "Element.h"
52
#include "FontPaletteValues.h"
53
#include "FontPaletteValues.h"
Lines 865-876 RefPtr<StyleRuleContainer> CSSParserImpl::consumeContainerRule(CSSParserTokenRan a/Source/WebCore/css/parser/CSSParserImpl.cpp_sec2
865
866
866
    auto name = consumeName();
867
    auto name = consumeName();
867
868
868
    auto query = MediaQueryParser::parseContainerQuery(prelude, MediaQueryParserContext(m_context));
869
    auto query = ContainerQueryParser::consumeContainerQuery(prelude, m_context);
869
    if (!query)
870
    if (!query)
870
        return nullptr;
871
        return nullptr;
871
872
873
    prelude.consumeWhitespace();
874
    if (!prelude.atEnd())
875
        return nullptr;
876
872
    if (m_deferredParser)
877
    if (m_deferredParser)
873
        return StyleRuleContainer::create({ name, query.releaseNonNull() }, makeUnique<DeferredStyleGroupRuleList>(block, *m_deferredParser));
878
        return StyleRuleContainer::create({ name, *query }, makeUnique<DeferredStyleGroupRuleList>(block, *m_deferredParser));
874
879
875
    Vector<RefPtr<StyleRuleBase>> rules;
880
    Vector<RefPtr<StyleRuleBase>> rules;
876
881
Lines 888-894 RefPtr<StyleRuleContainer> CSSParserImpl::consumeContainerRule(CSSParserTokenRan a/Source/WebCore/css/parser/CSSParserImpl.cpp_sec3
888
    if (m_observerWrapper)
893
    if (m_observerWrapper)
889
        m_observerWrapper->observer().endRuleBody(m_observerWrapper->endOffset(block));
894
        m_observerWrapper->observer().endRuleBody(m_observerWrapper->endOffset(block));
890
895
891
    return StyleRuleContainer::create({ name, query.releaseNonNull() }, WTFMove(rules));
896
    return StyleRuleContainer::create({ name, *query }, WTFMove(rules));
892
}
897
}
893
    
898
    
894
RefPtr<StyleRuleKeyframe> CSSParserImpl::consumeKeyframeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
899
RefPtr<StyleRuleKeyframe> CSSParserImpl::consumeKeyframeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
- a/Source/WebCore/style/ContainerQueryEvaluator.cpp -78 / +101 lines
Lines 35-64 a/Source/WebCore/style/ContainerQueryEvaluator.cpp_sec1
35
35
36
namespace WebCore::Style {
36
namespace WebCore::Style {
37
37
38
struct ContainerQueryEvaluator::EvaluationContext {
39
    RenderBox& renderer;
40
    CSSToLengthConversionData conversionData;
41
};
42
38
ContainerQueryEvaluator::ContainerQueryEvaluator(const Vector<Ref<const Element>>& containers)
43
ContainerQueryEvaluator::ContainerQueryEvaluator(const Vector<Ref<const Element>>& containers)
39
    : m_containers(containers)
44
    : m_containers(containers)
40
{
45
{
41
}
46
}
42
47
43
static std::optional<LayoutUnit> computeSize(CSSValue* value, const CSSToLengthConversionData& conversionData)
48
static std::optional<LayoutUnit> computeSize(const CSSPrimitiveValue& value, const CSSToLengthConversionData& conversionData)
44
{
49
{
45
    if (!is<CSSPrimitiveValue>(value))
50
    if (value.isNumberOrInteger()) {
46
        return { };
51
        if (value.doubleValue())
47
48
    auto& primitiveValue = downcast<CSSPrimitiveValue>(*value);
49
    if (primitiveValue.isNumberOrInteger()) {
50
        if (primitiveValue.doubleValue())
51
            return { };
52
            return { };
52
        return 0_lu;
53
        return 0_lu;
53
    }
54
    }
54
55
55
    if (!primitiveValue.isLength())
56
    if (!value.isLength())
56
        return { };
57
        return { };
57
    return primitiveValue.computeLength<LayoutUnit>(conversionData);
58
    return value.computeLength<LayoutUnit>(conversionData);
58
}
59
}
59
60
60
enum class Comparator { Lesser, Greater, LesserOrEqual, GreaterOrEqual, Equal, True };
61
62
bool ContainerQueryEvaluator::evaluate(const FilteredContainerQuery& filteredContainerQuery) const
61
bool ContainerQueryEvaluator::evaluate(const FilteredContainerQuery& filteredContainerQuery) const
63
{
62
{
64
    if (m_containers.isEmpty())
63
    if (m_containers.isEmpty())
Lines 83-172 bool ContainerQueryEvaluator::evaluate(const FilteredContainerQuery& filteredCon a/Source/WebCore/style/ContainerQueryEvaluator.cpp_sec2
83
        return false;
82
        return false;
84
83
85
    auto& view = renderer->view();
84
    auto& view = renderer->view();
86
    CSSToLengthConversionData conversionData { &renderer->style(), &view.style(), nullptr, &view, 1 };
85
    CSSToLengthConversionData { &renderer->style(), &view.style(), nullptr, &view, 1 };
87
86
88
    auto evaluateSize = [&](const MediaQueryExpression& expression, Comparator comparator, auto&& sizeGetter)
87
    EvaluationContext evaluationContext {
89
    {
88
        *renderer,
89
        CSSToLengthConversionData { &renderer->style(), &view.style(), nullptr, &view, 1 }
90
    };
91
92
    return evaluateQuery(filteredContainerQuery.query, evaluationContext) == EvaluationResult::True;
93
}
94
95
auto ContainerQueryEvaluator::evaluateQuery(const CQ::ContainerQuery& containerQuery, const EvaluationContext& context) const -> EvaluationResult
96
{
97
    return WTF::switchOn(containerQuery, [&](const CQ::ContainerCondition& containerCondition) {
98
        return evaluateCondition(containerCondition, context);
99
    }, [&](const CQ::SizeQuery& sizeQuery) {
100
        return evaluateQuery(sizeQuery, context);
101
    }, [&](const CQ::UnknownQuery&) {
102
        return EvaluationResult::Unknown;
103
    });
104
}
105
106
auto ContainerQueryEvaluator::evaluateQuery(const CQ::SizeQuery& sizeQuery, const EvaluationContext& context) const -> EvaluationResult
107
{
108
    return WTF::switchOn(sizeQuery, [&](const CQ::SizeCondition& sizeCondition) {
109
        return evaluateCondition(sizeCondition, context);
110
    }, [&](const CQ::SizeFeature& sizeFeature) {
111
        return evaluateSizeFeature(sizeFeature, context);
112
    });
113
}
114
115
template<typename ConditionType>
116
auto ContainerQueryEvaluator::evaluateCondition(const ConditionType& condition, const EvaluationContext& context) const -> EvaluationResult
117
{
118
    if (condition.queries.isEmpty())
119
        return EvaluationResult::Unknown;
120
121
    switch (condition.logicalOperator) {
122
    case CQ::LogicalOperator::Not: {
123
        switch (evaluateQuery(condition.queries.first(), context)) {
124
        case EvaluationResult::True:
125
            return EvaluationResult::False;
126
        case EvaluationResult::False:
127
            return EvaluationResult::True;
128
        case EvaluationResult::Unknown:
129
            return EvaluationResult::Unknown;
130
        }
131
    }
132
    case CQ::LogicalOperator::And: {
133
        auto result = EvaluationResult::True;
134
        for (auto query : condition.queries) {
135
            auto queryResult = evaluateQuery(query, context);
136
            if (queryResult == EvaluationResult::False)
137
                return EvaluationResult::False;
138
            if (queryResult == EvaluationResult::Unknown)
139
                result = EvaluationResult::Unknown;
140
        }
141
        return result;
142
    }
143
    case CQ::LogicalOperator::Or: {
144
        auto result = EvaluationResult::False;
145
        for (auto query : condition.queries) {
146
            auto queryResult = evaluateQuery(query, context);
147
            if (queryResult == EvaluationResult::True)
148
                return EvaluationResult::True;
149
            if (queryResult == EvaluationResult::Unknown)
150
                result = EvaluationResult::Unknown;
151
        }
152
        return result;
153
    }
154
    }
155
}
156
157
auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFeature, const EvaluationContext& context) const -> EvaluationResult
158
{
159
    auto evaluateSize = [&](LayoutUnit size) {
90
        std::optional<LayoutUnit> expressionSize;
160
        std::optional<LayoutUnit> expressionSize;
91
161
92
        if (comparator != Comparator::True) {
162
        if (sizeFeature.comparisonOperator != CQ::ComparisonOperator::True) {
93
            expressionSize = computeSize(expression.value(), conversionData);
163
            if (!sizeFeature.value)
164
                return false;
165
            expressionSize = computeSize(*sizeFeature.value, context.conversionData);
94
            if (!expressionSize)
166
            if (!expressionSize)
95
                return false;
167
                return false;
96
        }
168
        }
97
169
98
        auto size = sizeGetter(*renderer);
170
        switch (sizeFeature.comparisonOperator) {
99
171
        case CQ::ComparisonOperator::LessThan:
100
        switch (comparator) {
101
        case Comparator::Lesser:
102
            return size < *expressionSize;
172
            return size < *expressionSize;
103
        case Comparator::Greater:
173
        case CQ::ComparisonOperator::GreaterThan:
104
            return size > *expressionSize;
174
            return size > *expressionSize;
105
        case Comparator::LesserOrEqual:
175
        case CQ::ComparisonOperator::LessThanOrEqual:
106
            return size <= *expressionSize;
176
            return size <= *expressionSize;
107
        case Comparator::GreaterOrEqual:
177
        case CQ::ComparisonOperator::GreaterThanOrEqual:
108
            return size >= *expressionSize;
178
            return size >= *expressionSize;
109
        case Comparator::Equal:
179
        case CQ::ComparisonOperator::Equal:
110
            return size == *expressionSize;
180
            return size == *expressionSize;
111
        case Comparator::True:
181
        case CQ::ComparisonOperator::True:
112
            return !!size;
182
            return !!size;
113
        }
183
        }
114
    };
184
    };
115
185
116
    auto evaluateWidth = [&](const MediaQueryExpression& expression, Comparator comparator)
186
    // FIXME: Support all features.
117
    {
187
    if (sizeFeature.name == MediaFeatureNames::width)
118
        return evaluateSize(expression, comparator, [&](const RenderBox& renderer) {
188
        return evaluateSize(context.renderer.width()) ? EvaluationResult::True : EvaluationResult::False;
119
            return renderer.width();
189
    if (sizeFeature.name == MediaFeatureNames::height)
120
        });
190
        return evaluateSize(context.renderer.height()) ? EvaluationResult::True : EvaluationResult::False;
121
    };
122
123
    auto evaluateHeight = [&](const MediaQueryExpression& expression, Comparator comparator)
124
    {
125
        return evaluateSize(expression, comparator, [&](const RenderBox& renderer) {
126
            return renderer.height();
127
        });
128
    };
129
130
    bool result = false;
131
132
    // FIXME: This is very rudimentary.
133
    auto& queries = filteredContainerQuery.query->queryVector();
134
    for (auto& query : queries) {
135
        for (auto& expression : query.expressions()) {
136
            if (expression.mediaFeature() == MediaFeatureNames::minWidth) {
137
                if (evaluateWidth(expression, Comparator::GreaterOrEqual))
138
                    result = true;
139
                continue;
140
            }
141
            if (expression.mediaFeature() == MediaFeatureNames::maxWidth) {
142
                if (evaluateWidth(expression, Comparator::LesserOrEqual))
143
                    result = true;
144
                continue;
145
            }
146
            if (expression.mediaFeature() == MediaFeatureNames::width) {
147
                if (evaluateWidth(expression, expression.value() ? Comparator::Equal : Comparator::True))
148
                    result = true;
149
                continue;
150
            }
151
            if (expression.mediaFeature() == MediaFeatureNames::minHeight) {
152
                if (evaluateHeight(expression, Comparator::GreaterOrEqual))
153
                    result = true;
154
                continue;
155
            }
156
            if (expression.mediaFeature() == MediaFeatureNames::maxHeight) {
157
                if (evaluateHeight(expression, Comparator::LesserOrEqual))
158
                    result = true;
159
                continue;
160
            }
161
            if (expression.mediaFeature() == MediaFeatureNames::height) {
162
                if (evaluateHeight(expression, expression.value() ? Comparator::Equal : Comparator::True))
163
                    result = true;
164
                continue;
165
            }
166
        }
167
    }
168
191
169
    return result;
192
    return EvaluationResult::Unknown;
170
}
193
}
171
194
172
}
195
}
- a/Source/WebCore/style/ContainerQueryEvaluator.h -1 / +9 lines
Lines 24-34 a/Source/WebCore/style/ContainerQueryEvaluator.h_sec1
24
24
25
#pragma once
25
#pragma once
26
26
27
#include "ContainerQuery.h"
27
#include <wtf/Ref.h>
28
#include <wtf/Ref.h>
28
29
29
namespace WebCore {
30
namespace WebCore {
30
31
31
struct FilteredContainerQuery;
32
class Element;
32
class Element;
33
33
34
namespace Style {
34
namespace Style {
Lines 40-45 public: a/Source/WebCore/style/ContainerQueryEvaluator.h_sec2
40
    bool evaluate(const FilteredContainerQuery&) const;
40
    bool evaluate(const FilteredContainerQuery&) const;
41
41
42
private:
42
private:
43
    struct EvaluationContext;
44
    enum class EvaluationResult : uint8_t { False, True, Unknown };
45
46
    EvaluationResult evaluateQuery(const CQ::ContainerQuery&, const EvaluationContext&) const;
47
    EvaluationResult evaluateQuery(const CQ::SizeQuery&, const EvaluationContext&) const;
48
    template<typename ConditionType> EvaluationResult evaluateCondition(const ConditionType&, const EvaluationContext&) const;
49
    EvaluationResult evaluateSizeFeature(const CQ::SizeFeature&, const EvaluationContext&) const;
50
43
    const Vector<Ref<const Element>>& m_containers;
51
    const Vector<Ref<const Element>>& m_containers;
44
};
52
};
45
53
- a/LayoutTests/ChangeLog +9 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2022-02-14  Antti Koivisto  <antti@apple.com>
2
3
        [CSS Container Queries] Implement full query parser and evaluator
4
        https://bugs.webkit.org/show_bug.cgi?id=236580
5
6
        Reviewed by Sam Weinig.
7
8
        * TestExpectations:
9
1
2022-02-12  Tim Nguyen  <ntim@apple.com>
10
2022-02-12  Tim Nguyen  <ntim@apple.com>
2
11
3
        Skip imported/w3c/web-platform-tests/url/toascii.window.html on Catalina/Big Sur
12
        Skip imported/w3c/web-platform-tests/url/toascii.window.html on Catalina/Big Sur
- a/LayoutTests/imported/w3c/ChangeLog +13 lines
Lines 1-3 a/LayoutTests/imported/w3c/ChangeLog_sec1
1
2022-02-14  Antti Koivisto  <antti@apple.com>
2
3
        [CSS Container Queries] Implement full query parser and evaluator
4
        https://bugs.webkit.org/show_bug.cgi?id=236580
5
6
        Reviewed by 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/container-for-shadow-dom.tentative-expected.txt:
10
        * web-platform-tests/css/css-contain/container-queries/container-type-invalidation-expected.txt:
11
        * web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt:
12
        * web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt:
13
1
2022-02-12  Tim Nguyen  <ntim@apple.com>
14
2022-02-12  Tim Nguyen  <ntim@apple.com>
2
15
3
        Unreviewed test gardening: imported/w3c/web-platform-tests/url/toascii.window.html
16
        Unreviewed test gardening: imported/w3c/web-platform-tests/url/toascii.window.html
- a/LayoutTests/TestExpectations +1 lines
Lines 4710-4715 imported/w3c/web-platform-tests/css/css-contain/contain-html-overflow-004.html [ a/LayoutTests/TestExpectations_sec1
4710
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/display-in-container.html [ ImageOnlyFailure ]
4710
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/display-in-container.html [ ImageOnlyFailure ]
4711
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/pseudo-elements-002.tentative.html [ ImageOnlyFailure ]
4711
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/pseudo-elements-002.tentative.html [ ImageOnlyFailure ]
4712
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/multicol-inside-container.html [ ImageOnlyFailure ]
4712
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/multicol-inside-container.html [ ImageOnlyFailure ]
4713
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/inline-size-bfc-floats.html [ ImageOnlyFailure ]
4713
4714
4714
# Flaky css-contain test
4715
# Flaky css-contain test
4715
imported/w3c/web-platform-tests/css/css-contain/content-visibility/animation-display-lock.html [ Failure Pass ]
4716
imported/w3c/web-platform-tests/css/css-contain/content-visibility/animation-display-lock.html [ Failure Pass ]
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt -41 / +41 lines
Lines 1-36 a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt_sec1
1
1
2
FAIL size(width) assert_equals: expected "true" but got ""
2
PASS size(width)
3
FAIL size(min-width: 0px) assert_equals: expected "true" but got ""
3
PASS size(min-width: 0px)
4
FAIL size(max-width: 0px) assert_equals: expected "true" but got ""
4
PASS size(max-width: 0px)
5
FAIL size(height) assert_equals: expected "true" but got ""
5
PASS size(height)
6
FAIL size(min-height: 0px) assert_equals: expected "true" but got ""
6
PASS size(min-height: 0px)
7
FAIL size(max-height: 0px) assert_equals: expected "true" but got ""
7
PASS size(max-height: 0px)
8
FAIL size(aspect-ratio) assert_equals: expected "true" but got ""
8
FAIL size(aspect-ratio) assert_equals: expected "true" but got ""
9
FAIL size(min-aspect-ratio: 1/2) 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 "true" but got ""
10
FAIL size(max-aspect-ratio: 1/2) assert_equals: expected 2 but got 0
11
FAIL size(orientation: portrait) assert_equals: expected "true" but got ""
11
FAIL size(orientation: portrait) assert_equals: expected 2 but got 0
12
FAIL size(inline-size) assert_equals: expected "true" but got ""
12
FAIL size(inline-size) assert_equals: expected "true" but got ""
13
FAIL size(min-inline-size: 0px) 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 ""
14
FAIL size(max-inline-size: 0px) assert_equals: expected "true" but got ""
15
FAIL size(block-size) 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 ""
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 ""
17
FAIL size(max-block-size: 0px) assert_equals: expected "true" but got ""
18
FAIL size(width: 100px) assert_equals: expected "true" but got ""
18
PASS size(width: 100px)
19
FAIL size((width: 100px)) assert_equals: expected "true" but got ""
19
PASS size((width: 100px))
20
FAIL size(not (width: 100px)) assert_equals: expected "true" but got ""
20
PASS size(not (width: 100px))
21
FAIL size((width: 100px) and (height: 100px)) assert_equals: expected "true" but got ""
21
PASS size((width: 100px) and (height: 100px))
22
FAIL size((width: 50px) or (height: 100px)) assert_equals: expected "true" but got ""
22
PASS size((width: 50px) or (height: 100px))
23
FAIL size(width < 100px) assert_equals: expected "true" but got ""
23
PASS size(width < 100px)
24
FAIL size(100px < width) assert_equals: expected "true" but got ""
24
FAIL size(100px < width) assert_equals: expected 2 but got 0
25
FAIL size(100px < width < 200px) assert_equals: expected "true" but got ""
25
FAIL size(100px < width < 200px) assert_equals: expected 2 but got 0
26
PASS foo(width)
26
PASS foo(width)
27
PASS size(asdf)
27
PASS size(asdf)
28
PASS size(resolution > 100dpi)
28
FAIL size(resolution > 100dpi) assert_equals: expected 2 but got 0
29
PASS size(resolution: 150dpi)
29
FAIL size(resolution: 150dpi) assert_equals: expected 2 but got 0
30
PASS size(color)
30
PASS size(color)
31
PASS size(min-color: 1)
31
FAIL size(min-color: 1) assert_equals: expected 2 but got 0
32
PASS size(color-index >= 1)
32
FAIL size(color-index >= 1) assert_equals: expected 2 but got 0
33
PASS (color-index >= 1)
33
FAIL (color-index >= 1) assert_equals: expected 2 but got 0
34
PASS size(grid)
34
PASS size(grid)
35
PASS (grid)
35
PASS (grid)
36
PASS screen
36
PASS screen
Lines 41-68 PASS screen and (width: 100px) a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt_sec2
41
PASS screen or (width: 100px)
41
PASS screen or (width: 100px)
42
PASS not screen and (width: 100px)
42
PASS not screen and (width: 100px)
43
PASS not screen or (width: 100px)
43
PASS not screen or (width: 100px)
44
FAIL (width: 100px), (height: 100px) assert_equals: expected 0 but got 1
44
PASS (width: 100px), (height: 100px)
45
PASS Container selector:  foo
45
PASS Container selector:  foo
46
PASS Container selector:  foo
46
PASS Container selector:  foo
47
PASS Container selector: name(foo)
47
FAIL Container selector: name(foo) assert_equals: expected 1 but got 0
48
PASS Container selector: name( foo )
48
FAIL Container selector: name( foo ) assert_equals: expected 1 but got 0
49
PASS Container selector: type(size)
49
FAIL Container selector: type(size) assert_equals: expected 1 but got 0
50
PASS Container selector: type( size )
50
FAIL Container selector: type( size ) assert_equals: expected 1 but got 0
51
PASS Container selector: type(inline-size)
51
FAIL Container selector: type(inline-size) assert_equals: expected 1 but got 0
52
PASS Container selector: type(block-size)
52
FAIL Container selector: type(block-size) assert_equals: expected 1 but got 0
53
PASS Container selector: name(bar) type(block-size)
53
FAIL Container selector: name(bar) type(block-size) assert_equals: expected 1 but got 0
54
PASS Container selector: type(block-size) name(bar)
54
FAIL Container selector: type(block-size) name(bar) assert_equals: expected 1 but got 0
55
PASS Container selector: foo foo
55
PASS Container selector: foo foo
56
PASS Container selector: 1px
56
PASS Container selector: 1px
57
PASS Container selector: 50gil
57
PASS Container selector: 50gil
58
FAIL Container selector: name(1px) assert_equals: expected 0 but got 1
58
PASS Container selector: name(1px)
59
FAIL Container selector: type(1px) assert_equals: expected 0 but got 1
59
PASS Container selector: type(1px)
60
FAIL Container selector: type(red) assert_equals: expected 0 but got 1
60
PASS Container selector: type(red)
61
FAIL Container selector: type(size) type(size) assert_equals: expected 0 but got 1
61
PASS Container selector: type(size) type(size)
62
FAIL Container selector: type(inline-size) type(block-size) assert_equals: expected 0 but got 1
62
PASS Container selector: type(inline-size) type(block-size)
63
FAIL Container selector: name(foo) name(bar) assert_equals: expected 0 but got 1
63
PASS Container selector: name(foo) name(bar)
64
FAIL Container selector: type(inline-size) name(foo) type(block-size) assert_equals: expected 0 but got 1
64
PASS Container selector: type(inline-size) name(foo) type(block-size)
65
FAIL Container selector: name(foo) type(size) name(bar) assert_equals: expected 0 but got 1
65
PASS Container selector: name(foo) type(size) name(bar)
66
FAIL Container selector: name(type(size)) assert_equals: expected 0 but got 1
66
PASS Container selector: name(type(size))
67
FAIL Container selector: type(name(bar)) assert_equals: expected 0 but got 1
67
PASS Container selector: type(name(bar))
68
68
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom.tentative-expected.txt -1 / +1 lines
Lines 1-6 a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom.tentative-expected.txt_sec1
1
1
2
FAIL Match container in outer tree null is not an object (evaluating 'document.querySelector("#inclusive-ancestor-across-root > div").shadowRoot.querySelector')
2
FAIL Match container in outer tree null is not an object (evaluating 'document.querySelector("#inclusive-ancestor-across-root > div").shadowRoot.querySelector')
3
FAIL Match container in same tree, not walking flat tree ancestors assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
3
PASS Match container in same tree, not walking flat tree ancestors
4
FAIL Match container in ::slotted selector's originating element tree assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
4
FAIL Match container in ::slotted selector's originating element tree assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
5
FAIL Match container in outer tree for :host assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
5
FAIL Match container in outer tree for :host assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
6
FAIL Match container in ::part selector's originating element tree null is not an object (evaluating 'document.querySelector("#inclusive-ancestor-part > div").shadowRoot.querySelector')
6
FAIL Match container in ::part selector's originating element tree null is not an object (evaluating 'document.querySelector("#inclusive-ancestor-part > div").shadowRoot.querySelector')
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-type-invalidation-expected.txt -1 / +1 lines
Lines 1-4 a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-type-invalidation-expected.txt_sec1
1
Test
1
Test
2
2
3
FAIL Changing the container type invalidates relevant descendants assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
3
FAIL Changing the container type invalidates relevant descendants assert_equals: expected "rgb(0, 0, 0)" but got "rgb(0, 128, 0)"
4
4
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt -31 / +31 lines
Lines 3-20 PASS size(width) a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt_sec1
3
PASS size(height)
3
PASS size(height)
4
PASS size(unknown)
4
PASS size(unknown)
5
PASS unknown(width)
5
PASS unknown(width)
6
FAIL (size(width)) assert_equals: expected "true" but got "false"
6
PASS (size(width))
7
PASS (size(height))
7
PASS (size(height))
8
PASS (size(unknown))
8
PASS (size(unknown))
9
FAIL (((size(width)))) assert_equals: expected "true" but got "false"
9
PASS (((size(width))))
10
PASS (((size(height))))
10
PASS (((size(height))))
11
PASS (((size(unknown))))
11
PASS (((size(unknown))))
12
PASS (not size(width))
12
PASS (not size(width))
13
FAIL (not size(height)) assert_equals: expected "true" but got "false"
13
PASS (not size(height))
14
PASS (not size(unknown))
14
PASS (not size(unknown))
15
PASS (not unknown(width))
15
PASS (not unknown(width))
16
FAIL (size(width) and size(width)) assert_equals: expected "true" but got "false"
16
PASS (size(width) and size(width))
17
FAIL (size(width) and size(width) and size(width)) assert_equals: expected "true" but got "false"
17
PASS (size(width) and size(width) and size(width))
18
PASS (size(height) and size(height))
18
PASS (size(height) and size(height))
19
PASS (size(height) and size(width) and size(width))
19
PASS (size(height) and size(width) and size(width))
20
PASS (size(width) and size(height) and size(width))
20
PASS (size(width) and size(height) and size(width))
Lines 22-51 PASS (size(width) and size(width) and size(height)) a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt_sec2
22
PASS (size(unknown) and size(width) and size(width))
22
PASS (size(unknown) and size(width) and size(width))
23
PASS (size(width) and size(unknown) and size(width))
23
PASS (size(width) and size(unknown) and size(width))
24
PASS (size(width) and size(width) and size(unknown))
24
PASS (size(width) and size(width) and size(unknown))
25
FAIL (size(width) or size(width)) assert_equals: expected "true" but got "false"
25
PASS (size(width) or size(width))
26
FAIL (size(width) or size(width) or size(width)) assert_equals: expected "true" but got "false"
26
PASS (size(width) or size(width) or size(width))
27
PASS (size(height) or size(height))
27
PASS (size(height) or size(height))
28
FAIL (size(height) or size(width) or size(width)) assert_equals: expected "true" but got "false"
28
PASS (size(height) or size(width) or size(width))
29
FAIL (size(width) or size(height) or size(width)) assert_equals: expected "true" but got "false"
29
PASS (size(width) or size(height) or size(width))
30
FAIL (size(width) or size(width) or size(height)) assert_equals: expected "true" but got "false"
30
PASS (size(width) or size(width) or size(height))
31
FAIL (size(unknown) or size(width) or size(width)) assert_equals: expected "true" but got "false"
31
PASS (size(unknown) or size(width) or size(width))
32
FAIL (size(width) or size(unknown) or size(width)) assert_equals: expected "true" but got "false"
32
PASS (size(width) or size(unknown) or size(width))
33
FAIL (size(width) or size(width) or size(unknown)) assert_equals: expected "true" but got "false"
33
PASS (size(width) or size(width) or size(unknown))
34
FAIL (size(unknown) or size(height) or size(width)) assert_equals: expected "true" but got "false"
34
PASS (size(unknown) or size(height) or size(width))
35
PASS (not (size(width) and size(width)))
35
PASS (not (size(width) and size(width)))
36
FAIL (not (size(width) and size(height))) assert_equals: expected "true" but got "false"
36
PASS (not (size(width) and size(height)))
37
PASS (size(width) and (not (size(height) or size(width))))
37
PASS (size(width) and (not (size(height) or size(width))))
38
FAIL (size(height) or (not (size(height) and size(width)))) assert_equals: expected "true" but got "false"
38
PASS (size(height) or (not (size(height) and size(width))))
39
PASS (size(height) or (size(height) and size(width)))
39
PASS (size(height) or (size(height) and size(width)))
40
FAIL size((width)) assert_equals: expected "true" but got "false"
40
PASS size((width))
41
PASS size((height))
41
PASS size((height))
42
PASS size((unknown))
42
PASS size((unknown))
43
PASS unknown((width))
43
PASS unknown((width))
44
PASS size(not (width))
44
PASS size(not (width))
45
FAIL size(not (height)) assert_equals: expected "true" but got "false"
45
PASS size(not (height))
46
PASS size(not (unknown))
46
PASS size(not (unknown))
47
FAIL size((width) and (width)) assert_equals: expected "true" but got "false"
47
PASS size((width) and (width))
48
FAIL size((width) and (width) and (width)) assert_equals: expected "true" but got "false"
48
PASS size((width) and (width) and (width))
49
PASS size((height) and (height))
49
PASS size((height) and (height))
50
PASS size((height) and (width) and (width))
50
PASS size((height) and (width) and (width))
51
PASS size((width) and (height) and (width))
51
PASS size((width) and (height) and (width))
Lines 53-71 PASS size((width) and (width) and (height)) a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt_sec3
53
PASS size((unknown) and (width) and (width))
53
PASS size((unknown) and (width) and (width))
54
PASS size((width) and (unknown) and (width))
54
PASS size((width) and (unknown) and (width))
55
PASS size((width) and (width) and (unknown))
55
PASS size((width) and (width) and (unknown))
56
FAIL size((width) or (width)) assert_equals: expected "true" but got "false"
56
PASS size((width) or (width))
57
FAIL size((width) or (width) or (width)) assert_equals: expected "true" but got "false"
57
PASS size((width) or (width) or (width))
58
PASS size((height) or (height))
58
PASS size((height) or (height))
59
FAIL size((height) or (width) or (width)) assert_equals: expected "true" but got "false"
59
PASS size((height) or (width) or (width))
60
FAIL size((width) or (height) or (width)) assert_equals: expected "true" but got "false"
60
PASS size((width) or (height) or (width))
61
FAIL size((width) or (width) or (height)) assert_equals: expected "true" but got "false"
61
PASS size((width) or (width) or (height))
62
FAIL size((unknown) or (width) or (width)) assert_equals: expected "true" but got "false"
62
PASS size((unknown) or (width) or (width))
63
FAIL size((width) or (unknown) or (width)) assert_equals: expected "true" but got "false"
63
PASS size((width) or (unknown) or (width))
64
FAIL size((width) or (width) or (unknown)) assert_equals: expected "true" but got "false"
64
PASS size((width) or (width) or (unknown))
65
FAIL size((unknown) or (height) or (width)) assert_equals: expected "true" but got "false"
65
PASS size((unknown) or (height) or (width))
66
PASS size(not ((width) and (width)))
66
PASS size(not ((width) and (width)))
67
FAIL size(not ((width) and (height))) assert_equals: expected "true" but got "false"
67
PASS size(not ((width) and (height)))
68
PASS size((width) and (not ((height) or (width))))
68
PASS size((width) and (not ((height) or (width))))
69
FAIL size((height) or (not ((height) and (width)))) assert_equals: expected "true" but got "false"
69
PASS size((height) or (not ((height) and (width))))
70
PASS size((height) or ((height) and (width)))
70
PASS size((height) or ((height) and (width)))
71
71
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt -4 / +4 lines
Lines 1-12 a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt_sec1
1
Test
1
Test
2
2
3
PASS size(width < 100px) (.horizontal)
3
FAIL size(width < 100px) (.horizontal) assert_equals: expected "" but got "true"
4
FAIL size(width >= 100px) (.horizontal) assert_equals: expected "true" but got ""
4
FAIL size(width >= 100px) (.horizontal) assert_equals: expected "true" but got ""
5
PASS size(min-width: 100px) (.horizontal)
5
PASS size(min-width: 100px) (.horizontal)
6
PASS size(min-width: 101px) (.horizontal)
6
PASS size(min-width: 101px) (.horizontal)
7
PASS size(max-width: 100px) (.horizontal)
7
PASS size(max-width: 100px) (.horizontal)
8
PASS size(max-width: 99px) (.horizontal)
8
PASS size(max-width: 99px) (.horizontal)
9
PASS size(height < 200px) (.horizontal)
9
FAIL size(height < 200px) (.horizontal) assert_equals: expected "" but got "true"
10
FAIL size(height >= 200px) (.horizontal) assert_equals: expected "true" but got ""
10
FAIL size(height >= 200px) (.horizontal) assert_equals: expected "true" but got ""
11
PASS size(min-height: 200px) (.horizontal)
11
PASS size(min-height: 200px) (.horizontal)
12
PASS size(min-height: 201px) (.horizontal)
12
PASS size(min-height: 201px) (.horizontal)
Lines 28-40 PASS size(orientation: landscape) (.horizontal) a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt_sec2
28
FAIL size(orientation: portrait) (.horizontal) assert_equals: expected "true" but got ""
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 ""
29
FAIL size(aspect-ratio: 1/2) (.horizontal) assert_equals: expected "true" but got ""
30
PASS size(aspect-ratio: 2/1) (.horizontal)
30
PASS size(aspect-ratio: 2/1) (.horizontal)
31
PASS size(width < 100px) (.vertical)
31
FAIL size(width < 100px) (.vertical) assert_equals: expected "" but got "true"
32
FAIL size(width >= 100px) (.vertical) assert_equals: expected "true" but got ""
32
FAIL size(width >= 100px) (.vertical) assert_equals: expected "true" but got ""
33
PASS size(min-width: 100px) (.vertical)
33
PASS size(min-width: 100px) (.vertical)
34
PASS size(min-width: 101px) (.vertical)
34
PASS size(min-width: 101px) (.vertical)
35
PASS size(max-width: 100px) (.vertical)
35
PASS size(max-width: 100px) (.vertical)
36
PASS size(max-width: 99px) (.vertical)
36
PASS size(max-width: 99px) (.vertical)
37
PASS size(height < 200px) (.vertical)
37
FAIL size(height < 200px) (.vertical) assert_equals: expected "" but got "true"
38
FAIL size(height >= 200px) (.vertical) assert_equals: expected "true" but got ""
38
FAIL size(height >= 200px) (.vertical) assert_equals: expected "true" but got ""
39
PASS size(min-height: 200px) (.vertical)
39
PASS size(min-height: 200px) (.vertical)
40
PASS size(min-height: 201px) (.vertical)
40
PASS size(min-height: 201px) (.vertical)

Return to Bug 236580