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 media_queries::Device;
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::matching::{ElementSelectorFlags, QuirksMode, VisitedHandlingMode};
use selectors::sink::Push;
@ -895,7 +895,7 @@ pub trait TElement:
fn match_element_lang(
&self,
override_lang: Option<Option<AttrValue>>,
value: &PseudoClassStringArg,
value: &Lang,
) -> bool;
/// Returns whether this element is the main body element of the HTML

View file

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

View file

@ -69,7 +69,7 @@ use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
use properties::animated_properties::{AnimationValue, AnimationValueMap};
use properties::style_structs::Font;
use rule_tree::CascadeLevel as ServoCascadeLevel;
use selector_parser::{AttrValue, HorizontalDirection, PseudoClassStringArg};
use selector_parser::{AttrValue, HorizontalDirection, Lang};
use selectors::{Element, OpaqueElement};
use selectors::attr::{AttrSelectorOperation, AttrSelectorOperator};
use selectors::attr::{CaseSensitivity, NamespaceConstraint};
@ -1716,7 +1716,7 @@ impl<'le> TElement for GeckoElement<'le> {
fn match_element_lang(
&self,
override_lang: Option<Option<AttrValue>>,
value: &PseudoClassStringArg,
value: &Lang,
) -> bool {
// Gecko supports :lang() from CSS Selectors 3, which only accepts a
// 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.
pub type PseudoClassStringArg = Box<str>;
/// The type used for storing `:lang` arguments.
pub type Lang = Box<str>;
/// A non tree-structural pseudo-class.
/// See https://drafts.csswg.org/selectors-4/#structural-pseudos
@ -302,7 +302,7 @@ pub enum NonTSPseudoClass {
Fullscreen,
Hover,
Indeterminate,
Lang(PseudoClassStringArg),
Lang(Lang),
Link,
PlaceholderShown,
ReadWrite,