mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Auto merge of #15153 - upsuper:pseudo-class-list, r=emilio
Put stylo's pseudo-class into a list file r? @emilio <!-- 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/15153) <!-- Reviewable:end -->
This commit is contained in:
commit
dc8fc44238
2 changed files with 120 additions and 125 deletions
49
components/style/gecko/non_ts_pseudo_class_list.rs
Normal file
49
components/style/gecko/non_ts_pseudo_class_list.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains a helper macro includes all supported non-tree-structural
|
||||||
|
* pseudo-classes.
|
||||||
|
*
|
||||||
|
* This file is NOT INTENDED to be compiled as a standalone module.
|
||||||
|
*
|
||||||
|
* FIXME: Find a way to autogenerate this file.
|
||||||
|
*
|
||||||
|
* Expected usage is as follows:
|
||||||
|
* ```
|
||||||
|
* fn use_pseudo_class() {
|
||||||
|
* macro_rules! pseudo_class_list {
|
||||||
|
* ( $(
|
||||||
|
* ($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),
|
||||||
|
* )* ) => {
|
||||||
|
* // Do stuff.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* include!("non_ts_pseudo_class_list.rs")
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* $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,
|
||||||
|
* see selector_parser.rs for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pseudo_class_list! {
|
||||||
|
("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),
|
||||||
|
}
|
|
@ -123,63 +123,37 @@ impl ToCss for PseudoElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Our representation of a non tree-structural pseudo-class.
|
bitflags! {
|
||||||
///
|
flags NonTSPseudoClassFlag: u8 {
|
||||||
/// FIXME(emilio): Find a way to autogenerate this.
|
// See NonTSPseudoClass::is_internal()
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
const PSEUDO_CLASS_INTERNAL = 0x01,
|
||||||
pub enum NonTSPseudoClass {
|
}
|
||||||
/// :any-link
|
|
||||||
AnyLink,
|
|
||||||
/// :link
|
|
||||||
Link,
|
|
||||||
/// :visited
|
|
||||||
Visited,
|
|
||||||
/// :active
|
|
||||||
Active,
|
|
||||||
/// :focus
|
|
||||||
Focus,
|
|
||||||
/// :fullscreen
|
|
||||||
Fullscreen,
|
|
||||||
/// :hover
|
|
||||||
Hover,
|
|
||||||
/// :enabled
|
|
||||||
Enabled,
|
|
||||||
/// :disabled
|
|
||||||
Disabled,
|
|
||||||
/// :checked
|
|
||||||
Checked,
|
|
||||||
/// :indeterminate
|
|
||||||
Indeterminate,
|
|
||||||
/// :read-write
|
|
||||||
ReadWrite,
|
|
||||||
/// :read-only
|
|
||||||
ReadOnly,
|
|
||||||
|
|
||||||
// Internal pseudo-classes
|
|
||||||
/// :-moz-browser-frame
|
|
||||||
MozBrowserFrame,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! pseudo_class_list {
|
||||||
|
($(($css:expr, $name:ident, $_gecko_type:tt, $_state:tt, $_flags:tt),)*) => {
|
||||||
|
#[doc = "Our representation of a non tree-structural pseudo-class."]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub enum NonTSPseudoClass {
|
||||||
|
$(
|
||||||
|
#[doc = $css]
|
||||||
|
$name,
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
include!("non_ts_pseudo_class_list.rs");
|
||||||
|
|
||||||
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 {
|
||||||
use self::NonTSPseudoClass::*;
|
macro_rules! pseudo_class_list {
|
||||||
dest.write_str(match *self {
|
($(($css:expr, $name:ident, $_gecko_type:tt, $_state:tt, $_flags:tt),)*) => {
|
||||||
AnyLink => ":any-link",
|
match *self {
|
||||||
Link => ":link",
|
$(NonTSPseudoClass::$name => concat!(":", $css),)*
|
||||||
Visited => ":visited",
|
}
|
||||||
Active => ":active",
|
}
|
||||||
Focus => ":focus",
|
}
|
||||||
Fullscreen => ":fullscreen",
|
dest.write_str(include!("non_ts_pseudo_class_list.rs"))
|
||||||
Hover => ":hover",
|
|
||||||
Enabled => ":enabled",
|
|
||||||
Disabled => ":disabled",
|
|
||||||
Checked => ":checked",
|
|
||||||
Indeterminate => ":indeterminate",
|
|
||||||
ReadWrite => ":read-write",
|
|
||||||
ReadOnly => ":read-only",
|
|
||||||
|
|
||||||
MozBrowserFrame => ":-moz-browser-frame",
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,66 +161,51 @@ impl NonTSPseudoClass {
|
||||||
/// A pseudo-class is internal if it can only be used inside
|
/// A pseudo-class is internal if it can only be used inside
|
||||||
/// user agent style sheets.
|
/// user agent style sheets.
|
||||||
pub fn is_internal(&self) -> bool {
|
pub fn is_internal(&self) -> bool {
|
||||||
use self::NonTSPseudoClass::*;
|
macro_rules! check_flag {
|
||||||
match *self {
|
(_) => (false);
|
||||||
AnyLink |
|
($flags:expr) => ($flags.contains(PSEUDO_CLASS_INTERNAL));
|
||||||
Link |
|
|
||||||
Visited |
|
|
||||||
Active |
|
|
||||||
Focus |
|
|
||||||
Fullscreen |
|
|
||||||
Hover |
|
|
||||||
Enabled |
|
|
||||||
Disabled |
|
|
||||||
Checked |
|
|
||||||
Indeterminate |
|
|
||||||
ReadWrite |
|
|
||||||
ReadOnly => false,
|
|
||||||
MozBrowserFrame => true,
|
|
||||||
}
|
}
|
||||||
|
macro_rules! pseudo_class_list {
|
||||||
|
($(($_css:expr, $name:ident, $_gecko_type:tt, $_state:tt, $flags:tt),)*) => {
|
||||||
|
match *self {
|
||||||
|
$(NonTSPseudoClass::$name => check_flag!($flags),)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
include!("non_ts_pseudo_class_list.rs")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the state flag associated with a pseudo-class, if any.
|
/// Get the state flag associated with a pseudo-class, if any.
|
||||||
pub fn state_flag(&self) -> ElementState {
|
pub fn state_flag(&self) -> ElementState {
|
||||||
use element_state::*;
|
macro_rules! flag {
|
||||||
use self::NonTSPseudoClass::*;
|
(_) => (ElementState::empty());
|
||||||
match *self {
|
($state:ident) => (::element_state::$state);
|
||||||
Active => IN_ACTIVE_STATE,
|
|
||||||
Focus => IN_FOCUS_STATE,
|
|
||||||
Fullscreen => IN_FULLSCREEN_STATE,
|
|
||||||
Hover => IN_HOVER_STATE,
|
|
||||||
Enabled => IN_ENABLED_STATE,
|
|
||||||
Disabled => IN_DISABLED_STATE,
|
|
||||||
Checked => IN_CHECKED_STATE,
|
|
||||||
Indeterminate => IN_INDETERMINATE_STATE,
|
|
||||||
ReadOnly | ReadWrite => IN_READ_WRITE_STATE,
|
|
||||||
|
|
||||||
AnyLink |
|
|
||||||
Link |
|
|
||||||
Visited |
|
|
||||||
MozBrowserFrame => ElementState::empty(),
|
|
||||||
}
|
}
|
||||||
|
macro_rules! pseudo_class_list {
|
||||||
|
($(($_css:expr, $name:ident, $_gecko_type:tt, $state:tt, $_flags:tt),)*) => {
|
||||||
|
match *self {
|
||||||
|
$(NonTSPseudoClass::$name => flag!($state),)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
include!("non_ts_pseudo_class_list.rs")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert NonTSPseudoClass to Gecko's CSSPseudoClassType.
|
/// Convert NonTSPseudoClass to Gecko's CSSPseudoClassType.
|
||||||
pub fn to_gecko_pseudoclasstype(&self) -> Option<CSSPseudoClassType> {
|
pub fn to_gecko_pseudoclasstype(&self) -> Option<CSSPseudoClassType> {
|
||||||
use gecko_bindings::structs::CSSPseudoClassType::*;
|
macro_rules! gecko_type {
|
||||||
use self::NonTSPseudoClass::*;
|
(_) => (None);
|
||||||
Some(match *self {
|
($gecko_type:ident) =>
|
||||||
AnyLink => anyLink,
|
(Some(::gecko_bindings::structs::CSSPseudoClassType::$gecko_type));
|
||||||
Link => link,
|
}
|
||||||
Visited => visited,
|
macro_rules! pseudo_class_list {
|
||||||
Active => active,
|
($(($_css:expr, $name:ident, $gecko_type:tt, $_state:tt, $_flags:tt),)*) => {
|
||||||
Focus => focus,
|
match *self {
|
||||||
Fullscreen => fullscreen,
|
$(NonTSPseudoClass::$name => gecko_type!($gecko_type),)*
|
||||||
Hover => hover,
|
}
|
||||||
Enabled => enabled,
|
}
|
||||||
Disabled => disabled,
|
}
|
||||||
Checked => checked,
|
include!("non_ts_pseudo_class_list.rs")
|
||||||
Indeterminate => indeterminate,
|
|
||||||
MozBrowserFrame => mozBrowserFrame,
|
|
||||||
ReadWrite | ReadOnly => { return None; }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,28 +240,15 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> {
|
||||||
type Impl = SelectorImpl;
|
type Impl = SelectorImpl;
|
||||||
|
|
||||||
fn parse_non_ts_pseudo_class(&self, name: Cow<str>) -> Result<NonTSPseudoClass, ()> {
|
fn parse_non_ts_pseudo_class(&self, name: Cow<str>) -> Result<NonTSPseudoClass, ()> {
|
||||||
use self::NonTSPseudoClass::*;
|
macro_rules! pseudo_class_list {
|
||||||
let pseudo_class = match_ignore_ascii_case! { &name,
|
($(($css:expr, $name:ident, $_gecko_type:tt, $_state:tt, $_flags:tt),)*) => {
|
||||||
"any-link" => AnyLink,
|
match_ignore_ascii_case! { &name,
|
||||||
"link" => Link,
|
$($css => NonTSPseudoClass::$name,)*
|
||||||
"visited" => Visited,
|
_ => return Err(())
|
||||||
"active" => Active,
|
}
|
||||||
"focus" => Focus,
|
}
|
||||||
"fullscreen" => Fullscreen,
|
}
|
||||||
"hover" => Hover,
|
let pseudo_class = include!("non_ts_pseudo_class_list.rs");
|
||||||
"enabled" => Enabled,
|
|
||||||
"disabled" => Disabled,
|
|
||||||
"checked" => Checked,
|
|
||||||
"indeterminate" => Indeterminate,
|
|
||||||
"read-write" => ReadWrite,
|
|
||||||
"read-only" => ReadOnly,
|
|
||||||
|
|
||||||
// Internal
|
|
||||||
"-moz-browser-frame" => MozBrowserFrame,
|
|
||||||
|
|
||||||
_ => return Err(())
|
|
||||||
};
|
|
||||||
|
|
||||||
if !pseudo_class.is_internal() || self.in_user_agent_stylesheet() {
|
if !pseudo_class.is_internal() || self.in_user_agent_stylesheet() {
|
||||||
Ok(pseudo_class)
|
Ok(pseudo_class)
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue