mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
style: Move :-moz-locale-dir matching to rust.
This commit is contained in:
parent
1a4df8f876
commit
b6a2bff032
4 changed files with 55 additions and 66 deletions
|
@ -116,9 +116,6 @@ macro_rules! apply_non_ts_list {
|
||||||
],
|
],
|
||||||
string: [
|
string: [
|
||||||
("lang", Lang, lang, _, _),
|
("lang", Lang, lang, _, _),
|
||||||
],
|
|
||||||
keyword: [
|
|
||||||
("-moz-locale-dir", MozLocaleDir, mozLocaleDir, _, _),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,8 @@ pub type PseudoClassStringArg = Box<[u16]>;
|
||||||
|
|
||||||
macro_rules! pseudo_class_name {
|
macro_rules! pseudo_class_name {
|
||||||
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
|
(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),)*],
|
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),)*]) => {
|
/// Our representation of a non tree-structural pseudo-class.
|
||||||
#[doc = "Our representation of a non tree-structural pseudo-class."]
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum NonTSPseudoClass {
|
pub enum NonTSPseudoClass {
|
||||||
$(
|
$(
|
||||||
|
@ -49,10 +48,6 @@ macro_rules! pseudo_class_name {
|
||||||
#[doc = $s_css]
|
#[doc = $s_css]
|
||||||
$s_name(PseudoClassStringArg),
|
$s_name(PseudoClassStringArg),
|
||||||
)*
|
)*
|
||||||
$(
|
|
||||||
#[doc = $k_css]
|
|
||||||
$k_name(Box<[u16]>),
|
|
||||||
)*
|
|
||||||
/// The `:dir` pseudo-class.
|
/// The `:dir` pseudo-class.
|
||||||
Dir(Box<Direction>),
|
Dir(Box<Direction>),
|
||||||
/// The non-standard `:-moz-any` pseudo-class.
|
/// The non-standard `:-moz-any` pseudo-class.
|
||||||
|
@ -60,6 +55,8 @@ macro_rules! pseudo_class_name {
|
||||||
/// TODO(emilio): We disallow combinators and pseudos here, so we
|
/// TODO(emilio): We disallow combinators and pseudos here, so we
|
||||||
/// should use SimpleSelector instead
|
/// should use SimpleSelector instead
|
||||||
MozAny(Box<[Selector<SelectorImpl>]>),
|
MozAny(Box<[Selector<SelectorImpl>]>),
|
||||||
|
/// The non-standard `:-moz-locale-dir` pseudo-class.
|
||||||
|
MozLocaleDir(Box<Direction>),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,8 +68,7 @@ impl ToCss for NonTSPseudoClass {
|
||||||
use fmt::Write;
|
use fmt::Write;
|
||||||
macro_rules! pseudo_class_serialize {
|
macro_rules! pseudo_class_serialize {
|
||||||
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
|
(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),)*],
|
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),)*]) => {
|
|
||||||
match *self {
|
match *self {
|
||||||
$(NonTSPseudoClass::$name => concat!(":", $css),)*
|
$(NonTSPseudoClass::$name => concat!(":", $css),)*
|
||||||
$(NonTSPseudoClass::$s_name(ref s) => {
|
$(NonTSPseudoClass::$s_name(ref s) => {
|
||||||
|
@ -87,16 +83,14 @@ impl ToCss for NonTSPseudoClass {
|
||||||
}
|
}
|
||||||
return dest.write_str(")")
|
return dest.write_str(")")
|
||||||
}, )*
|
}, )*
|
||||||
$(NonTSPseudoClass::$k_name(ref s) => {
|
NonTSPseudoClass::MozLocaleDir(ref dir) => {
|
||||||
// Don't include the terminating nul.
|
dest.write_str(":-moz-locale-dir(")?;
|
||||||
let value = String::from_utf16(&s[..s.len() - 1]).unwrap();
|
dir.to_css(dest)?;
|
||||||
dest.write_str(concat!(":", $k_css, "("))?;
|
|
||||||
dest.write_str(&value)?;
|
|
||||||
return dest.write_char(')')
|
return dest.write_char(')')
|
||||||
}, )*
|
},
|
||||||
NonTSPseudoClass::Dir(ref dir) => {
|
NonTSPseudoClass::Dir(ref dir) => {
|
||||||
dest.write_str(":dir(")?;
|
dest.write_str(":dir(")?;
|
||||||
(**dir).to_css(dest)?;
|
dir.to_css(dest)?;
|
||||||
return dest.write_char(')')
|
return dest.write_char(')')
|
||||||
},
|
},
|
||||||
NonTSPseudoClass::MozAny(ref selectors) => {
|
NonTSPseudoClass::MozAny(ref selectors) => {
|
||||||
|
@ -146,13 +140,14 @@ 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),)*],
|
(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),)*],
|
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),)*]) => {
|
|
||||||
match *self {
|
match *self {
|
||||||
$(NonTSPseudoClass::$name => check_flag!($flags),)*
|
$(NonTSPseudoClass::$name => check_flag!($flags),)*
|
||||||
$(NonTSPseudoClass::$s_name(..) => check_flag!($s_flags),)*
|
$(NonTSPseudoClass::$s_name(..) => check_flag!($s_flags),)*
|
||||||
$(NonTSPseudoClass::$k_name(..) => check_flag!($k_flags),)*
|
// TODO(emilio): Maybe -moz-locale-dir shouldn't be
|
||||||
NonTSPseudoClass::Dir(_) => false,
|
// content-exposed.
|
||||||
|
NonTSPseudoClass::MozLocaleDir(_) |
|
||||||
|
NonTSPseudoClass::Dir(_) |
|
||||||
NonTSPseudoClass::MozAny(_) => false,
|
NonTSPseudoClass::MozAny(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,13 +186,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),)*],
|
(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),)*],
|
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),)*]) => {
|
|
||||||
match *self {
|
match *self {
|
||||||
$(NonTSPseudoClass::$name => flag!($state),)*
|
$(NonTSPseudoClass::$name => flag!($state),)*
|
||||||
$(NonTSPseudoClass::$s_name(..) => flag!($s_state),)*
|
$(NonTSPseudoClass::$s_name(..) => flag!($s_state),)*
|
||||||
$(NonTSPseudoClass::$k_name(..) => flag!($k_state),)*
|
NonTSPseudoClass::Dir(..) |
|
||||||
NonTSPseudoClass::Dir(..) => ElementState::empty(),
|
NonTSPseudoClass::MozLocaleDir(..) |
|
||||||
NonTSPseudoClass::MozAny(..) => ElementState::empty(),
|
NonTSPseudoClass::MozAny(..) => ElementState::empty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,12 +250,11 @@ impl NonTSPseudoClass {
|
||||||
}
|
}
|
||||||
macro_rules! pseudo_class_geckotype {
|
macro_rules! pseudo_class_geckotype {
|
||||||
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
|
(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),)*],
|
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),)*]) => {
|
|
||||||
match *self {
|
match *self {
|
||||||
$(NonTSPseudoClass::$name => gecko_type!($gecko_type),)*
|
$(NonTSPseudoClass::$name => gecko_type!($gecko_type),)*
|
||||||
$(NonTSPseudoClass::$s_name(..) => gecko_type!($s_gecko_type),)*
|
$(NonTSPseudoClass::$s_name(..) => gecko_type!($s_gecko_type),)*
|
||||||
$(NonTSPseudoClass::$k_name(..) => gecko_type!($k_gecko_type),)*
|
NonTSPseudoClass::MozLocaleDir(_) => gecko_type!(mozLocaleDir),
|
||||||
NonTSPseudoClass::Dir(_) => gecko_type!(dir),
|
NonTSPseudoClass::Dir(_) => gecko_type!(dir),
|
||||||
NonTSPseudoClass::MozAny(_) => gecko_type!(any),
|
NonTSPseudoClass::MozAny(_) => gecko_type!(any),
|
||||||
}
|
}
|
||||||
|
@ -353,8 +346,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
) -> Result<NonTSPseudoClass, ParseError<'i>> {
|
) -> Result<NonTSPseudoClass, ParseError<'i>> {
|
||||||
macro_rules! pseudo_class_parse {
|
macro_rules! pseudo_class_parse {
|
||||||
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
|
(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),)*],
|
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),)*]) => {
|
|
||||||
match_ignore_ascii_case! { &name,
|
match_ignore_ascii_case! { &name,
|
||||||
$($css => NonTSPseudoClass::$name,)*
|
$($css => NonTSPseudoClass::$name,)*
|
||||||
_ => return Err(location.new_custom_error(
|
_ => return Err(location.new_custom_error(
|
||||||
|
@ -378,8 +370,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
) -> Result<NonTSPseudoClass, ParseError<'i>> {
|
) -> Result<NonTSPseudoClass, ParseError<'i>> {
|
||||||
macro_rules! pseudo_class_string_parse {
|
macro_rules! pseudo_class_string_parse {
|
||||||
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
|
(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),)*],
|
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),)*]) => {
|
|
||||||
match_ignore_ascii_case! { &name,
|
match_ignore_ascii_case! { &name,
|
||||||
$($s_css => {
|
$($s_css => {
|
||||||
let name = parser.expect_ident_or_string()?;
|
let name = parser.expect_ident_or_string()?;
|
||||||
|
@ -388,23 +379,15 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
let utf16: Vec<u16> = name.encode_utf16().chain(Some(0u16)).collect();
|
let utf16: Vec<u16> = name.encode_utf16().chain(Some(0u16)).collect();
|
||||||
NonTSPseudoClass::$s_name(utf16.into_boxed_slice())
|
NonTSPseudoClass::$s_name(utf16.into_boxed_slice())
|
||||||
}, )*
|
}, )*
|
||||||
$($k_css => {
|
"-moz-locale-dir" => {
|
||||||
let name = parser.expect_ident()?;
|
NonTSPseudoClass::MozLocaleDir(
|
||||||
// Convert to ASCII-lowercase nul-terminated UTF-16 string.
|
Box::new(Direction::parse(parser)?)
|
||||||
let utf16: Vec<u16> = name.encode_utf16().map(utf16_to_ascii_lowercase)
|
)
|
||||||
.chain(Some(0u16)).collect();
|
|
||||||
NonTSPseudoClass::$k_name(utf16.into_boxed_slice())
|
|
||||||
}, )*
|
|
||||||
"dir" => {
|
|
||||||
let name: &str = parser.expect_ident()?;
|
|
||||||
let direction = match_ignore_ascii_case! { name,
|
|
||||||
"rtl" => Direction::Rtl,
|
|
||||||
"ltr" => Direction::Ltr,
|
|
||||||
_ => {
|
|
||||||
Direction::Other(Box::from(name))
|
|
||||||
},
|
},
|
||||||
};
|
"dir" => {
|
||||||
NonTSPseudoClass::Dir(Box::new(direction))
|
NonTSPseudoClass::Dir(
|
||||||
|
Box::new(Direction::parse(parser)?)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
"-moz-any" => {
|
"-moz-any" => {
|
||||||
NonTSPseudoClass::MozAny(
|
NonTSPseudoClass::MozAny(
|
||||||
|
@ -496,13 +479,6 @@ impl SelectorImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn utf16_to_ascii_lowercase(unit: u16) -> u16 {
|
|
||||||
match unit {
|
|
||||||
65...90 => unit + 32, // A-Z => a-z
|
|
||||||
_ => unit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl HasFFI for SelectorList<SelectorImpl> {
|
unsafe impl HasFFI for SelectorList<SelectorImpl> {
|
||||||
type FFIType = RawServoSelectorList;
|
type FFIType = RawServoSelectorList;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ use gecko_bindings::bindings::Gecko_GetUnvisitedLinkAttrDeclarationBlock;
|
||||||
use gecko_bindings::bindings::Gecko_GetVisitedLinkAttrDeclarationBlock;
|
use gecko_bindings::bindings::Gecko_GetVisitedLinkAttrDeclarationBlock;
|
||||||
use gecko_bindings::bindings::Gecko_IsSignificantChild;
|
use gecko_bindings::bindings::Gecko_IsSignificantChild;
|
||||||
use gecko_bindings::bindings::Gecko_MatchLang;
|
use gecko_bindings::bindings::Gecko_MatchLang;
|
||||||
use gecko_bindings::bindings::Gecko_MatchStringArgPseudo;
|
|
||||||
use gecko_bindings::bindings::Gecko_UnsetDirtyStyleAttr;
|
use gecko_bindings::bindings::Gecko_UnsetDirtyStyleAttr;
|
||||||
use gecko_bindings::bindings::Gecko_UpdateAnimations;
|
use gecko_bindings::bindings::Gecko_UpdateAnimations;
|
||||||
use gecko_bindings::structs;
|
use gecko_bindings::structs;
|
||||||
|
@ -2111,7 +2110,8 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
self.get_document_theme() == DocumentTheme::Doc_Theme_Dark
|
self.get_document_theme() == DocumentTheme::Doc_Theme_Dark
|
||||||
}
|
}
|
||||||
NonTSPseudoClass::MozWindowInactive => {
|
NonTSPseudoClass::MozWindowInactive => {
|
||||||
self.document_state().contains(DocumentState::NS_DOCUMENT_STATE_WINDOW_INACTIVE)
|
self.document_state()
|
||||||
|
.contains(DocumentState::NS_DOCUMENT_STATE_WINDOW_INACTIVE)
|
||||||
}
|
}
|
||||||
NonTSPseudoClass::MozPlaceholder => false,
|
NonTSPseudoClass::MozPlaceholder => false,
|
||||||
NonTSPseudoClass::MozAny(ref sels) => {
|
NonTSPseudoClass::MozAny(ref sels) => {
|
||||||
|
@ -2125,13 +2125,15 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
NonTSPseudoClass::Lang(ref lang_arg) => {
|
NonTSPseudoClass::Lang(ref lang_arg) => {
|
||||||
self.match_element_lang(None, lang_arg)
|
self.match_element_lang(None, lang_arg)
|
||||||
}
|
}
|
||||||
NonTSPseudoClass::MozLocaleDir(ref s) => {
|
NonTSPseudoClass::MozLocaleDir(ref dir) => {
|
||||||
unsafe {
|
let doc_is_rtl =
|
||||||
Gecko_MatchStringArgPseudo(
|
self.document_state()
|
||||||
self.0,
|
.contains(DocumentState::NS_DOCUMENT_STATE_RTL_LOCALE);
|
||||||
pseudo_class.to_gecko_pseudoclasstype().unwrap(),
|
|
||||||
s.as_ptr(),
|
match **dir {
|
||||||
)
|
Direction::Ltr => !doc_is_rtl,
|
||||||
|
Direction::Rtl => doc_is_rtl,
|
||||||
|
Direction::Other(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NonTSPseudoClass::Dir(ref dir) => {
|
NonTSPseudoClass::Dir(ref dir) => {
|
||||||
|
|
|
@ -183,9 +183,23 @@ pub enum Direction {
|
||||||
/// right-to-left semantic directionality
|
/// right-to-left semantic directionality
|
||||||
Rtl,
|
Rtl,
|
||||||
/// Some other provided directionality value
|
/// Some other provided directionality value
|
||||||
|
///
|
||||||
|
/// TODO(emilio): If we atomize we can then unbox in NonTSPseudoClass.
|
||||||
Other(Box<str>),
|
Other(Box<str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Direction {
|
||||||
|
/// Parse a direction value.
|
||||||
|
pub fn parse<'i, 't>(parser: &mut CssParser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||||
|
let ident = parser.expect_ident()?;
|
||||||
|
Ok(match_ignore_ascii_case! { &ident,
|
||||||
|
"rtl" => Direction::Rtl,
|
||||||
|
"ltr" => Direction::Ltr,
|
||||||
|
_ => Direction::Other(Box::from(ident.as_ref())),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToCss for Direction {
|
impl ToCss for Direction {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: Write {
|
||||||
let dir_str = match *self {
|
let dir_str = match *self {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue