WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-236580-20220214120904.patch (text/plain), 45.45 KB, created by
Antti Koivisto
on 2022-02-14 02:09:06 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Antti Koivisto
Created:
2022-02-14 02:09:06 PST
Size:
45.45 KB
patch
obsolete
>Subversion Revision: 289706 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 3025ba2841ec0f67a7f85aeebf07e6e8998baaa8..c4422d5cbc5909ae8211b405185789e502e42ea9 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,40 @@ >+2022-02-14 Antti Koivisto <antti@apple.com> >+ >+ [CSS Container Queries] Implement full query parser and evaluator >+ https://bugs.webkit.org/show_bug.cgi?id=236580 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ So far we have been using the media query parser to parse container queries. >+ It does not support nesting and other necessary features. Also the produced data >+ structure are awkward to evaluate. >+ >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * css/ContainerQuery.h: >+ * css/ContainerQueryParser.cpp: Added. >+ (WebCore::ContainerQueryParser::parse): >+ (WebCore::ContainerQueryParser::consumeContainerQuery): >+ (WebCore::ContainerQueryParser::consumeCondition): >+ (WebCore::ContainerQueryParser::consumeSizeQuery): >+ >+ No support for range operators ('<' etc) yet. >+ >+ * css/ContainerQueryParser.h: Copied from Source/WebCore/css/ContainerQuery.h. >+ (WebCore::ContainerQueryParser::ContainerQueryParser): >+ * css/parser/CSSParserImpl.cpp: >+ (WebCore::CSSParserImpl::consumeContainerRule): >+ * style/ContainerQueryEvaluator.cpp: >+ (WebCore::Style::computeSize): >+ (WebCore::Style::ContainerQueryEvaluator::evaluate const): >+ (WebCore::Style::ContainerQueryEvaluator::evaluateQuery const): >+ (WebCore::Style::ContainerQueryEvaluator::evaluateCondition const): >+ (WebCore::Style::ContainerQueryEvaluator::evaluateSizeFeature const): >+ >+ Just 'width' and 'height' for now, now new size features. >+ >+ * style/ContainerQueryEvaluator.h: >+ > 2022-02-13 Antti Koivisto <antti@apple.com> > > [CSS Container Queries] Add separate ContainerQuery and FilteredContainerQuery types >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index 20190562c1336168325a3498e5b31d4082db67cb..bcb39ec3600954225d85ace45cbf09b239930694 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -704,6 +704,7 @@ crypto/keys/CryptoKeyRSA.cpp > crypto/keys/CryptoKeyRSAComponents.cpp > crypto/keys/CryptoKeyRaw.cpp > css/BasicShapeFunctions.cpp >+css/ContainerQueryParser.cpp > css/CSSAspectRatioValue.cpp > css/CSSBasicShapes.cpp > css/CSSBorderImage.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index f3c3524b4576c465de7fee193399459b591b5bf8..cddfff66d7b3ba76543bf9628b1b4458521f183d 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -5429,6 +5429,7 @@ > E4ED3ECC2768A51D00F17AC8 /* HasSelectorFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = E4ED3ECA2768A51C00F17AC8 /* HasSelectorFilter.h */; }; > E4F0BE3125712F6E009E7431 /* CaretRectComputation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */; }; > E4F1573927B9261500B330D8 /* ContainerQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F1573227B6991F00B330D8 /* ContainerQuery.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ E4F1574127B93B7700B330D8 /* ContainerQueryParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F1573D27B93B4C00B330D8 /* ContainerQueryParser.h */; }; > E4F38D1B2626F13B007B1064 /* DefaultResourceLoadPriority.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F38D192626F13B007B1064 /* DefaultResourceLoadPriority.h */; }; > E4F819C626FB4EBF0094E162 /* InlineBoxPainter.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F819C526FB4EBF0094E162 /* InlineBoxPainter.h */; }; > E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -17611,6 +17612,8 @@ > E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CaretRectComputation.h; sourceTree = "<group>"; }; > E4F0BE3025710A76009E7431 /* CaretRectComputation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CaretRectComputation.cpp; sourceTree = "<group>"; }; > E4F1573227B6991F00B330D8 /* ContainerQuery.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContainerQuery.h; sourceTree = "<group>"; }; >+ E4F1573D27B93B4C00B330D8 /* ContainerQueryParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContainerQueryParser.h; sourceTree = "<group>"; }; >+ E4F1573F27B93B5800B330D8 /* ContainerQueryParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ContainerQueryParser.cpp; sourceTree = "<group>"; }; > E4F38D192626F13B007B1064 /* DefaultResourceLoadPriority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DefaultResourceLoadPriority.h; sourceTree = "<group>"; }; > E4F38D1C2626F144007B1064 /* DefaultResourceLoadPriority.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DefaultResourceLoadPriority.cpp; sourceTree = "<group>"; }; > E4F819C226FB4EAF0094E162 /* InlineBoxPainter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineBoxPainter.cpp; sourceTree = "<group>"; }; >@@ -31596,6 +31599,8 @@ > FBD6AF8415EF21D4008B7110 /* BasicShapeFunctions.cpp */, > FBD6AF8515EF21D4008B7110 /* BasicShapeFunctions.h */, > E4F1573227B6991F00B330D8 /* ContainerQuery.h */, >+ E4F1573F27B93B5800B330D8 /* ContainerQueryParser.cpp */, >+ E4F1573D27B93B4C00B330D8 /* ContainerQueryParser.h */, > A80E6CDA0A1989CA007FB8C5 /* Counter.h */, > CAE9F90D146441F000C245B0 /* CSSAspectRatioValue.cpp */, > CAE9F90E146441F000C245B0 /* CSSAspectRatioValue.h */, >@@ -33871,7 +33876,9 @@ > E596DD352519041400C275A7 /* ContactsSelectOptions.h in Headers */, > A818721C0977D3C0005826D9 /* ContainerNode.h in Headers */, > E1A1470811102B1500EEC0F3 /* ContainerNodeAlgorithms.h in Headers */, >+ E4F1573927B9261500B330D8 /* ContainerQuery.h in Headers */, > E4AAB38727AA95D7009F5899 /* ContainerQueryEvaluator.h in Headers */, >+ E4F1574127B93B7700B330D8 /* ContainerQueryParser.h in Headers */, > 6FB5E214221F2453003989CF /* ContentChangeObserver.h in Headers */, > BC5EB9810E82072500B25965 /* ContentData.h in Headers */, > 51B45D211AB8D1E200117CD2 /* ContentExtension.h in Headers */, >@@ -37188,7 +37195,6 @@ > E45322AC140CE267005A0F92 /* SelectorQuery.h in Headers */, > F4D43D662188038B00ECECAC /* SerializedAttachmentData.h in Headers */, > E18DF33518AAF12C00773E59 /* SerializedCryptoKeyWrap.h in Headers */, >- E4F1573927B9261500B330D8 /* ContainerQuery.h in Headers */, > 077AF14018F4AE400001ED61 /* SerializedPlatformDataCue.h in Headers */, > 077AF14318F4B1BB0001ED61 /* SerializedPlatformDataCueMac.h in Headers */, > 076D1C1F23F6EB5B00D95B06 /* SerializedPlatformDataCueValue.h in Headers */, >diff --git a/Source/WebCore/css/ContainerQuery.h b/Source/WebCore/css/ContainerQuery.h >index 8d8de0c00c5b219e40f58d62656842053b9b520b..76966d893de50897b43eeabfb7c93baf7246881a 100644 >--- a/Source/WebCore/css/ContainerQuery.h >+++ b/Source/WebCore/css/ContainerQuery.h >@@ -24,17 +24,50 @@ > > #pragma once > >+#include "Length.h" > #include <wtf/text/AtomString.h> > > namespace WebCore { > >-class MediaQuerySet; >+class CSSPrimitiveValue; > >-using ContainerQuery = MediaQuerySet; >+namespace CQ { >+ >+struct ContainerCondition; >+struct SizeCondition; >+struct SizeFeature; >+ >+struct UnknownQuery { }; >+ >+using SizeQuery = std::variant<SizeCondition, SizeFeature>; >+using ContainerQuery = std::variant<ContainerCondition, SizeQuery, UnknownQuery>; >+ >+enum class LogicalOperator : uint8_t { And, Or, Not }; >+enum class ComparisonOperator : uint8_t { Less, LessOrEqual, Equal, Greater, GreaterOrEqual, True }; >+ >+struct ContainerCondition { >+ LogicalOperator logicalOperator { LogicalOperator::And }; >+ Vector<ContainerQuery> queries; >+}; >+ >+struct SizeCondition { >+ LogicalOperator logicalOperator { LogicalOperator::And }; >+ Vector<SizeQuery> queries; >+}; >+ >+struct SizeFeature { >+ ComparisonOperator comparisonOperator { ComparisonOperator::Equal }; >+ AtomString name; >+ RefPtr<CSSPrimitiveValue> value; >+}; >+ >+} >+ >+using ContainerQuery = CQ::ContainerQuery; > > struct FilteredContainerQuery { > AtomString nameFilter; >- Ref<ContainerQuery> query; >+ ContainerQuery query; > }; > > } >diff --git a/Source/WebCore/css/ContainerQueryParser.cpp b/Source/WebCore/css/ContainerQueryParser.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..ace81bb3541113fb96a9ec8d5726f3aa4c2655bb >--- /dev/null >+++ b/Source/WebCore/css/ContainerQueryParser.cpp >@@ -0,0 +1,170 @@ >+/* >+ * Copyright (C) 2022 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ContainerQueryParser.h" >+ >+#include "CSSPrimitiveValue.h" >+#include "CSSPropertyParserHelpers.h" >+ >+namespace WebCore { >+ >+std::optional<ContainerQuery> ContainerQueryParser::parse(CSSParserTokenRange& range, const CSSParserContext& context) >+{ >+ ContainerQueryParser parser(context); >+ return parser.consumeContainerQuery(range); >+} >+ >+std::optional<CQ::ContainerQuery> ContainerQueryParser::consumeContainerQuery(CSSParserTokenRange& range) >+{ >+ if (range.peek().type() == FunctionToken) { >+ bool isSizeQuery = equalIgnoringASCIICase(range.peek().value(), "size"); >+ >+ auto blockRange = range.consumeBlock(); >+ blockRange.consumeWhitespace(); >+ >+ if (!isSizeQuery) >+ return CQ::UnknownQuery { }; >+ >+ auto sizeQuery = consumeSizeQuery(blockRange); >+ if (!sizeQuery) >+ return { }; >+ return { *sizeQuery }; >+ } >+ >+ if (range.peek().type() == LeftParenthesisToken) { >+ auto blockRange = range.consumeBlock(); >+ blockRange.consumeWhitespace(); >+ >+ // Try to parse as a size query first. >+ auto blockForSizeQuery = blockRange; >+ if (auto sizeQuery = consumeSizeQuery(blockForSizeQuery)) >+ return { *sizeQuery }; >+ >+ if (auto condition = consumeCondition<CQ::ContainerCondition>(blockRange)) >+ return { condition }; >+ } >+ >+ return { }; >+} >+ >+template<typename ConditionType> >+std::optional<ConditionType> ContainerQueryParser::consumeCondition(CSSParserTokenRange& range) >+{ >+ auto consumeQuery = [&](CSSParserTokenRange& range) { >+ if constexpr (std::is_same_v<CQ::ContainerCondition, ConditionType>) >+ return consumeContainerQuery(range); >+ if constexpr (std::is_same_v<CQ::SizeCondition, ConditionType>) { >+ if (range.peek().type() != LeftParenthesisToken) >+ return std::optional<CQ::SizeQuery>(); >+ auto blockRange = range.consumeBlock(); >+ return consumeSizeQuery(blockRange); >+ } >+ }; >+ >+ if (range.peek().type() == IdentToken) { >+ if (equalIgnoringASCIICase(range.peek().value(), "not")) { >+ range.consumeIncludingWhitespace(); >+ if (auto query = consumeQuery(range)) >+ return ConditionType { CQ::LogicalOperator::Not, { *query } }; >+ return { }; >+ } >+ } >+ >+ ConditionType condition; >+ >+ auto query = consumeQuery(range); >+ if (!query) >+ return { }; >+ >+ condition.queries.append(*query); >+ range.consumeWhitespace(); >+ >+ while (!range.atEnd()) { >+ auto operatorToken = range.consumeIncludingWhitespace(); >+ >+ if (operatorToken.type() != IdentToken) >+ return { }; >+ if (equalIgnoringASCIICase(operatorToken.value(), "and")) { >+ if (condition.queries.size() > 1 && condition.logicalOperator != CQ::LogicalOperator::And) >+ return { }; >+ condition.logicalOperator = CQ::LogicalOperator::And; >+ } else if (equalIgnoringASCIICase(operatorToken.value(), "or")) { >+ if (condition.queries.size() > 1 && condition.logicalOperator != CQ::LogicalOperator::Or) >+ return { }; >+ condition.logicalOperator = CQ::LogicalOperator::Or; >+ } else >+ return { }; >+ >+ auto query = consumeQuery(range); >+ if (!query) >+ return { }; >+ >+ condition.queries.append(*query); >+ range.consumeWhitespace(); >+ } >+ >+ return condition; >+} >+ >+std::optional<CQ::SizeQuery> ContainerQueryParser::consumeSizeQuery(CSSParserTokenRange& range) >+{ >+ if (range.peek().type() != IdentToken || equalIgnoringASCIICase(range.peek().value(), "not")) { >+ auto sizeCondition = consumeCondition<CQ::SizeCondition>(range); >+ if (!sizeCondition) >+ return { }; >+ return { *sizeCondition }; >+ } >+ >+ auto nameToken = range.consumeIncludingWhitespace(); >+ auto name = nameToken.value().toAtomString(); >+ >+ if (range.atEnd()) >+ return CQ::SizeFeature { CQ::ComparisonOperator::True, name, { } }; >+ >+ auto opToken = range.consumeIncludingWhitespace(); >+ if (range.atEnd()) >+ return { }; >+ >+ auto op = CQ::ComparisonOperator::Equal; >+ if (opToken.type() == ColonToken) { >+ if (name.startsWith("min-")) >+ op = CQ::ComparisonOperator::GreaterOrEqual; >+ else if (name.startsWith("max-")) >+ op = CQ::ComparisonOperator::LessOrEqual; >+ >+ if (op != CQ::ComparisonOperator::Equal) >+ name = StringView(name).substring(4).toAtomString(); >+ if (name.isEmpty()) >+ return { }; >+ } >+ >+ auto length = CSSPropertyParserHelpers::consumeLength(range, m_context.mode, ValueRange::NonNegative); >+ if (!length) >+ return { }; >+ >+ return CQ::SizeFeature { op, name, length }; >+} >+ >+} >diff --git a/Source/WebCore/css/ContainerQueryParser.h b/Source/WebCore/css/ContainerQueryParser.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b0bb19823bed25df7944bbd6f111b592918bebcc >--- /dev/null >+++ b/Source/WebCore/css/ContainerQueryParser.h >@@ -0,0 +1,47 @@ >+/* >+ * Copyright (C) 2022 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "CSSParserToken.h" >+#include "ContainerQuery.h" >+ >+namespace WebCore { >+ >+class ContainerQueryParser { >+public: >+ static std::optional<ContainerQuery> parse(CSSParserTokenRange&, const CSSParserContext&); >+ >+private: >+ std::optional<CQ::ContainerQuery> consumeContainerQuery(CSSParserTokenRange&); >+ std::optional<CQ::SizeQuery> consumeSizeQuery(CSSParserTokenRange&); >+ template<typename ConditionType> std::optional<ConditionType> consumeCondition(CSSParserTokenRange&); >+ >+ ContainerQueryParser(const CSSParserContext& context) >+ : m_context(context) { } >+ >+ const CSSParserContext m_context; >+}; >+ >+} >diff --git a/Source/WebCore/css/parser/CSSParserImpl.cpp b/Source/WebCore/css/parser/CSSParserImpl.cpp >index f7d55922057f34f43ec6a23c8336f5d52c1eab33..e0003604a3261d815c104370e2e02b5001656c3d 100644 >--- a/Source/WebCore/css/parser/CSSParserImpl.cpp >+++ b/Source/WebCore/css/parser/CSSParserImpl.cpp >@@ -47,6 +47,7 @@ > #include "CSSSupportsParser.h" > #include "CSSTokenizer.h" > #include "CSSVariableParser.h" >+#include "ContainerQueryParser.h" > #include "Document.h" > #include "Element.h" > #include "FontPaletteValues.h" >@@ -865,12 +866,12 @@ RefPtr<StyleRuleContainer> CSSParserImpl::consumeContainerRule(CSSParserTokenRan > > auto name = consumeName(); > >- auto query = MediaQueryParser::parseContainerQuery(prelude, MediaQueryParserContext(m_context)); >+ auto query = ContainerQueryParser::parse(prelude, m_context); > if (!query) > return nullptr; > > if (m_deferredParser) >- return StyleRuleContainer::create({ name, query.releaseNonNull() }, makeUnique<DeferredStyleGroupRuleList>(block, *m_deferredParser)); >+ return StyleRuleContainer::create({ name, *query }, makeUnique<DeferredStyleGroupRuleList>(block, *m_deferredParser)); > > Vector<RefPtr<StyleRuleBase>> rules; > >@@ -888,7 +889,7 @@ RefPtr<StyleRuleContainer> CSSParserImpl::consumeContainerRule(CSSParserTokenRan > if (m_observerWrapper) > m_observerWrapper->observer().endRuleBody(m_observerWrapper->endOffset(block)); > >- return StyleRuleContainer::create({ name, query.releaseNonNull() }, WTFMove(rules)); >+ return StyleRuleContainer::create({ name, *query }, WTFMove(rules)); > } > > RefPtr<StyleRuleKeyframe> CSSParserImpl::consumeKeyframeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block) >diff --git a/Source/WebCore/style/ContainerQueryEvaluator.cpp b/Source/WebCore/style/ContainerQueryEvaluator.cpp >index 5f0c55782d1cae64654c7dbf1fc5dbe40bf7c96b..59b172986bf42bdb3a5ad1e011307b479b9e9ce5 100644 >--- a/Source/WebCore/style/ContainerQueryEvaluator.cpp >+++ b/Source/WebCore/style/ContainerQueryEvaluator.cpp >@@ -35,30 +35,29 @@ > > namespace WebCore::Style { > >+struct ContainerQueryEvaluator::EvaluationContext { >+ RenderBox& renderer; >+ CSSToLengthConversionData conversionData; >+}; >+ > ContainerQueryEvaluator::ContainerQueryEvaluator(const Vector<Ref<const Element>>& containers) > : m_containers(containers) > { > } > >-static std::optional<LayoutUnit> computeSize(CSSValue* value, const CSSToLengthConversionData& conversionData) >+static std::optional<LayoutUnit> computeSize(const CSSPrimitiveValue& value, const CSSToLengthConversionData& conversionData) > { >- if (!is<CSSPrimitiveValue>(value)) >- return { }; >- >- auto& primitiveValue = downcast<CSSPrimitiveValue>(*value); >- if (primitiveValue.isNumberOrInteger()) { >- if (primitiveValue.doubleValue()) >+ if (value.isNumberOrInteger()) { >+ if (value.doubleValue()) > return { }; > return 0_lu; > } > >- if (!primitiveValue.isLength()) >+ if (!value.isLength()) > return { }; >- return primitiveValue.computeLength<LayoutUnit>(conversionData); >+ return value.computeLength<LayoutUnit>(conversionData); > } > >-enum class Comparator { Lesser, Greater, LesserOrEqual, GreaterOrEqual, Equal, True }; >- > bool ContainerQueryEvaluator::evaluate(const FilteredContainerQuery& filteredContainerQuery) const > { > if (m_containers.isEmpty()) >@@ -83,90 +82,114 @@ bool ContainerQueryEvaluator::evaluate(const FilteredContainerQuery& filteredCon > return false; > > auto& view = renderer->view(); >- CSSToLengthConversionData conversionData { &renderer->style(), &view.style(), nullptr, &view, 1 }; >+ CSSToLengthConversionData { &renderer->style(), &view.style(), nullptr, &view, 1 }; > >- auto evaluateSize = [&](const MediaQueryExpression& expression, Comparator comparator, auto&& sizeGetter) >- { >+ EvaluationContext evaluationContext { >+ *renderer, >+ CSSToLengthConversionData { &renderer->style(), &view.style(), nullptr, &view, 1 } >+ }; >+ >+ return evaluateQuery(filteredContainerQuery.query, evaluationContext) == EvaluationResult::True; >+} >+ >+auto ContainerQueryEvaluator::evaluateQuery(const CQ::ContainerQuery& containerQuery, const EvaluationContext& context) const -> EvaluationResult >+{ >+ return WTF::switchOn(containerQuery, [&](const CQ::ContainerCondition& containerCondition) { >+ return evaluateCondition(containerCondition, context); >+ }, [&](const CQ::SizeQuery& sizeQuery) { >+ return evaluateQuery(sizeQuery, context); >+ }, [&](const CQ::UnknownQuery&) { >+ return EvaluationResult::Unknown; >+ }); >+} >+ >+auto ContainerQueryEvaluator::evaluateQuery(const CQ::SizeQuery& sizeQuery, const EvaluationContext& context) const -> EvaluationResult >+{ >+ return WTF::switchOn(sizeQuery, [&](const CQ::SizeCondition& sizeCondition) { >+ return evaluateCondition(sizeCondition, context); >+ }, [&](const CQ::SizeFeature& sizeFeature) { >+ return evaluateSizeFeature(sizeFeature, context); >+ }); >+} >+ >+template<typename ConditionType> >+auto ContainerQueryEvaluator::evaluateCondition(const ConditionType& condition, const EvaluationContext& context) const -> EvaluationResult >+{ >+ if (condition.queries.isEmpty()) >+ return EvaluationResult::Unknown; >+ >+ switch (condition.logicalOperator) { >+ case CQ::LogicalOperator::Not: { >+ switch (evaluateQuery(condition.queries.first(), context)) { >+ case EvaluationResult::True: >+ return EvaluationResult::False; >+ case EvaluationResult::False: >+ return EvaluationResult::True; >+ case EvaluationResult::Unknown: >+ return EvaluationResult::Unknown; >+ } >+ } >+ case CQ::LogicalOperator::And: { >+ auto result = EvaluationResult::True; >+ for (auto query : condition.queries) { >+ auto queryResult = evaluateQuery(query, context); >+ if (queryResult == EvaluationResult::False) >+ return EvaluationResult::False; >+ if (queryResult == EvaluationResult::Unknown) >+ result = EvaluationResult::Unknown; >+ } >+ return result; >+ } >+ case CQ::LogicalOperator::Or: { >+ auto result = EvaluationResult::False; >+ for (auto query : condition.queries) { >+ auto queryResult = evaluateQuery(query, context); >+ if (queryResult == EvaluationResult::True) >+ return EvaluationResult::True; >+ if (queryResult == EvaluationResult::Unknown) >+ result = EvaluationResult::Unknown; >+ } >+ return result; >+ } >+ } >+} >+ >+auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFeature, const EvaluationContext& context) const -> EvaluationResult >+{ >+ auto evaluateSize = [&](LayoutUnit size) { > std::optional<LayoutUnit> expressionSize; > >- if (comparator != Comparator::True) { >- expressionSize = computeSize(expression.value(), conversionData); >+ if (sizeFeature.comparisonOperator != CQ::ComparisonOperator::True) { >+ if (!sizeFeature.value) >+ return false; >+ expressionSize = computeSize(*sizeFeature.value, context.conversionData); > if (!expressionSize) > return false; > } > >- auto size = sizeGetter(*renderer); >- >- switch (comparator) { >- case Comparator::Lesser: >+ switch (sizeFeature.comparisonOperator) { >+ case CQ::ComparisonOperator::Less: > return size < *expressionSize; >- case Comparator::Greater: >+ case CQ::ComparisonOperator::Greater: > return size > *expressionSize; >- case Comparator::LesserOrEqual: >+ case CQ::ComparisonOperator::LessOrEqual: > return size <= *expressionSize; >- case Comparator::GreaterOrEqual: >+ case CQ::ComparisonOperator::GreaterOrEqual: > return size >= *expressionSize; >- case Comparator::Equal: >+ case CQ::ComparisonOperator::Equal: > return size == *expressionSize; >- case Comparator::True: >+ case CQ::ComparisonOperator::True: > return !!size; > } > }; > >- auto evaluateWidth = [&](const MediaQueryExpression& expression, Comparator comparator) >- { >- return evaluateSize(expression, comparator, [&](const RenderBox& renderer) { >- return renderer.width(); >- }); >- }; >- >- auto evaluateHeight = [&](const MediaQueryExpression& expression, Comparator comparator) >- { >- return evaluateSize(expression, comparator, [&](const RenderBox& renderer) { >- return renderer.height(); >- }); >- }; >- >- bool result = false; >- >- // FIXME: This is very rudimentary. >- auto& queries = filteredContainerQuery.query->queryVector(); >- for (auto& query : queries) { >- for (auto& expression : query.expressions()) { >- if (expression.mediaFeature() == MediaFeatureNames::minWidth) { >- if (evaluateWidth(expression, Comparator::GreaterOrEqual)) >- result = true; >- continue; >- } >- if (expression.mediaFeature() == MediaFeatureNames::maxWidth) { >- if (evaluateWidth(expression, Comparator::LesserOrEqual)) >- result = true; >- continue; >- } >- if (expression.mediaFeature() == MediaFeatureNames::width) { >- if (evaluateWidth(expression, expression.value() ? Comparator::Equal : Comparator::True)) >- result = true; >- continue; >- } >- if (expression.mediaFeature() == MediaFeatureNames::minHeight) { >- if (evaluateHeight(expression, Comparator::GreaterOrEqual)) >- result = true; >- continue; >- } >- if (expression.mediaFeature() == MediaFeatureNames::maxHeight) { >- if (evaluateHeight(expression, Comparator::LesserOrEqual)) >- result = true; >- continue; >- } >- if (expression.mediaFeature() == MediaFeatureNames::height) { >- if (evaluateHeight(expression, expression.value() ? Comparator::Equal : Comparator::True)) >- result = true; >- continue; >- } >- } >- } >+ // FIXME: Support all features. >+ if (sizeFeature.name == MediaFeatureNames::width) >+ return evaluateSize(context.renderer.width()) ? EvaluationResult::True : EvaluationResult::False; >+ if (sizeFeature.name == MediaFeatureNames::height) >+ return evaluateSize(context.renderer.height()) ? EvaluationResult::True : EvaluationResult::False; > >- return result; >+ return EvaluationResult::Unknown; > } > > } >diff --git a/Source/WebCore/style/ContainerQueryEvaluator.h b/Source/WebCore/style/ContainerQueryEvaluator.h >index 8f6e73007f75fab5b854e11ce2297c069fb58974..99be222d15d9f9d1ab07a386741d23b29f499cd6 100644 >--- a/Source/WebCore/style/ContainerQueryEvaluator.h >+++ b/Source/WebCore/style/ContainerQueryEvaluator.h >@@ -24,11 +24,11 @@ > > #pragma once > >+#include "ContainerQuery.h" > #include <wtf/Ref.h> > > namespace WebCore { > >-struct FilteredContainerQuery; > class Element; > > namespace Style { >@@ -40,6 +40,14 @@ public: > bool evaluate(const FilteredContainerQuery&) const; > > private: >+ struct EvaluationContext; >+ enum class EvaluationResult : uint8_t { False, True, Unknown }; >+ >+ EvaluationResult evaluateQuery(const CQ::ContainerQuery&, const EvaluationContext&) const; >+ EvaluationResult evaluateQuery(const CQ::SizeQuery&, const EvaluationContext&) const; >+ template<typename ConditionType> EvaluationResult evaluateCondition(const ConditionType&, const EvaluationContext&) const; >+ EvaluationResult evaluateSizeFeature(const CQ::SizeFeature&, const EvaluationContext&) const; >+ > const Vector<Ref<const Element>>& m_containers; > }; > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 3be07245d1efefa04cd1cde4998c064ebcd5ac08..991656e88bf0e318748b164a9f48367d39ff21ee 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,12 @@ >+2022-02-14 Antti Koivisto <antti@apple.com> >+ >+ [CSS Container Queries] Implement full query parser and evaluator >+ https://bugs.webkit.org/show_bug.cgi?id=236580 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * TestExpectations: >+ > 2022-02-12 Tim Nguyen <ntim@apple.com> > > Skip imported/w3c/web-platform-tests/url/toascii.window.html on Catalina/Big Sur >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index b840e372c04da2d030eb6172d73b8d222e1526c9..e1a8546de0f1f9770c9859d0f66b0eb7f6fc30da 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,16 @@ >+2022-02-14 Antti Koivisto <antti@apple.com> >+ >+ [CSS Container Queries] Implement full query parser and evaluator >+ https://bugs.webkit.org/show_bug.cgi?id=236580 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt: >+ * web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom.tentative-expected.txt: >+ * web-platform-tests/css/css-contain/container-queries/container-type-invalidation-expected.txt: >+ * web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt: >+ * web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt: >+ > 2022-02-12 Tim Nguyen <ntim@apple.com> > > Unreviewed test gardening: imported/w3c/web-platform-tests/url/toascii.window.html >diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations >index 539f1ceba6beb90eba810df234934864beaa0d55..67e8d0c1360996ddccfa58baf24282160b0623d5 100644 >--- a/LayoutTests/TestExpectations >+++ b/LayoutTests/TestExpectations >@@ -4710,6 +4710,7 @@ imported/w3c/web-platform-tests/css/css-contain/contain-html-overflow-004.html [ > webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/display-in-container.html [ ImageOnlyFailure ] > webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/pseudo-elements-002.tentative.html [ ImageOnlyFailure ] > webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/multicol-inside-container.html [ ImageOnlyFailure ] >+webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/inline-size-bfc-floats.html [ ImageOnlyFailure ] > > # Flaky css-contain test > imported/w3c/web-platform-tests/css/css-contain/content-visibility/animation-display-lock.html [ Failure Pass ] >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt >index 502b9f76673f4e962a46319c36128550f3030123..30797997f5eb0080ad5f89f6e6bb5e9c6eb9abea 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt >@@ -1,36 +1,36 @@ > >-FAIL size(width) assert_equals: expected "true" but got "" >-FAIL size(min-width: 0px) assert_equals: expected "true" but got "" >-FAIL size(max-width: 0px) assert_equals: expected "true" but got "" >-FAIL size(height) assert_equals: expected "true" but got "" >-FAIL size(min-height: 0px) assert_equals: expected "true" but got "" >-FAIL size(max-height: 0px) assert_equals: expected "true" but got "" >+PASS size(width) >+PASS size(min-width: 0px) >+PASS size(max-width: 0px) >+PASS size(height) >+PASS size(min-height: 0px) >+PASS size(max-height: 0px) > FAIL size(aspect-ratio) assert_equals: expected "true" but got "" >-FAIL size(min-aspect-ratio: 1/2) assert_equals: expected "true" but got "" >-FAIL size(max-aspect-ratio: 1/2) assert_equals: expected "true" but got "" >-FAIL size(orientation: portrait) assert_equals: expected "true" but got "" >+FAIL size(min-aspect-ratio: 1/2) assert_equals: expected 2 but got 0 >+FAIL size(max-aspect-ratio: 1/2) assert_equals: expected 2 but got 0 >+FAIL size(orientation: portrait) assert_equals: expected 2 but got 0 > FAIL size(inline-size) assert_equals: expected "true" but got "" > FAIL size(min-inline-size: 0px) assert_equals: expected "true" but got "" > FAIL size(max-inline-size: 0px) assert_equals: expected "true" but got "" > FAIL size(block-size) assert_equals: expected "true" but got "" > FAIL size(min-block-size: 0px) assert_equals: expected "true" but got "" > FAIL size(max-block-size: 0px) assert_equals: expected "true" but got "" >-FAIL size(width: 100px) assert_equals: expected "true" but got "" >-FAIL size((width: 100px)) assert_equals: expected "true" but got "" >-FAIL size(not (width: 100px)) assert_equals: expected "true" but got "" >-FAIL size((width: 100px) and (height: 100px)) assert_equals: expected "true" but got "" >-FAIL size((width: 50px) or (height: 100px)) assert_equals: expected "true" but got "" >-FAIL size(width < 100px) assert_equals: expected "true" but got "" >-FAIL size(100px < width) assert_equals: expected "true" but got "" >-FAIL size(100px < width < 200px) assert_equals: expected "true" but got "" >+PASS size(width: 100px) >+PASS size((width: 100px)) >+PASS size(not (width: 100px)) >+PASS size((width: 100px) and (height: 100px)) >+PASS size((width: 50px) or (height: 100px)) >+PASS size(width < 100px) >+FAIL size(100px < width) assert_equals: expected 2 but got 0 >+FAIL size(100px < width < 200px) assert_equals: expected 2 but got 0 > PASS foo(width) > PASS size(asdf) >-PASS size(resolution > 100dpi) >-PASS size(resolution: 150dpi) >+FAIL size(resolution > 100dpi) assert_equals: expected 2 but got 0 >+FAIL size(resolution: 150dpi) assert_equals: expected 2 but got 0 > PASS size(color) >-PASS size(min-color: 1) >-PASS size(color-index >= 1) >-PASS (color-index >= 1) >+FAIL size(min-color: 1) assert_equals: expected 2 but got 0 >+FAIL size(color-index >= 1) assert_equals: expected 2 but got 0 >+FAIL (color-index >= 1) assert_equals: expected 2 but got 0 > PASS size(grid) > PASS (grid) > PASS screen >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom.tentative-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom.tentative-expected.txt >index d81ef243564bc251c04aabf94e2acf0f455a80a7..e376a2c0920ef13c53bcd3a81bc090d50492a5b5 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom.tentative-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom.tentative-expected.txt >@@ -1,6 +1,6 @@ > > FAIL Match container in outer tree null is not an object (evaluating 'document.querySelector("#inclusive-ancestor-across-root > div").shadowRoot.querySelector') >-FAIL Match container in same tree, not walking flat tree ancestors assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)" >+PASS Match container in same tree, not walking flat tree ancestors > FAIL Match container in ::slotted selector's originating element tree assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)" > FAIL Match container in outer tree for :host assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)" > FAIL Match container in ::part selector's originating element tree null is not an object (evaluating 'document.querySelector("#inclusive-ancestor-part > div").shadowRoot.querySelector') >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-type-invalidation-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-type-invalidation-expected.txt >index c351c237c78dcbf4f8e8f43ff942cc0cf9abb6a9..7e1fbf1d22ca2b2b95f2ddef687258f9af058389 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-type-invalidation-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-type-invalidation-expected.txt >@@ -1,4 +1,4 @@ > Test > >-FAIL Changing the container type invalidates relevant descendants assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)" >+FAIL Changing the container type invalidates relevant descendants assert_equals: expected "rgb(0, 0, 0)" but got "rgb(0, 128, 0)" > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt >index 9b1cb36ac5e1fd2706bac785126afde90869ef1b..e08092bc08a74481ed5120c07ae29376695ed6a2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/query-evaluation-expected.txt >@@ -3,18 +3,18 @@ PASS size(width) > PASS size(height) > PASS size(unknown) > PASS unknown(width) >-FAIL (size(width)) assert_equals: expected "true" but got "false" >+PASS (size(width)) > PASS (size(height)) > PASS (size(unknown)) >-FAIL (((size(width)))) assert_equals: expected "true" but got "false" >+PASS (((size(width)))) > PASS (((size(height)))) > PASS (((size(unknown)))) > PASS (not size(width)) >-FAIL (not size(height)) assert_equals: expected "true" but got "false" >+PASS (not size(height)) > PASS (not size(unknown)) > PASS (not unknown(width)) >-FAIL (size(width) and size(width)) assert_equals: expected "true" but got "false" >-FAIL (size(width) and size(width) and size(width)) assert_equals: expected "true" but got "false" >+PASS (size(width) and size(width)) >+PASS (size(width) and size(width) and size(width)) > PASS (size(height) and size(height)) > PASS (size(height) and size(width) and size(width)) > PASS (size(width) and size(height) and size(width)) >@@ -22,30 +22,30 @@ PASS (size(width) and size(width) and size(height)) > PASS (size(unknown) and size(width) and size(width)) > PASS (size(width) and size(unknown) and size(width)) > PASS (size(width) and size(width) and size(unknown)) >-FAIL (size(width) or size(width)) assert_equals: expected "true" but got "false" >-FAIL (size(width) or size(width) or size(width)) assert_equals: expected "true" but got "false" >+PASS (size(width) or size(width)) >+PASS (size(width) or size(width) or size(width)) > PASS (size(height) or size(height)) >-FAIL (size(height) or size(width) or size(width)) assert_equals: expected "true" but got "false" >-FAIL (size(width) or size(height) or size(width)) assert_equals: expected "true" but got "false" >-FAIL (size(width) or size(width) or size(height)) assert_equals: expected "true" but got "false" >-FAIL (size(unknown) or size(width) or size(width)) assert_equals: expected "true" but got "false" >-FAIL (size(width) or size(unknown) or size(width)) assert_equals: expected "true" but got "false" >-FAIL (size(width) or size(width) or size(unknown)) assert_equals: expected "true" but got "false" >-FAIL (size(unknown) or size(height) or size(width)) assert_equals: expected "true" but got "false" >+PASS (size(height) or size(width) or size(width)) >+PASS (size(width) or size(height) or size(width)) >+PASS (size(width) or size(width) or size(height)) >+PASS (size(unknown) or size(width) or size(width)) >+PASS (size(width) or size(unknown) or size(width)) >+PASS (size(width) or size(width) or size(unknown)) >+PASS (size(unknown) or size(height) or size(width)) > PASS (not (size(width) and size(width))) >-FAIL (not (size(width) and size(height))) assert_equals: expected "true" but got "false" >+PASS (not (size(width) and size(height))) > PASS (size(width) and (not (size(height) or size(width)))) >-FAIL (size(height) or (not (size(height) and size(width)))) assert_equals: expected "true" but got "false" >+PASS (size(height) or (not (size(height) and size(width)))) > PASS (size(height) or (size(height) and size(width))) >-FAIL size((width)) assert_equals: expected "true" but got "false" >+PASS size((width)) > PASS size((height)) > PASS size((unknown)) > PASS unknown((width)) > PASS size(not (width)) >-FAIL size(not (height)) assert_equals: expected "true" but got "false" >+PASS size(not (height)) > PASS size(not (unknown)) >-FAIL size((width) and (width)) assert_equals: expected "true" but got "false" >-FAIL size((width) and (width) and (width)) assert_equals: expected "true" but got "false" >+PASS size((width) and (width)) >+PASS size((width) and (width) and (width)) > PASS size((height) and (height)) > PASS size((height) and (width) and (width)) > PASS size((width) and (height) and (width)) >@@ -53,19 +53,19 @@ PASS size((width) and (width) and (height)) > PASS size((unknown) and (width) and (width)) > PASS size((width) and (unknown) and (width)) > PASS size((width) and (width) and (unknown)) >-FAIL size((width) or (width)) assert_equals: expected "true" but got "false" >-FAIL size((width) or (width) or (width)) assert_equals: expected "true" but got "false" >+PASS size((width) or (width)) >+PASS size((width) or (width) or (width)) > PASS size((height) or (height)) >-FAIL size((height) or (width) or (width)) assert_equals: expected "true" but got "false" >-FAIL size((width) or (height) or (width)) assert_equals: expected "true" but got "false" >-FAIL size((width) or (width) or (height)) assert_equals: expected "true" but got "false" >-FAIL size((unknown) or (width) or (width)) assert_equals: expected "true" but got "false" >-FAIL size((width) or (unknown) or (width)) assert_equals: expected "true" but got "false" >-FAIL size((width) or (width) or (unknown)) assert_equals: expected "true" but got "false" >-FAIL size((unknown) or (height) or (width)) assert_equals: expected "true" but got "false" >+PASS size((height) or (width) or (width)) >+PASS size((width) or (height) or (width)) >+PASS size((width) or (width) or (height)) >+PASS size((unknown) or (width) or (width)) >+PASS size((width) or (unknown) or (width)) >+PASS size((width) or (width) or (unknown)) >+PASS size((unknown) or (height) or (width)) > PASS size(not ((width) and (width))) >-FAIL size(not ((width) and (height))) assert_equals: expected "true" but got "false" >+PASS size(not ((width) and (height))) > PASS size((width) and (not ((height) or (width)))) >-FAIL size((height) or (not ((height) and (width)))) assert_equals: expected "true" but got "false" >+PASS size((height) or (not ((height) and (width)))) > PASS size((height) or ((height) and (width))) > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt >index c2f2d69aab240a0d13009b02451356f1d92c47c4..9b4b97c6744231658df105ab347fc3a44c900bee 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/size-feature-evaluation-expected.txt >@@ -1,12 +1,12 @@ > Test > >-PASS size(width < 100px) (.horizontal) >+FAIL size(width < 100px) (.horizontal) assert_equals: expected "" but got "true" > FAIL size(width >= 100px) (.horizontal) assert_equals: expected "true" but got "" > PASS size(min-width: 100px) (.horizontal) > PASS size(min-width: 101px) (.horizontal) > PASS size(max-width: 100px) (.horizontal) > PASS size(max-width: 99px) (.horizontal) >-PASS size(height < 200px) (.horizontal) >+FAIL size(height < 200px) (.horizontal) assert_equals: expected "" but got "true" > FAIL size(height >= 200px) (.horizontal) assert_equals: expected "true" but got "" > PASS size(min-height: 200px) (.horizontal) > PASS size(min-height: 201px) (.horizontal) >@@ -28,13 +28,13 @@ PASS size(orientation: landscape) (.horizontal) > FAIL size(orientation: portrait) (.horizontal) assert_equals: expected "true" but got "" > FAIL size(aspect-ratio: 1/2) (.horizontal) assert_equals: expected "true" but got "" > PASS size(aspect-ratio: 2/1) (.horizontal) >-PASS size(width < 100px) (.vertical) >+FAIL size(width < 100px) (.vertical) assert_equals: expected "" but got "true" > FAIL size(width >= 100px) (.vertical) assert_equals: expected "true" but got "" > PASS size(min-width: 100px) (.vertical) > PASS size(min-width: 101px) (.vertical) > PASS size(max-width: 100px) (.vertical) > PASS size(max-width: 99px) (.vertical) >-PASS size(height < 200px) (.vertical) >+FAIL size(height < 200px) (.vertical) assert_equals: expected "" but got "true" > FAIL size(height >= 200px) (.vertical) assert_equals: expected "true" but got "" > PASS size(min-height: 200px) (.vertical) > PASS size(min-height: 201px) (.vertical)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 236580
:
451874
|
451880
|
451884
|
451894
|
451921