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"
spec="https://drafts.csswg.org/css-align/#propdef-place-content"
products="gecko">
use properties::longhands::align_content;
use properties::longhands::justify_content;
use values::specified::align::{AlignJustifyContent, FallbackAllowed};
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Longhands, ParseError<'i>> {
let align = align_content::parse(context, input)?;
pub fn parse_value<'i, 't>(
_: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Longhands, ParseError<'i>> {
let align = AlignJustifyContent::parse_with_fallback(input, FallbackAllowed::No)?;
if align.has_extra_flags() {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
}
let justify = input.try(|input| justify_content::parse(context, input))
.unwrap_or(justify_content::SpecifiedValue::from(align));
let justify =
input.try(|input| AlignJustifyContent::parse_with_fallback(input, FallbackAllowed::No))
.unwrap_or(align);
if justify.has_extra_flags() {
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))]
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 {
/// The initial value 'normal'
#[inline]
@ -159,6 +174,38 @@ impl AlignJustifyContent {
pub fn has_extra_flags(self) -> bool {
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 {
@ -180,27 +227,7 @@ impl Parse for AlignJustifyContent {
// normal | <baseline-position> |
// [ <content-distribution> || [ <overflow-position>? && <content-position> ] ]
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> 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 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))
Self::parse_with_fallback(input, FallbackAllowed::Yes)
}
}