From 07de715bb584784b0d66341b074008e08b6057b6 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Sun, 29 Apr 2018 09:03:31 +1000 Subject: [PATCH] style: Manually implement collect_completion_keywords for some types. Bug: 1434130 Reviewed-by: emilio MozReview-Commit-ID: 6T35uylxgho --- components/style/gecko/url.rs | 6 +- .../helpers/animated_properties.mako.rs | 11 +- components/style/values/generics/font.rs | 9 +- components/style/values/generics/mod.rs | 22 ++- components/style/values/specified/align.rs | 161 ++++++++++++++++-- components/style/values/specified/image.rs | 23 ++- components/style_traits/cursor.rs | 11 +- 7 files changed, 209 insertions(+), 34 deletions(-) diff --git a/components/style/gecko/url.rs b/components/style/gecko/url.rs index a0ecfc7b381..bca7e10883a 100644 --- a/components/style/gecko/url.rs +++ b/components/style/gecko/url.rs @@ -15,11 +15,11 @@ use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use parser::{Parse, ParserContext}; use servo_arc::{Arc, RawOffsetArc}; use std::mem; -use style_traits::{ParseError, SpecifiedValueInfo}; +use style_traits::ParseError; /// A CSS url() value for gecko. #[css(function = "url")] -#[derive(Clone, Debug, PartialEq, ToCss)] +#[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss)] pub struct CssUrl { /// The URL in unresolved string form. /// @@ -120,8 +120,6 @@ impl MallocSizeOf for CssUrl { } } -impl SpecifiedValueInfo for CssUrl {} - /// A specified url() value for general usage. #[derive(Clone, Debug, SpecifiedValueInfo, ToComputedValue, ToCss)] pub struct SpecifiedUrl { diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 059d5a51c1b..57a8ed99880 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -27,7 +27,7 @@ use smallvec::SmallVec; use std::{cmp, ptr}; use std::mem::{self, ManuallyDrop}; #[cfg(feature = "gecko")] use hash::FnvHashMap; -use style_traits::{ParseError, SpecifiedValueInfo}; +use style_traits::{KeywordsCollectFn, ParseError, SpecifiedValueInfo}; use super::ComputedValues; use values::{CSSFloat, CustomIdent, Either}; use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; @@ -172,7 +172,14 @@ impl From for TransitionProperty { } } -impl SpecifiedValueInfo for TransitionProperty {} +impl SpecifiedValueInfo for TransitionProperty { + fn collect_completion_keywords(f: KeywordsCollectFn) { + // `transition-property` can actually accept all properties and + // arbitrary identifiers, but `all` is a special one we'd like + // to list. + f(&["all"]); + } +} /// Returns true if this nsCSSPropertyID is one of the transitionable properties. #[cfg(feature = "gecko")] diff --git a/components/style/values/generics/font.rs b/components/style/values/generics/font.rs index d48a0a36bbc..d4e55af6a61 100644 --- a/components/style/values/generics/font.rs +++ b/components/style/values/generics/font.rs @@ -11,7 +11,8 @@ use num_traits::One; use parser::{Parse, ParserContext}; use std::fmt::{self, Write}; use std::io::Cursor; -use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss}; +use style_traits::{CssWriter, KeywordsCollectFn, ParseError}; +use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; use values::distance::{ComputeSquaredDistance, SquaredDistance}; /// https://drafts.csswg.org/css-fonts-4/#feature-tag-value @@ -181,8 +182,10 @@ where } } -impl SpecifiedValueInfo for KeywordInfo { - const SUPPORTED_TYPES: u8 = ::SUPPORTED_TYPES; +impl SpecifiedValueInfo for KeywordInfo { + fn collect_completion_keywords(f: KeywordsCollectFn) { + ::collect_completion_keywords(f); + } } /// CSS font keywords diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index f47b2f29b89..59d9748ea5b 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -8,7 +8,8 @@ use counter_style::{parse_counter_style_name, Symbols}; use cssparser::Parser; use parser::{Parse, ParserContext}; -use style_traits::{ParseError, StyleParseErrorKind}; +use style_traits::{KeywordsCollectFn, ParseError}; +use style_traits::{SpecifiedValueInfo, StyleParseErrorKind}; use super::CustomIdent; pub mod background; @@ -79,8 +80,7 @@ impl SymbolsType { /// Since wherever is used, 'none' is a valid value as /// well, we combine them into one type to make code simpler. #[cfg_attr(feature = "gecko", derive(MallocSizeOf))] -#[derive(Clone, Debug, Eq, PartialEq, SpecifiedValueInfo, ToComputedValue, - ToCss)] +#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss)] pub enum CounterStyleOrNone { /// `none` None, @@ -138,6 +138,22 @@ impl Parse for CounterStyleOrNone { } } +impl SpecifiedValueInfo for CounterStyleOrNone { + fn collect_completion_keywords(f: KeywordsCollectFn) { + // XXX The best approach for implementing this is probably + // having a CounterStyleName type wrapping CustomIdent, and + // put the predefined list for that type in counter_style mod. + // But that's a non-trivial change itself, so we use a simpler + // approach here. + macro_rules! predefined { + ($($name:expr,)+) => { + f(&["none", "symbols", $($name,)+]); + } + } + include!("../../counter_style/predefined.rs"); + } +} + /// A wrapper of Non-negative values. #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, diff --git a/components/style/values/specified/align.rs b/components/style/values/specified/align.rs index a92ca52c8b4..731844bcb52 100644 --- a/components/style/values/specified/align.rs +++ b/components/style/values/specified/align.rs @@ -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. /// /// -#[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> { + // 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. /// /// -#[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> { + // 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 for AlignContent { fn from(bits: u16) -> Self { @@ -266,8 +288,7 @@ impl From for u16 { /// Value for the `justify-content` property. /// /// -#[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> { + // 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 for JustifyContent { fn from(bits: u16) -> Self { @@ -297,8 +326,7 @@ impl From for u16 { } /// -#[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> { + // NOTE Please also update the `list_keywords` function below + // when this function is updated. + // // // It's weird that this accepts , 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. /// /// -#[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> { + // 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 for AlignSelf { fn from(bits: u8) -> Self { AlignSelf(SelfAlignment(AlignFlags::from_bits_truncate(bits))) @@ -379,8 +424,7 @@ impl From for u8 { /// The specified value of the justify-self property. /// /// -#[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> { + // 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 for JustifySelf { fn from(bits: u8) -> Self { JustifySelf(SelfAlignment(AlignFlags::from_bits_truncate(bits))) @@ -410,8 +462,7 @@ impl From for u8 { /// Value of the `align-items` property /// /// -#[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> { + // NOTE Please also update `impl SpecifiedValueInfo` below when + // this function is updated. + // 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 /// /// -#[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> { + // NOTE Please also update `impl SpecifiedValueInfo` below when + // this function is updated. + // // // It's weird that this accepts , 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> { + // 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> { + // 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"]); +} + // fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { + // 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 fn parse_content_distribution<'i, 't>( input: &mut Parser<'i, 't>, ) -> Result> { + // 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"]); +} + // fn parse_overflow_position<'i, 't>( input: &mut Parser<'i, 't>, ) -> Result> { + // 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"]); +} + // | left | right in the inline axis. fn parse_self_position<'i, 't>( input: &mut Parser<'i, 't>, axis: AxisDirection, ) -> Result> { + // 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> { + // 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> { + // 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