style: Simplify the Lang pseudo-class stuff a bit.

Differential Revision: https://phabricator.services.mozilla.com/D4754
This commit is contained in:
Emilio Cobos Álvarez 2018-09-02 22:54:12 +00:00
parent d56e537882
commit 72b29d3202
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
5 changed files with 45 additions and 70 deletions

View file

@ -19,7 +19,7 @@ use element_state::ElementState;
use font_metrics::FontMetricsProvider; use font_metrics::FontMetricsProvider;
use media_queries::Device; use media_queries::Device;
use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock}; use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock};
use selector_parser::{AttrValue, PseudoClassStringArg, PseudoElement, SelectorImpl}; use selector_parser::{AttrValue, Lang, PseudoElement, SelectorImpl};
use selectors::Element as SelectorsElement; use selectors::Element as SelectorsElement;
use selectors::matching::{ElementSelectorFlags, QuirksMode, VisitedHandlingMode}; use selectors::matching::{ElementSelectorFlags, QuirksMode, VisitedHandlingMode};
use selectors::sink::Push; use selectors::sink::Push;
@ -895,7 +895,7 @@ pub trait TElement:
fn match_element_lang( fn match_element_lang(
&self, &self,
override_lang: Option<Option<AttrValue>>, override_lang: Option<Option<AttrValue>>,
value: &PseudoClassStringArg, value: &Lang,
) -> bool; ) -> bool;
/// Returns whether this element is the main body element of the HTML /// Returns whether this element is the main body element of the HTML

View file

@ -12,22 +12,13 @@
* Expected usage is as follows: * Expected usage is as follows:
* ``` * ```
* macro_rules! pseudo_class_macro{ * macro_rules! pseudo_class_macro{
* (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], * ([$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*]) => {
* string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
* keyword: [$(($k_css:expr, $k_name:ident, $k_gecko_type:tt, $k_state:tt, $k_flags:tt),)*]) => {
* // do stuff * // do stuff
* } * }
* } * }
* apply_non_ts_list!(pseudo_class_macro) * apply_non_ts_list!(pseudo_class_macro)
* ``` * ```
* *
* The `string` and `keyword` variables will be applied to pseudoclasses that are of the form of
* functions with string or keyword arguments.
*
* Pending pseudo-classes:
*
* :scope -> <style scoped>, pending discussion.
*
* $gecko_type can be either "_" or an ident in Gecko's CSSPseudoClassType. * $gecko_type can be either "_" or an ident in Gecko's CSSPseudoClassType.
* $state can be either "_" or an expression of type ElementState. If present, * $state can be either "_" or an expression of type ElementState. If present,
* the semantics are that the pseudo-class matches if any of the bits in * the semantics are that the pseudo-class matches if any of the bits in
@ -39,7 +30,7 @@
macro_rules! apply_non_ts_list { macro_rules! apply_non_ts_list {
($apply_macro:ident) => { ($apply_macro:ident) => {
$apply_macro! { $apply_macro! {
bare: [ [
("-moz-table-border-nonzero", MozTableBorderNonzero, mozTableBorderNonzero, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), ("-moz-table-border-nonzero", MozTableBorderNonzero, mozTableBorderNonzero, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
("-moz-browser-frame", MozBrowserFrame, mozBrowserFrame, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME), ("-moz-browser-frame", MozBrowserFrame, mozBrowserFrame, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
("link", Link, link, IN_UNVISITED_STATE, _), ("link", Link, link, IN_UNVISITED_STATE, _),
@ -111,9 +102,6 @@ macro_rules! apply_non_ts_list {
("-moz-lwtheme-brighttext", MozLWThemeBrightText, mozLWThemeBrightText, _, _), ("-moz-lwtheme-brighttext", MozLWThemeBrightText, mozLWThemeBrightText, _, _),
("-moz-lwtheme-darktext", MozLWThemeDarkText, mozLWThemeDarkText, _, _), ("-moz-lwtheme-darktext", MozLWThemeDarkText, mozLWThemeDarkText, _, _),
("-moz-window-inactive", MozWindowInactive, mozWindowInactive, _, _), ("-moz-window-inactive", MozWindowInactive, mozWindowInactive, _, _),
],
string: [
("lang", Lang, lang, _, _),
] ]
} }
} }

View file

@ -37,12 +37,11 @@ bitflags! {
} }
} }
/// The type used for storing pseudo-class string arguments. /// The type used to store the language argument to the `:lang` pseudo-class.
pub type PseudoClassStringArg = Atom; pub type Lang = Atom;
macro_rules! pseudo_class_name { macro_rules! pseudo_class_name {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], ([$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*]) => {
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
/// Our representation of a non tree-structural pseudo-class. /// Our representation of a non tree-structural pseudo-class.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
pub enum NonTSPseudoClass { pub enum NonTSPseudoClass {
@ -50,10 +49,8 @@ macro_rules! pseudo_class_name {
#[doc = $css] #[doc = $css]
$name, $name,
)* )*
$( /// The `:lang` pseudo-class.
#[doc = $s_css] Lang(Lang),
$s_name(PseudoClassStringArg),
)*
/// The `:dir` pseudo-class. /// The `:dir` pseudo-class.
Dir(Direction), Dir(Direction),
/// The non-standard `:-moz-any` pseudo-class. /// The non-standard `:-moz-any` pseudo-class.
@ -74,15 +71,14 @@ impl ToCss for NonTSPseudoClass {
W: fmt::Write, W: fmt::Write,
{ {
macro_rules! pseudo_class_serialize { macro_rules! pseudo_class_serialize {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], ([$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*]) => {
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
match *self { match *self {
$(NonTSPseudoClass::$name => concat!(":", $css),)* $(NonTSPseudoClass::$name => concat!(":", $css),)*
$(NonTSPseudoClass::$s_name(ref s) => { NonTSPseudoClass::Lang(ref s) => {
write!(dest, concat!(":", $s_css, "("))?; dest.write_str(":lang(")?;
serialize_atom_identifier(s, dest)?; serialize_atom_identifier(s, dest)?;
return dest.write_char(')'); return dest.write_char(')');
}, )* },
NonTSPseudoClass::MozLocaleDir(ref dir) => { NonTSPseudoClass::MozLocaleDir(ref dir) => {
dest.write_str(":-moz-locale-dir(")?; dest.write_str(":-moz-locale-dir(")?;
dir.to_css(&mut CssWriter::new(dest))?; dir.to_css(&mut CssWriter::new(dest))?;
@ -137,8 +133,7 @@ impl NonTSPseudoClass {
/// in a particular state. /// in a particular state.
pub fn parse_non_functional(name: &str) -> Option<Self> { pub fn parse_non_functional(name: &str) -> Option<Self> {
macro_rules! pseudo_class_parse { macro_rules! pseudo_class_parse {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], ([$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*]) => {
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
match_ignore_ascii_case! { &name, match_ignore_ascii_case! { &name,
$($css => Some(NonTSPseudoClass::$name),)* $($css => Some(NonTSPseudoClass::$name),)*
_ => None, _ => None,
@ -159,12 +154,11 @@ impl NonTSPseudoClass {
}; };
} }
macro_rules! pseudo_class_check_is_enabled_in { macro_rules! pseudo_class_check_is_enabled_in {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], ([$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*]) => {
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
match *self { match *self {
$(NonTSPseudoClass::$name => check_flag!($flags),)* $(NonTSPseudoClass::$name => check_flag!($flags),)*
$(NonTSPseudoClass::$s_name(..) => check_flag!($s_flags),)*
NonTSPseudoClass::MozLocaleDir(_) | NonTSPseudoClass::MozLocaleDir(_) |
NonTSPseudoClass::Lang(_) |
NonTSPseudoClass::Dir(_) | NonTSPseudoClass::Dir(_) |
NonTSPseudoClass::MozAny(_) => false, NonTSPseudoClass::MozAny(_) => false,
} }
@ -214,13 +208,12 @@ impl NonTSPseudoClass {
}; };
} }
macro_rules! pseudo_class_state { macro_rules! pseudo_class_state {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], ([$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*]) => {
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
match *self { match *self {
$(NonTSPseudoClass::$name => flag!($state),)* $(NonTSPseudoClass::$name => flag!($state),)*
$(NonTSPseudoClass::$s_name(..) => flag!($s_state),)*
NonTSPseudoClass::Dir(..) | NonTSPseudoClass::Dir(..) |
NonTSPseudoClass::MozLocaleDir(..) | NonTSPseudoClass::MozLocaleDir(..) |
NonTSPseudoClass::Lang(..) |
NonTSPseudoClass::MozAny(..) => ElementState::empty(), NonTSPseudoClass::MozAny(..) => ElementState::empty(),
} }
} }
@ -391,35 +384,29 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
name: CowRcStr<'i>, name: CowRcStr<'i>,
parser: &mut Parser<'i, 't>, parser: &mut Parser<'i, 't>,
) -> Result<NonTSPseudoClass, ParseError<'i>> { ) -> Result<NonTSPseudoClass, ParseError<'i>> {
macro_rules! pseudo_class_string_parse { let pseudo_class = match_ignore_ascii_case! { &name,
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], "lang" => {
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => { let name = parser.expect_ident_or_string()?;
match_ignore_ascii_case! { &name, NonTSPseudoClass::Lang(Atom::from(name.as_ref()))
$($s_css => { },
let name = parser.expect_ident_or_string()?; "-moz-locale-dir" => {
NonTSPseudoClass::$s_name(Atom::from(name.as_ref())) NonTSPseudoClass::MozLocaleDir(Direction::parse(parser)?)
}, )* },
"-moz-locale-dir" => { "dir" => {
NonTSPseudoClass::MozLocaleDir(Direction::parse(parser)?) NonTSPseudoClass::Dir(Direction::parse(parser)?)
}, },
"dir" => { "-moz-any" => {
NonTSPseudoClass::Dir(Direction::parse(parser)?) NonTSPseudoClass::MozAny(
}, selector_parser::parse_compound_selector_list(
"-moz-any" => { self,
NonTSPseudoClass::MozAny( parser,
selector_parser::parse_compound_selector_list( )?.into()
self, )
parser,
)?.into()
)
}
_ => return Err(parser.new_custom_error(
SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())
))
}
} }
} _ => return Err(parser.new_custom_error(
let pseudo_class = apply_non_ts_list!(pseudo_class_string_parse); SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())
))
};
if self.is_pseudo_class_enabled(&pseudo_class) { if self.is_pseudo_class_enabled(&pseudo_class) {
Ok(pseudo_class) Ok(pseudo_class)
} else { } else {

View file

@ -69,7 +69,7 @@ use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
use properties::animated_properties::{AnimationValue, AnimationValueMap}; use properties::animated_properties::{AnimationValue, AnimationValueMap};
use properties::style_structs::Font; use properties::style_structs::Font;
use rule_tree::CascadeLevel as ServoCascadeLevel; use rule_tree::CascadeLevel as ServoCascadeLevel;
use selector_parser::{AttrValue, HorizontalDirection, PseudoClassStringArg}; use selector_parser::{AttrValue, HorizontalDirection, Lang};
use selectors::{Element, OpaqueElement}; use selectors::{Element, OpaqueElement};
use selectors::attr::{AttrSelectorOperation, AttrSelectorOperator}; use selectors::attr::{AttrSelectorOperation, AttrSelectorOperator};
use selectors::attr::{CaseSensitivity, NamespaceConstraint}; use selectors::attr::{CaseSensitivity, NamespaceConstraint};
@ -1716,7 +1716,7 @@ impl<'le> TElement for GeckoElement<'le> {
fn match_element_lang( fn match_element_lang(
&self, &self,
override_lang: Option<Option<AttrValue>>, override_lang: Option<Option<AttrValue>>,
value: &PseudoClassStringArg, value: &Lang,
) -> bool { ) -> bool {
// Gecko supports :lang() from CSS Selectors 3, which only accepts a // Gecko supports :lang() from CSS Selectors 3, which only accepts a
// single language tag, and which performs simple dash-prefix matching // single language tag, and which performs simple dash-prefix matching

View file

@ -284,8 +284,8 @@ impl PseudoElement {
} }
} }
/// The type used for storing pseudo-class string arguments. /// The type used for storing `:lang` arguments.
pub type PseudoClassStringArg = Box<str>; pub type Lang = Box<str>;
/// A non tree-structural pseudo-class. /// A non tree-structural pseudo-class.
/// See https://drafts.csswg.org/selectors-4/#structural-pseudos /// See https://drafts.csswg.org/selectors-4/#structural-pseudos
@ -302,7 +302,7 @@ pub enum NonTSPseudoClass {
Fullscreen, Fullscreen,
Hover, Hover,
Indeterminate, Indeterminate,
Lang(PseudoClassStringArg), Lang(Lang),
Link, Link,
PlaceholderShown, PlaceholderShown,
ReadWrite, ReadWrite,