style: Don't allow fallback alignment in place-content shorthand.

Bug: 1430622
Reviewed-by: xidorn,mats
MozReview-Commit-ID: sALBFJeqvr
This commit is contained in:
Emilio Cobos Álvarez 2018-01-15 22:34:34 +01:00
parent 1c1f9c94fd
commit 404148c82e
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
2 changed files with 57 additions and 28 deletions

View file

@ -611,17 +611,19 @@
<%helpers:shorthand name="place-content" sub_properties="align-content justify-content" <%helpers:shorthand name="place-content" sub_properties="align-content justify-content"
spec="https://drafts.csswg.org/css-align/#propdef-place-content" spec="https://drafts.csswg.org/css-align/#propdef-place-content"
products="gecko"> products="gecko">
use properties::longhands::align_content; use values::specified::align::{AlignJustifyContent, FallbackAllowed};
use properties::longhands::justify_content;
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) pub fn parse_value<'i, 't>(
-> Result<Longhands, ParseError<'i>> { _: &ParserContext,
let align = align_content::parse(context, input)?; input: &mut Parser<'i, 't>,
) -> Result<Longhands, ParseError<'i>> {
let align = AlignJustifyContent::parse_with_fallback(input, FallbackAllowed::No)?;
if align.has_extra_flags() { if align.has_extra_flags() {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
} }
let justify = input.try(|input| justify_content::parse(context, input)) let justify =
.unwrap_or(justify_content::SpecifiedValue::from(align)); input.try(|input| AlignJustifyContent::parse_with_fallback(input, FallbackAllowed::No))
.unwrap_or(align);
if justify.has_extra_flags() { if justify.has_extra_flags() {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
} }

View file

@ -119,6 +119,21 @@ const ALIGN_ALL_SHIFT: u32 = structs::NS_STYLE_ALIGN_ALL_SHIFT;
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
pub struct AlignJustifyContent(u16); pub struct AlignJustifyContent(u16);
/// Whether fallback is allowed in align-content / justify-content parsing.
///
/// This is used for the place-content shorthand, until the resolutions from [1]
/// are specified.
///
/// [1]: https://github.com/w3c/csswg-drafts/issues/1002
#[derive(Clone, Copy, PartialEq)]
pub enum FallbackAllowed {
/// Allow fallback alignment.
Yes,
/// Don't allow fallback alignment.
No,
}
impl AlignJustifyContent { impl AlignJustifyContent {
/// The initial value 'normal' /// The initial value 'normal'
#[inline] #[inline]
@ -159,6 +174,38 @@ impl AlignJustifyContent {
pub fn has_extra_flags(self) -> bool { pub fn has_extra_flags(self) -> bool {
self.primary().intersects(AlignFlags::FLAG_BITS) || self.fallback().intersects(AlignFlags::FLAG_BITS) self.primary().intersects(AlignFlags::FLAG_BITS) || self.fallback().intersects(AlignFlags::FLAG_BITS)
} }
/// Parse a value for align-content / justify-content, optionally allowing
/// fallback.
pub fn parse_with_fallback<'i, 't>(
input: &mut Parser<'i, 't>,
fallback_allowed: FallbackAllowed,
) -> Result<Self, ParseError<'i>> {
// normal | <baseline-position>
if let Ok(value) = input.try(|input| parse_normal_or_baseline(input)) {
return Ok(AlignJustifyContent::new(value))
}
// <content-distribution> followed by optional <*-position>
if let Ok(value) = input.try(|input| parse_content_distribution(input)) {
if fallback_allowed == FallbackAllowed::Yes {
if let Ok(fallback) = input.try(|input| parse_overflow_content_position(input)) {
return Ok(AlignJustifyContent::with_fallback(value, fallback))
}
}
return Ok(AlignJustifyContent::new(value))
}
// <*-position> followed by optional <content-distribution>
let fallback = parse_overflow_content_position(input)?;
if fallback_allowed == FallbackAllowed::Yes {
if let Ok(value) = input.try(|input| parse_content_distribution(input)) {
return Ok(AlignJustifyContent::with_fallback(value, fallback))
}
}
Ok(AlignJustifyContent::new(fallback))
}
} }
impl ToCss for AlignJustifyContent { impl ToCss for AlignJustifyContent {
@ -180,27 +227,7 @@ impl Parse for AlignJustifyContent {
// normal | <baseline-position> | // normal | <baseline-position> |
// [ <content-distribution> || [ <overflow-position>? && <content-position> ] ] // [ <content-distribution> || [ <overflow-position>? && <content-position> ] ]
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
// normal | <baseline-position> Self::parse_with_fallback(input, FallbackAllowed::Yes)
if let Ok(value) = input.try(|input| parse_normal_or_baseline(input)) {
return Ok(AlignJustifyContent::new(value))
}
// <content-distribution> followed by optional <*-position>
if let Ok(value) = input.try(|input| parse_content_distribution(input)) {
if let Ok(fallback) = input.try(|input| parse_overflow_content_position(input)) {
return Ok(AlignJustifyContent::with_fallback(value, fallback))
}
return Ok(AlignJustifyContent::new(value))
}
// <*-position> followed by optional <content-distribution>
if let Ok(fallback) = input.try(|input| parse_overflow_content_position(input)) {
if let Ok(value) = input.try(|input| parse_content_distribution(input)) {
return Ok(AlignJustifyContent::with_fallback(value, fallback))
}
return Ok(AlignJustifyContent::new(fallback))
}
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
} }
} }