mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
stylo: Add parsing support for functional non-ts pseudoclasses, add stub -moz-system-metric pseudo
MozReview-Commit-ID: KADDH6adZqR
This commit is contained in:
parent
261a51a13a
commit
b37f991cb8
3 changed files with 79 additions and 32 deletions
|
@ -11,18 +11,18 @@
|
||||||
*
|
*
|
||||||
* Expected usage is as follows:
|
* Expected usage is as follows:
|
||||||
* ```
|
* ```
|
||||||
* fn use_pseudo_class() {
|
* macro_rules! pseudo_class_macro{
|
||||||
* macro_rules! use_pseudo_class_list {
|
* (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),
|
* // do stuff
|
||||||
* )* ) => {
|
|
||||||
* // Do stuff.
|
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* apply_non_ts_list!(use_pseudo_class_list)
|
* apply_non_ts_list!(pseudo_class_macro)
|
||||||
* }
|
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
* The string variables will be applied to pseudoclasses that are of the form
|
||||||
|
* of a function with a string argument.
|
||||||
|
*
|
||||||
* $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.
|
* $state can be either "_" or an expression of type ElementState.
|
||||||
* $flags can be either "_" or an expression of type NonTSPseudoClassFlag,
|
* $flags can be either "_" or an expression of type NonTSPseudoClassFlag,
|
||||||
|
@ -32,6 +32,7 @@
|
||||||
macro_rules! apply_non_ts_list {
|
macro_rules! apply_non_ts_list {
|
||||||
($apply_macro:ident) => {
|
($apply_macro:ident) => {
|
||||||
$apply_macro! {
|
$apply_macro! {
|
||||||
|
bare: [
|
||||||
("any-link", AnyLink, anyLink, _, _),
|
("any-link", AnyLink, anyLink, _, _),
|
||||||
("link", Link, link, _, _),
|
("link", Link, link, _, _),
|
||||||
("visited", Visited, visited, _, _),
|
("visited", Visited, visited, _, _),
|
||||||
|
@ -48,6 +49,10 @@ macro_rules! apply_non_ts_list {
|
||||||
|
|
||||||
("-moz-browser-frame", MozBrowserFrame, mozBrowserFrame, _, PSEUDO_CLASS_INTERNAL),
|
("-moz-browser-frame", MozBrowserFrame, mozBrowserFrame, _, PSEUDO_CLASS_INTERNAL),
|
||||||
("-moz-table-border-nonzero", MozTableBorderNonzero, mozTableBorderNonzero, _, PSEUDO_CLASS_INTERNAL),
|
("-moz-table-border-nonzero", MozTableBorderNonzero, mozTableBorderNonzero, _, PSEUDO_CLASS_INTERNAL),
|
||||||
|
],
|
||||||
|
string: [
|
||||||
|
("-moz-system-metric", MozSystemMetric, mozSystemMetric, _, PSEUDO_CLASS_INTERNAL),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! Gecko-specific bits for selector-parsing.
|
//! Gecko-specific bits for selector-parsing.
|
||||||
|
|
||||||
use cssparser::ToCss;
|
use cssparser::{Parser, ToCss};
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use gecko_bindings::structs::CSSPseudoClassType;
|
use gecko_bindings::structs::CSSPseudoClassType;
|
||||||
use gecko_bindings::structs::nsIAtom;
|
use gecko_bindings::structs::nsIAtom;
|
||||||
|
@ -139,7 +139,8 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! pseudo_class_name {
|
macro_rules! pseudo_class_name {
|
||||||
($(($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),)*]) => {
|
||||||
#[doc = "Our representation of a non tree-structural pseudo-class."]
|
#[doc = "Our representation of a non tree-structural pseudo-class."]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum NonTSPseudoClass {
|
pub enum NonTSPseudoClass {
|
||||||
|
@ -147,6 +148,10 @@ macro_rules! pseudo_class_name {
|
||||||
#[doc = $css]
|
#[doc = $css]
|
||||||
$name,
|
$name,
|
||||||
)*
|
)*
|
||||||
|
$(
|
||||||
|
#[doc = $s_css]
|
||||||
|
$s_name(Box<str>),
|
||||||
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,13 +160,18 @@ apply_non_ts_list!(pseudo_class_name);
|
||||||
impl ToCss for NonTSPseudoClass {
|
impl ToCss for NonTSPseudoClass {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
macro_rules! pseudo_class_serialize {
|
macro_rules! pseudo_class_serialize {
|
||||||
($(($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),)*]) => {
|
||||||
match *self {
|
match *self {
|
||||||
$(NonTSPseudoClass::$name => concat!(":", $css),)*
|
$(NonTSPseudoClass::$name => concat!(":", $css),)*
|
||||||
|
$(NonTSPseudoClass::$s_name(ref s) => {
|
||||||
|
return dest.write_str(&format!(":{}({})", $s_css, s))
|
||||||
|
}, )*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dest.write_str(apply_non_ts_list!(pseudo_class_serialize))
|
let ser = apply_non_ts_list!(pseudo_class_serialize);
|
||||||
|
dest.write_str(ser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,9 +184,11 @@ impl NonTSPseudoClass {
|
||||||
($flags:expr) => ($flags.contains(PSEUDO_CLASS_INTERNAL));
|
($flags:expr) => ($flags.contains(PSEUDO_CLASS_INTERNAL));
|
||||||
}
|
}
|
||||||
macro_rules! pseudo_class_check_internal {
|
macro_rules! pseudo_class_check_internal {
|
||||||
($(($_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),)*]) => {
|
||||||
match *self {
|
match *self {
|
||||||
$(NonTSPseudoClass::$name => check_flag!($flags),)*
|
$(NonTSPseudoClass::$name => check_flag!($flags),)*
|
||||||
|
$(NonTSPseudoClass::$s_name(..) => check_flag!($s_flags),)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,9 +202,11 @@ impl NonTSPseudoClass {
|
||||||
($state:ident) => (::element_state::$state);
|
($state:ident) => (::element_state::$state);
|
||||||
}
|
}
|
||||||
macro_rules! pseudo_class_state {
|
macro_rules! pseudo_class_state {
|
||||||
($(($_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),)*]) => {
|
||||||
match *self {
|
match *self {
|
||||||
$(NonTSPseudoClass::$name => flag!($state),)*
|
$(NonTSPseudoClass::$name => flag!($state),)*
|
||||||
|
$(NonTSPseudoClass::$s_name(..) => flag!($s_state),)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,9 +221,11 @@ impl NonTSPseudoClass {
|
||||||
(Some(::gecko_bindings::structs::CSSPseudoClassType::$gecko_type));
|
(Some(::gecko_bindings::structs::CSSPseudoClassType::$gecko_type));
|
||||||
}
|
}
|
||||||
macro_rules! pseudo_class_geckotype {
|
macro_rules! pseudo_class_geckotype {
|
||||||
($(($_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),)*]) => {
|
||||||
match *self {
|
match *self {
|
||||||
$(NonTSPseudoClass::$name => gecko_type!($gecko_type),)*
|
$(NonTSPseudoClass::$name => gecko_type!($gecko_type),)*
|
||||||
|
$(NonTSPseudoClass::$s_name(..) => gecko_type!($s_gecko_type),)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +265,8 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> {
|
||||||
|
|
||||||
fn parse_non_ts_pseudo_class(&self, name: Cow<str>) -> Result<NonTSPseudoClass, ()> {
|
fn parse_non_ts_pseudo_class(&self, name: Cow<str>) -> Result<NonTSPseudoClass, ()> {
|
||||||
macro_rules! pseudo_class_parse {
|
macro_rules! pseudo_class_parse {
|
||||||
($(($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),)*]) => {
|
||||||
match_ignore_ascii_case! { &name,
|
match_ignore_ascii_case! { &name,
|
||||||
$($css => NonTSPseudoClass::$name,)*
|
$($css => NonTSPseudoClass::$name,)*
|
||||||
_ => return Err(())
|
_ => return Err(())
|
||||||
|
@ -264,6 +281,30 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_non_ts_functional_pseudo_class(&self,
|
||||||
|
name: Cow<str>,
|
||||||
|
parser: &mut Parser)
|
||||||
|
-> Result<NonTSPseudoClass, ()> {
|
||||||
|
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 name = String::from(parser.expect_ident_or_string()?).into_boxed_str();
|
||||||
|
NonTSPseudoClass::$s_name(name)
|
||||||
|
}, )*
|
||||||
|
_ => return Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let pseudo_class = apply_non_ts_list!(pseudo_class_string_parse);
|
||||||
|
if !pseudo_class.is_internal() || self.in_user_agent_stylesheet() {
|
||||||
|
Ok(pseudo_class)
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_pseudo_element(&self, name: Cow<str>) -> Result<PseudoElement, ()> {
|
fn parse_pseudo_element(&self, name: Cow<str>) -> Result<PseudoElement, ()> {
|
||||||
match PseudoElement::from_slice(&name, self.in_user_agent_stylesheet()) {
|
match PseudoElement::from_slice(&name, self.in_user_agent_stylesheet()) {
|
||||||
Some(pseudo) => Ok(pseudo),
|
Some(pseudo) => Ok(pseudo),
|
||||||
|
|
|
@ -661,7 +661,8 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
NonTSPseudoClass::MozTableBorderNonzero |
|
NonTSPseudoClass::MozTableBorderNonzero |
|
||||||
NonTSPseudoClass::MozBrowserFrame => unsafe {
|
NonTSPseudoClass::MozBrowserFrame => unsafe {
|
||||||
Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0)
|
Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0)
|
||||||
}
|
},
|
||||||
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue