style: Fix container orientation evaluation

Allow keyword evaluators to return unknown.

Do you know of a good test to extend here? Otherwise I can add a new
one, though I gotta run atm.

Differential Revision: https://phabricator.services.mozilla.com/D165630
This commit is contained in:
Emilio Cobos Álvarez 2022-12-29 13:02:37 +00:00 committed by Martin Robinson
parent 2389650734
commit d30400d3ea
4 changed files with 20 additions and 13 deletions

View file

@ -8,6 +8,7 @@ use crate::parser::ParserContext;
use crate::values::computed::{self, CSSPixelLength, Ratio, Resolution}; use crate::values::computed::{self, CSSPixelLength, Ratio, Resolution};
use crate::Atom; use crate::Atom;
use cssparser::Parser; use cssparser::Parser;
use super::condition::KleeneValue;
use std::fmt; use std::fmt;
use style_traits::ParseError; use style_traits::ParseError;
@ -54,7 +55,7 @@ pub enum Evaluator {
serializer: KeywordSerializer, serializer: KeywordSerializer,
/// The evaluator itself. This is guaranteed to be called with a /// The evaluator itself. This is guaranteed to be called with a
/// keyword that `parser` has produced. /// keyword that `parser` has produced.
evaluator: fn(&computed::Context, Option<KeywordDiscriminant>) -> bool, evaluator: fn(&computed::Context, Option<KeywordDiscriminant>) -> KleeneValue,
}, },
} }
@ -84,12 +85,12 @@ macro_rules! keyword_evaluator {
fn __evaluate( fn __evaluate(
context: &$crate::values::computed::Context, context: &$crate::values::computed::Context,
value: Option<$crate::queries::feature::KeywordDiscriminant>, value: Option<$crate::queries::feature::KeywordDiscriminant>,
) -> bool { ) -> $crate::queries::condition::KleeneValue {
// This unwrap is ok because the only discriminants that get // This unwrap is ok because the only discriminants that get
// back to us is the ones that `parse` produces. // back to us is the ones that `parse` produces.
let value: Option<$keyword_type> = let value: Option<$keyword_type> =
value.map(|kw| ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap()); value.map(|kw| ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap());
$actual_evaluator(context, value) $crate::queries::condition::KleeneValue::from($actual_evaluator(context, value))
} }
$crate::queries::feature::Evaluator::Enumerated { $crate::queries::feature::Evaluator::Enumerated {

View file

@ -637,7 +637,7 @@ impl QueryFeatureExpression {
.kind .kind
.non_ranged_value() .non_ranged_value()
.map(|v| *expect!(Enumerated, v)); .map(|v| *expect!(Enumerated, v));
evaluator(context, computed) return evaluator(context, computed)
}, },
Evaluator::BoolInteger(eval) => { Evaluator::BoolInteger(eval) => {
let computed = self let computed = self

View file

@ -4,6 +4,9 @@
//! Common feature values between media and container features. //! Common feature values between media and container features.
use app_units::Au;
use euclid::default::Size2D;
/// The orientation media / container feature. /// The orientation media / container feature.
/// https://drafts.csswg.org/mediaqueries-5/#orientation /// https://drafts.csswg.org/mediaqueries-5/#orientation
/// https://drafts.csswg.org/css-contain-3/#orientation /// https://drafts.csswg.org/css-contain-3/#orientation
@ -17,10 +20,7 @@ pub enum Orientation {
impl Orientation { impl Orientation {
/// A helper to evaluate a orientation query given a generic size getter. /// A helper to evaluate a orientation query given a generic size getter.
pub fn eval<T>(size: euclid::default::Size2D<T>, value: Option<Self>) -> bool pub fn eval(size: Size2D<Au>, value: Option<Self>) -> bool {
where
T: PartialOrd,
{
let query_orientation = match value { let query_orientation = match value {
Some(v) => v, Some(v) => v,
None => return true, None => return true,

View file

@ -296,6 +296,12 @@ pub struct ContainerInfo {
wm: WritingMode, wm: WritingMode,
} }
impl ContainerInfo {
fn size(&self) -> Option<Size2D<Au>> {
Some(Size2D::new(self.size.width?, self.size.height?))
}
}
fn eval_width(context: &Context) -> Option<CSSPixelLength> { fn eval_width(context: &Context) -> Option<CSSPixelLength> {
let info = context.container_info.as_ref()?; let info = context.container_info.as_ref()?;
Some(CSSPixelLength::new(info.size.width?.to_f32_px())) Some(CSSPixelLength::new(info.size.width?.to_f32_px()))
@ -332,12 +338,12 @@ fn eval_aspect_ratio(context: &Context) -> Option<Ratio> {
)) ))
} }
fn eval_orientation(context: &Context, value: Option<Orientation>) -> bool { fn eval_orientation(context: &Context, value: Option<Orientation>) -> KleeneValue {
let info = match context.container_info.as_ref() { let size = match context.container_info.as_ref().and_then(|info| info.size()) {
Some(info) => info, Some(size) => size,
None => return false, None => return KleeneValue::Unknown,
}; };
Orientation::eval(info.size, value) KleeneValue::from(Orientation::eval(size, value))
} }
/// https://drafts.csswg.org/css-contain-3/#container-features /// https://drafts.csswg.org/css-contain-3/#container-features