mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
style: Fix container query evaluation on unsupported axis
We were falling back to viewport size, which is not what the spec says. Differential Revision: https://phabricator.services.mozilla.com/D161132
This commit is contained in:
parent
aba0a4bce0
commit
81ae588ec9
3 changed files with 47 additions and 35 deletions
|
@ -34,11 +34,13 @@ pub type KeywordParser = for<'a, 'i, 't> fn(
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub enum Evaluator {
|
pub enum Evaluator {
|
||||||
Length(QueryFeatureGetter<CSSPixelLength>),
|
Length(QueryFeatureGetter<CSSPixelLength>),
|
||||||
|
OptionalLength(QueryFeatureGetter<Option<CSSPixelLength>>),
|
||||||
Integer(QueryFeatureGetter<u32>),
|
Integer(QueryFeatureGetter<u32>),
|
||||||
Float(QueryFeatureGetter<f32>),
|
Float(QueryFeatureGetter<f32>),
|
||||||
BoolInteger(QueryFeatureGetter<bool>),
|
BoolInteger(QueryFeatureGetter<bool>),
|
||||||
/// A non-negative number ratio, such as the one from device-pixel-ratio.
|
/// A non-negative number ratio, such as the one from device-pixel-ratio.
|
||||||
NumberRatio(QueryFeatureGetter<Ratio>),
|
NumberRatio(QueryFeatureGetter<Ratio>),
|
||||||
|
OptionalNumberRatio(QueryFeatureGetter<Option<Ratio>>),
|
||||||
/// A resolution.
|
/// A resolution.
|
||||||
Resolution(QueryFeatureGetter<Resolution>),
|
Resolution(QueryFeatureGetter<Resolution>),
|
||||||
/// A keyword value.
|
/// A keyword value.
|
||||||
|
|
|
@ -591,6 +591,14 @@ impl QueryFeatureExpression {
|
||||||
self.kind
|
self.kind
|
||||||
.evaluate(v, |v| expect!(Length, v).to_computed_value(context))
|
.evaluate(v, |v| expect!(Length, v).to_computed_value(context))
|
||||||
},
|
},
|
||||||
|
Evaluator::OptionalLength(eval) => {
|
||||||
|
let v = match eval(context) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
self.kind
|
||||||
|
.evaluate(v, |v| expect!(Length, v).to_computed_value(context))
|
||||||
|
},
|
||||||
Evaluator::Integer(eval) => {
|
Evaluator::Integer(eval) => {
|
||||||
let v = eval(context);
|
let v = eval(context);
|
||||||
self.kind.evaluate(v, |v| *expect!(Integer, v))
|
self.kind.evaluate(v, |v| *expect!(Integer, v))
|
||||||
|
@ -608,6 +616,15 @@ impl QueryFeatureExpression {
|
||||||
self.kind
|
self.kind
|
||||||
.evaluate(ratio, |v| expect!(NumberRatio, v).used_value())
|
.evaluate(ratio, |v| expect!(NumberRatio, v).used_value())
|
||||||
},
|
},
|
||||||
|
Evaluator::OptionalNumberRatio(eval) => {
|
||||||
|
let ratio = match eval(context) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
// See above for subtleties here.
|
||||||
|
self.kind
|
||||||
|
.evaluate(ratio, |v| expect!(NumberRatio, v).used_value())
|
||||||
|
},
|
||||||
Evaluator::Resolution(eval) => {
|
Evaluator::Resolution(eval) => {
|
||||||
let v = eval(context).dppx();
|
let v = eval(context).dppx();
|
||||||
self.kind.evaluate(v, |v| {
|
self.kind.evaluate(v, |v| {
|
||||||
|
@ -686,7 +703,7 @@ impl QueryExpressionValue {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<QueryExpressionValue, ParseError<'i>> {
|
) -> Result<QueryExpressionValue, ParseError<'i>> {
|
||||||
Ok(match for_feature.evaluator {
|
Ok(match for_feature.evaluator {
|
||||||
Evaluator::Length(..) => {
|
Evaluator::OptionalLength(..) | Evaluator::Length(..) => {
|
||||||
let length = Length::parse_non_negative(context, input)?;
|
let length = Length::parse_non_negative(context, input)?;
|
||||||
QueryExpressionValue::Length(length)
|
QueryExpressionValue::Length(length)
|
||||||
},
|
},
|
||||||
|
@ -706,7 +723,7 @@ impl QueryExpressionValue {
|
||||||
let number = Number::parse(context, input)?;
|
let number = Number::parse(context, input)?;
|
||||||
QueryExpressionValue::Float(number.get())
|
QueryExpressionValue::Float(number.get())
|
||||||
},
|
},
|
||||||
Evaluator::NumberRatio(..) => {
|
Evaluator::OptionalNumberRatio(..) | Evaluator::NumberRatio(..) => {
|
||||||
use crate::values::specified::Ratio as SpecifiedRatio;
|
use crate::values::specified::Ratio as SpecifiedRatio;
|
||||||
let ratio = SpecifiedRatio::parse(context, input)?;
|
let ratio = SpecifiedRatio::parse(context, input)?;
|
||||||
QueryExpressionValue::NumberRatio(Ratio::new(ratio.0.get(), ratio.1.get()))
|
QueryExpressionValue::NumberRatio(Ratio::new(ratio.0.get(), ratio.1.get()))
|
||||||
|
|
|
@ -261,51 +261,44 @@ pub struct ContainerInfo {
|
||||||
wm: WritingMode,
|
wm: WritingMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_container(context: &Context) -> ContainerInfo {
|
fn eval_width(context: &Context) -> Option<CSSPixelLength> {
|
||||||
if let Some(ref info) = context.container_info {
|
let info = context.container_info.as_ref()?;
|
||||||
return info.clone();
|
Some(CSSPixelLength::new(info.size.width.to_f32_px()))
|
||||||
}
|
|
||||||
ContainerInfo {
|
|
||||||
size: context.device().au_viewport_size(),
|
|
||||||
wm: WritingMode::horizontal_tb(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_width(context: &Context) -> CSSPixelLength {
|
fn eval_height(context: &Context) -> Option<CSSPixelLength> {
|
||||||
let info = get_container(context);
|
let info = context.container_info.as_ref()?;
|
||||||
CSSPixelLength::new(info.size.width.to_f32_px())
|
Some(CSSPixelLength::new(info.size.height.to_f32_px()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_height(context: &Context) -> CSSPixelLength {
|
fn eval_inline_size(context: &Context) -> Option<CSSPixelLength> {
|
||||||
let info = get_container(context);
|
let info = context.container_info.as_ref()?;
|
||||||
CSSPixelLength::new(info.size.height.to_f32_px())
|
Some(CSSPixelLength::new(
|
||||||
}
|
|
||||||
|
|
||||||
fn eval_inline_size(context: &Context) -> CSSPixelLength {
|
|
||||||
let info = get_container(context);
|
|
||||||
CSSPixelLength::new(
|
|
||||||
LogicalSize::from_physical(info.wm, info.size)
|
LogicalSize::from_physical(info.wm, info.size)
|
||||||
.inline
|
.inline
|
||||||
.to_f32_px(),
|
.to_f32_px(),
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_block_size(context: &Context) -> CSSPixelLength {
|
fn eval_block_size(context: &Context) -> Option<CSSPixelLength> {
|
||||||
let info = get_container(context);
|
let info = context.container_info.as_ref()?;
|
||||||
CSSPixelLength::new(
|
Some(CSSPixelLength::new(
|
||||||
LogicalSize::from_physical(info.wm, info.size)
|
LogicalSize::from_physical(info.wm, info.size)
|
||||||
.block
|
.block
|
||||||
.to_f32_px(),
|
.to_f32_px(),
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_aspect_ratio(context: &Context) -> Ratio {
|
fn eval_aspect_ratio(context: &Context) -> Option<Ratio> {
|
||||||
let info = get_container(context);
|
let info = context.container_info.as_ref()?;
|
||||||
Ratio::new(info.size.width.0 as f32, info.size.height.0 as f32)
|
Some(Ratio::new(info.size.width.0 as f32, info.size.height.0 as f32))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_orientation(context: &Context, value: Option<Orientation>) -> bool {
|
fn eval_orientation(context: &Context, value: Option<Orientation>) -> bool {
|
||||||
let info = get_container(context);
|
let info = match context.container_info.as_ref() {
|
||||||
|
Some(info) => info,
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
Orientation::eval(info.size, value)
|
Orientation::eval(info.size, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,31 +309,31 @@ pub static CONTAINER_FEATURES: [QueryFeatureDescription; 6] = [
|
||||||
feature!(
|
feature!(
|
||||||
atom!("width"),
|
atom!("width"),
|
||||||
AllowsRanges::Yes,
|
AllowsRanges::Yes,
|
||||||
Evaluator::Length(eval_width),
|
Evaluator::OptionalLength(eval_width),
|
||||||
FeatureFlags::CONTAINER_REQUIRES_WIDTH_AXIS,
|
FeatureFlags::CONTAINER_REQUIRES_WIDTH_AXIS,
|
||||||
),
|
),
|
||||||
feature!(
|
feature!(
|
||||||
atom!("height"),
|
atom!("height"),
|
||||||
AllowsRanges::Yes,
|
AllowsRanges::Yes,
|
||||||
Evaluator::Length(eval_height),
|
Evaluator::OptionalLength(eval_height),
|
||||||
FeatureFlags::CONTAINER_REQUIRES_HEIGHT_AXIS,
|
FeatureFlags::CONTAINER_REQUIRES_HEIGHT_AXIS,
|
||||||
),
|
),
|
||||||
feature!(
|
feature!(
|
||||||
atom!("inline-size"),
|
atom!("inline-size"),
|
||||||
AllowsRanges::Yes,
|
AllowsRanges::Yes,
|
||||||
Evaluator::Length(eval_inline_size),
|
Evaluator::OptionalLength(eval_inline_size),
|
||||||
FeatureFlags::CONTAINER_REQUIRES_INLINE_AXIS,
|
FeatureFlags::CONTAINER_REQUIRES_INLINE_AXIS,
|
||||||
),
|
),
|
||||||
feature!(
|
feature!(
|
||||||
atom!("block-size"),
|
atom!("block-size"),
|
||||||
AllowsRanges::Yes,
|
AllowsRanges::Yes,
|
||||||
Evaluator::Length(eval_block_size),
|
Evaluator::OptionalLength(eval_block_size),
|
||||||
FeatureFlags::CONTAINER_REQUIRES_BLOCK_AXIS,
|
FeatureFlags::CONTAINER_REQUIRES_BLOCK_AXIS,
|
||||||
),
|
),
|
||||||
feature!(
|
feature!(
|
||||||
atom!("aspect-ratio"),
|
atom!("aspect-ratio"),
|
||||||
AllowsRanges::Yes,
|
AllowsRanges::Yes,
|
||||||
Evaluator::NumberRatio(eval_aspect_ratio),
|
Evaluator::OptionalNumberRatio(eval_aspect_ratio),
|
||||||
// XXX from_bits_truncate is const, but the pipe operator isn't, so this
|
// XXX from_bits_truncate is const, but the pipe operator isn't, so this
|
||||||
// works around it.
|
// works around it.
|
||||||
FeatureFlags::from_bits_truncate(
|
FeatureFlags::from_bits_truncate(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue