|
Lines 76-82
bool ContainerQueryEvaluator::evaluate(const FilteredContainerQuery& filteredCon
a/Source/WebCore/style/ContainerQueryEvaluator.cpp_sec1
|
| 76 |
|
76 |
|
| 77 |
auto container = resolveContainer(); |
77 |
auto container = resolveContainer(); |
| 78 |
if (!container) |
78 |
if (!container) |
| 79 |
return { }; |
79 |
return false; |
| 80 |
|
80 |
|
| 81 |
return evaluateQuery(filteredContainerQuery.query, *container) == EvaluationResult::True; |
81 |
return evaluateQuery(filteredContainerQuery.query, *container) == EvaluationResult::True; |
| 82 |
} |
82 |
} |
|
Lines 108-123
auto ContainerQueryEvaluator::evaluateCondition(const ConditionType& condition,
a/Source/WebCore/style/ContainerQueryEvaluator.cpp_sec2
|
| 108 |
return EvaluationResult::Unknown; |
108 |
return EvaluationResult::Unknown; |
| 109 |
|
109 |
|
| 110 |
switch (condition.logicalOperator) { |
110 |
switch (condition.logicalOperator) { |
| 111 |
case CQ::LogicalOperator::Not: { |
111 |
case CQ::LogicalOperator::Not: |
| 112 |
switch (evaluateQuery(condition.queries.first(), container)) { |
112 |
return !evaluateQuery(condition.queries.first(), container); |
| 113 |
case EvaluationResult::True: |
|
|
| 114 |
return EvaluationResult::False; |
| 115 |
case EvaluationResult::False: |
| 116 |
return EvaluationResult::True; |
| 117 |
case EvaluationResult::Unknown: |
| 118 |
return EvaluationResult::Unknown; |
| 119 |
} |
| 120 |
} |
| 121 |
case CQ::LogicalOperator::And: { |
113 |
case CQ::LogicalOperator::And: { |
| 122 |
auto result = EvaluationResult::True; |
114 |
auto result = EvaluationResult::True; |
| 123 |
for (auto query : condition.queries) { |
115 |
for (auto query : condition.queries) { |
|
Lines 162-173
static std::optional<LayoutUnit> computeSize(const CSSValue* value, const CSSToL
a/Source/WebCore/style/ContainerQueryEvaluator.cpp_sec3
|
| 162 |
|
154 |
|
| 163 |
auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFeature, const ResolvedContainer& container) const -> EvaluationResult |
155 |
auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFeature, const ResolvedContainer& container) const -> EvaluationResult |
| 164 |
{ |
156 |
{ |
| 165 |
auto toEvaluationResult = [](bool boolean) { |
157 |
auto compare = [](CQ::ComparisonOperator op, auto left, auto right) { |
| 166 |
return boolean ? EvaluationResult::True : EvaluationResult::False; |
158 |
switch (op) { |
| 167 |
}; |
|
|
| 168 |
|
| 169 |
auto compare = [&](auto left, auto right) { |
| 170 |
switch (sizeFeature.comparisonOperator) { |
| 171 |
case CQ::ComparisonOperator::LessThan: |
159 |
case CQ::ComparisonOperator::LessThan: |
| 172 |
return left < right; |
160 |
return left < right; |
| 173 |
case CQ::ComparisonOperator::GreaterThan: |
161 |
case CQ::ComparisonOperator::GreaterThan: |
|
Lines 178-198
auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFea
a/Source/WebCore/style/ContainerQueryEvaluator.cpp_sec4
|
| 178 |
return left >= right; |
166 |
return left >= right; |
| 179 |
case CQ::ComparisonOperator::Equal: |
167 |
case CQ::ComparisonOperator::Equal: |
| 180 |
return left == right; |
168 |
return left == right; |
| 181 |
case CQ::ComparisonOperator::True: |
|
|
| 182 |
ASSERT_NOT_REACHED(); |
| 183 |
return false; |
| 184 |
} |
169 |
} |
| 185 |
}; |
170 |
}; |
| 186 |
|
171 |
|
|
|
172 |
enum class Side : uint8_t { Left, Right }; |
| 173 |
auto evaluateSizeComparison = [&](LayoutUnit size, const std::optional<CQ::Comparison>& comparison, Side side) { |
| 174 |
if (!comparison) |
| 175 |
return EvaluationResult::True; |
| 176 |
auto expressionSize = computeSize(comparison->value.get(), container.conversionData); |
| 177 |
if (!expressionSize) |
| 178 |
return EvaluationResult::Unknown; |
| 179 |
auto left = side == Side::Left ? *expressionSize : size; |
| 180 |
auto right = side == Side::Left ? size : *expressionSize; |
| 181 |
|
| 182 |
return toEvaluationResult(compare(comparison->op, left, right)); |
| 183 |
}; |
| 184 |
|
| 187 |
auto evaluateSize = [&](LayoutUnit size) { |
185 |
auto evaluateSize = [&](LayoutUnit size) { |
| 188 |
if (sizeFeature.comparisonOperator == CQ::ComparisonOperator::True) |
186 |
if (!sizeFeature.leftComparison && !sizeFeature.rightComparison) |
| 189 |
return toEvaluationResult(!!size); |
187 |
return toEvaluationResult(!!size); |
| 190 |
|
188 |
|
| 191 |
auto expressionSize = computeSize(sizeFeature.value.get(), container.conversionData); |
189 |
auto leftResult = evaluateSizeComparison(size, sizeFeature.leftComparison, Side::Left); |
| 192 |
if (!expressionSize) |
190 |
auto rightResult = evaluateSizeComparison(size, sizeFeature.rightComparison, Side::Right); |
|
|
191 |
|
| 192 |
return leftResult & rightResult; |
| 193 |
}; |
| 194 |
|
| 195 |
auto evaluateAspectRatioComparison = [&](double aspectRatio, const std::optional<CQ::Comparison>& comparison, Side side) { |
| 196 |
if (!comparison) |
| 197 |
return EvaluationResult::True; |
| 198 |
|
| 199 |
if (!is<CSSValueList>(comparison->value)) |
| 200 |
return EvaluationResult::Unknown; |
| 201 |
|
| 202 |
auto& ratioList = downcast<CSSValueList>(*comparison->value); |
| 203 |
if (ratioList.length() != 2) |
| 193 |
return EvaluationResult::Unknown; |
204 |
return EvaluationResult::Unknown; |
| 194 |
|
205 |
|
| 195 |
return toEvaluationResult(compare(size, *expressionSize)); |
206 |
auto first = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(0)); |
|
|
207 |
auto second = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(1)); |
| 208 |
|
| 209 |
if (!first || !second || !first->isNumberOrInteger() || !second->isNumberOrInteger()) |
| 210 |
return EvaluationResult::Unknown; |
| 211 |
|
| 212 |
auto expressionRatio = first->doubleValue() / second->doubleValue(); |
| 213 |
|
| 214 |
auto left = side == Side::Left ? expressionRatio : aspectRatio; |
| 215 |
auto right = side == Side::Left ? aspectRatio : expressionRatio; |
| 216 |
|
| 217 |
return toEvaluationResult(compare(comparison->op, left, right)); |
| 196 |
}; |
218 |
}; |
| 197 |
|
219 |
|
| 198 |
enum class Axis : uint8_t { Both, Block, Inline, Width, Height }; |
220 |
enum class Axis : uint8_t { Both, Block, Inline, Width, Height }; |
|
Lines 245-279
auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFea
a/Source/WebCore/style/ContainerQueryEvaluator.cpp_sec5
|
| 245 |
return EvaluationResult::Unknown; |
267 |
return EvaluationResult::Unknown; |
| 246 |
|
268 |
|
| 247 |
auto boxRatio = container.renderer.contentWidth().toDouble() / container.renderer.contentHeight().toDouble(); |
269 |
auto boxRatio = container.renderer.contentWidth().toDouble() / container.renderer.contentHeight().toDouble(); |
| 248 |
if (sizeFeature.comparisonOperator == CQ::ComparisonOperator::True) |
270 |
|
|
|
271 |
if (!sizeFeature.leftComparison && !sizeFeature.rightComparison) |
| 249 |
return toEvaluationResult(!!boxRatio); |
272 |
return toEvaluationResult(!!boxRatio); |
| 250 |
|
273 |
|
| 251 |
if (!is<CSSValueList>(sizeFeature.value)) |
274 |
auto leftResult = evaluateAspectRatioComparison(boxRatio, sizeFeature.leftComparison, Side::Left); |
| 252 |
return EvaluationResult::Unknown; |
275 |
auto rightResult = evaluateAspectRatioComparison(boxRatio, sizeFeature.rightComparison, Side::Right); |
| 253 |
|
|
|
| 254 |
auto& ratioList = downcast<CSSValueList>(*sizeFeature.value); |
| 255 |
if (ratioList.length() != 2) |
| 256 |
return EvaluationResult::Unknown; |
| 257 |
|
| 258 |
auto first = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(0)); |
| 259 |
auto second = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(1)); |
| 260 |
|
| 261 |
if (!first || !second || !first->isNumberOrInteger() || !second->isNumberOrInteger()) |
| 262 |
return EvaluationResult::Unknown; |
| 263 |
|
| 264 |
auto expressionRatio = first->doubleValue() / second->doubleValue(); |
| 265 |
|
276 |
|
| 266 |
return toEvaluationResult(compare(boxRatio, expressionRatio)); |
277 |
return leftResult & rightResult; |
| 267 |
} |
278 |
} |
| 268 |
|
279 |
|
| 269 |
if (sizeFeature.name == CQ::FeatureNames::orientation()) { |
280 |
if (sizeFeature.name == CQ::FeatureNames::orientation()) { |
| 270 |
if (!containerSupportsRequiredAxis(Axis::Both)) |
281 |
if (!containerSupportsRequiredAxis(Axis::Both)) |
| 271 |
return EvaluationResult::Unknown; |
282 |
return EvaluationResult::Unknown; |
| 272 |
|
283 |
|
| 273 |
if (!is<CSSPrimitiveValue>(sizeFeature.value) || sizeFeature.comparisonOperator != CQ::ComparisonOperator::Equal) |
284 |
if (!sizeFeature.rightComparison) |
|
|
285 |
return EvaluationResult::Unknown; |
| 286 |
|
| 287 |
auto& comparison = *sizeFeature.rightComparison; |
| 288 |
|
| 289 |
if (!is<CSSPrimitiveValue>(comparison.value) || comparison.op != CQ::ComparisonOperator::Equal) |
| 274 |
return EvaluationResult::Unknown; |
290 |
return EvaluationResult::Unknown; |
| 275 |
|
291 |
|
| 276 |
auto& value = downcast<CSSPrimitiveValue>(*sizeFeature.value); |
292 |
auto& value = downcast<CSSPrimitiveValue>(*sizeFeature.rightComparison->value); |
| 277 |
|
293 |
|
| 278 |
bool isPortrait = container.renderer.contentHeight() >= container.renderer.contentWidth(); |
294 |
bool isPortrait = container.renderer.contentHeight() >= container.renderer.contentWidth(); |
| 279 |
if (value.valueID() == CSSValuePortrait) |
295 |
if (value.valueID() == CSSValuePortrait) |