aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-03-16 00:01:19 -0700
committerGitHub <noreply@github.com>2017-03-16 00:01:19 -0700
commit78c8edfb0a0556b3a579214c42b5bae37f0d73fd (patch)
tree7326f655798873efa679cd5a0f08c2f8d32d4922
parent261a51a13a4a7742a7362534ae92023dfe38e630 (diff)
parentb37f991cb86aa969e87e16a8d3639ab930a43cb2 (diff)
downloadservo-78c8edfb0a0556b3a579214c42b5bae37f0d73fd.tar.gz
servo-78c8edfb0a0556b3a579214c42b5bae37f0d73fd.zip
Auto merge of #15976 - Manishearth:stylo-stub-system-metric, r=heycam
stylo: Add parsing support for functional non-ts pseudoclasses, add stub -moz-system-metric pseudo r=heycam from https://bugzilla.mozilla.org/show_bug.cgi?id=1341086 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15976) <!-- Reviewable:end -->
-rw-r--r--components/style/gecko/non_ts_pseudo_class_list.rs51
-rw-r--r--components/style/gecko/selector_parser.rs57
-rw-r--r--components/style/gecko/wrapper.rs3
3 files changed, 79 insertions, 32 deletions
diff --git a/components/style/gecko/non_ts_pseudo_class_list.rs b/components/style/gecko/non_ts_pseudo_class_list.rs
index ef0ec883d3d..0fc580cdc08 100644
--- a/components/style/gecko/non_ts_pseudo_class_list.rs
+++ b/components/style/gecko/non_ts_pseudo_class_list.rs
@@ -11,18 +11,18 @@
*
* Expected usage is as follows:
* ```
- * fn use_pseudo_class() {
- * macro_rules! use_pseudo_class_list {
- * ( $(
- * ($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),
- * )* ) => {
- * // Do stuff.
- * }
+ * 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),)*]) => {
+ * // 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.
* $state can be either "_" or an expression of type ElementState.
* $flags can be either "_" or an expression of type NonTSPseudoClassFlag,
@@ -32,22 +32,27 @@
macro_rules! apply_non_ts_list {
($apply_macro:ident) => {
$apply_macro! {
- ("any-link", AnyLink, anyLink, _, _),
- ("link", Link, link, _, _),
- ("visited", Visited, visited, _, _),
- ("active", Active, active, IN_ACTIVE_STATE, _),
- ("focus", Focus, focus, IN_FOCUS_STATE, _),
- ("fullscreen", Fullscreen, fullscreen, IN_FULLSCREEN_STATE, _),
- ("hover", Hover, hover, IN_HOVER_STATE, _),
- ("enabled", Enabled, enabled, IN_ENABLED_STATE, _),
- ("disabled", Disabled, disabled, IN_DISABLED_STATE, _),
- ("checked", Checked, checked, IN_CHECKED_STATE, _),
- ("indeterminate", Indeterminate, indeterminate, IN_INDETERMINATE_STATE, _),
- ("read-write", ReadWrite, _, IN_READ_WRITE_STATE, _),
- ("read-only", ReadOnly, _, IN_READ_WRITE_STATE, _),
+ bare: [
+ ("any-link", AnyLink, anyLink, _, _),
+ ("link", Link, link, _, _),
+ ("visited", Visited, visited, _, _),
+ ("active", Active, active, IN_ACTIVE_STATE, _),
+ ("focus", Focus, focus, IN_FOCUS_STATE, _),
+ ("fullscreen", Fullscreen, fullscreen, IN_FULLSCREEN_STATE, _),
+ ("hover", Hover, hover, IN_HOVER_STATE, _),
+ ("enabled", Enabled, enabled, IN_ENABLED_STATE, _),
+ ("disabled", Disabled, disabled, IN_DISABLED_STATE, _),
+ ("checked", Checked, checked, IN_CHECKED_STATE, _),
+ ("indeterminate", Indeterminate, indeterminate, IN_INDETERMINATE_STATE, _),
+ ("read-write", ReadWrite, _, IN_READ_WRITE_STATE, _),
+ ("read-only", ReadOnly, _, IN_READ_WRITE_STATE, _),
- ("-moz-browser-frame", MozBrowserFrame, mozBrowserFrame, _, PSEUDO_CLASS_INTERNAL),
- ("-moz-table-border-nonzero", MozTableBorderNonzero, mozTableBorderNonzero, _, PSEUDO_CLASS_INTERNAL),
+ ("-moz-browser-frame", MozBrowserFrame, mozBrowserFrame, _, PSEUDO_CLASS_INTERNAL),
+ ("-moz-table-border-nonzero", MozTableBorderNonzero, mozTableBorderNonzero, _, PSEUDO_CLASS_INTERNAL),
+ ],
+ string: [
+ ("-moz-system-metric", MozSystemMetric, mozSystemMetric, _, PSEUDO_CLASS_INTERNAL),
+ ]
}
}
}
diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs
index efed114f657..d465b7fa791 100644
--- a/components/style/gecko/selector_parser.rs
+++ b/components/style/gecko/selector_parser.rs
@@ -4,7 +4,7 @@
//! Gecko-specific bits for selector-parsing.
-use cssparser::ToCss;
+use cssparser::{Parser, ToCss};
use element_state::ElementState;
use gecko_bindings::structs::CSSPseudoClassType;
use gecko_bindings::structs::nsIAtom;
@@ -139,7 +139,8 @@ bitflags! {
}
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."]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum NonTSPseudoClass {
@@ -147,6 +148,10 @@ macro_rules! pseudo_class_name {
#[doc = $css]
$name,
)*
+ $(
+ #[doc = $s_css]
+ $s_name(Box<str>),
+ )*
}
}
}
@@ -155,13 +160,18 @@ apply_non_ts_list!(pseudo_class_name);
impl ToCss for NonTSPseudoClass {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
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 {
$(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));
}
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 {
$(NonTSPseudoClass::$name => check_flag!($flags),)*
+ $(NonTSPseudoClass::$s_name(..) => check_flag!($s_flags),)*
}
}
}
@@ -190,9 +202,11 @@ impl NonTSPseudoClass {
($state:ident) => (::element_state::$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 {
$(NonTSPseudoClass::$name => flag!($state),)*
+ $(NonTSPseudoClass::$s_name(..) => flag!($s_state),)*
}
}
}
@@ -207,9 +221,11 @@ impl NonTSPseudoClass {
(Some(::gecko_bindings::structs::CSSPseudoClassType::$gecko_type));
}
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 {
$(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, ()> {
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,
$($css => NonTSPseudoClass::$name,)*
_ => 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, ()> {
match PseudoElement::from_slice(&name, self.in_user_agent_stylesheet()) {
Some(pseudo) => Ok(pseudo),
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index 83cf8788bd4..2c1f07b28b1 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -661,7 +661,8 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
NonTSPseudoClass::MozTableBorderNonzero |
NonTSPseudoClass::MozBrowserFrame => unsafe {
Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0)
- }
+ },
+ _ => false
}
}