style: Manually implement collect_completion_keywords for some types.

Bug: 1434130
Reviewed-by: emilio
MozReview-Commit-ID: 6T35uylxgho
This commit is contained in:
Xidorn Quan 2018-04-29 09:03:31 +10:00 committed by Emilio Cobos Álvarez
parent 0f7f9eebc0
commit 07de715bb5
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
7 changed files with 209 additions and 34 deletions

View file

@ -10,13 +10,13 @@ use cssparser::Parser;
use gecko_bindings::structs;
use parser::{Parse, ParserContext};
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, ToCss};
use style_traits::{CssWriter, KeywordsCollectFn, ParseError, SpecifiedValueInfo, ToCss};
bitflags! {
/// Constants shared by multiple CSS Box Alignment properties
///
/// These constants match Gecko's `NS_STYLE_ALIGN_*` constants.
#[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue)]
#[derive(MallocSizeOf, ToComputedValue)]
pub struct AlignFlags: u8 {
// Enumeration stored in the lower 5 bits:
/// 'auto'
@ -135,8 +135,7 @@ pub enum AxisDirection {
/// Shared value for the `align-content` and `justify-content` properties.
///
/// <https://drafts.csswg.org/css-align/#content-distribution>
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
pub struct ContentDistribution {
primary: AlignFlags,
@ -192,6 +191,9 @@ impl ContentDistribution {
input: &mut Parser<'i, 't>,
axis: AxisDirection,
) -> Result<Self, ParseError<'i>> {
// NOTE Please also update the `list_keywords` function below
// when this function is updated.
// Try to parse normal first
if input.try(|i| i.expect_ident_matching("normal")).is_ok() {
return Ok(ContentDistribution::normal());
@ -228,13 +230,25 @@ impl ContentDistribution {
content_position | overflow_position,
))
}
fn list_keywords(f: KeywordsCollectFn, axis: AxisDirection) {
f(&["normal"]);
if axis == AxisDirection::Block {
list_baseline_keywords(f);
}
list_content_distribution_keywords(f);
list_overflow_position_keywords(f);
f(&["start", "end", "flex-start", "flex-end", "center"]);
if axis == AxisDirection::Inline {
f(&["left", "right"]);
}
}
}
/// Value for the `align-content` property.
///
/// <https://drafts.csswg.org/css-align/#propdef-align-content>
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub struct AlignContent(pub ContentDistribution);
impl Parse for AlignContent {
@ -242,6 +256,8 @@ impl Parse for AlignContent {
_: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
// NOTE Please also update `impl SpecifiedValueInfo` below when
// this function is updated.
Ok(AlignContent(ContentDistribution::parse(
input,
AxisDirection::Block,
@ -249,6 +265,12 @@ impl Parse for AlignContent {
}
}
impl SpecifiedValueInfo for AlignContent {
fn collect_completion_keywords(f: KeywordsCollectFn) {
ContentDistribution::list_keywords(f, AxisDirection::Block);
}
}
#[cfg(feature = "gecko")]
impl From<u16> for AlignContent {
fn from(bits: u16) -> Self {
@ -266,8 +288,7 @@ impl From<AlignContent> for u16 {
/// Value for the `justify-content` property.
///
/// <https://drafts.csswg.org/css-align/#propdef-align-content>
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub struct JustifyContent(pub ContentDistribution);
impl Parse for JustifyContent {
@ -275,6 +296,8 @@ impl Parse for JustifyContent {
_: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
// NOTE Please also update `impl SpecifiedValueInfo` below when
// this function is updated.
Ok(JustifyContent(ContentDistribution::parse(
input,
AxisDirection::Inline,
@ -282,6 +305,12 @@ impl Parse for JustifyContent {
}
}
impl SpecifiedValueInfo for JustifyContent {
fn collect_completion_keywords(f: KeywordsCollectFn) {
ContentDistribution::list_keywords(f, AxisDirection::Inline);
}
}
#[cfg(feature = "gecko")]
impl From<u16> for JustifyContent {
fn from(bits: u16) -> Self {
@ -297,8 +326,7 @@ impl From<JustifyContent> for u16 {
}
/// <https://drafts.csswg.org/css-align/#self-alignment>
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub struct SelfAlignment(pub AlignFlags);
impl SelfAlignment {
@ -323,6 +351,9 @@ impl SelfAlignment {
input: &mut Parser<'i, 't>,
axis: AxisDirection,
) -> Result<Self, ParseError<'i>> {
// NOTE Please also update the `list_keywords` function below
// when this function is updated.
// <baseline-position>
//
// It's weird that this accepts <baseline-position>, but not
@ -343,13 +374,19 @@ impl SelfAlignment {
let self_position = parse_self_position(input, axis)?;
Ok(SelfAlignment(overflow_position | self_position))
}
fn list_keywords(f: KeywordsCollectFn, axis: AxisDirection) {
list_baseline_keywords(f);
list_auto_normal_stretch(f);
list_overflow_position_keywords(f);
list_self_position_keywords(f, axis);
}
}
/// The specified value of the align-self property.
///
/// <https://drafts.csswg.org/css-align/#propdef-align-self>
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub struct AlignSelf(pub SelfAlignment);
impl Parse for AlignSelf {
@ -357,6 +394,8 @@ impl Parse for AlignSelf {
_: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
// NOTE Please also update `impl SpecifiedValueInfo` below when
// this function is updated.
Ok(AlignSelf(SelfAlignment::parse(
input,
AxisDirection::Block,
@ -364,6 +403,12 @@ impl Parse for AlignSelf {
}
}
impl SpecifiedValueInfo for AlignSelf {
fn collect_completion_keywords(f: KeywordsCollectFn) {
SelfAlignment::list_keywords(f, AxisDirection::Block);
}
}
impl From<u8> for AlignSelf {
fn from(bits: u8) -> Self {
AlignSelf(SelfAlignment(AlignFlags::from_bits_truncate(bits)))
@ -379,8 +424,7 @@ impl From<AlignSelf> for u8 {
/// The specified value of the justify-self property.
///
/// <https://drafts.csswg.org/css-align/#propdef-justify-self>
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub struct JustifySelf(pub SelfAlignment);
impl Parse for JustifySelf {
@ -388,6 +432,8 @@ impl Parse for JustifySelf {
_: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
// NOTE Please also update `impl SpecifiedValueInfo` below when
// this function is updated.
Ok(JustifySelf(SelfAlignment::parse(
input,
AxisDirection::Inline,
@ -395,6 +441,12 @@ impl Parse for JustifySelf {
}
}
impl SpecifiedValueInfo for JustifySelf {
fn collect_completion_keywords(f: KeywordsCollectFn) {
SelfAlignment::list_keywords(f, AxisDirection::Inline);
}
}
impl From<u8> for JustifySelf {
fn from(bits: u8) -> Self {
JustifySelf(SelfAlignment(AlignFlags::from_bits_truncate(bits)))
@ -410,8 +462,7 @@ impl From<JustifySelf> for u8 {
/// Value of the `align-items` property
///
/// <https://drafts.csswg.org/css-align/#self-alignment>
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub struct AlignItems(pub AlignFlags);
impl AlignItems {
@ -429,6 +480,9 @@ impl Parse for AlignItems {
_: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
// NOTE Please also update `impl SpecifiedValueInfo` below when
// this function is updated.
// <baseline-position>
if let Ok(baseline) = input.try(parse_baseline) {
return Ok(AlignItems(baseline));
@ -447,11 +501,19 @@ impl Parse for AlignItems {
}
}
impl SpecifiedValueInfo for AlignItems {
fn collect_completion_keywords(f: KeywordsCollectFn) {
list_baseline_keywords(f);
list_normal_stretch(f);
list_overflow_position_keywords(f);
list_self_position_keywords(f, AxisDirection::Block);
}
}
/// Value of the `justify-items` property
///
/// <https://drafts.csswg.org/css-align/#justify-items-property>
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)]
pub struct JustifyItems(pub AlignFlags);
impl JustifyItems {
@ -473,6 +535,9 @@ impl Parse for JustifyItems {
_: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
// NOTE Please also update `impl SpecifiedValueInfo` below when
// this function is updated.
// <baseline-position>
//
// It's weird that this accepts <baseline-position>, but not
@ -500,10 +565,22 @@ impl Parse for JustifyItems {
}
}
impl SpecifiedValueInfo for JustifyItems {
fn collect_completion_keywords(f: KeywordsCollectFn) {
list_baseline_keywords(f);
list_normal_stretch(f);
list_legacy_keywords(f);
list_overflow_position_keywords(f);
list_self_position_keywords(f, AxisDirection::Inline);
}
}
// auto | normal | stretch
fn parse_auto_normal_stretch<'i, 't>(
input: &mut Parser<'i, 't>,
) -> Result<AlignFlags, ParseError<'i>> {
// NOTE Please also update the `list_auto_normal_stretch` function
// below when this function is updated.
try_match_ident_ignore_ascii_case! { input,
"auto" => Ok(AlignFlags::AUTO),
"normal" => Ok(AlignFlags::NORMAL),
@ -511,16 +588,28 @@ fn parse_auto_normal_stretch<'i, 't>(
}
}
fn list_auto_normal_stretch(f: KeywordsCollectFn) {
f(&["auto", "normal", "stretch"]);
}
// normal | stretch
fn parse_normal_stretch<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
// NOTE Please also update the `list_normal_stretch` function below
// when this function is updated.
try_match_ident_ignore_ascii_case! { input,
"normal" => Ok(AlignFlags::NORMAL),
"stretch" => Ok(AlignFlags::STRETCH),
}
}
fn list_normal_stretch(f: KeywordsCollectFn) {
f(&["normal", "stretch"]);
}
// <baseline-position>
fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
// NOTE Please also update the `list_baseline_keywords` function
// below when this function is updated.
try_match_ident_ignore_ascii_case! { input,
"baseline" => Ok(AlignFlags::BASELINE),
"first" => {
@ -534,10 +623,16 @@ fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, Pars
}
}
fn list_baseline_keywords(f: KeywordsCollectFn) {
f(&["baseline", "first baseline", "last baseline"]);
}
// <content-distribution>
fn parse_content_distribution<'i, 't>(
input: &mut Parser<'i, 't>,
) -> Result<AlignFlags, ParseError<'i>> {
// NOTE Please also update the `list_content_distribution_keywords`
// function below when this function is updated.
try_match_ident_ignore_ascii_case! { input,
"stretch" => Ok(AlignFlags::STRETCH),
"space-between" => Ok(AlignFlags::SPACE_BETWEEN),
@ -546,21 +641,33 @@ fn parse_content_distribution<'i, 't>(
}
}
fn list_content_distribution_keywords(f: KeywordsCollectFn) {
f(&["stretch", "space-between", "space-around", "space-evenly"]);
}
// <overflow-position>
fn parse_overflow_position<'i, 't>(
input: &mut Parser<'i, 't>,
) -> Result<AlignFlags, ParseError<'i>> {
// NOTE Please also update the `list_overflow_position_keywords`
// function below when this function is updated.
try_match_ident_ignore_ascii_case! { input,
"safe" => Ok(AlignFlags::SAFE),
"unsafe" => Ok(AlignFlags::UNSAFE),
}
}
fn list_overflow_position_keywords(f: KeywordsCollectFn) {
f(&["safe", "unsafe"]);
}
// <self-position> | left | right in the inline axis.
fn parse_self_position<'i, 't>(
input: &mut Parser<'i, 't>,
axis: AxisDirection,
) -> Result<AlignFlags, ParseError<'i>> {
// NOTE Please also update the `list_self_position_keywords`
// function below when this function is updated.
Ok(try_match_ident_ignore_ascii_case! { input,
"start" => AlignFlags::START,
"end" => AlignFlags::END,
@ -574,9 +681,21 @@ fn parse_self_position<'i, 't>(
})
}
fn list_self_position_keywords(f: KeywordsCollectFn, axis: AxisDirection) {
f(&[
"start", "end", "flex-start", "flex-end",
"center", "self-start", "self-end",
]);
if axis == AxisDirection::Inline {
f(&["left", "right"]);
}
}
fn parse_left_right_center<'i, 't>(
input: &mut Parser<'i, 't>,
) -> Result<AlignFlags, ParseError<'i>> {
// NOTE Please also update the `list_legacy_keywords` function below
// when this function is updated.
Ok(try_match_ident_ignore_ascii_case! { input,
"left" => AlignFlags::LEFT,
"right" => AlignFlags::RIGHT,
@ -586,6 +705,8 @@ fn parse_left_right_center<'i, 't>(
// legacy | [ legacy && [ left | right | center ] ]
fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
// NOTE Please also update the `list_legacy_keywords` function below
// when this function is updated.
let flags = try_match_ident_ignore_ascii_case! { input,
"legacy" => {
let flags = input.try(parse_left_right_center)
@ -601,3 +722,7 @@ fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseE
input.expect_ident_matching("legacy")?;
Ok(AlignFlags::LEGACY | flags)
}
fn list_legacy_keywords(f: KeywordsCollectFn) {
f(&["legacy", "left", "right", "center"]);
}